Frontend Revamp

This commit is contained in:
Koncept Kit
2025-12-08 14:46:16 +07:00
parent 79cebd205c
commit d8c1e133ac
14 changed files with 425 additions and 351 deletions

View File

@@ -4,6 +4,12 @@
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<!-- Google Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Nunito+Sans:wght@400;600;700;800&display=swap" rel="stylesheet">
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
@@ -17,7 +23,7 @@
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>Membershi Website</title>
<title>LOAF - Lesbians Over Age Fifty</title>
<script src="#"></script>
</head>
<body>

View File

@@ -5,28 +5,28 @@
}
body {
font-family: 'DM Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', sans-serif;
background-color: #FDFCF8;
color: #3D405B;
font-family: 'Nunito Sans', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', sans-serif;
background-color: #FFFFFF;
color: #422268;
}
h1, h2, h3, h4, h5, h6 {
font-family: 'Fraunces', serif;
font-family: 'Inter', sans-serif;
font-weight: 600;
}
.fraunces {
font-family: 'Fraunces', serif;
.inter {
font-family: 'Inter', sans-serif;
}
.dm-sans {
font-family: 'DM Sans', sans-serif;
.nunito-sans {
font-family: 'Nunito Sans', sans-serif;
}
.bg-warm-gradient {
background: linear-gradient(135deg, rgba(242, 204, 143, 0.2) 0%, rgba(224, 122, 95, 0.2) 100%);
.bg-purple-gradient {
background: linear-gradient(135deg, rgba(100, 76, 159, 0.2) 0%, rgba(72, 40, 110, 0.2) 100%);
}
.bg-soft-mesh {
background: radial-gradient(ellipse at top right, rgba(242, 204, 143, 0.4) 0%, #FDFCF8 50%, #FDFCF8 100%);
background: radial-gradient(ellipse at top right, rgba(221, 216, 235, 0.4) 0%, #FFFFFF 50%, #FFFFFF 100%);
}

View File

@@ -20,29 +20,29 @@ code {
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 0 0% 3.9%;
--foreground: 280 47% 27%;
--card: 0 0% 100%;
--card-foreground: 0 0% 3.9%;
--card-foreground: 280 47% 27%;
--popover: 0 0% 100%;
--popover-foreground: 0 0% 3.9%;
--primary: 0 0% 9%;
--primary-foreground: 0 0% 98%;
--secondary: 0 0% 96.1%;
--secondary-foreground: 0 0% 9%;
--muted: 0 0% 96.1%;
--muted-foreground: 0 0% 45.1%;
--accent: 0 0% 96.1%;
--accent-foreground: 0 0% 9%;
--popover-foreground: 280 47% 27%;
--primary: 280 47% 27%;
--primary-foreground: 0 0% 100%;
--secondary: 268 33% 89%;
--secondary-foreground: 280 47% 27%;
--muted: 268 43% 95%;
--muted-foreground: 268 35% 47%;
--accent: 17 100% 73%;
--accent-foreground: 280 47% 27%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 0 0% 89.8%;
--input: 0 0% 89.8%;
--ring: 0 0% 3.9%;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
--border: 268 33% 89%;
--input: 268 33% 89%;
--ring: 268 35% 47%;
--chart-1: 268 36% 46%;
--chart-2: 17 100% 73%;
--chart-3: 268 33% 89%;
--chart-4: 280 44% 29%;
--chart-5: 268 35% 47%;
--radius: 0.5rem;
}
.dark {

View File

@@ -83,19 +83,19 @@ const ChangePasswordRequired = () => {
}
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-md mx-auto px-6 py-12">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg">
<div className="mb-8 text-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#FFEBEE] mb-4">
<AlertTriangle className="h-8 w-8 text-[#E07A5F]" />
<AlertTriangle className="h-8 w-8 text-orange-500" />
</div>
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Password Change Required
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Your password was reset by an administrator. Please create a new password to continue.
</p>
</div>
@@ -111,7 +111,7 @@ const ChangePasswordRequired = () => {
value={formData.currentPassword}
onChange={handleInputChange}
placeholder="Enter temporary password"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
/>
</div>
@@ -125,7 +125,7 @@ const ChangePasswordRequired = () => {
value={formData.newPassword}
onChange={handleInputChange}
placeholder="Enter new password (min. 6 characters)"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
/>
</div>
@@ -139,15 +139,15 @@ const ChangePasswordRequired = () => {
value={formData.confirmPassword}
onChange={handleInputChange}
placeholder="Re-enter new password"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
/>
</div>
<div className="bg-[#FFF3E0] border-l-4 border-[#E07A5F] p-4 rounded-lg">
<div className="bg-[#f1eef9] border-l-4 border-[#664fa3] p-4 rounded-lg">
<div className="flex items-start">
<Lock className="h-5 w-5 text-[#E07A5F] mr-2 mt-0.5 flex-shrink-0" />
<div className="text-sm text-[#6B708D]">
<p className="font-medium text-[#3D405B] mb-1">Password Requirements:</p>
<Lock className="h-5 w-5 text-[#664fa3] mr-2 mt-0.5 flex-shrink-0" />
<div className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="font-medium text-[#422268] mb-1">Password Requirements:</p>
<ul className="list-disc list-inside space-y-1">
<li>At least 6 characters long</li>
<li>Both passwords must match</li>
@@ -159,17 +159,17 @@ const ChangePasswordRequired = () => {
<Button
type="submit"
disabled={loading}
className="w-full bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
>
{loading ? 'Changing Password...' : 'Change Password'}
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
<div className="text-center pt-4 border-t border-[#EAE0D5]">
<div className="text-center pt-4 border-t border-[#ddd8eb]">
<button
type="button"
onClick={handleLogout}
className="text-[#6B708D] hover:text-[#E07A5F] text-sm underline"
className="text-[#664fa3] hover:text-[#ff9e77] text-sm underline"
>
Logout instead
</button>

View File

@@ -46,12 +46,12 @@ const Dashboard = () => {
const getStatusBadge = (status) => {
const statusConfig = {
pending_email: { icon: Clock, label: 'Pending Email', className: 'bg-[#F2CC8F] text-[#3D405B]' },
pending_approval: { icon: Clock, label: 'Pending Approval', className: 'bg-[#A3B1C6] text-white' },
pending_email: { icon: Clock, label: 'Pending Email', className: 'bg-orange-100 text-orange-700' },
pending_approval: { icon: Clock, label: 'Pending Approval', className: 'bg-gray-200 text-gray-700' },
pre_approved: { icon: CheckCircle, label: 'Pre-Approved', className: 'bg-[#81B29A] text-white' },
payment_pending: { icon: AlertCircle, label: 'Payment Pending', className: 'bg-[#E07A5F] text-white' },
payment_pending: { icon: AlertCircle, label: 'Payment Pending', className: 'bg-orange-500 text-white' },
active: { icon: CheckCircle, label: 'Active', className: 'bg-[#81B29A] text-white' },
inactive: { icon: AlertCircle, label: 'Inactive', className: 'bg-[#6B708D] text-white' }
inactive: { icon: AlertCircle, label: 'Inactive', className: 'bg-gray-400 text-white' }
};
const config = statusConfig[status] || statusConfig.inactive;
@@ -79,30 +79,30 @@ const Dashboard = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-7xl mx-auto px-6 py-12">
{/* Welcome Section */}
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Welcome Back, {user?.first_name}!
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Here's an overview of your membership status and upcoming events.
</p>
</div>
{/* Email Verification Alert */}
{user && !user.email_verified && (
<Card className="p-6 bg-[#FFF3E0] border-2 border-[#E07A5F] mb-8">
<Card className="p-6 bg-[#f1eef9] border-2 border-[#664fa3] mb-8">
<div className="flex items-start gap-4">
<AlertCircle className="h-6 w-6 text-[#E07A5F] flex-shrink-0 mt-1" />
<AlertCircle className="h-6 w-6 text-[#664fa3] flex-shrink-0 mt-1" />
<div className="flex-1">
<h3 className="text-lg font-semibold text-[#3D405B] mb-2">
<h3 className="text-lg font-semibold text-[#422268] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
Verify Your Email Address
</h3>
<p className="text-[#6B708D] mb-4">
<p className="text-[#664fa3] mb-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Please verify your email address to complete your registration.
Check your inbox for the verification link.
</p>
@@ -110,7 +110,7 @@ const Dashboard = () => {
onClick={handleResendVerification}
disabled={resendLoading}
variant="outline"
className="border-2 border-[#E07A5F] text-[#E07A5F] hover:bg-[#E07A5F] hover:text-white"
className="border-2 border-[#664fa3] text-[#664fa3] hover:bg-[#664fa3] hover:text-white"
>
<Mail className="h-4 w-4 mr-2" />
{resendLoading ? 'Sending...' : 'Resend Verification Email'}
@@ -121,22 +121,22 @@ const Dashboard = () => {
)}
{/* Status Card */}
<Card className="p-8 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg mb-8" data-testid="status-card">
<Card className="p-8 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg mb-8" data-testid="status-card">
<div className="flex items-start justify-between flex-wrap gap-4">
<div>
<h2 className="text-2xl font-semibold fraunces text-[#3D405B] mb-2">
<h2 className="text-2xl font-semibold text-[#422268] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
Membership Status
</h2>
<div className="mb-4">
{getStatusBadge(user?.status)}
</div>
<p className="text-[#6B708D]">
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{getStatusMessage(user?.status)}
</p>
</div>
<Link to="/profile">
<Button
className="bg-[#F2CC8F] text-[#3D405B] hover:bg-[#E5B875] rounded-full px-6"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-6"
data-testid="view-profile-button"
>
<User className="h-4 w-4 mr-2" />
@@ -149,22 +149,22 @@ const Dashboard = () => {
{/* Grid Layout */}
<div className="grid lg:grid-cols-3 gap-8">
{/* Quick Stats */}
<Card className="p-6 bg-white rounded-2xl border border-[#EAE0D5]" data-testid="quick-stats-card">
<h3 className="text-xl font-semibold fraunces text-[#3D405B] mb-4">
<Card className="p-6 bg-white rounded-2xl border border-[#ddd8eb]" data-testid="quick-stats-card">
<h3 className="text-xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Quick Info
</h3>
<div className="space-y-4">
<div>
<p className="text-sm text-[#6B708D]">Email</p>
<p className="text-[#3D405B] font-medium">{user?.email}</p>
<p className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Email</p>
<p className="text-[#422268] font-medium" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{user?.email}</p>
</div>
<div>
<p className="text-sm text-[#6B708D]">Role</p>
<p className="text-[#3D405B] font-medium capitalize">{user?.role}</p>
<p className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Role</p>
<p className="text-[#422268] font-medium capitalize" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{user?.role}</p>
</div>
<div>
<p className="text-sm text-[#6B708D]">Member Since</p>
<p className="text-[#3D405B] font-medium">
<p className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Member Since</p>
<p className="text-[#422268] font-medium" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{user?.created_at ? new Date(user.created_at).toLocaleDateString() : 'N/A'}
</p>
</div>
@@ -172,15 +172,15 @@ const Dashboard = () => {
</Card>
{/* Upcoming Events */}
<Card className="lg:col-span-2 p-6 bg-white rounded-2xl border border-[#EAE0D5]" data-testid="upcoming-events-card">
<Card className="lg:col-span-2 p-6 bg-white rounded-2xl border border-[#ddd8eb]" data-testid="upcoming-events-card">
<div className="flex justify-between items-center mb-6">
<h3 className="text-xl font-semibold fraunces text-[#3D405B]">
<h3 className="text-xl font-semibold text-[#422268]" style={{ fontFamily: "'Inter', sans-serif" }}>
Upcoming Events
</h3>
<Link to="/events">
<Button
variant="ghost"
className="text-[#E07A5F] hover:text-[#D0694E]"
className="text-[#ff9e77] hover:text-[#664fa3]"
data-testid="view-all-events-button"
>
View All
@@ -189,26 +189,26 @@ const Dashboard = () => {
</div>
{loading ? (
<p className="text-[#6B708D]">Loading events...</p>
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Loading events...</p>
) : events.length > 0 ? (
<div className="space-y-4">
{events.map((event) => (
<Link to={`/events/${event.id}`} key={event.id}>
<div
className="p-4 border border-[#EAE0D5] rounded-xl hover:border-[#E07A5F] hover:shadow-md transition-all cursor-pointer"
className="p-4 border border-[#ddd8eb] rounded-xl hover:border-[#664fa3] hover:shadow-md transition-all cursor-pointer"
data-testid={`event-card-${event.id}`}
>
<div className="flex items-start gap-4">
<div className="bg-[#F2CC8F]/20 p-3 rounded-lg">
<Calendar className="h-6 w-6 text-[#E07A5F]" />
<div className="bg-[#DDD8EB]/20 p-3 rounded-lg">
<Calendar className="h-6 w-6 text-[#664fa3]" />
</div>
<div className="flex-1">
<h4 className="font-semibold text-[#3D405B] mb-1">{event.title}</h4>
<p className="text-sm text-[#6B708D] mb-2">
<h4 className="font-semibold text-[#422268] mb-1" style={{ fontFamily: "'Inter', sans-serif" }}>{event.title}</h4>
<p className="text-sm text-[#664fa3] mb-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{new Date(event.start_at).toLocaleDateString()} at{' '}
{new Date(event.start_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
</p>
<p className="text-sm text-[#6B708D]">{event.location}</p>
<p className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{event.location}</p>
</div>
</div>
</div>
@@ -217,9 +217,9 @@ const Dashboard = () => {
</div>
) : (
<div className="text-center py-12">
<Calendar className="h-16 w-16 text-[#EAE0D5] mx-auto mb-4" />
<p className="text-[#6B708D] mb-4">No upcoming events at the moment.</p>
<p className="text-sm text-[#6B708D]">Check back later for new events!</p>
<Calendar className="h-16 w-16 text-[#ddd8eb] mx-auto mb-4" />
<p className="text-[#664fa3] mb-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>No upcoming events at the moment.</p>
<p className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Check back later for new events!</p>
</div>
)}
</Card>
@@ -227,12 +227,12 @@ const Dashboard = () => {
{/* CTA Section */}
{user?.status === 'pending_approval' && (
<Card className="mt-8 p-8 bg-gradient-to-br from-[#F2CC8F]/20 to-[#E07A5F]/20 rounded-2xl border border-[#EAE0D5]">
<Card className="mt-8 p-8 bg-gradient-to-br from-[#DDD8EB]/20 to-[#f1eef9]/20 rounded-2xl border border-[#ddd8eb]">
<div className="text-center">
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
<h3 className="text-2xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Application Under Review
</h3>
<p className="text-[#6B708D] mb-6">
<p className="text-[#664fa3] mb-6" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Your membership application is being reviewed by our admin team. You'll be notified once approved!
</p>
</div>
@@ -241,20 +241,20 @@ const Dashboard = () => {
{/* Payment Prompt for payment_pending status */}
{user?.status === 'payment_pending' && (
<Card className="mt-8 p-8 bg-gradient-to-br from-[#E07A5F]/20 to-[#F2CC8F]/20 rounded-2xl border-2 border-[#E07A5F]">
<Card className="mt-8 p-8 bg-gradient-to-br from-[#DDD8EB]/20 to-[#f1eef9]/20 rounded-2xl border-2 border-[#664fa3]">
<div className="text-center">
<div className="mb-4">
<AlertCircle className="h-16 w-16 text-[#E07A5F] mx-auto" />
<AlertCircle className="h-16 w-16 text-[#664fa3] mx-auto" />
</div>
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
<h3 className="text-2xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Complete Your Payment
</h3>
<p className="text-[#6B708D] mb-6">
<p className="text-[#664fa3] mb-6" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Great news! Your membership application has been approved. Complete your payment to activate your membership and gain full access to all member benefits.
</p>
<Link to="/plans">
<Button
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-8 py-6 text-lg font-semibold"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-8 py-6 text-lg font-semibold"
data-testid="complete-payment-cta"
>
<CheckCircle className="mr-2 h-5 w-5" />

View File

@@ -30,8 +30,8 @@ const Events = () => {
const config = {
yes: { label: 'Going', className: 'bg-[#81B29A] text-white' },
no: { label: 'Not Going', className: 'bg-[#6B708D] text-white' },
maybe: { label: 'Maybe', className: 'bg-[#F2CC8F] text-[#3D405B]' }
no: { label: 'Not Going', className: 'bg-gray-400 text-white' },
maybe: { label: 'Maybe', className: 'bg-orange-100 text-orange-700' }
};
const rsvpConfig = config[rsvpStatus];
@@ -45,67 +45,67 @@ const Events = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-7xl mx-auto px-6 py-12">
<div className="mb-12">
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Upcoming Events
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Browse and RSVP to our community events.
</p>
</div>
{loading ? (
<div className="text-center py-20">
<p className="text-[#6B708D]">Loading events...</p>
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Loading events...</p>
</div>
) : events.length > 0 ? (
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{events.map((event) => (
<Link to={`/events/${event.id}`} key={event.id}>
<Card
className="p-6 bg-white rounded-2xl border border-[#EAE0D5] hover:shadow-lg hover:-translate-y-1 transition-all cursor-pointer h-full"
className="p-6 bg-white rounded-2xl border border-[#ddd8eb] hover:shadow-lg hover:-translate-y-1 transition-all cursor-pointer h-full"
data-testid={`event-card-${event.id}`}
>
<div className="flex justify-between items-start mb-4">
<div className="bg-[#F2CC8F]/20 p-3 rounded-lg">
<Calendar className="h-6 w-6 text-[#E07A5F]" />
<div className="bg-[#DDD8EB]/20 p-3 rounded-lg">
<Calendar className="h-6 w-6 text-[#664fa3]" />
</div>
{getRSVPBadge(event.user_rsvp_status)}
</div>
<h3 className="text-xl font-semibold fraunces text-[#3D405B] mb-3">
<h3 className="text-xl font-semibold text-[#422268] mb-3" style={{ fontFamily: "'Inter', sans-serif" }}>
{event.title}
</h3>
{event.description && (
<p className="text-[#6B708D] mb-4 line-clamp-2">
<p className="text-[#664fa3] mb-4 line-clamp-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{event.description}
</p>
)}
<div className="space-y-2 text-sm">
<div className="flex items-center gap-2 text-[#6B708D]">
<div className="flex items-center gap-2 text-[#664fa3]">
<Calendar className="h-4 w-4" />
<span>
<span style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{new Date(event.start_at).toLocaleDateString()} at{' '}
{new Date(event.start_at).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}
</span>
</div>
<div className="flex items-center gap-2 text-[#6B708D]">
<div className="flex items-center gap-2 text-[#664fa3]">
<MapPin className="h-4 w-4" />
<span>{event.location}</span>
<span style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{event.location}</span>
</div>
<div className="flex items-center gap-2 text-[#6B708D]">
<div className="flex items-center gap-2 text-[#664fa3]">
<Users className="h-4 w-4" />
<span>{event.rsvp_count || 0} attending</span>
<span style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{event.rsvp_count || 0} attending</span>
</div>
</div>
<div className="mt-6 flex items-center text-[#E07A5F] font-medium">
<div className="mt-6 flex items-center text-[#ff9e77] font-medium">
View Details
<ArrowRight className="ml-2 h-4 w-4" />
</div>
@@ -115,11 +115,11 @@ const Events = () => {
</div>
) : (
<div className="text-center py-20">
<Calendar className="h-20 w-20 text-[#EAE0D5] mx-auto mb-6" />
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
<Calendar className="h-20 w-20 text-[#ddd8eb] mx-auto mb-6" />
<h3 className="text-2xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
No Events Available
</h3>
<p className="text-[#6B708D]">
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
There are no upcoming events at the moment. Check back later!
</p>
</div>

View File

@@ -31,28 +31,28 @@ const ForgotPassword = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-md mx-auto px-6 py-12">
<div className="mb-8">
<Link to="/login" className="inline-flex items-center text-[#6B708D] hover:text-[#E07A5F] transition-colors">
<Link to="/login" className="inline-flex items-center text-[#664fa3] hover:text-[#ff9e77] transition-colors">
<ArrowLeft className="h-4 w-4 mr-2" />
Back to Login
</Link>
</div>
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg">
{!submitted ? (
<>
<div className="mb-8 text-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#FFF3E0] mb-4">
<Mail className="h-8 w-8 text-[#E07A5F]" />
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#f1eef9] mb-4">
<Mail className="h-8 w-8 text-[#664fa3]" />
</div>
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Forgot Password?
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
No worries! Enter your email and we'll send you reset instructions.
</p>
</div>
@@ -68,22 +68,22 @@ const ForgotPassword = () => {
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="your.email@example.com"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
/>
</div>
<Button
type="submit"
disabled={loading}
className="w-full bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
>
{loading ? 'Sending...' : 'Send Reset Link'}
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
<p className="text-center text-[#6B708D]">
<p className="text-center text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Remember your password?{' '}
<Link to="/login" className="text-[#E07A5F] hover:underline font-medium">
<Link to="/login" className="text-[#ff9e77] hover:underline font-medium">
Login here
</Link>
</p>
@@ -94,18 +94,18 @@ const ForgotPassword = () => {
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#E8F5E9] mb-6">
<CheckCircle className="h-8 w-8 text-[#4CAF50]" />
</div>
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Check Your Email
</h1>
<p className="text-lg text-[#6B708D] mb-8">
If an account exists for <span className="font-medium text-[#3D405B]">{email}</span>,
<p className="text-lg text-[#664fa3] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
If an account exists for <span className="font-medium text-[#422268]">{email}</span>,
you will receive a password reset link shortly.
</p>
<p className="text-sm text-[#6B708D] mb-8">
<p className="text-sm text-[#664fa3] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
The link will expire in 1 hour. If you don't see the email, check your spam folder.
</p>
<Link to="/login">
<Button className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-8 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform">
<Button className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-8 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform">
Return to Login
<ArrowRight className="ml-2 h-5 w-5" />
</Button>

View File

@@ -2,136 +2,204 @@ import React from 'react';
import { Link } from 'react-router-dom';
import { Button } from '../components/ui/button';
import { Card } from '../components/ui/card';
import { Calendar, Users, Heart, ArrowRight } from 'lucide-react';
import Navbar from '../components/Navbar';
const Landing = () => {
// LOAF brand assets from Figma
const loafLogo = "https://www.figma.com/api/mcp/asset/5e3c057c-ffb0-4ceb-aa60-70a5ddbe10ab";
const taglineImage = "https://www.figma.com/api/mcp/asset/ce184873-0c46-45eb-8480-76a9411011bf";
const shootingStar = "https://www.figma.com/api/mcp/asset/6db528f4-493b-4560-9ff6-076bc42421ca";
const iconMeetGreet = "https://www.figma.com/api/mcp/asset/3519deee-3f78-45e1-b537-f9c61102c18b";
const iconSocials = "https://www.figma.com/api/mcp/asset/e95f23c6-e893-472e-a3cf-38a05290790b";
const iconActive = "https://www.figma.com/api/mcp/asset/cab1679a-a7d6-4a5f-8732-c6c1cd578320";
const heroLoaf = "https://www.figma.com/api/mcp/asset/f3fb05af-0fef-49b7-bc50-f5914dfe1705";
return (
<div className="min-h-screen bg-[#FDFCF8]">
<Navbar />
<div className="min-h-screen bg-white">
{/* Top Header - Auth Actions */}
<header className="bg-gradient-to-r from-[#644c9f] to-[#48286e] px-16 py-4 flex justify-end items-center gap-6">
<Link to="/register" className="text-white text-base font-medium hover:opacity-80 transition-opacity">
Register
</Link>
<Link to="/login" className="text-white text-base font-medium hover:opacity-80 transition-opacity">
Login
</Link>
<Button className="bg-[#ff9e77] hover:bg-[#ff8c64] text-[#644c9f] rounded-full px-6 py-3 text-base font-medium">
Donate
</Button>
</header>
{/* Main Header - Navigation */}
<header className="bg-[#664fa3] px-16 py-2 flex justify-between items-center">
<img src={loafLogo} alt="LOAF Logo" className="h-28 w-28 object-contain" />
<nav className="flex gap-10 items-center">
<a href="#welcome" className="text-white text-lg font-bold hover:opacity-80 transition-opacity" style={{ fontFamily: "'Nunito Sans', sans-serif", textShadow: '0px 4px 4px rgba(0,0,0,0.25)' }}>
Welcome
</a>
<a href="#about" className="text-white text-lg font-bold hover:opacity-80 transition-opacity" style={{ fontFamily: "'Nunito Sans', sans-serif", textShadow: '0px 4px 4px rgba(0,0,0,0.25)' }}>
About Us
</a>
<Link to="/register" className="text-white text-lg font-bold hover:opacity-80 transition-opacity" style={{ fontFamily: "'Nunito Sans', sans-serif", textShadow: '0px 4px 4px rgba(0,0,0,0.25)' }}>
Become a Member
</Link>
<Link to="/login" className="text-white text-lg font-bold hover:opacity-80 transition-opacity" style={{ fontFamily: "'Nunito Sans', sans-serif", textShadow: '0px 4px 4px rgba(0,0,0,0.25)' }}>
Members Only
</Link>
<a href="#resources" className="text-white text-lg font-bold hover:opacity-80 transition-opacity" style={{ fontFamily: "'Nunito Sans', sans-serif", textShadow: '0px 4px 4px rgba(0,0,0,0.25)' }}>
Resources
</a>
<a href="#contact" className="text-white text-lg font-bold hover:opacity-80 transition-opacity" style={{ fontFamily: "'Nunito Sans', sans-serif", textShadow: '0px 4px 4px rgba(0,0,0,0.25)' }}>
Contact Us
</a>
</nav>
</header>
{/* Hero Section */}
<section className="relative overflow-hidden">
<div className="absolute inset-0 bg-soft-mesh"></div>
<div className="max-w-7xl mx-auto px-6 py-20 lg:py-32 relative">
<div className="grid lg:grid-cols-2 gap-12 items-center">
<div className="space-y-8">
<h1 className="text-5xl md:text-7xl font-semibold fraunces text-[#3D405B] leading-tight">
Building Friendships, One Event at a Time
</h1>
<p className="text-lg md:text-xl text-[#6B708D] leading-relaxed">
Join our vibrant community of members connecting through shared experiences, events, and meaningful relationships.
</p>
<div className="flex gap-4 flex-wrap">
<Link to="/register">
<Button
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-8 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform"
data-testid="hero-join-button"
>
Become a Member
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
</Link>
<Link to="/login">
<Button
variant="outline"
className="border-2 border-[#3D405B] text-[#3D405B] hover:bg-[#3D405B] hover:text-white rounded-full px-8 py-6 text-lg font-medium transition-all"
data-testid="hero-login-button"
>
Member Login
</Button>
</Link>
</div>
</div>
<div className="relative">
<img
src="https://images.unsplash.com/photo-1660405251862-c023df45d075?crop=entropy&cs=srgb&fm=jpg&ixid=M3w3NDk1ODF8MHwxfHNlYXJjaHwxfHxhY3RpdmUlMjBzZW5pb3IlMjB3b21lbiUyMGdyb3VwJTIwaGlraW5nJTIwbmF0dXJlfGVufDB8fHx8MTc2NDc1NjIwM3ww&ixlib=rb-4.1.0&q=85"
alt="Community members enjoying outdoor activities"
className="rounded-2xl shadow-2xl w-full h-[500px] object-cover"
/>
</div>
<section className="bg-gradient-to-b from-[#48286e] to-[#664fa3] px-16 py-0 flex gap-16 items-center justify-center">
<div className="py-10 flex flex-col gap-8 items-center justify-center w-[420px]">
<div className="flex flex-col gap-6 items-center">
<img src={heroLoaf} alt="LOAF" className="w-[334px] h-[105px] object-contain" />
</div>
<div className="flex flex-col gap-4 items-center justify-center w-full">
<Link to="/register" className="w-full max-w-[339px]">
<Button className="bg-[#DDD8EB] hover:bg-white text-[#422268] rounded-full px-6 py-[32px] text-lg font-medium w-full transition-colors">
Become a Member
</Button>
</Link>
</div>
<p className="text-white text-lg text-center" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
LOAF is supported by the Hollyfield Foundation
</p>
</div>
<div className="py-16 flex items-center justify-center w-[594px] h-[636px]">
<img src={taglineImage} alt="LOAF Tagline" className="w-[483px] h-[297px] object-contain" />
</div>
</section>
{/* About Section */}
<section id="about" className="bg-gradient-to-b from-white to-[#f1eef9] px-16 pt-30 pb-0 flex flex-col gap-8">
<div className="flex flex-col items-center pt-12">
<h3 className="text-[#48286e] text-5xl font-extrabold text-center" style={{ fontFamily: "'Inter', sans-serif" }}>
Welcome to LOAF
</h3>
</div>
<p className="text-[rgba(0,0,0,0.55)] text-lg text-center font-medium" style={{ fontFamily: "'Inter', sans-serif" }}>
LOAF is Houston's social networking group for lesbians who are 50 years of age and older. LOAF hosts three main activities each month, Meet and Greets, Socials, and ActiveLOAFers. TheaterLOAFers coordinate events throughout the year.
</p>
<img src={shootingStar} alt="Decorative element" className="w-full h-[197px] object-contain" />
</section>
{/* Feature Cards Section */}
<section className="bg-gradient-to-b from-[#f1eef9] to-[#ddd8eb] px-16 py-30 flex gap-8 items-start justify-center">
<Card className="bg-white rounded-2xl overflow-hidden flex flex-col gap-3.5 items-center pt-5 pb-0 w-full max-w-[363px]">
<img src={iconMeetGreet} alt="Meet and Greet" className="w-[300px] h-[270px] object-contain" />
<div className="p-6 flex flex-col gap-4.5 w-full">
<h5 className="text-[#48286e] text-2xl font-semibold text-center" style={{ fontFamily: "'Inter', sans-serif" }}>
Meet and Greet
</h5>
<p className="text-[#48286e] text-lg text-center" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
The MEET and GREETs provide opportunities for prospective members to get acquainted with LOAF, have conversations with members, and ask the board of directors questions. They are held the 3rd Sunday of the month and usually take place at a restaurant or other fun places conducive to its purpose. Please email{' '}
<a href="mailto:info@loaftx.org" className="underline">info@loaftx.org</a> for upcoming times and locations.
</p>
</div>
</Card>
<Card className="bg-white rounded-2xl overflow-hidden flex flex-col gap-3.5 items-center pt-5 pb-0 w-full max-w-[363px]">
<img src={iconSocials} alt="Socials" className="w-[300px] h-[270px] object-contain" />
<div className="p-6 flex flex-col gap-4.5 w-full">
<h5 className="text-[#48286e] text-2xl font-semibold text-center" style={{ fontFamily: "'Inter', sans-serif" }}>
Socials
</h5>
<p className="text-[#48286e] text-lg text-center" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Our social events provide opportunities for members to explore Houston and connect with other lesbians. Past social events include, bowling, museums, painting lessons, sporting events, Miller Outdoor Theater, bingo and board games, pool parties, putt putt golf, camping and holiday get togethers. No matter your age or ability, there is something for everyone.
</p>
</div>
</Card>
<Card className="bg-white rounded-2xl overflow-hidden flex flex-col gap-3.5 items-center pt-5 pb-0 w-full max-w-[363px]">
<img src={iconActive} alt="Active LOAFers" className="w-[300px] h-[270px] object-contain" />
<div className="p-6 flex flex-col gap-4.5 w-full">
<h5 className="text-[#48286e] text-2xl font-semibold text-center" style={{ fontFamily: "'Inter', sans-serif" }}>
Active LOAFers
</h5>
<p className="text-[#48286e] text-lg text-center" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
ActiveLOAFers events provide members with opportunities to be physically active. Past activities have included, hiking/walking in the park, swimming (or floating), pickleball, kayaking, bike riding, axe throwing, and strolling through the botanic gardens or the Arboretum.
</p>
</div>
</Card>
</section>
{/* CTA Section */}
<section className="bg-gradient-to-b from-[#644c9f] to-[#48286e] px-16 py-30 flex items-center justify-center">
<div className="flex gap-12 items-center justify-center h-[191px]">
<Link to="/register">
<Button className="bg-[#DDD8EB] hover:bg-white text-[#422268] rounded-full px-6 py-[32px] text-lg font-medium w-[392px] transition-colors">
Become a Member
</Button>
</Link>
<div className="flex-1 flex items-center justify-center">
<h4 className="text-white text-4xl font-bold max-w-[718px]" style={{ fontFamily: "'Inter', sans-serif" }}>
No matter your age or ability, there is something for everyone.
</h4>
</div>
</div>
</section>
{/* Features Section */}
<section className="max-w-7xl mx-auto px-6 py-20">
<div className="text-center mb-16">
<h2 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
What We Offer
</h2>
<p className="text-lg text-[#6B708D] max-w-2xl mx-auto">
No matter your age or ability, there is something for everyone in our community.
</p>
</div>
<div className="grid md:grid-cols-3 gap-8">
<Card className="p-8 bg-white rounded-2xl border border-[#EAE0D5] hover:shadow-lg transition-shadow" data-testid="feature-community-card">
<div className="bg-[#F2CC8F]/20 w-16 h-16 rounded-full flex items-center justify-center mb-6">
<Users className="h-8 w-8 text-[#E07A5F]" strokeWidth={1.5} />
{/* Main Footer */}
<footer className="bg-[#644c9f] px-16 py-0 flex items-center justify-center h-[420px]">
<div className="border-t border-[rgba(0,0,0,0.1)] py-20 flex gap-30 items-center justify-center flex-1">
<div className="w-[232px]">
<img src={loafLogo} alt="LOAF Logo" className="w-[232px] h-[232px] object-contain" />
</div>
<nav className="flex gap-28 items-start justify-center w-[811px]">
<div className="flex flex-col gap-2 w-[163px]">
<div className="pb-4">
<p className="text-white text-base font-semibold" style={{ fontFamily: "'Inter', sans-serif" }}>About</p>
</div>
<a href="#history" className="text-[#ddd8eb] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>History</a>
<a href="#mission" className="text-[#ddd8eb] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>Mission and Values</a>
<a href="#board" className="text-[#ddd8eb] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>Board of Directors</a>
</div>
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
Meet & Greet
</h3>
<p className="text-[#6B708D] leading-relaxed">
Connect with prospective members and get acquainted with our community. Meet the board and ask questions in a welcoming environment.
</p>
</Card>
<Card className="p-8 bg-white rounded-2xl border border-[#EAE0D5] hover:shadow-lg transition-shadow" data-testid="feature-events-card">
<div className="bg-[#F2CC8F]/20 w-16 h-16 rounded-full flex items-center justify-center mb-6">
<Calendar className="h-8 w-8 text-[#E07A5F]" strokeWidth={1.5} />
<div className="flex flex-col gap-2 w-[148px]">
<div className="pb-4">
<p className="text-white text-base font-semibold" style={{ fontFamily: "'Inter', sans-serif" }}>Connect</p>
</div>
<Link to="/register" className="text-[#ddd8eb] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>Become a Member</Link>
<a href="#contact" className="text-[#ddd8eb] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>Contact Us</a>
<a href="#resources" className="text-[#ddd8eb] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>Resources</a>
</div>
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
Social Events
</h3>
<p className="text-[#6B708D] leading-relaxed">
Explore your city with fellow members. From museums to sporting events, board games to pool parties - there's always something happening.
</p>
</Card>
<Card className="p-8 bg-white rounded-2xl border border-[#EAE0D5] hover:shadow-lg transition-shadow" data-testid="feature-activities-card">
<div className="bg-[#F2CC8F]/20 w-16 h-16 rounded-full flex items-center justify-center mb-6">
<Heart className="h-8 w-8 text-[#E07A5F]" strokeWidth={1.5} />
<div className="flex flex-col gap-2 items-center w-[271px]">
<div className="pb-4 w-full">
<Button className="bg-[#ff9e77] hover:bg-[#ff8c64] text-[#48286e] rounded-full px-6 py-3 text-lg font-medium w-[217px]">
Donate
</Button>
</div>
<p className="text-[#ddd8eb] text-base font-medium text-center w-full" style={{ fontFamily: "'Inter', sans-serif" }}>
LOAF is supported by<br />the Hollyfield Foundation
</p>
</div>
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
Active Living
</h3>
<p className="text-[#6B708D] leading-relaxed">
Stay active with hiking, swimming, pickleball, kayaking, and more. Activities designed for all abilities and fitness levels.
</p>
</Card>
</nav>
</div>
</section>
</footer>
{/* CTA Section */}
<section className="bg-gradient-to-br from-[#F2CC8F]/20 to-[#E07A5F]/20 py-20">
<div className="max-w-4xl mx-auto px-6 text-center">
<h2 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-6">
Ready to Join Our Community?
</h2>
<p className="text-lg text-[#6B708D] mb-8">
Start your membership journey today and connect with amazing people in your area.
</p>
<Link to="/register">
<Button
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-12 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform"
data-testid="cta-register-button"
>
Get Started Now
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
</Link>
</div>
</section>
{/* Footer */}
<footer className="bg-[#3D405B] text-white py-12">
<div className="max-w-7xl mx-auto px-6 text-center">
<p className="text-[#A3B1C6]">
© 2025 Membership Platform. Building connections, creating community.
</p>
</div>
{/* Bottom Footer */}
<footer className="bg-gradient-to-r from-[#48286e] to-[#644c9f] border-t border-[rgba(0,0,0,0.1)] px-16 py-6 flex justify-between items-center h-[76px]">
<nav className="flex gap-8 items-center">
<a href="#terms" className="text-[#c5b4e3] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>
Terms of Service
</a>
<a href="#privacy" className="text-[#c5b4e3] text-base font-medium hover:text-white transition-colors" style={{ fontFamily: "'Inter', sans-serif" }}>
Privacy Policy
</a>
</nav>
<p className="text-[#c5b4e3] text-base font-medium" style={{ fontFamily: "'Inter', sans-serif" }}>
© 2025 LOAF. All Rights Reserved.
</p>
<p className="text-[#c5b4e3] text-base font-medium" style={{ fontFamily: "'Inter', sans-serif" }}>
Designed and Managed by{' '}
<a href="https://konceptkit.com/" className="text-[#d1c3e9] underline hover:text-white transition-colors">
Koncept Kit
</a>
</p>
</footer>
</div>
);

View File

@@ -54,23 +54,23 @@ const Login = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-md mx-auto px-6 py-12">
<div className="mb-8">
<Link to="/" className="inline-flex items-center text-[#6B708D] hover:text-[#E07A5F] transition-colors">
<Link to="/" className="inline-flex items-center text-[#664fa3] hover:text-[#ff9e77] transition-colors">
<ArrowLeft className="h-4 w-4 mr-2" />
Back to Home
</Link>
</div>
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg">
<div className="mb-8 text-center">
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Welcome Back
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Login to access your member dashboard.
</p>
</div>
@@ -86,7 +86,7 @@ const Login = () => {
value={formData.email}
onChange={handleInputChange}
placeholder="your.email@example.com"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="login-email-input"
/>
</div>
@@ -94,7 +94,7 @@ const Login = () => {
<div>
<div className="flex items-center justify-between mb-2">
<Label htmlFor="password">Password</Label>
<Link to="/forgot-password" className="text-sm text-[#E07A5F] hover:underline">
<Link to="/forgot-password" className="text-sm text-[#ff9e77] hover:underline">
Forgot password?
</Link>
</div>
@@ -105,7 +105,7 @@ const Login = () => {
value={formData.password}
onChange={handleInputChange}
placeholder="Enter your password"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="login-password-input"
/>
</div>
@@ -113,16 +113,16 @@ const Login = () => {
<Button
type="submit"
disabled={loading}
className="w-full bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
data-testid="login-submit-button"
>
{loading ? 'Logging in...' : 'Login'}
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
<p className="text-center text-[#6B708D]">
<p className="text-center text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Don't have an account?{' '}
<Link to="/register" className="text-[#E07A5F] hover:underline font-medium">
<Link to="/register" className="text-[#ff9e77] hover:underline font-medium">
Register here
</Link>
</p>

View File

@@ -66,43 +66,43 @@ const Plans = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-7xl mx-auto px-6 py-12">
{/* Header */}
<div className="mb-12 text-center">
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Membership Plans
</h1>
<p className="text-lg text-[#6B708D] max-w-2xl mx-auto">
<p className="text-lg text-[#664fa3] max-w-2xl mx-auto" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Choose the membership plan that works best for you and become part of our vibrant community.
</p>
</div>
{loading ? (
<div className="text-center py-20">
<Loader2 className="h-12 w-12 text-[#E07A5F] mx-auto mb-4 animate-spin" />
<p className="text-[#6B708D]">Loading plans...</p>
<Loader2 className="h-12 w-12 text-[#664fa3] mx-auto mb-4 animate-spin" />
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Loading plans...</p>
</div>
) : plans.length > 0 ? (
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8 max-w-5xl mx-auto">
{plans.map((plan) => (
<Card
key={plan.id}
className="p-8 bg-white rounded-2xl border-2 border-[#EAE0D5] hover:border-[#E07A5F] hover:shadow-xl transition-all"
className="p-8 bg-white rounded-2xl border-2 border-[#ddd8eb] hover:border-[#664fa3] hover:shadow-xl transition-all"
data-testid={`plan-card-${plan.id}`}
>
{/* Plan Header */}
<div className="text-center mb-6">
<div className="bg-[#F2CC8F]/20 p-4 rounded-full w-16 h-16 mx-auto mb-4 flex items-center justify-center">
<CreditCard className="h-8 w-8 text-[#E07A5F]" />
<div className="bg-[#DDD8EB]/20 p-4 rounded-full w-16 h-16 mx-auto mb-4 flex items-center justify-center">
<CreditCard className="h-8 w-8 text-[#664fa3]" />
</div>
<h2 className="text-2xl font-semibold fraunces text-[#3D405B] mb-2">
<h2 className="text-2xl font-semibold text-[#422268] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
{plan.name}
</h2>
{plan.description && (
<p className="text-sm text-[#6B708D] mb-4">
<p className="text-sm text-[#664fa3] mb-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{plan.description}
</p>
)}
@@ -110,10 +110,10 @@ const Plans = () => {
{/* Pricing */}
<div className="text-center mb-8">
<div className="text-4xl font-bold fraunces text-[#3D405B] mb-2">
<div className="text-4xl font-bold text-[#422268] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
{formatPrice(plan.price_cents)}
</div>
<p className="text-[#6B708D]">
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{getBillingCycleLabel(plan.billing_cycle)}
</p>
</div>
@@ -122,19 +122,19 @@ const Plans = () => {
<div className="space-y-3 mb-8">
<div className="flex items-start gap-3">
<CheckCircle className="h-5 w-5 text-[#81B29A] flex-shrink-0 mt-0.5" />
<span className="text-sm text-[#3D405B]">Access to all member events</span>
<span className="text-sm text-[#422268]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Access to all member events</span>
</div>
<div className="flex items-start gap-3">
<CheckCircle className="h-5 w-5 text-[#81B29A] flex-shrink-0 mt-0.5" />
<span className="text-sm text-[#3D405B]">Community directory access</span>
<span className="text-sm text-[#422268]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Community directory access</span>
</div>
<div className="flex items-start gap-3">
<CheckCircle className="h-5 w-5 text-[#81B29A] flex-shrink-0 mt-0.5" />
<span className="text-sm text-[#3D405B]">Exclusive member benefits</span>
<span className="text-sm text-[#422268]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Exclusive member benefits</span>
</div>
<div className="flex items-start gap-3">
<CheckCircle className="h-5 w-5 text-[#81B29A] flex-shrink-0 mt-0.5" />
<span className="text-sm text-[#3D405B]">Newsletter subscription</span>
<span className="text-sm text-[#422268]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Newsletter subscription</span>
</div>
</div>
@@ -142,7 +142,7 @@ const Plans = () => {
<Button
onClick={() => handleSubscribe(plan.id)}
disabled={processingPlanId === plan.id}
className="w-full bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full py-6 text-lg font-semibold"
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-semibold"
data-testid={`subscribe-button-${plan.id}`}
>
{processingPlanId === plan.id ? (
@@ -159,11 +159,11 @@ const Plans = () => {
</div>
) : (
<div className="text-center py-20">
<CreditCard className="h-20 w-20 text-[#EAE0D5] mx-auto mb-6" />
<h3 className="text-2xl font-semibold fraunces text-[#3D405B] mb-4">
<CreditCard className="h-20 w-20 text-[#ddd8eb] mx-auto mb-6" />
<h3 className="text-2xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
No Plans Available
</h3>
<p className="text-[#6B708D]">
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Membership plans are not currently available. Please check back later!
</p>
</div>
@@ -171,17 +171,17 @@ const Plans = () => {
{/* Info Section */}
<div className="mt-16 max-w-3xl mx-auto">
<Card className="p-8 bg-gradient-to-br from-[#F2CC8F]/20 to-[#E07A5F]/20 rounded-2xl border border-[#EAE0D5]">
<h3 className="text-xl font-semibold fraunces text-[#3D405B] mb-4 text-center">
<Card className="p-8 bg-gradient-to-br from-[#DDD8EB]/20 to-[#f1eef9]/20 rounded-2xl border border-[#ddd8eb]">
<h3 className="text-xl font-semibold text-[#422268] mb-4 text-center" style={{ fontFamily: "'Inter', sans-serif" }}>
Need Help Choosing?
</h3>
<p className="text-[#6B708D] text-center mb-4">
<p className="text-[#664fa3] text-center mb-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
If you have any questions about our membership plans or need assistance, please contact us.
</p>
<div className="text-center">
<a
href="mailto:support@loaf.org"
className="text-[#E07A5F] hover:text-[#D0694E] font-medium"
className="text-[#ff9e77] hover:text-[#664fa3] font-medium"
>
support@loaf.org
</a>

View File

@@ -69,52 +69,52 @@ const Profile = () => {
if (!profileData) {
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="flex items-center justify-center min-h-[60vh]">
<p className="text-[#6B708D]">Loading profile...</p>
<p className="text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Loading profile...</p>
</div>
</div>
);
}
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-4xl mx-auto px-6 py-12">
<div className="mb-8">
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
My Profile
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Update your personal information below.
</p>
</div>
<Card className="p-8 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg">
<Card className="p-8 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg">
{/* Read-only Information */}
<div className="mb-8 pb-8 border-b border-[#EAE0D5]">
<h2 className="text-2xl font-semibold fraunces text-[#3D405B] mb-6 flex items-center gap-2">
<User className="h-6 w-6 text-[#E07A5F]" />
<div className="mb-8 pb-8 border-b border-[#ddd8eb]">
<h2 className="text-2xl font-semibold text-[#422268] mb-6 flex items-center gap-2" style={{ fontFamily: "'Inter', sans-serif" }}>
<User className="h-6 w-6 text-[#664fa3]" />
Account Information
</h2>
<div className="grid md:grid-cols-2 gap-6">
<div>
<p className="text-sm text-[#6B708D] mb-1">Email</p>
<p className="text-[#3D405B] font-medium">{profileData.email}</p>
<p className="text-sm text-[#664fa3] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Email</p>
<p className="text-[#422268] font-medium" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{profileData.email}</p>
</div>
<div>
<p className="text-sm text-[#6B708D] mb-1">Status</p>
<p className="text-[#3D405B] font-medium capitalize">{profileData.status.replace('_', ' ')}</p>
<p className="text-sm text-[#664fa3] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Status</p>
<p className="text-[#422268] font-medium capitalize" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{profileData.status.replace('_', ' ')}</p>
</div>
<div>
<p className="text-sm text-[#6B708D] mb-1">Role</p>
<p className="text-[#3D405B] font-medium capitalize">{profileData.role}</p>
<p className="text-sm text-[#664fa3] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Role</p>
<p className="text-[#422268] font-medium capitalize" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{profileData.role}</p>
</div>
<div>
<p className="text-sm text-[#6B708D] mb-1">Date of Birth</p>
<p className="text-[#3D405B] font-medium">
<p className="text-sm text-[#664fa3] mb-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Date of Birth</p>
<p className="text-[#422268] font-medium" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{new Date(profileData.date_of_birth).toLocaleDateString()}
</p>
</div>
@@ -125,7 +125,7 @@ const Profile = () => {
type="button"
onClick={() => setPasswordDialogOpen(true)}
variant="outline"
className="border-2 border-[#E07A5F] text-[#E07A5F] hover:bg-[#FFF3E0] rounded-full px-6 py-3"
className="border-2 border-[#664fa3] text-[#664fa3] hover:bg-[#f1eef9] rounded-full px-6 py-3"
>
<Lock className="h-4 w-4 mr-2" />
Change Password
@@ -135,7 +135,7 @@ const Profile = () => {
{/* Editable Form */}
<form onSubmit={handleSubmit} className="space-y-6" data-testid="profile-form">
<h2 className="text-2xl font-semibold fraunces text-[#3D405B] mb-6">
<h2 className="text-2xl font-semibold text-[#422268] mb-6" style={{ fontFamily: "'Inter', sans-serif" }}>
Personal Information
</h2>
@@ -147,7 +147,7 @@ const Profile = () => {
name="first_name"
value={formData.first_name}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="first-name-input"
/>
</div>
@@ -158,7 +158,7 @@ const Profile = () => {
name="last_name"
value={formData.last_name}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="last-name-input"
/>
</div>
@@ -172,7 +172,7 @@ const Profile = () => {
type="tel"
value={formData.phone}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="phone-input"
/>
</div>
@@ -184,7 +184,7 @@ const Profile = () => {
name="address"
value={formData.address}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="address-input"
/>
</div>
@@ -197,7 +197,7 @@ const Profile = () => {
name="city"
value={formData.city}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="city-input"
/>
</div>
@@ -208,7 +208,7 @@ const Profile = () => {
name="state"
value={formData.state}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="state-input"
/>
</div>
@@ -219,7 +219,7 @@ const Profile = () => {
name="zipcode"
value={formData.zipcode}
onChange={handleInputChange}
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
data-testid="zipcode-input"
/>
</div>
@@ -228,7 +228,7 @@ const Profile = () => {
<Button
type="submit"
disabled={loading}
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-8 py-6 text-lg font-medium shadow-lg disabled:opacity-50"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-8 py-6 text-lg font-medium shadow-lg disabled:opacity-50"
data-testid="save-profile-button"
>
<Save className="h-5 w-5 mr-2" />

View File

@@ -182,23 +182,23 @@ const Register = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-4xl mx-auto px-6 py-12">
<div className="mb-8">
<Link to="/" className="inline-flex items-center text-[#6B708D] hover:text-[#E07A5F] transition-colors">
<Link to="/" className="inline-flex items-center text-[#664fa3] hover:text-[#ff9e77] transition-colors">
<ArrowLeft className="h-4 w-4 mr-2" />
Back to Home
</Link>
</div>
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg">
<div className="mb-8">
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Join Our Community
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Fill out the form below to start your membership journey.
</p>
</div>
@@ -244,7 +244,7 @@ const Register = () => {
type="button"
onClick={handleBack}
variant="outline"
className="rounded-full px-6 py-6 text-lg border-2 border-[#EAE0D5] hover:border-[#6B708D] text-[#3D405B]"
className="rounded-full px-6 py-6 text-lg border-2 border-[#ddd8eb] hover:border-[#664fa3] text-[#422268]"
>
<ArrowLeft className="mr-2 h-5 w-5" />
Back
@@ -257,7 +257,7 @@ const Register = () => {
<Button
type="button"
onClick={handleNext}
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-6 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-6 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform"
>
Next
<ArrowRight className="ml-2 h-5 w-5" />
@@ -266,7 +266,7 @@ const Register = () => {
<Button
type="submit"
disabled={loading}
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-6 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50 disabled:cursor-not-allowed"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-6 py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50 disabled:cursor-not-allowed"
data-testid="submit-register-button"
>
{loading ? 'Creating Account...' : 'Create Account'}
@@ -275,9 +275,9 @@ const Register = () => {
)}
</div>
<p className="text-center text-[#6B708D] mt-4">
<p className="text-center text-[#664fa3] mt-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Already have an account?{' '}
<Link to="/login" className="text-[#E07A5F] hover:underline font-medium">
<Link to="/login" className="text-[#ff9e77] hover:underline font-medium">
Login here
</Link>
</p>

View File

@@ -63,19 +63,19 @@ const ResetPassword = () => {
};
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-md mx-auto px-6 py-12">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg">
<Card className="p-8 md:p-12 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg">
<div className="mb-8 text-center">
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#FFF3E0] mb-4">
<Lock className="h-8 w-8 text-[#E07A5F]" />
<div className="inline-flex items-center justify-center w-16 h-16 rounded-full bg-[#f1eef9] mb-4">
<Lock className="h-8 w-8 text-[#664fa3]" />
</div>
<h1 className="text-4xl md:text-5xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-4xl md:text-5xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Reset Password
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Enter your new password below.
</p>
</div>
@@ -91,7 +91,7 @@ const ResetPassword = () => {
value={formData.newPassword}
onChange={handleInputChange}
placeholder="Enter new password (min. 6 characters)"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
/>
</div>
@@ -105,15 +105,15 @@ const ResetPassword = () => {
value={formData.confirmPassword}
onChange={handleInputChange}
placeholder="Re-enter new password"
className="h-14 rounded-xl border-2 border-[#EAE0D5] focus:border-[#E07A5F]"
className="h-14 rounded-xl border-2 border-[#ddd8eb] focus:border-[#664fa3]"
/>
</div>
<div className="bg-[#FFF3E0] border-l-4 border-[#E07A5F] p-4 rounded-lg">
<div className="bg-[#f1eef9] border-l-4 border-[#664fa3] p-4 rounded-lg">
<div className="flex items-start">
<AlertCircle className="h-5 w-5 text-[#E07A5F] mr-2 mt-0.5 flex-shrink-0" />
<div className="text-sm text-[#6B708D]">
<p className="font-medium text-[#3D405B] mb-1">Password Requirements:</p>
<AlertCircle className="h-5 w-5 text-[#664fa3] mr-2 mt-0.5 flex-shrink-0" />
<div className="text-sm text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="font-medium text-[#422268] mb-1">Password Requirements:</p>
<ul className="list-disc list-inside space-y-1">
<li>At least 6 characters long</li>
<li>Both passwords must match</li>
@@ -125,15 +125,15 @@ const ResetPassword = () => {
<Button
type="submit"
disabled={loading}
className="w-full bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
className="w-full bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full py-6 text-lg font-medium shadow-lg hover:scale-105 transition-transform disabled:opacity-50"
>
{loading ? 'Resetting Password...' : 'Reset Password'}
<ArrowRight className="ml-2 h-5 w-5" />
</Button>
<p className="text-center text-[#6B708D]">
<p className="text-center text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Remember your password?{' '}
<Link to="/login" className="text-[#E07A5F] hover:underline font-medium">
<Link to="/login" className="text-[#ff9e77] hover:underline font-medium">
Login here
</Link>
</p>

View File

@@ -37,18 +37,18 @@ const VerifyEmail = () => {
}, [token]);
return (
<div className="min-h-screen bg-[#FDFCF8]">
<div className="min-h-screen bg-white">
<Navbar />
<div className="max-w-2xl mx-auto px-6 py-20">
<Card className="p-12 bg-white rounded-2xl border border-[#EAE0D5] shadow-lg text-center">
<Card className="p-12 bg-white rounded-2xl border border-[#ddd8eb] shadow-lg text-center">
{status === 'loading' && (
<>
<Loader2 className="h-20 w-20 text-[#E07A5F] mx-auto mb-6 animate-spin" />
<h1 className="text-3xl font-semibold fraunces text-[#3D405B] mb-4">
<Loader2 className="h-20 w-20 text-[#664fa3] mx-auto mb-6 animate-spin" />
<h1 className="text-3xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Verifying Your Email...
</h1>
<p className="text-lg text-[#6B708D]">
<p className="text-lg text-[#664fa3]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Please wait while we verify your email address.
</p>
</>
@@ -57,18 +57,18 @@ const VerifyEmail = () => {
{status === 'success' && (
<>
<CheckCircle className="h-20 w-20 text-[#81B29A] mx-auto mb-6" />
<h1 className="text-3xl font-semibold fraunces text-[#3D405B] mb-4">
<h1 className="text-3xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Email Verified Successfully!
</h1>
<p className="text-lg text-[#6B708D] mb-8">
<p className="text-lg text-[#664fa3] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{message}
</p>
<p className="text-base text-[#6B708D] mb-8">
<p className="text-base text-[#664fa3] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Next steps: Attend an event and meet a board member within 90 days. Once you've attended an event, our admin team will review your application.
</p>
<Link to="/login">
<Button
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-12 py-6 text-lg font-medium shadow-lg"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-12 py-6 text-lg font-medium shadow-lg"
data-testid="login-redirect-button"
>
Go to Login
@@ -79,16 +79,16 @@ const VerifyEmail = () => {
{status === 'error' && (
<>
<XCircle className="h-20 w-20 text-[#E07A5F] mx-auto mb-6" />
<h1 className="text-3xl font-semibold fraunces text-[#3D405B] mb-4">
<XCircle className="h-20 w-20 text-red-500 mx-auto mb-6" />
<h1 className="text-3xl font-semibold text-[#422268] mb-4" style={{ fontFamily: "'Inter', sans-serif" }}>
Verification Failed
</h1>
<p className="text-lg text-[#6B708D] mb-8">
<p className="text-lg text-[#664fa3] mb-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{message}
</p>
<Link to="/">
<Button
className="bg-[#E07A5F] text-white hover:bg-[#D0694E] rounded-full px-12 py-6 text-lg font-medium shadow-lg"
className="bg-[#DDD8EB] text-[#422268] hover:bg-white rounded-full px-12 py-6 text-lg font-medium shadow-lg"
data-testid="home-redirect-button"
>
Go to Home