-
-
Forgot Password
-
- No worries, we'll send you reset instructions.
-
-
-
-
-
-
-
-
-
-
-
-
- Recover password
-
-
-
-
- Back to Login
-
+
+
+
+ GratiText
+
+
Forgot Password
+
+ No worries, we'll send you reset instructions.
+
+
+
+
+
+
+ (
+
+ )),
+ }}
+ errors={fields.countryCode.errors}
+ />
+
-
+
+
+ Recover password
+
+
+
+ Back to Login
+
+
)
}
diff --git a/app/routes/_app+/_auth+/login.tsx b/app/routes/_app+/_auth+/login.tsx
index 3ba21979..d6f03257 100644
--- a/app/routes/_app+/_auth+/login.tsx
+++ b/app/routes/_app+/_auth+/login.tsx
@@ -1,4 +1,9 @@
-import { getFormProps, getInputProps, useForm } from '@conform-to/react'
+import {
+ getFormProps,
+ getInputProps,
+ getSelectProps,
+ useForm,
+} from '@conform-to/react'
import { getZodConstraint, parseWithZod } from '@conform-to/zod'
import {
json,
@@ -10,22 +15,31 @@ import { Form, Link, useActionData, useSearchParams } from '@remix-run/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { z } from 'zod'
import { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'
-import { CheckboxField, ErrorList, Field } from '#app/components/forms.tsx'
+import { CheckboxField, ErrorList, Field, SelectField } from '#app/components/forms.tsx'
import { Spacer } from '#app/components/spacer.tsx'
import { StatusButton } from '#app/components/ui/status-button.tsx'
import { login, requireAnonymous } from '#app/utils/auth.server.ts'
import { checkHoneypot } from '#app/utils/honeypot.server.ts'
import { useIsPending } from '#app/utils/misc.tsx'
-import { PasswordSchema, UsernameSchema } from '#app/utils/user-validation.ts'
+import { PasswordSchema } from '#app/utils/user-validation.ts'
import { handleNewSession } from './login.server.ts'
const LoginFormSchema = z.object({
- username: UsernameSchema,
+ countryCode: z.string().min(1, 'Country code is required'),
+ phoneNumber: z.string().min(1, 'Phone number is required'),
password: PasswordSchema,
redirectTo: z.string().optional(),
remember: z.boolean().optional(),
})
+const countryCodes = [
+ { label: 'United States (+1)', value: '+1' },
+ { label: 'United Kingdom (+44)', value: '+44' },
+ { label: 'Czech Republic (+420)', value: '+420' },
+ { label: 'Canada (+1)', value: '+1' },
+ { label: 'Australia (+61)', value: '+61' },
+]
+
export async function loader({ request }: LoaderFunctionArgs) {
await requireAnonymous(request)
return json({})
@@ -40,11 +54,15 @@ export async function action({ request }: ActionFunctionArgs) {
LoginFormSchema.transform(async (data, ctx) => {
if (intent !== null) return { ...data, session: null }
- const session = await login(data)
+ const session = await login({
+ identifier: data.phoneNumber,
+ countryCode: data.countryCode,
+ password: data.password,
+ })
if (!session) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
- message: 'Invalid username or password',
+ message: 'Invalid phone number or password',
})
return z.NEVER
}
@@ -80,7 +98,10 @@ export default function LoginPage() {
const [form, fields] = useForm({
id: 'login-form',
constraint: getZodConstraint(LoginFormSchema),
- defaultValue: { redirectTo },
+ defaultValue: {
+ redirectTo,
+ countryCode: countryCodes[0]?.value ?? '+1',
+ },
lastResult: actionData?.result,
onValidate({ formData }) {
return parseWithZod(formData, { schema: LoginFormSchema })
@@ -89,92 +110,94 @@ export default function LoginPage() {
})
return (
-
-
-
-
Welcome back!
-
- Please enter your details.
-
-
-
-
-
-
-
-
- New here?
-
- Create an account
-
-
+
+
+
+ GratiText
+
+
Stay Close, Even When Apart
+
+ Please enter your account details.
+
+
+
+
+
+
+ New here?
+
+ Create an account
+
diff --git a/app/routes/_app+/_auth+/onboarding.tsx b/app/routes/_app+/_auth+/onboarding.tsx
index 45537983..ab636839 100644
--- a/app/routes/_app+/_auth+/onboarding.tsx
+++ b/app/routes/_app+/_auth+/onboarding.tsx
@@ -7,12 +7,7 @@ import {
type ActionFunctionArgs,
type MetaFunction,
} from '@remix-run/node'
-import {
- Form,
- useActionData,
- useLoaderData,
- useSearchParams,
-} from '@remix-run/react'
+import { Form, useActionData, useSearchParams } from '@remix-run/react'
import { HoneypotInputs } from 'remix-utils/honeypot/react'
import { safeRedirect } from 'remix-utils/safe-redirect'
import { z } from 'zod'
@@ -130,7 +125,6 @@ export const meta: MetaFunction = () => {
}
export default function SignupRoute() {
- const data = useLoaderData
()
const actionData = useActionData()
const isPending = useIsPending()
const [searchParams] = useSearchParams()
@@ -148,21 +142,29 @@ export default function SignupRoute() {
})
return (
-
-
-
-
Welcome aboard {data.phoneNumber}!
-
- Please enter your details.
-
-
-
-