chore: starter template
This commit is contained in:
78
apps/app/src/pages/LoginPage.tsx
Normal file
78
apps/app/src/pages/LoginPage.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
import type { FC } from 'react'
|
||||
import { Anchor } from '@pikku/mantine/core'
|
||||
import { Link, useNavigate } from '@tanstack/react-router'
|
||||
import { useMutation } from '@tanstack/react-query'
|
||||
import { m } from '@/i18n/messages'
|
||||
import { useLocale } from '@/i18n/config'
|
||||
import { AuthCard, type AuthFormValues } from '@/components/AuthCard'
|
||||
import {
|
||||
DEV_LOGIN,
|
||||
INVALID_CREDENTIALS,
|
||||
devQuickLogin,
|
||||
signInWithGoogle,
|
||||
signInWithPassword,
|
||||
} from '@/lib/auth'
|
||||
|
||||
export const LoginPage: FC = () => {
|
||||
useLocale()
|
||||
const navigate = useNavigate()
|
||||
const appName = m.app__name()
|
||||
// Dev builds (sandboxes run `vite dev`) prefill the test account and expose a
|
||||
// one-click quick-login; production builds strip both (import.meta.env.DEV).
|
||||
const isDev = import.meta.env.DEV
|
||||
|
||||
const signIn = useMutation({
|
||||
mutationFn: (values: AuthFormValues) =>
|
||||
signInWithPassword(values.email, values.password, '/app'),
|
||||
onSuccess: () => navigate({ to: '/app' }),
|
||||
})
|
||||
const google = useMutation({ mutationFn: () => signInWithGoogle('/app') })
|
||||
const quick = useMutation({
|
||||
mutationFn: () => devQuickLogin(),
|
||||
onSuccess: () => navigate({ to: '/app' }),
|
||||
})
|
||||
|
||||
const error = signIn.isError
|
||||
? signIn.error instanceof Error && signIn.error.message === INVALID_CREDENTIALS
|
||||
? m.auth__login__invalid_credentials()
|
||||
: m.auth__login__error()
|
||||
: google.isError
|
||||
? m.auth__google_error()
|
||||
: quick.isError
|
||||
? m.auth__login__error()
|
||||
: null
|
||||
|
||||
return (
|
||||
<AuthCard
|
||||
appName={appName}
|
||||
title={m.auth__login__title()}
|
||||
description={m.auth__login__description({ name: appName })}
|
||||
cta={m.auth__login__cta()}
|
||||
passwordAutoComplete="current-password"
|
||||
busy={signIn.isPending}
|
||||
googleBusy={google.isPending}
|
||||
error={error}
|
||||
initialValues={isDev ? { email: DEV_LOGIN.email, password: DEV_LOGIN.password } : undefined}
|
||||
quickLogin={
|
||||
isDev
|
||||
? {
|
||||
label: m.auth__dev_quick_login(),
|
||||
hint: m.auth__dev_quick_login_hint(),
|
||||
onClick: () => quick.mutate(),
|
||||
busy: quick.isPending,
|
||||
}
|
||||
: null
|
||||
}
|
||||
onAuthSubmit={(values) => signIn.mutate(values)}
|
||||
onGoogle={() => google.mutate()}
|
||||
footer={
|
||||
<>
|
||||
{m.auth__login__footer_prompt()}{' '}
|
||||
<Anchor component={Link} to="/signup">
|
||||
{m.auth__login__footer_action()}
|
||||
</Anchor>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user