Marina CRM
-{errors.password.message}
} +Reset your password
-Check your email
-- If an account exists for that email address, we have sent a password reset link. - Please check your inbox and spam folder. -
-{errors.email.message}
- )} -We'll email you a link
+Check your email
++ If an account exists for that email address, we have sent a password reset link. Please + check your inbox and spam folder. +
+ + Back to sign in + +{errors.email.message}
} +- Remember your password?{' '} - - Sign in - -
-+ Remember your password?{' '} + + Sign in + +
+ + )} + ); } diff --git a/src/app/(auth)/set-password/page.tsx b/src/app/(auth)/set-password/page.tsx index d16db42..4ca3fed 100644 --- a/src/app/(auth)/set-password/page.tsx +++ b/src/app/(auth)/set-password/page.tsx @@ -1,27 +1,23 @@ 'use client'; import { Suspense, useState } from 'react'; +import Link from 'next/link'; import { useRouter, useSearchParams } from 'next/navigation'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { toast } from 'sonner'; -import { CheckCircle2, Circle } from 'lucide-react'; import { cn } from '@/lib/utils'; import { Button } from '@/components/ui/button'; -import { Card, CardContent, CardHeader } from '@/components/ui/card'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; +import { BrandedAuthShell } from '@/components/shared/branded-auth-shell'; + +const MIN_LENGTH = 9; const passwordSchema = z .object({ - password: z - .string() - .min(12, 'Must be at least 12 characters') - .regex(/[A-Z]/, 'Must contain an uppercase letter') - .regex(/[a-z]/, 'Must contain a lowercase letter') - .regex(/[0-9]/, 'Must contain a number') - .regex(/[^A-Za-z0-9]/, 'Must contain a special character'), + password: z.string().min(MIN_LENGTH, `Must be at least ${MIN_LENGTH} characters`), confirmPassword: z.string().min(1, 'Please confirm your password'), }) .refine((data) => data.password === data.confirmPassword, { @@ -31,25 +27,11 @@ const passwordSchema = z type SetPasswordFormData = z.infer+ Please use the link from the email we sent you. If the link is broken, ask your + administrator for a new one. +
+ + Back to sign in + +Set your password
-- Invalid or missing token. Please request a new password reset link. -
- ) : ( -{errors.password.message}
- )} +Choose a password for your CRM account
+At least {MIN_LENGTH} characters.
+ {errors.password &&{errors.password.message}
} +{errors.confirmPassword.message}
- )} -{errors.confirmPassword.message}
)} - - -Create and manage intake form templates
-Coming in Layer 3
-- This feature will be implemented in the next phase. -
-Send and manage client communications
-Coming in Layer 3
-- This feature will be implemented in the next phase. -
+Send and manage client communications
++ Choose which notifications you receive and how. +
++
If {email} matches a portal account, we've sent a reset link. The link expires in 30 minutes.
Back to sign in- Enter your email and we'll send you a reset link. -
-+ Enter your email and we'll send you a reset link. +
+ Remember your password?{' '} + + Sign in + +
+Sign in to your account
@@ -110,6 +110,6 @@ export default function PortalLoginPage() {This portal is for existing clients only.
- + ); } diff --git a/src/app/api/auth/set-password/route.ts b/src/app/api/auth/set-password/route.ts new file mode 100644 index 0000000..09b4141 --- /dev/null +++ b/src/app/api/auth/set-password/route.ts @@ -0,0 +1,37 @@ +import { NextRequest, NextResponse } from 'next/server'; +import { z } from 'zod'; + +import { errorResponse } from '@/lib/errors'; +import { consumeCrmInvite } from '@/lib/services/crm-invite.service'; + +const bodySchema = z.object({ + token: z.string().min(1), + password: z.string().min(9), +}); + +export async function POST(req: NextRequest): PromiseLoading…
+ ) : templates.length === 0 ? ( +No form templates yet.
++ Grant this user access to residential clients and interests in addition to their + primary role. +
+{reason}
- )} + {reason &&{reason}
}{entry.clientId}
- {entry.notes && ( -{entry.notes}
- )} + {entry.notes &&{entry.notes}
}