many styling changes and updates
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<meta name="theme-color" content="#664fa3" />
|
||||
<meta name="description" content="LOAF - Lesbian Organization of Atlanta Family" />
|
||||
<meta name="description" content="LOAF - Lesbians Over Age Fifty" />
|
||||
|
||||
<!-- Google Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
|
||||
@@ -10,7 +10,7 @@ const MemberBadge = ({ memberSince, tiers }) => {
|
||||
|
||||
return (
|
||||
<Badge className={`px-3 py-2 rounded-md text-sm flex items-center gap-2 border hover:text-white ${tier.badgeClass}`}>
|
||||
<Icon className="size-6" />
|
||||
<Icon className="size-4" />
|
||||
{tier.label}
|
||||
</Badge>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React from 'react'
|
||||
import { Card } from './ui/card';
|
||||
import { Button } from './ui/button';
|
||||
import { Heart, Calendar, Mail, Phone, MapPin, Facebook, Instagram, Twitter, Linkedin, UserCircle } from 'lucide-react';
|
||||
import { Heart, Calendar, Mail, User, Phone, MapPin, Facebook, Instagram, Twitter, Linkedin, UserCircle, UserRound } from 'lucide-react';
|
||||
import MemberBadge from './MemberBadge';
|
||||
import useDirectoryConfig from '../hooks/use-directory-config';
|
||||
|
||||
@@ -28,26 +28,44 @@ const MemberCard = ({ member, onViewProfile, tiers }) => {
|
||||
<div className='flex justify-end items-center mb-2'>
|
||||
<MemberBadge memberSince={memberSince} tiers={tiers} />
|
||||
</div>
|
||||
<div className="flex justify-center mb-4">
|
||||
{member.profile_photo_url ? (
|
||||
<img
|
||||
src={member.profile_photo_url}
|
||||
alt={`${member.first_name} ${member.last_name}`}
|
||||
className="w-32 h-32 rounded-full object-cover border-4 border-[var(--neutral-800)]"
|
||||
/>
|
||||
) : (
|
||||
<div className="w-32 h-32 rounded-full bg-[var(--neutral-800)] border-4 border-[var(--neutral-800)] flex items-center justify-center">
|
||||
<span className="text-4xl font-semibold text-brand-purple " style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
{getInitials(member.first_name, member.last_name)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='flex gap-3 items-start'>
|
||||
<div className="flex justify-center mb-4">
|
||||
{member.profile_photo_url ? (
|
||||
<img
|
||||
src={member.profile_photo_url}
|
||||
alt={`${member.first_name} ${member.last_name}`}
|
||||
className="size-20 rounded-full object-cover border-4 border-[var(--neutral-800)]"
|
||||
/>
|
||||
) : (
|
||||
<div className="size-20 rounded-full bg-[var(--neutral-800)] border-4 border-[var(--neutral-800)] flex items-center justify-center">
|
||||
<span className="text-4xl font-semibold text-brand-purple " style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
{getInitials(member.first_name, member.last_name)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className='pt-4'>
|
||||
{/* Name */}
|
||||
<h3 className="text-2xl font-semibold text-[var(--purple-ink)] text-center mb-3" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
{member.first_name} {member.last_name}
|
||||
</h3>
|
||||
{/* Member Since */}
|
||||
{memberSince && (
|
||||
<div className="flex gap-2 mb-4">
|
||||
<Calendar className="size-4 text-brand-lavender " />
|
||||
<span className="text-sm text-brand-purple font-medium" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Member since {new Date(memberSince).toLocaleDateString('en-US', {
|
||||
// month: 'short',
|
||||
year: 'numeric'
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Name */}
|
||||
<h3 className="text-2xl font-semibold text-[var(--purple-ink)] text-center mb-3" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
{member.first_name} {member.last_name}
|
||||
</h3>
|
||||
|
||||
{/* Partner Name */}
|
||||
{isFieldEnabled('directory_partner_name') && member.directory_partner_name && (
|
||||
@@ -66,19 +84,6 @@ const MemberCard = ({ member, onViewProfile, tiers }) => {
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* Member Since */}
|
||||
{memberSince && (
|
||||
<div className="flex items-center justify-center gap-2 mb-4">
|
||||
<Calendar className="h-4 w-4 text-brand-purple " />
|
||||
<span className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Member since {new Date(memberSince).toLocaleDateString('en-US', {
|
||||
month: 'long',
|
||||
year: 'numeric'
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Contact Information */}
|
||||
<div className="space-y-3 mb-4">
|
||||
{isFieldEnabled('directory_email') && member.directory_email && (
|
||||
@@ -94,27 +99,6 @@ const MemberCard = ({ member, onViewProfile, tiers }) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isFieldEnabled('directory_phone') && member.directory_phone && (
|
||||
<div className="flex items-center gap-2 text-sm">
|
||||
<Phone className="h-4 w-4 text-brand-purple flex-shrink-0" />
|
||||
<a
|
||||
href={`tel:${member.directory_phone}`}
|
||||
className="text-brand-purple hover:text-[var(--purple-ink)]"
|
||||
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
|
||||
>
|
||||
{member.directory_phone}
|
||||
</a>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{isFieldEnabled('directory_address') && member.directory_address && (
|
||||
<div className="flex items-start gap-2 text-sm">
|
||||
<MapPin className="h-4 w-4 text-brand-purple flex-shrink-0 mt-0.5" />
|
||||
<span className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{member.directory_address}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Social Media Links */}
|
||||
@@ -171,14 +155,14 @@ const MemberCard = ({ member, onViewProfile, tiers }) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='border-b-2 mx-4 border-[var(--neutral-800)] mb-6'></div>
|
||||
{/* View Profile Button */}
|
||||
<div className="pt-4 mt-4 border-t border-[var(--neutral-800)]">
|
||||
<div className=" ">
|
||||
<Button
|
||||
onClick={() => onViewProfile?.(member.id)}
|
||||
className="w-full bg-[var(--neutral-800)] text-[var(--purple-ink)] hover:bg-brand-purple hover:text-white rounded-full py-5"
|
||||
className="w-full bg-brand-purple text-background hover:bg-brand-purple/90 hover:text-white rounded-full py-5"
|
||||
>
|
||||
<UserCircle className="h-4 w-4 mr-2" />
|
||||
<UserRound className="size-6 mr-2 font-bold text-brand-lavender" />
|
||||
View Full Profile
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,7 @@ const MemberFooter = () => {
|
||||
LOAF
|
||||
</h3>
|
||||
<p className="text-gray-300 text-sm" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Lesbian Organization of Atlanta Family
|
||||
Lesbians Over Age Fifty
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ const BecomeMember = () => {
|
||||
</div>
|
||||
|
||||
{/* Membership Process Section */}
|
||||
<div className="relative bg-gray-50 py-32 bg-gradient-to-bl from-[var(--neutral-100:)] to-[var(--neutral-800)] ">
|
||||
<div className="relative bg-gray-50 py-32 bg-gradient-to-bl from-[var(--neutral-100)] to-[var(--neutral-800)] ">
|
||||
{/* Decorative shooting star element */}
|
||||
<div className="hidden lg:block absolute left-0 top-64 w-[195px] h-[1130px] pointer-events-none opacity-50">
|
||||
<img
|
||||
|
||||
@@ -69,7 +69,7 @@ const BoardOfDirectors = () => {
|
||||
<div className="min-h-screen bg-background">
|
||||
<PublicNavbar />
|
||||
|
||||
<main className="bg-gradient-to-b from-[var(--neutral-100:)] to-[var(--neutral-800)] pt-8 sm:pt-10 md:pt-12">
|
||||
<main className="bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)] pt-8 sm:pt-10 md:pt-12">
|
||||
{/* Hero Section */}
|
||||
<section className=" pt-16 pb-4 px-4 sm:px-6 md:px-8 lg:px-12 xl:px-20">
|
||||
<div className="max-w-5xl mx-auto text-center px-8">
|
||||
|
||||
@@ -136,7 +136,7 @@ const Dashboard = () => {
|
||||
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 py-12">
|
||||
@@ -286,7 +286,7 @@ const Dashboard = () => {
|
||||
{loading ? (
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Loading events...</p>
|
||||
) : events.length > 0 ? (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-4 gap-4">
|
||||
{events.map((event) => (
|
||||
<Link to={`/events/${event.id}`} key={event.id}>
|
||||
<div
|
||||
@@ -311,7 +311,7 @@ const Dashboard = () => {
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-center py-12">
|
||||
<div className="text-center gap-4 py-12">
|
||||
<Calendar className="h-16 w-16 text-[var(--neutral-800)] mx-auto mb-4" />
|
||||
<p className="text-brand-purple mb-4" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>No upcoming events at the moment.</p>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Check back later for new events!</p>
|
||||
|
||||
@@ -58,7 +58,7 @@ const Donate = () => {
|
||||
<div className="min-h-screen">
|
||||
<PublicNavbar />
|
||||
|
||||
<main className="bg-gradient-to-bl from-[var(--neutral-100:)] to-[var(--neutral-800)] px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 py-8 sm:py-10 md:py-12">
|
||||
<main className="bg-gradient-to-bl from-[var(--neutral-100)] to-[var(--neutral-800)] px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 py-8 sm:py-10 md:py-12">
|
||||
{/* Hero Section */}
|
||||
<section className="py-12">
|
||||
<div className="max-w-4xl mx-auto text-center h-full">
|
||||
|
||||
@@ -46,7 +46,7 @@ const Events = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 py-12">
|
||||
|
||||
@@ -46,7 +46,7 @@ const History = () => {
|
||||
<div className="min-h-screen bg-background">
|
||||
<PublicNavbar />
|
||||
|
||||
<main className="bg-gradient-to-br from-[var(--neutral-100:)] to-[var(--neutral-700)] px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 py-8 sm:py-10 md:py-12">
|
||||
<main className="bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)] px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 py-8 sm:py-10 md:py-12">
|
||||
{/* Hero Section */}
|
||||
<section className="py-12">
|
||||
<div className="max-w-3xl mx-auto flex justify-around mb-12 flex-col gap-6 items-center lg:flex-row">
|
||||
|
||||
@@ -84,12 +84,14 @@ const Landing = () => {
|
||||
<div className="absolute inset-0 z-[1] bg-background/5 backdrop-blur-xs"></div>
|
||||
{/* Left column Loaf Image */}
|
||||
<div className="relative z-10 lg:py-20 py-7 flex flex-col gap-6 sm:gap-8 items-center justify-center w-full lg:w-[530px] lg:flex-shrink-0">
|
||||
<div className="flex flex-col gap-6 items-center">
|
||||
<div className="flex flex-col gap-3 items-center">
|
||||
<img src={heroLoaf} alt="LOAF" className="w-full max-w-xs md:max-w-[370px] h-auto object-contain" />
|
||||
<div className='text-background font-medium text-[2rem] text-center mb-2'>Lesbians Over Age Fifty</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col gap-4 items-center justify-center w-full max-w-[339px]">
|
||||
<Link to="/become-a-member" className="w-full">
|
||||
<Button style={{ fontFamily: "'Nunito sans', sans-serif" }} className="bg-[var(--neutral-800)] hover:bg-background text-[var(--purple-ink)] rounded-full px-6 py-6 sm:py-[32px] text-base sm:text-lg font-medium w-full transition-colors">
|
||||
<Button style={{ fontFamily: "'Nunito sans', sans-serif" }} className="bg-[var(--neutral-800)] hover:bg-background text-[var(--purple-ink)] rounded-full px-6 py-6 sm:py-[32px] text-base sm:text-lg font-semibold w-full transition-colors">
|
||||
Become a Member
|
||||
</Button>
|
||||
</Link>
|
||||
@@ -107,11 +109,11 @@ const Landing = () => {
|
||||
{/* About Section */}
|
||||
<section id="about" className="bg-gradient-to-b pb-10 lg:pb-44 from-white to-[var(--lavender-300)] px-4 sm:px-6 md:px-8 lg:px-12 xl:px-16 pt-4 sm:pt-16 md:pt-20 lg:pt-30 flex flex-col">
|
||||
<div className="flex flex-col items-center pt-4">
|
||||
<h3 className="text-[var(--purple-deep)] px-4 pb-6 md:py-8 text-4xl leading-[60px] md:text-5xl lg:text-6xl font-extrabold text-center" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
<h3 className="text-[var(--purple-deep)] px-4 pb-6 md:py-8 text-4xl leading-[60px] md:text-5xl lg:text-6xl font-extrabold text-center" style={{ fontFamily: "'Poppins', sans-serif" }}>
|
||||
Welcome to LOAF
|
||||
</h3>
|
||||
</div>
|
||||
<p className="text-[rgba(0,0,0,0.55)] text-lg lg:text-2xl text-center font-medium" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
<p className="text-[rgba(0,0,0,0.55)] text-lg lg:text-2xl text-center mx-auto font-medium max-w-[940px]" style={{ fontFamily: "'Poppins', 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" />
|
||||
@@ -129,7 +131,7 @@ const Landing = () => {
|
||||
<div className="flex flex-col-reverse md:flex-col lg:flex-row gap-8 sm:gap-10 md:gap-12 items-center justify-center w-full max-w-6xl">
|
||||
<Link to="/register" className="w-full sm:w-auto flex items-center justify-center">
|
||||
<Button className="bg-[var(--neutral-800)] hover:bg-background text-[var(--purple-ink)] rounded-full
|
||||
py-8 text-xl font-normal px-12 sm:w-[392px] transition-colors ">
|
||||
py-8 text-xl font-medium px-12 sm:w-[392px] transition-colors ">
|
||||
Become a Member
|
||||
</Button>
|
||||
</Link>
|
||||
|
||||
@@ -82,10 +82,10 @@ const Login = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<PublicNavbar />
|
||||
|
||||
<div className="max-w-md mx-auto px-6 py-12">
|
||||
<div className="max-w-md mx-auto px-6 py-12 ">
|
||||
<div className="mb-8">
|
||||
<Link to="/" className="inline-flex items-center text-brand-purple hover:text-[var(--orange-light)] transition-colors">
|
||||
<ArrowLeft className="h-4 w-4 mr-2" />
|
||||
|
||||
@@ -12,7 +12,7 @@ const MissionValues = () => {
|
||||
<div className="min-h-screen bg-background">
|
||||
<PublicNavbar />
|
||||
|
||||
<main className="bg-gradient-to-b from-[var(--neutral-100:)] to-[var(--neutral-800)] px-4 sm:px-6 py-8 sm:py-12 md:py-20">
|
||||
<main className="bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)] px-4 sm:px-6 py-8 sm:py-12 md:py-20">
|
||||
<div className="max-w-[1400px] mx-auto">
|
||||
<div className="flex md:flex-row flex-col gap-10 items-stretch">
|
||||
{/* Left Card - Mission (Purple Gradient) */}
|
||||
|
||||
@@ -7,7 +7,7 @@ export default function PrivacyPolicy() {
|
||||
return (
|
||||
<>
|
||||
<PublicNavbar />
|
||||
<main className="bg-gradient-to-bl from-[var(--neutral-100:)] to-[var(--neutral-800)] text-[var(--purple-deep)]">
|
||||
<main className="bg-gradient-to-bl from-[var(--neutral-100)] to-[var(--neutral-800)] text-[var(--purple-deep)]">
|
||||
<div className="mx-auto w-full max-w-5xl px-4 sm:px-6 lg:px-8 py-10">
|
||||
<header className="border-b pb-6">
|
||||
<h1 className="text-3xl sm:text-4xl font-bold tracking-tight" style={{ fontFamily: 'Poppins' }}>
|
||||
|
||||
@@ -8,7 +8,7 @@ export default function TermsOfService() {
|
||||
return (
|
||||
<>
|
||||
<PublicNavbar />
|
||||
<main className="bg-gradient-to-bl from-[var(--neutral-100:)] to-[var(--neutral-800)] text-[var(--purple-deep)]">
|
||||
<main className="bg-gradient-to-bl from-[var(--neutral-100)] to-[var(--neutral-800)] text-[var(--purple-deep)]">
|
||||
<div className="mx-auto w-full max-w-5xl px-4 sm:px-6 lg:px-8 py-10">
|
||||
{/* Title */}
|
||||
<header className="border-b pb-6">
|
||||
|
||||
@@ -108,7 +108,7 @@ export default function Bylaws() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-5xl mx-auto px-6 py-12">
|
||||
|
||||
@@ -159,7 +159,7 @@ const EventGallery = () => {
|
||||
// Event Gallery Grid View
|
||||
if (!selectedEvent) {
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 py-12">
|
||||
|
||||
@@ -87,7 +87,7 @@ export default function Financials() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-5xl mx-auto px-6 py-12">
|
||||
|
||||
@@ -89,6 +89,20 @@ export default function MemberCalendar() {
|
||||
setRsvpLoading(false);
|
||||
}
|
||||
};
|
||||
const getReadableTextColor = (hex) => {
|
||||
const cleaned = hex.replace('#', '');
|
||||
const r = parseInt(cleaned.substring(0, 2), 16) / 255;
|
||||
const g = parseInt(cleaned.substring(2, 4), 16) / 255;
|
||||
const b = parseInt(cleaned.substring(4, 6), 16) / 255;
|
||||
|
||||
const srgb = [r, g, b].map((c) =>
|
||||
c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4)
|
||||
);
|
||||
const luminance = 0.2126 * srgb[0] + 0.7152 * srgb[1] + 0.0722 * srgb[2];
|
||||
|
||||
// tweak threshold to taste
|
||||
return luminance > 0.6 ? 'var(--brand-purple)' : 'white';
|
||||
};
|
||||
|
||||
const eventStyleGetter = (event) => {
|
||||
const rsvpStatus = event.resource?.user_rsvp_status;
|
||||
@@ -99,12 +113,16 @@ export default function MemberCalendar() {
|
||||
if (rsvpStatus === 'yes') {
|
||||
backgroundColor = '#81B29A';
|
||||
borderColor = '#66927e';
|
||||
|
||||
} else if (rsvpStatus === 'no') {
|
||||
backgroundColor = '#9ca3af';
|
||||
borderColor = '#6b7280';
|
||||
|
||||
} else if (rsvpStatus === 'maybe') {
|
||||
backgroundColor = '#fb923c';
|
||||
borderColor = '#ea580c';
|
||||
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -114,7 +132,7 @@ export default function MemberCalendar() {
|
||||
borderWidth: '2px',
|
||||
borderStyle: 'solid',
|
||||
borderRadius: '6px',
|
||||
color: 'white',
|
||||
color: getReadableTextColor(backgroundColor),
|
||||
fontWeight: '500',
|
||||
fontSize: '0.875rem',
|
||||
padding: '2px 6px',
|
||||
@@ -136,7 +154,7 @@ export default function MemberCalendar() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 py-12">
|
||||
@@ -175,7 +193,7 @@ export default function MemberCalendar() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="p-6 bg-background rounded-2xl border border-[var(--neutral-800)] shadow-lg">
|
||||
<Card className="p-6 bg-background text-brand-purple rounded-2xl border border-[var(--neutral-800)] shadow-lg">
|
||||
<Calendar
|
||||
localizer={localizer}
|
||||
events={calendarEvents}
|
||||
@@ -190,7 +208,7 @@ export default function MemberCalendar() {
|
||||
eventPropGetter={eventStyleGetter}
|
||||
views={['month', 'week', 'day', 'agenda']}
|
||||
popup
|
||||
className="member-calendar"
|
||||
className="member-calendar "
|
||||
/>
|
||||
</Card>
|
||||
|
||||
@@ -275,9 +293,10 @@ export default function MemberCalendar() {
|
||||
onClick={() => handleRSVP('yes')}
|
||||
disabled={rsvpLoading}
|
||||
size="sm"
|
||||
className={`rounded-full px-6 flex items-center gap-2 ${selectedEvent.user_rsvp_status === 'yes'
|
||||
? 'bg-[var(--green-light)] text-white hover:bg-[var(--green-muted)]'
|
||||
: 'bg-[var(--neutral-800)] text-[var(--purple-ink)] hover:bg-[var(--neutral-400:)]'
|
||||
variant='outline'
|
||||
className={`rounded-full px-6 flex items-center gap-2 ${selectedEvent.user_rsvp_status === 'yes'
|
||||
? 'border-success bg-success/20 text-success'
|
||||
: 'border-brand-purple text-brand-purple hover:bg-[var(--lavender-300)]'
|
||||
}`}
|
||||
>
|
||||
<Check className="h-4 w-4" />
|
||||
@@ -303,7 +322,7 @@ export default function MemberCalendar() {
|
||||
variant="outline"
|
||||
className={`rounded-full px-6 flex items-center gap-2 border-2 ${selectedEvent.user_rsvp_status === 'no'
|
||||
? 'border-gray-400 bg-gray-100 text-gray-700'
|
||||
: 'border-gray-400 text-gray-600 hover:bg-gray-50'
|
||||
: 'border-brand-purple text-brand-purple hover:bg-[var(--lavender-300)]'
|
||||
}`}
|
||||
>
|
||||
<X className="h-4 w-4" />
|
||||
|
||||
@@ -14,13 +14,33 @@ import {
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from '../../components/ui/dialog';
|
||||
import { User, Search, Mail, MapPin, Phone, Heart, Facebook, Instagram, Twitter, Linkedin, UserCircle, Calendar } from 'lucide-react';
|
||||
import {
|
||||
User,
|
||||
Search,
|
||||
Mail,
|
||||
MapPin,
|
||||
Phone,
|
||||
Heart,
|
||||
Facebook,
|
||||
Instagram,
|
||||
Twitter,
|
||||
Linkedin,
|
||||
CircleUserRound,
|
||||
Calendar,
|
||||
ChevronsRight,
|
||||
ChevronRight,
|
||||
ChevronLeft,
|
||||
ChevronsLeft,
|
||||
UserRound
|
||||
} from 'lucide-react';
|
||||
import { useToast } from '../../hooks/use-toast';
|
||||
import MemberCard from '../../components/MemberCard';
|
||||
import MemberBadge from '../../components/MemberBadge';
|
||||
import useMembers from '../../hooks/use-members';
|
||||
import useMemberTiers from '../../hooks/use-member-tiers';
|
||||
import useDirectoryConfig from '../../hooks/use-directory-config';
|
||||
import { useThemeConfig } from '@/context/ThemeConfigContext';
|
||||
|
||||
|
||||
const MembersDirectory = () => {
|
||||
const [selectedMember, setSelectedMember] = useState(null);
|
||||
@@ -37,6 +57,12 @@ const MembersDirectory = () => {
|
||||
}
|
||||
return status;
|
||||
}, []);
|
||||
|
||||
const { getLogoUrl } = useThemeConfig();
|
||||
// Get logo URL from theme config (with fallback to default)
|
||||
const logo = getLogoUrl();
|
||||
|
||||
|
||||
const normalizeMembers = useCallback(
|
||||
(data) => {
|
||||
const list = Array.isArray(data)
|
||||
@@ -147,18 +173,27 @@ const MembersDirectory = () => {
|
||||
<div className='px-9'>
|
||||
|
||||
{/* Header */}
|
||||
<div className="m-8 mt-14 flex flex-col sm:flex-row justify-between items-center ">
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Poppins', sans-serif" }}>
|
||||
LOAF Members
|
||||
</h1>
|
||||
<p className="text-lg " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<span className='text-foreground'>Number of current members in the directory: </span> <span className='text-brand-purple font-medium'>{totalMembers}</span>
|
||||
</p>
|
||||
<div className="my-8 mb-8 mt-14 gap-4 flex flex-col sm:flex-row items-center ">
|
||||
<Link to="/dashboard">
|
||||
<img src={logo} alt="LOAF Logo" className="h-16 w-16 sm:h-20 sm:w-20 md:h-28 md:w-28 object-contain" />
|
||||
</Link>
|
||||
|
||||
<div className='flex flex-col items-start'>
|
||||
<h1 className="text-4xl md:text-5xl font-bold text-[var(--purple-ink)] mb-4" style={{ fontFamily: "'Poppins', sans-serif" }}>
|
||||
Members Directory
|
||||
</h1>
|
||||
|
||||
<p className="text-lg font-bold flex gap-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<UserRound className='text-brand-purple/80' />
|
||||
<span className='text-foreground'>Active Members Count: </span> <span className='text-brand-purple font-medium'>{totalMembers}</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Search Bar */}
|
||||
<div className="mb-24 w-full">
|
||||
<div className=" w-full flex gap-3">
|
||||
<div className="relative w-full ">
|
||||
|
||||
<Search className="absolute left-4 top-1/2 transform -translate-y-1/2 h-5 w-5 text-brand-purple " />
|
||||
<Input
|
||||
type="text"
|
||||
@@ -169,17 +204,19 @@ const MembersDirectory = () => {
|
||||
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
|
||||
/>
|
||||
</div>
|
||||
{searchQuery && (
|
||||
<p className="mt-3 text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Found {filteredMembers.length} {filteredMembers.length === 1 ? 'member' : 'members'}
|
||||
</p>
|
||||
)}
|
||||
<Button size='lg' className='self-center bg-brand-purple hover:bg-brand-purple/90 px-16'>Search</Button>
|
||||
<Button className='text-brand-purple/80 bg-transparent hover:bg-transparent hover:underline shadow-none p-2 self-center'>Clear Search</Button>
|
||||
</div>
|
||||
{searchQuery && (
|
||||
<p className="mt-3 text-sm ml-6 text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif " }}>
|
||||
Found {filteredMembers.length} {filteredMembers.length === 1 ? 'member' : 'members'}
|
||||
</p>
|
||||
)}
|
||||
<div className='mb-24'></div>
|
||||
|
||||
</div>
|
||||
{/* Border Decoration */}
|
||||
|
||||
<Border />
|
||||
<Border className='' />
|
||||
|
||||
{/* Members Grid */}
|
||||
{loading ? (
|
||||
@@ -206,23 +243,21 @@ const MembersDirectory = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
{/* Border Decoration */}
|
||||
<Border yaxis="true" />
|
||||
{/* todo: use badge to display if member */}
|
||||
{/* Info Card */}
|
||||
{!loading && members.length > 0 && (
|
||||
<Card className="mt-12 p-6 bg-[var(--lavender-500)] border-[var(--neutral-800)]">
|
||||
<Card className="mt-12 p-4 bg-[var(--lavender-500)] border-[var(--neutral-800)]">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="bg-[var(--neutral-800)]/20 p-3 rounded-lg">
|
||||
<User className="h-6 w-6 text-brand-purple " />
|
||||
<div className="bg-[var(--neutral-800)]/20 rounded-lg">
|
||||
<CircleUserRound className="size-20 text-brand-lavender " />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
<div className='self-center'>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2" style={{ fontFamily: "'Poppins', sans-serif" }}>
|
||||
Want to appear in the directory?
|
||||
</h3>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple/90 font-medium " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Update your profile settings to show in the directory and add your photo, bio, and contact information.{' '}
|
||||
|
||||
<Link to="/profile" className="text-[var(--orange-light)] hover:underline font-medium">
|
||||
@@ -432,16 +467,16 @@ const MembersDirectory = () => {
|
||||
<Button
|
||||
onClick={() => setCurrentPage(1)}
|
||||
disabled={currentPage === 1}
|
||||
className="bg-[var(--neutral-800)] rounded-full text-[var(--purple-ink)] hover:bg-brand-purple hover:text-white"
|
||||
className="bg-transparent text-brand-purple shadow-none "
|
||||
>
|
||||
First Page
|
||||
<ChevronsLeft />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setCurrentPage((page) => Math.max(1, page - 1))}
|
||||
disabled={currentPage === 1}
|
||||
className="bg-[var(--neutral-800)] rounded-full text-[var(--purple-ink)] hover:bg-brand-purple hover:text-white"
|
||||
className="bg-transparent text-brand-purple shadow-none"
|
||||
>
|
||||
Previous
|
||||
<ChevronLeft size={64} />
|
||||
</Button>
|
||||
|
||||
{Array.from({ length: totalPages }, (_, index) => {
|
||||
@@ -465,16 +500,17 @@ const MembersDirectory = () => {
|
||||
<Button
|
||||
onClick={() => setCurrentPage((page) => Math.min(totalPages, page + 1))}
|
||||
disabled={currentPage === totalPages}
|
||||
className="bg-[var(--neutral-800)] text-[var(--purple-ink)] hover:bg-brand-purple rounded-full hover:text-white"
|
||||
className="bg-transparent text-brand-purple shadow-none"
|
||||
>
|
||||
Next
|
||||
<ChevronRight />
|
||||
</Button>
|
||||
<Button
|
||||
onClick={() => setCurrentPage(totalPages)}
|
||||
disabled={currentPage === totalPages}
|
||||
className="bg-[var(--neutral-800)] text-[var(--purple-ink)] hover:bg-brand-purple rounded-full hover:text-white"
|
||||
className="bg-transparent text-brand-purple shadow-none"
|
||||
>
|
||||
Last Page
|
||||
<ChevronsRight />
|
||||
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -95,7 +95,7 @@ export default function NewsletterArchive() {
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="min-h-screen bg-background">
|
||||
<div className="min-h-screen bg-gradient-to-b from-[var(--neutral-100)] to-[var(--neutral-800)]">
|
||||
<Navbar />
|
||||
|
||||
<div className="max-w-7xl mx-auto px-6 py-12">
|
||||
|
||||
Reference in New Issue
Block a user