This commit is contained in:
2026-01-12 20:37:38 -06:00
parent 7694532d53
commit 9c2d516f9d
74 changed files with 1842 additions and 1842 deletions

View File

@@ -163,9 +163,9 @@ const AcceptInvitation = () => {
const getRoleBadge = (role) => {
const config = {
superadmin: { label: 'Superadmin', className: 'bg-var(--purple-lavender) text-white' },
admin: { label: 'Admin', className: 'bg-var(--green-light) text-white' },
member: { label: 'Member', className: 'bg-var(--neutral-800) text-var(--purple-ink)' }
superadmin: { label: 'Superadmin', className: 'bg-[var(--purple-lavender)] text-white' },
admin: { label: 'Admin', className: 'bg-[var(--green-light)] text-white' },
member: { label: 'Member', className: 'bg-[var(--neutral-800)] text-[var(--purple-ink)]' }
};
const roleConfig = config[role] || { label: role, className: 'bg-gray-500 text-white' };
@@ -179,10 +179,10 @@ const AcceptInvitation = () => {
if (loading) {
return (
<div className="min-h-screen bg-gradient-to-br from-var(--lavender-700) to-white flex items-center justify-center p-4">
<Card className="w-full max-w-md p-12 bg-background rounded-2xl border border-var(--neutral-800) text-center">
<Loader2 className="h-12 w-12 text-var(--purple-lavender) mx-auto mb-4 animate-spin" />
<p className="text-lg text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<div className="min-h-screen bg-gradient-to-br from-[var(--lavender-700)] to-white flex items-center justify-center p-4">
<Card className="w-full max-w-md p-12 bg-background rounded-2xl border border-[var(--neutral-800)] text-center">
<Loader2 className="h-12 w-12 text-[var(--purple-lavender)] mx-auto mb-4 animate-spin" />
<p className="text-lg text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Verifying your invitation...
</p>
</Card>
@@ -192,18 +192,18 @@ const AcceptInvitation = () => {
if (error) {
return (
<div className="min-h-screen bg-gradient-to-br from-var(--lavender-700) to-white flex items-center justify-center p-4">
<Card className="w-full max-w-md p-12 bg-background rounded-2xl border border-var(--neutral-800) text-center">
<div className="min-h-screen bg-gradient-to-br from-[var(--lavender-700)] to-white flex items-center justify-center p-4">
<Card className="w-full max-w-md p-12 bg-background rounded-2xl border border-[var(--neutral-800)] text-center">
<XCircle className="h-16 w-16 text-red-500 mx-auto mb-6" />
<h1 className="text-2xl font-semibold text-var(--purple-ink) mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
<h1 className="text-2xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Invalid Invitation
</h1>
<p className="text-var(--purple-lavender) mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-[var(--purple-lavender)] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{error}
</p>
<Button
onClick={() => navigate('/login')}
className="rounded-xl bg-var(--purple-lavender) hover:bg-var(--purple-ink) text-white"
className="rounded-xl bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)] text-white"
>
Go to Login
</Button>
@@ -216,53 +216,53 @@ const AcceptInvitation = () => {
const redirectPath = successUser?.role === 'admin' || successUser?.role === 'superadmin' ? '/admin' : '/dashboard';
return (
<div className="min-h-screen bg-gradient-to-br from-var(--lavender-700) to-white flex items-center justify-center p-4">
<Card className="w-full max-w-2xl p-12 bg-background rounded-2xl border border-var(--neutral-800) text-center">
<div className="min-h-screen bg-gradient-to-br from-[var(--lavender-700)] to-white flex items-center justify-center p-4">
<Card className="w-full max-w-2xl p-12 bg-background rounded-2xl border border-[var(--neutral-800)] text-center">
{/* Success Animation */}
<div className="mb-8">
<div className="h-24 w-24 mx-auto rounded-full bg-gradient-to-br from-var(--green-light) to-var(--green-fern) flex items-center justify-center animate-bounce">
<div className="h-24 w-24 mx-auto rounded-full bg-gradient-to-br from-[var(--green-light)] to-[var(--green-fern)] flex items-center justify-center animate-bounce">
<CheckCircle className="h-12 w-12 text-white" />
</div>
</div>
{/* Success Message */}
<h1 className="text-4xl font-semibold text-var(--purple-ink) mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
<h1 className="text-4xl font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Welcome to LOAF! 🎉
</h1>
<p className="text-xl text-var(--purple-lavender) mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-xl text-[var(--purple-lavender)] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Your account has been created successfully.
</p>
{/* User Info Card */}
<div className="mb-8 p-6 bg-gradient-to-r from-var(--neutral-800) to-var(--lavender-700) rounded-xl">
<div className="mb-8 p-6 bg-gradient-to-r from-[var(--neutral-800)] to-[var(--lavender-700)] rounded-xl">
<div className="grid md:grid-cols-2 gap-4 text-left">
<div>
<p className="text-sm text-var(--purple-lavender) mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-sm text-[var(--purple-lavender)] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Name
</p>
<p className="font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<p className="font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
{successUser?.first_name} {successUser?.last_name}
</p>
</div>
<div>
<p className="text-sm text-var(--purple-lavender) mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-sm text-[var(--purple-lavender)] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Email
</p>
<p className="font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<p className="font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
{successUser?.email}
</p>
</div>
<div>
<p className="text-sm text-var(--purple-lavender) mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-sm text-[var(--purple-lavender)] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Role
</p>
<div>{getRoleBadge(successUser?.role)}</div>
</div>
<div>
<p className="text-sm text-var(--purple-lavender) mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-sm text-[var(--purple-lavender)] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Status
</p>
<Badge className="bg-var(--green-light) text-white px-4 py-2 rounded-full text-sm">
<Badge className="bg-[var(--green-light)] text-white px-4 py-2 rounded-full text-sm">
{successUser?.status}
</Badge>
</div>
@@ -280,7 +280,7 @@ const AcceptInvitation = () => {
{/* Manual Continue Button */}
<Button
onClick={() => navigate(redirectPath)}
className="w-full h-14 rounded-xl bg-gradient-to-r from-var(--green-light) to-var(--green-fern) hover:from-var(--green-fern) hover:to-var(--green-sage] text-white text-lg font-semibold"
className="w-full h-14 rounded-xl bg-gradient-to-r from-[var(--green-light)] to-[var(--green-fern)] hover:from-[var(--green-fern)] hover:to-[var(--green-sage)] text-white text-lg font-semibold"
>
Continue to Dashboard
</Button>
@@ -290,46 +290,46 @@ const AcceptInvitation = () => {
}
return (
<div className="min-h-screen bg-gradient-to-br from-var(--lavender-700) to-white flex items-center justify-center p-4">
<Card className="w-full max-w-3xl p-8 md:p-12 bg-background rounded-2xl border border-var(--neutral-800)">
<div className="min-h-screen bg-gradient-to-br from-[var(--lavender-700)] to-white flex items-center justify-center p-4">
<Card className="w-full max-w-3xl p-8 md:p-12 bg-background rounded-2xl border border-[var(--neutral-800)]">
{/* Header */}
<div className="text-center mb-8">
<div className="flex justify-center mb-4">
<div className="h-16 w-16 rounded-full bg-gradient-to-br from-var(--purple-lavender) to-var(--purple-ink) flex items-center justify-center">
<div className="h-16 w-16 rounded-full bg-gradient-to-br from-[var(--purple-lavender)] to-[var(--purple-ink)] flex items-center justify-center">
<Mail className="h-8 w-8 text-white" />
</div>
</div>
<h1 className="text-3xl md:text-4xl font-semibold text-var(--purple-ink) mb-3" style={{ fontFamily: "'Inter', sans-serif" }}>
<h1 className="text-3xl md:text-4xl font-semibold text-[var(--purple-ink)] mb-3" style={{ fontFamily: "'Inter', sans-serif" }}>
Welcome to LOAF!
</h1>
<p className="text-lg text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-lg text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Complete your profile to accept the invitation
</p>
</div>
{/* Invitation Details */}
<div className="mb-8 p-6 bg-gradient-to-r from-var(--neutral-800) to-var(--lavender-700) rounded-xl">
<div className="mb-8 p-6 bg-gradient-to-r from-[var(--neutral-800)] to-[var(--lavender-700)] rounded-xl">
<div className="grid md:grid-cols-2 gap-4 text-sm">
<div>
<p className="text-var(--purple-lavender) mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-[var(--purple-lavender)] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Email Address
</p>
<p className="font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<p className="font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
{invitation?.email}
</p>
</div>
<div>
<p className="text-var(--purple-lavender) mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-[var(--purple-lavender)] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Role
</p>
<div>{getRoleBadge(invitation?.role)}</div>
</div>
<div className="md:col-span-2">
<p className="text-var(--purple-lavender) mb-1 flex items-center gap-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-[var(--purple-lavender)] mb-1 flex items-center gap-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<Calendar className="h-4 w-4" />
Invitation Expires
</p>
<p className="font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<p className="font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
{invitation?.expires_at ? new Date(invitation.expires_at).toLocaleString() : 'N/A'}
</p>
</div>
@@ -342,7 +342,7 @@ const AcceptInvitation = () => {
{/* Password Fields */}
<div className="grid md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="password" className="text-var(--purple-ink)">
<Label htmlFor="password" className="text-[var(--purple-ink)]">
Password <span className="text-red-500">*</span>
</Label>
<Input
@@ -350,7 +350,7 @@ const AcceptInvitation = () => {
type="password"
value={formData.password}
onChange={(e) => handleChange('password', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="Minimum 8 characters"
/>
{formErrors.password && (
@@ -359,7 +359,7 @@ const AcceptInvitation = () => {
</div>
<div className="grid gap-2">
<Label htmlFor="confirmPassword" className="text-var(--purple-ink)">
<Label htmlFor="confirmPassword" className="text-[var(--purple-ink)]">
Confirm Password <span className="text-red-500">*</span>
</Label>
<Input
@@ -367,7 +367,7 @@ const AcceptInvitation = () => {
type="password"
value={formData.confirmPassword}
onChange={(e) => handleChange('confirmPassword', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="Re-enter password"
/>
{formErrors.confirmPassword && (
@@ -379,14 +379,14 @@ const AcceptInvitation = () => {
{/* Name Fields */}
<div className="grid md:grid-cols-2 gap-4">
<div className="grid gap-2">
<Label htmlFor="first_name" className="text-var(--purple-ink)">
<Label htmlFor="first_name" className="text-[var(--purple-ink)]">
First Name <span className="text-red-500">*</span>
</Label>
<Input
id="first_name"
value={formData.first_name}
onChange={(e) => handleChange('first_name', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="John"
/>
{formErrors.first_name && (
@@ -395,14 +395,14 @@ const AcceptInvitation = () => {
</div>
<div className="grid gap-2">
<Label htmlFor="last_name" className="text-var(--purple-ink)">
<Label htmlFor="last_name" className="text-[var(--purple-ink)]">
Last Name <span className="text-red-500">*</span>
</Label>
<Input
id="last_name"
value={formData.last_name}
onChange={(e) => handleChange('last_name', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="Doe"
/>
{formErrors.last_name && (
@@ -413,7 +413,7 @@ const AcceptInvitation = () => {
{/* Phone */}
<div className="grid gap-2">
<Label htmlFor="phone" className="text-var(--purple-ink)">
<Label htmlFor="phone" className="text-[var(--purple-ink)]">
Phone <span className="text-red-500">*</span>
</Label>
<Input
@@ -421,7 +421,7 @@ const AcceptInvitation = () => {
type="tel"
value={formData.phone}
onChange={(e) => handleChange('phone', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="(555) 123-4567"
/>
{formErrors.phone && (
@@ -432,20 +432,20 @@ const AcceptInvitation = () => {
{/* Optional Fields Section */}
{invitation?.role === 'member' && (
<>
<div className="border-t border-var(--neutral-800) pt-6 mt-2">
<h3 className="text-lg font-semibold text-var(--purple-ink) mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
<div className="border-t border-[var(--neutral-800)] pt-6 mt-2">
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Additional Information (Optional)
</h3>
</div>
{/* Address */}
<div className="grid gap-2">
<Label htmlFor="address" className="text-var(--purple-ink)">Address</Label>
<Label htmlFor="address" className="text-[var(--purple-ink)]">Address</Label>
<Input
id="address"
value={formData.address}
onChange={(e) => handleChange('address', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="123 Main St"
/>
</div>
@@ -453,35 +453,35 @@ const AcceptInvitation = () => {
{/* City, State, Zipcode */}
<div className="grid md:grid-cols-3 gap-4">
<div className="grid gap-2">
<Label htmlFor="city" className="text-var(--purple-ink)">City</Label>
<Label htmlFor="city" className="text-[var(--purple-ink)]">City</Label>
<Input
id="city"
value={formData.city}
onChange={(e) => handleChange('city', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="San Francisco"
/>
</div>
<div className="grid gap-2">
<Label htmlFor="state" className="text-var(--purple-ink)">State</Label>
<Label htmlFor="state" className="text-[var(--purple-ink)]">State</Label>
<Input
id="state"
value={formData.state}
onChange={(e) => handleChange('state', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="CA"
maxLength={2}
/>
</div>
<div className="grid gap-2">
<Label htmlFor="zipcode" className="text-var(--purple-ink)">Zipcode</Label>
<Label htmlFor="zipcode" className="text-[var(--purple-ink)]">Zipcode</Label>
<Input
id="zipcode"
value={formData.zipcode}
onChange={(e) => handleChange('zipcode', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
placeholder="94102"
/>
</div>
@@ -489,13 +489,13 @@ const AcceptInvitation = () => {
{/* Date of Birth */}
<div className="grid gap-2">
<Label htmlFor="date_of_birth" className="text-var(--purple-ink)">Date of Birth</Label>
<Label htmlFor="date_of_birth" className="text-[var(--purple-ink)]">Date of Birth</Label>
<Input
id="date_of_birth"
type="date"
value={formData.date_of_birth}
onChange={(e) => handleChange('date_of_birth', e.target.value)}
className="rounded-xl border-2 border-var(--neutral-800) focus:border-var(--purple-lavender)"
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
/>
</div>
</>
@@ -507,7 +507,7 @@ const AcceptInvitation = () => {
<Button
type="submit"
disabled={submitting}
className="w-full h-14 rounded-xl bg-gradient-to-r from-var(--green-light) to-var(--green-fern) hover:from-var(--green-fern) hover:to-var(--green-sage] text-white text-lg font-semibold"
className="w-full h-14 rounded-xl bg-gradient-to-r from-[var(--green-light)] to-[var(--green-fern)] hover:from-[var(--green-fern)] hover:to-[var(--green-sage)] text-white text-lg font-semibold"
>
{submitting ? (
<>
@@ -526,11 +526,11 @@ const AcceptInvitation = () => {
{/* Footer Note */}
<div className="mt-6 text-center">
<p className="text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Already have an account?{' '}
<button
onClick={() => navigate('/login')}
className="text-var(--purple-lavender) hover:text-var(--purple-ink) font-semibold underline"
className="text-[var(--purple-lavender)] hover:text-[var(--purple-ink)] font-semibold underline"
>
Sign in instead
</button>