feat: complete Phase 3 — advanced features for Casera web app
Adds sharing (residence share codes, join, user management, .casera file export/import), subscription status with feature comparison, notification preferences with bell icon, profile settings (edit info, change password, theme picker, delete account), onboarding wizard with create/join paths, enhanced dashboard with stats cards, Recharts completion chart, recent activity feed, and task report PDF download. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Login
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const loginSchema = z.object({
|
||||
username: z.string().min(1, 'Username or email is required'),
|
||||
password: z.string().min(1, 'Password is required'),
|
||||
});
|
||||
|
||||
export type LoginFormData = z.infer<typeof loginSchema>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Register
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const registerSchema = z
|
||||
.object({
|
||||
first_name: z.string().min(1, 'First name is required').max(150),
|
||||
last_name: z.string().min(1, 'Last name is required').max(150),
|
||||
username: z
|
||||
.string()
|
||||
.min(3, 'Username must be at least 3 characters')
|
||||
.max(150),
|
||||
email: z.string().email('Invalid email address').max(254),
|
||||
password: z.string().min(8, 'Password must be at least 8 characters'),
|
||||
confirm_password: z.string(),
|
||||
})
|
||||
.refine((data) => data.password === data.confirm_password, {
|
||||
message: "Passwords don't match",
|
||||
path: ['confirm_password'],
|
||||
});
|
||||
|
||||
export type RegisterFormData = z.infer<typeof registerSchema>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Verify email
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const verifyEmailSchema = z.object({
|
||||
code: z.string().length(6, 'Code must be 6 digits'),
|
||||
});
|
||||
|
||||
export type VerifyEmailFormData = z.infer<typeof verifyEmailSchema>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Forgot password
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const forgotPasswordSchema = z.object({
|
||||
email: z.string().email('Invalid email address'),
|
||||
});
|
||||
|
||||
export type ForgotPasswordFormData = z.infer<typeof forgotPasswordSchema>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Verify reset code
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const verifyResetCodeSchema = z.object({
|
||||
email: z.string().email(),
|
||||
code: z.string().length(6, 'Code must be 6 digits'),
|
||||
});
|
||||
|
||||
export type VerifyResetCodeFormData = z.infer<typeof verifyResetCodeSchema>;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Reset password
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export const resetPasswordSchema = z
|
||||
.object({
|
||||
email: z.string().email(),
|
||||
code: z.string(),
|
||||
new_password: z.string().min(8, 'Password must be at least 8 characters'),
|
||||
confirm_password: z.string(),
|
||||
})
|
||||
.refine((data) => data.new_password === data.confirm_password, {
|
||||
message: "Passwords don't match",
|
||||
path: ['confirm_password'],
|
||||
});
|
||||
|
||||
export type ResetPasswordFormData = z.infer<typeof resetPasswordSchema>;
|
||||
Reference in New Issue
Block a user