Refactor color scheme in member-related pages to use brand colors instead of CSS variables for consistency and improved readability
This commit is contained in:
@@ -187,7 +187,7 @@ export default function AddToCalendarButton({
|
||||
>
|
||||
<RefreshCw className="h-4 w-4 mr-2" />
|
||||
Subscribe to My Events
|
||||
<div className="text-xs text-[var(--purple-lavender)] mt-0.5">
|
||||
<div className="text-xs text-brand-purple mt-0.5">
|
||||
Auto-syncs your RSVP'd events
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
@@ -198,7 +198,7 @@ export default function AddToCalendarButton({
|
||||
>
|
||||
<Download className="h-4 w-4 mr-2" />
|
||||
Download All Events
|
||||
<div className="text-xs text-[var(--purple-lavender)] mt-0.5">
|
||||
<div className="text-xs text-brand-purple mt-0.5">
|
||||
One-time import of all upcoming events
|
||||
</div>
|
||||
</DropdownMenuItem>
|
||||
@@ -206,7 +206,7 @@ export default function AddToCalendarButton({
|
||||
)}
|
||||
|
||||
{!event && !showSubscribe && (
|
||||
<div className="px-2 py-6 text-center text-sm text-[var(--purple-lavender)]">
|
||||
<div className="px-2 py-6 text-center text-sm text-brand-purple ">
|
||||
No event selected
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -211,7 +211,7 @@ const AdminSidebar = ({ isOpen, onToggle, isMobile }) => {
|
||||
className={`
|
||||
flex items-center gap-3 px-4 py-3 rounded-lg transition-all relative
|
||||
${item.disabled
|
||||
? 'opacity-50 cursor-not-allowed text-[var(--purple-lavender)]'
|
||||
? 'opacity-50 cursor-not-allowed text-brand-purple '
|
||||
: active
|
||||
? 'bg-[var(--orange-light)]/10 text-[var(--orange-light)]'
|
||||
: 'text-[var(--purple-ink)] hover:bg-[var(--neutral-800)]/20'
|
||||
|
||||
@@ -64,12 +64,12 @@ export const AttendanceDialog = ({ event, open, onOpenChange, onSuccess }) => {
|
||||
|
||||
<div className="space-y-4 mt-4">
|
||||
{rsvps.length === 0 ? (
|
||||
<p className="text-center text-[var(--purple-lavender)] py-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>No RSVPs yet</p>
|
||||
<p className="text-center text-brand-purple py-8" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>No RSVPs yet</p>
|
||||
) : (
|
||||
rsvps.map((rsvp) => (
|
||||
<div
|
||||
key={rsvp.user_id}
|
||||
className="flex items-center gap-3 p-4 border-2 border-[var(--neutral-800)] rounded-xl hover:border-[var(--purple-lavender)] transition-colors"
|
||||
className="flex items-center gap-3 p-4 border-2 border-[var(--neutral-800)] rounded-xl hover:border-brand-purple transition-colors"
|
||||
>
|
||||
<Checkbox
|
||||
checked={attendance[rsvp.user_id] || false}
|
||||
@@ -80,7 +80,7 @@ export const AttendanceDialog = ({ event, open, onOpenChange, onSuccess }) => {
|
||||
/>
|
||||
<div className="flex-1">
|
||||
<p className="font-medium text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>{rsvp.user_name}</p>
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{rsvp.user_email}</p>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>{rsvp.user_email}</p>
|
||||
</div>
|
||||
{rsvp.attended && (
|
||||
<span className="text-sm text-[var(--green-light)] font-medium">
|
||||
@@ -103,7 +103,7 @@ export const AttendanceDialog = ({ event, open, onOpenChange, onSuccess }) => {
|
||||
<Button
|
||||
onClick={() => onOpenChange(false)}
|
||||
variant="outline"
|
||||
className="flex-1 border-2 border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-background hover:text-[var(--purple-ink)] rounded-full"
|
||||
className="flex-1 border-2 border-[var(--neutral-800)] text-brand-purple hover:bg-background hover:text-[var(--purple-ink)] rounded-full"
|
||||
>
|
||||
Cancel
|
||||
</Button>
|
||||
|
||||
@@ -76,7 +76,7 @@ const ChangePasswordDialog = ({ open, onOpenChange }) => {
|
||||
Change Password
|
||||
</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Update your password to keep your account secure.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -92,7 +92,7 @@ const ChangePasswordDialog = ({ open, onOpenChange }) => {
|
||||
value={formData.currentPassword}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Enter current password"
|
||||
className="h-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -106,7 +106,7 @@ const ChangePasswordDialog = ({ open, onOpenChange }) => {
|
||||
value={formData.newPassword}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Enter new password (min. 6 characters)"
|
||||
className="h-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -120,7 +120,7 @@ const ChangePasswordDialog = ({ open, onOpenChange }) => {
|
||||
value={formData.confirmPassword}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Re-enter new password"
|
||||
className="h-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ const ConfirmationDialog = ({
|
||||
},
|
||||
info: {
|
||||
icon: Info,
|
||||
iconColor: 'text-[var(--purple-lavender)]',
|
||||
confirmButtonClass: 'bg-[var(--purple-lavender)] text-white hover:bg-[var(--purple-plum)] rounded-full px-6',
|
||||
iconColor: 'text-brand-purple ',
|
||||
confirmButtonClass: 'bg-brand-purple text-white hover:bg-[var(--purple-plum)] rounded-full px-6',
|
||||
},
|
||||
success: {
|
||||
icon: CheckCircle,
|
||||
@@ -77,7 +77,7 @@ const ConfirmationDialog = ({
|
||||
{title}
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription
|
||||
className="text-[var(--purple-lavender)] text-sm leading-relaxed"
|
||||
className="text-brand-purple text-sm leading-relaxed"
|
||||
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
|
||||
>
|
||||
{description}
|
||||
@@ -87,7 +87,7 @@ const ConfirmationDialog = ({
|
||||
</AlertDialogHeader>
|
||||
<AlertDialogFooter className="p-6 pt-4 bg-[var(--lavender-500)] flex-row gap-3 justify-end">
|
||||
<AlertDialogCancel
|
||||
className="border-2 border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-background rounded-full px-6"
|
||||
className="border-2 border-[var(--neutral-800)] text-brand-purple hover:bg-background rounded-full px-6"
|
||||
disabled={loading}
|
||||
>
|
||||
{cancelText}
|
||||
|
||||
@@ -125,7 +125,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
<UserPlus className="h-6 w-6" />
|
||||
Create Member
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Create a new member account with direct login access. Member will be created immediately.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -143,7 +143,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="email"
|
||||
value={formData.email}
|
||||
onChange={(e) => handleChange('email', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="member@example.com"
|
||||
/>
|
||||
{errors.email && (
|
||||
@@ -160,7 +160,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="password"
|
||||
value={formData.password}
|
||||
onChange={(e) => handleChange('password', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="Minimum 8 characters"
|
||||
/>
|
||||
{errors.password && (
|
||||
@@ -179,7 +179,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="first_name"
|
||||
value={formData.first_name}
|
||||
onChange={(e) => handleChange('first_name', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="John"
|
||||
/>
|
||||
{errors.first_name && (
|
||||
@@ -195,7 +195,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="last_name"
|
||||
value={formData.last_name}
|
||||
onChange={(e) => handleChange('last_name', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="Doe"
|
||||
/>
|
||||
{errors.last_name && (
|
||||
@@ -214,7 +214,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="tel"
|
||||
value={formData.phone}
|
||||
onChange={(e) => handleChange('phone', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
{errors.phone && (
|
||||
@@ -231,7 +231,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="address"
|
||||
value={formData.address}
|
||||
onChange={(e) => handleChange('address', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="123 Main St"
|
||||
/>
|
||||
</div>
|
||||
@@ -244,7 +244,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="city"
|
||||
value={formData.city}
|
||||
onChange={(e) => handleChange('city', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="San Francisco"
|
||||
/>
|
||||
</div>
|
||||
@@ -255,7 +255,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="state"
|
||||
value={formData.state}
|
||||
onChange={(e) => handleChange('state', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="CA"
|
||||
maxLength={2}
|
||||
/>
|
||||
@@ -267,7 +267,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="zipcode"
|
||||
value={formData.zipcode}
|
||||
onChange={(e) => handleChange('zipcode', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="94102"
|
||||
/>
|
||||
</div>
|
||||
@@ -282,7 +282,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="date"
|
||||
value={formData.date_of_birth}
|
||||
onChange={(e) => handleChange('date_of_birth', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -293,7 +293,7 @@ const CreateMemberDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="date"
|
||||
value={formData.member_since}
|
||||
onChange={(e) => handleChange('member_since', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -105,7 +105,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
<UserPlus className="h-6 w-6" />
|
||||
Create Staff Member
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Create a new staff account with direct login access. User will be created immediately.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -122,7 +122,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="email"
|
||||
value={formData.email}
|
||||
onChange={(e) => handleChange('email', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="staff@example.com"
|
||||
/>
|
||||
{errors.email && (
|
||||
@@ -140,7 +140,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="password"
|
||||
value={formData.password}
|
||||
onChange={(e) => handleChange('password', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="Minimum 8 characters"
|
||||
/>
|
||||
{errors.password && (
|
||||
@@ -157,7 +157,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="first_name"
|
||||
value={formData.first_name}
|
||||
onChange={(e) => handleChange('first_name', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="John"
|
||||
/>
|
||||
{errors.first_name && (
|
||||
@@ -174,7 +174,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="last_name"
|
||||
value={formData.last_name}
|
||||
onChange={(e) => handleChange('last_name', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="Doe"
|
||||
/>
|
||||
{errors.last_name && (
|
||||
@@ -192,7 +192,7 @@ const CreateStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="tel"
|
||||
value={formData.phone}
|
||||
onChange={(e) => handleChange('phone', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
{errors.phone && (
|
||||
|
||||
@@ -144,7 +144,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
<Upload className="h-6 w-6" />
|
||||
{importResult ? 'Import Results' : 'Import Members from CSV'}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{importResult
|
||||
? 'Review the import results below'
|
||||
: 'Upload a CSV file to bulk import members. Ensure the CSV has the required columns.'}
|
||||
@@ -155,7 +155,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
// Upload Form
|
||||
<div className="grid gap-6 py-4">
|
||||
{/* CSV Format Instructions */}
|
||||
<Alert className="border-[var(--purple-lavender)] bg-[var(--lavender-700)]">
|
||||
<Alert className="border-brand-purple bg-[var(--lavender-700)]">
|
||||
<AlertDescription className="text-sm text-[var(--purple-ink)]">
|
||||
<strong>Required columns:</strong> Email, First Name, Last Name, Phone, Role
|
||||
<br />
|
||||
@@ -168,8 +168,8 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
{/* File Upload Area */}
|
||||
<div
|
||||
className={`border-2 border-dashed rounded-2xl p-12 text-center transition-colors ${dragActive
|
||||
? 'border-[var(--purple-lavender)] bg-[var(--lavender-700)]'
|
||||
: 'border-[var(--neutral-800)] hover:border-[var(--purple-lavender)] hover:bg-[var(--lavender-700)]'
|
||||
? 'border-brand-purple bg-[var(--lavender-700)]'
|
||||
: 'border-[var(--neutral-800)] hover:border-brand-purple hover:bg-[var(--lavender-700)]'
|
||||
}`}
|
||||
onDragEnter={handleDrag}
|
||||
onDragLeave={handleDrag}
|
||||
@@ -183,7 +183,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
<p className="text-lg font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
{file.name}
|
||||
</p>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
{(file.size / 1024).toFixed(2)} KB
|
||||
</p>
|
||||
</div>
|
||||
@@ -203,7 +203,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
<p className="text-lg font-semibold text-[var(--purple-ink)] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
Drag and drop your CSV file here
|
||||
</p>
|
||||
<p className="text-sm text-[var(--purple-lavender)] mb-4">or</p>
|
||||
<p className="text-sm text-brand-purple mb-4">or</p>
|
||||
<Label htmlFor="file-upload">
|
||||
<Button variant="outline" className="rounded-xl cursor-pointer" asChild>
|
||||
<span>Browse Files</span>
|
||||
@@ -227,7 +227,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
checked={updateExisting}
|
||||
onCheckedChange={setUpdateExisting}
|
||||
id="update-existing"
|
||||
className="h-5 w-5 border-2 border-[var(--purple-lavender)] data-[state=checked]:bg-[var(--purple-lavender)]"
|
||||
className="h-5 w-5 border-2 border-brand-purple data-[state=checked]:bg-brand-purple "
|
||||
/>
|
||||
<Label htmlFor="update-existing" className="text-[var(--purple-ink)] cursor-pointer">
|
||||
Update existing members (if email already exists)
|
||||
@@ -240,7 +240,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
{/* Summary Cards */}
|
||||
<div className="grid md:grid-cols-4 gap-4">
|
||||
<div className="p-4 bg-background rounded-xl border border-[var(--neutral-800)] text-center">
|
||||
<p className="text-sm text-[var(--purple-lavender)] mb-1">Total Rows</p>
|
||||
<p className="text-sm text-brand-purple mb-1">Total Rows</p>
|
||||
<p className="text-2xl font-semibold text-[var(--purple-ink)]">{importResult.total_rows}</p>
|
||||
</div>
|
||||
<div className="p-4 bg-green-50 rounded-xl border border-green-200 text-center">
|
||||
@@ -276,7 +276,7 @@ const ImportMembersDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
{importResult.errors.map((error, idx) => (
|
||||
<TableRow key={idx} className="hover:bg-[var(--lavender-700)]">
|
||||
<TableCell className="font-medium text-[var(--purple-ink)]">{error.row}</TableCell>
|
||||
<TableCell className="text-[var(--purple-lavender)]">{error.email}</TableCell>
|
||||
<TableCell className="text-brand-purple ">{error.email}</TableCell>
|
||||
<TableCell className="text-red-600 text-sm">{error.error}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
||||
@@ -129,7 +129,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
<Mail className="h-6 w-6" />
|
||||
{invitationUrl ? 'Invitation Sent' : 'Invite Staff Member'}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{invitationUrl
|
||||
? 'The invitation has been sent via email. You can also copy the link below.'
|
||||
: 'Send an email invitation to join as staff. They will set their own password.'}
|
||||
@@ -148,7 +148,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
/>
|
||||
<Button
|
||||
onClick={copyToClipboard}
|
||||
className="rounded-xl bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)] text-white flex-shrink-0"
|
||||
className="rounded-xl bg-brand-purple hover:bg-[var(--purple-ink)] text-white flex-shrink-0"
|
||||
>
|
||||
{copied ? (
|
||||
<>
|
||||
@@ -178,7 +178,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="email"
|
||||
value={formData.email}
|
||||
onChange={(e) => handleChange('email', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="staff@example.com"
|
||||
/>
|
||||
{errors.email && (
|
||||
@@ -195,7 +195,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="first_name"
|
||||
value={formData.first_name}
|
||||
onChange={(e) => handleChange('first_name', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="John"
|
||||
/>
|
||||
</div>
|
||||
@@ -209,7 +209,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
id="last_name"
|
||||
value={formData.last_name}
|
||||
onChange={(e) => handleChange('last_name', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="Doe"
|
||||
/>
|
||||
</div>
|
||||
@@ -224,7 +224,7 @@ const InviteStaffDialog = ({ open, onOpenChange, onSuccess }) => {
|
||||
type="tel"
|
||||
value={formData.phone}
|
||||
onChange={(e) => handleChange('phone', e.target.value)}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
placeholder="(555) 123-4567"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,7 @@ import { Calendar, Users, User, BookOpen, FileText, DollarSign, Scale } from 'lu
|
||||
|
||||
const MemberFooter = () => {
|
||||
return (
|
||||
<footer className="bg-[var(--purple-ink)] text-white mt-auto">
|
||||
<footer className="bg-brand-dark-lavender text-white mt-auto">
|
||||
<div className="max-w-7xl mx-auto px-6 py-12">
|
||||
<div className="grid md:grid-cols-4 gap-8">
|
||||
{/* Logo & About */}
|
||||
@@ -89,12 +89,12 @@ const MemberFooter = () => {
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/#contact" className="text-gray-300 hover:text-white transition-colors">
|
||||
<a href="/membership/contact-us" className="text-gray-300 hover:text-white transition-colors">
|
||||
Contact Us
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/#donate" className="text-gray-300 hover:text-white transition-colors">
|
||||
<a href="/membership/donate" className="text-gray-300 hover:text-white transition-colors">
|
||||
Donate
|
||||
</a>
|
||||
</li>
|
||||
@@ -106,10 +106,10 @@ const MemberFooter = () => {
|
||||
{/* Bottom Bar */}
|
||||
<div className="border-t border-[var(--purple-lavender)]">
|
||||
<div className="max-w-7xl mx-auto px-6 py-4">
|
||||
<div className="flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-gray-400" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<div className="flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-gray-300" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<div className="flex gap-6">
|
||||
<a href="/#terms" className="hover:text-white transition-colors">Terms of Service</a>
|
||||
<a href="/#privacy" className="hover:text-white transition-colors">Privacy Policy</a>
|
||||
<a href="/membership/terms-of-service" className="hover:text-white transition-colors">Terms of Service</a>
|
||||
<a href="/membership/privacy-policy" className="hover:text-white transition-colors">Privacy Policy</a>
|
||||
</div>
|
||||
<p>© 2025 LOAF. All rights reserved.</p>
|
||||
</div>
|
||||
|
||||
@@ -162,7 +162,7 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
<DialogTitle className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
Activate Manual Payment
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Record offline payment for {user.first_name} {user.last_name} ({user.email})
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -203,7 +203,7 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
</SelectContent>
|
||||
</Select>
|
||||
{selectedPlan && (
|
||||
<p className="text-xs text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-xs text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{selectedPlan.description || `${selectedPlan.billing_cycle} subscription`}
|
||||
</p>
|
||||
)}
|
||||
@@ -222,11 +222,11 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
placeholder="Enter amount"
|
||||
value={formData.amount}
|
||||
onChange={(e) => setFormData({ ...formData, amount: e.target.value })}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
required
|
||||
/>
|
||||
{selectedPlan && (
|
||||
<p className="text-xs text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-xs text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Minimum: {formatPrice(selectedPlan.minimum_price_cents || selectedPlan.price_cents || 3000)}
|
||||
</p>
|
||||
)}
|
||||
@@ -263,13 +263,13 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
Payment Date
|
||||
</Label>
|
||||
<div className="relative">
|
||||
<Calendar className="absolute left-4 top-1/2 transform -translate-y-1/2 h-5 w-5 text-[var(--purple-lavender)]" />
|
||||
<Calendar className="absolute left-4 top-1/2 transform -translate-y-1/2 h-5 w-5 text-brand-purple " />
|
||||
<Input
|
||||
id="payment_date"
|
||||
type="date"
|
||||
value={formData.payment_date}
|
||||
onChange={(e) => setFormData({ ...formData, payment_date: e.target.value })}
|
||||
className="pl-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="pl-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
@@ -308,7 +308,7 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
onChange={(e) => setUseCustomPeriod(e.target.checked)}
|
||||
className="rounded border-[var(--neutral-800)]"
|
||||
/>
|
||||
<Label htmlFor="use_custom_period" className="text-sm text-[var(--purple-lavender)] font-normal cursor-pointer" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<Label htmlFor="use_custom_period" className="text-sm text-brand-purple font-normal cursor-pointer" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Use custom dates instead of plan's billing cycle
|
||||
</Label>
|
||||
</div>
|
||||
@@ -324,7 +324,7 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
type="date"
|
||||
value={formData.custom_period_start}
|
||||
onChange={(e) => setFormData({ ...formData, custom_period_start: e.target.value })}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
required={useCustomPeriod}
|
||||
/>
|
||||
</div>
|
||||
@@ -337,14 +337,14 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
type="date"
|
||||
value={formData.custom_period_end}
|
||||
onChange={(e) => setFormData({ ...formData, custom_period_end: e.target.value })}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
required={useCustomPeriod}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
selectedPlan && (
|
||||
<div className="text-sm text-[var(--purple-lavender)] bg-[var(--lavender-300)] p-3 rounded-lg space-y-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<div className="text-sm text-brand-purple bg-[var(--lavender-300)] p-3 rounded-lg space-y-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{selectedPlan.custom_cycle_enabled ? (
|
||||
<>
|
||||
<p>
|
||||
@@ -386,7 +386,7 @@ const PaymentActivationDialog = ({ open, onOpenChange, user, onSuccess }) => {
|
||||
placeholder="Additional notes about the payment..."
|
||||
value={formData.notes}
|
||||
onChange={(e) => setFormData({ ...formData, notes: e.target.value })}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)] min-h-[100px]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple min-h-[100px]"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ const PendingInvitationsTable = () => {
|
||||
|
||||
const getRoleBadge = (role) => {
|
||||
const config = {
|
||||
superadmin: { label: 'Superadmin', className: 'bg-[var(--purple-lavender)] text-white' },
|
||||
superadmin: { label: 'Superadmin', className: 'bg-brand-purple text-white' },
|
||||
admin: { label: 'Admin', className: 'bg-[var(--green-light)] text-white' },
|
||||
member: { label: 'Member', className: 'bg-[var(--neutral-800)] text-[var(--purple-ink)]' }
|
||||
};
|
||||
@@ -111,7 +111,7 @@ const PendingInvitationsTable = () => {
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="text-center py-8">
|
||||
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Loading invitations...
|
||||
</p>
|
||||
</div>
|
||||
@@ -125,7 +125,7 @@ const PendingInvitationsTable = () => {
|
||||
<h3 className="text-xl font-semibold text-[var(--purple-ink)] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
No Pending Invitations
|
||||
</h3>
|
||||
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
All invitations have been accepted or expired
|
||||
</p>
|
||||
</Card>
|
||||
@@ -152,19 +152,19 @@ const PendingInvitationsTable = () => {
|
||||
<TableCell className="font-medium text-[var(--purple-ink)]">
|
||||
{invitation.email}
|
||||
</TableCell>
|
||||
<TableCell className="text-[var(--purple-lavender)]">
|
||||
<TableCell className="text-brand-purple ">
|
||||
{invitation.first_name && invitation.last_name
|
||||
? `${invitation.first_name} ${invitation.last_name}`
|
||||
: '-'}
|
||||
</TableCell>
|
||||
<TableCell>{getRoleBadge(invitation.role)}</TableCell>
|
||||
<TableCell className="text-[var(--purple-lavender)]">
|
||||
<TableCell className="text-brand-purple ">
|
||||
{new Date(invitation.invited_at).toLocaleDateString()}
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock className={`h-4 w-4 ${isExpiringSoon(invitation.expires_at) ? 'text-orange-500' : 'text-[var(--purple-lavender)]'}`} />
|
||||
<span className={`text-sm ${isExpiringSoon(invitation.expires_at) ? 'text-orange-500 font-semibold' : 'text-[var(--purple-lavender)]'}`}>
|
||||
<Clock className={`h-4 w-4 ${isExpiringSoon(invitation.expires_at) ? 'text-orange-500' : 'text-brand-purple '}`} />
|
||||
<span className={`text-sm ${isExpiringSoon(invitation.expires_at) ? 'text-orange-500 font-semibold' : 'text-brand-purple '}`}>
|
||||
{formatDate(invitation.expires_at)}
|
||||
</span>
|
||||
</div>
|
||||
@@ -211,7 +211,7 @@ const PendingInvitationsTable = () => {
|
||||
<AlertDialogTitle className="text-2xl text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
Revoke Invitation
|
||||
</AlertDialogTitle>
|
||||
<AlertDialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<AlertDialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Are you sure you want to revoke the invitation for{' '}
|
||||
<span className="font-semibold">{revokeDialog.invitation?.email}</span>?
|
||||
This action cannot be undone.
|
||||
|
||||
@@ -164,7 +164,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
<DialogTitle className="text-2xl text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
{plan ? 'Edit Plan' : 'Create New Plan'}
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{plan ? 'Update plan details below' : 'Enter plan details to create a new subscription plan'}
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -216,7 +216,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
required
|
||||
className="mt-2"
|
||||
/>
|
||||
<p className="text-xs text-[var(--purple-lavender)] mt-1">Minimum $30</p>
|
||||
<p className="text-xs text-brand-purple mt-1">Minimum $30</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -232,7 +232,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
required
|
||||
className="mt-2"
|
||||
/>
|
||||
<p className="text-xs text-[var(--purple-lavender)] mt-1">Pre-filled amount</p>
|
||||
<p className="text-xs text-brand-purple mt-1">Pre-filled amount</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -240,7 +240,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
<div className="flex items-center justify-between pt-2">
|
||||
<div>
|
||||
<Label htmlFor="allow_donation">Allow Donations</Label>
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Members can pay more than minimum
|
||||
</p>
|
||||
</div>
|
||||
@@ -252,7 +252,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
onChange={(e) => setFormData({ ...formData, allow_donation: e.target.checked })}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[var(--purple-lavender)]/20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-background after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--green-light)]"></div>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-brand-purple /20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-background after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--green-light)]"></div>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
@@ -283,7 +283,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
<h3 className="font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
Custom Billing Period
|
||||
</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Set recurring date range (e.g., Jan 1 - Dec 31 for calendar year)
|
||||
</p>
|
||||
|
||||
@@ -361,7 +361,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<Label htmlFor="active">Active Status</Label>
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Inactive plans won't appear for new subscriptions
|
||||
</p>
|
||||
</div>
|
||||
@@ -373,7 +373,7 @@ const PlanDialog = ({ open, onOpenChange, plan, onSuccess }) => {
|
||||
onChange={(e) => setFormData({ ...formData, active: e.target.checked })}
|
||||
className="sr-only peer"
|
||||
/>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-[var(--purple-lavender)]/20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-background after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--green-light)]"></div>
|
||||
<div className="w-11 h-6 bg-gray-200 peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-brand-purple /20 rounded-full peer peer-checked:after:translate-x-full peer-checked:after:border-white after:content-[''] after:absolute after:top-[2px] after:left-[2px] after:bg-background after:border-gray-300 after:border after:rounded-full after:h-5 after:w-5 after:transition-all peer-checked:bg-[var(--green-light)]"></div>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -105,7 +105,7 @@ const PublicNavbar = () => {
|
||||
</header>
|
||||
|
||||
{/* Main Header - Navigation */}
|
||||
<header className=" bg-[var(--purple-lavender)] px-[20px] py-2 flex justify-between items-center">
|
||||
<header className=" bg-brand-purple px-[20px] py-2 flex justify-between items-center">
|
||||
<Link to="/">
|
||||
<img src={loafLogo} alt="LOAF Logo" className="h-16 w-16 sm:h-20 sm:w-20 md:h-28 md:w-28 object-contain" />
|
||||
</Link>
|
||||
@@ -204,7 +204,7 @@ const PublicNavbar = () => {
|
||||
/>
|
||||
|
||||
{/* Drawer */}
|
||||
<div className="fixed right-0 top-0 h-full w-[280px] bg-[var(--purple-lavender)] shadow-xl overflow-y-auto">
|
||||
<div className="fixed right-0 top-0 h-full w-[280px] bg-brand-purple shadow-xl overflow-y-auto">
|
||||
{/* Header */}
|
||||
<div className="flex justify-between items-center p-6 border-b border-[var(--purple-deep)]">
|
||||
<span className="text-white text-lg font-semibold" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
|
||||
@@ -41,17 +41,17 @@ export default function RejectionDialog({ open, onOpenChange, onConfirm, user, l
|
||||
Reject Application
|
||||
</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<DialogDescription className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
You are about to reject <strong>{user?.first_name} {user?.last_name}</strong>'s membership application.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
|
||||
<div className="space-y-4 py-4">
|
||||
<div className="bg-[var(--lavender-400)] border border-[var(--neutral-800)] rounded-lg p-4">
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<strong>Applicant:</strong> {user?.email}
|
||||
</p>
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<strong>Status:</strong> {user?.status}
|
||||
</p>
|
||||
</div>
|
||||
@@ -74,7 +74,7 @@ export default function RejectionDialog({ open, onOpenChange, onConfirm, user, l
|
||||
{error && (
|
||||
<p className="text-sm text-red-500">{error}</p>
|
||||
)}
|
||||
<p className="text-xs text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-xs text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
The applicant will receive an email with this reason.
|
||||
</p>
|
||||
</div>
|
||||
@@ -85,7 +85,7 @@ export default function RejectionDialog({ open, onOpenChange, onConfirm, user, l
|
||||
type="button"
|
||||
onClick={handleClose}
|
||||
variant="outline"
|
||||
className="border-2 border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-[var(--lavender-300)] rounded-full px-6"
|
||||
className="border-2 border-[var(--neutral-800)] text-brand-purple hover:bg-[var(--lavender-300)] rounded-full px-6"
|
||||
disabled={loading}
|
||||
>
|
||||
<X className="h-4 w-4 mr-2" />
|
||||
|
||||
@@ -371,14 +371,14 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2">Upload WordPress CSV Export</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
Select the WordPress user export CSV file. The file will be analyzed for data quality issues.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<Card className="p-6 border-2 border-dashed border-[var(--neutral-800)] bg-[var(--lavender-400)]">
|
||||
<div className="flex flex-col items-center gap-4">
|
||||
<Upload className="h-12 w-12 text-[var(--purple-lavender)]" />
|
||||
<Upload className="h-12 w-12 text-brand-purple " />
|
||||
<div className="text-center">
|
||||
<Input
|
||||
type="file"
|
||||
@@ -387,7 +387,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
className="max-w-xs"
|
||||
/>
|
||||
{uploadedFile && (
|
||||
<p className="text-sm text-[var(--purple-lavender)] mt-2">
|
||||
<p className="text-sm text-brand-purple mt-2">
|
||||
Selected: {uploadedFile.name}
|
||||
</p>
|
||||
)}
|
||||
@@ -399,7 +399,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<Button
|
||||
onClick={handleUpload}
|
||||
disabled={uploading}
|
||||
className="w-full bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)]"
|
||||
className="w-full bg-brand-purple hover:bg-[var(--purple-ink)]"
|
||||
>
|
||||
{uploading ? (
|
||||
<>
|
||||
@@ -466,7 +466,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2">Field Mapping</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
WordPress fields have been automatically mapped to LOAF platform fields.
|
||||
</p>
|
||||
</div>
|
||||
@@ -538,7 +538,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2">Review & Adjust User Status</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
Review suggested status mappings and override as needed before import.
|
||||
</p>
|
||||
</div>
|
||||
@@ -550,7 +550,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
checked={selectedRows.size === previewData.length && previewData.length > 0}
|
||||
onCheckedChange={toggleSelectAll}
|
||||
/>
|
||||
<span className="text-sm text-[var(--purple-lavender)] font-medium">
|
||||
<span className="text-sm text-brand-purple font-medium">
|
||||
{selectedRows.size > 0 ? `${selectedRows.size} selected` : 'Select all'}
|
||||
</span>
|
||||
{selectedRows.size > 0 && (
|
||||
@@ -572,7 +572,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
{/* Data table */}
|
||||
{loading ? (
|
||||
<div className="flex items-center justify-center py-12">
|
||||
<Loader2 className="h-8 w-8 animate-spin text-[var(--purple-lavender)]" />
|
||||
<Loader2 className="h-8 w-8 animate-spin text-brand-purple " />
|
||||
</div>
|
||||
) : (
|
||||
<div className="border rounded-lg overflow-hidden">
|
||||
@@ -651,7 +651,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
{/* Pagination */}
|
||||
{totalPages > 1 && (
|
||||
<div className="flex items-center justify-between">
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
Page {currentPage} of {totalPages}
|
||||
</p>
|
||||
<div className="flex gap-2">
|
||||
@@ -690,22 +690,22 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2">Import Preview</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
Review the final import settings before execution.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-3 gap-4">
|
||||
<Card className="p-6">
|
||||
<p className="text-sm text-[var(--purple-lavender)]">Total Users</p>
|
||||
<p className="text-sm text-brand-purple ">Total Users</p>
|
||||
<p className="text-3xl font-semibold text-[var(--purple-ink)]">{analysisResult?.total_rows}</p>
|
||||
</Card>
|
||||
<Card className="p-6">
|
||||
<p className="text-sm text-[var(--purple-lavender)]">Status Overrides</p>
|
||||
<p className="text-sm text-brand-purple ">Status Overrides</p>
|
||||
<p className="text-3xl font-semibold text-[var(--purple-ink)]">{overrideCount}</p>
|
||||
</Card>
|
||||
<Card className="p-6">
|
||||
<p className="text-sm text-[var(--purple-lavender)]">Expected Imports</p>
|
||||
<p className="text-sm text-brand-purple ">Expected Imports</p>
|
||||
<p className="text-3xl font-semibold text-[var(--purple-ink)]">{analysisResult?.valid_rows}</p>
|
||||
</Card>
|
||||
</div>
|
||||
@@ -715,15 +715,15 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div className="space-y-3">
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircle className="h-5 w-5 text-green-600" />
|
||||
<span className="text-sm text-[var(--purple-lavender)]">Send password reset emails to all imported users</span>
|
||||
<span className="text-sm text-brand-purple ">Send password reset emails to all imported users</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircle className="h-5 w-5 text-green-600" />
|
||||
<span className="text-sm text-[var(--purple-lavender)]">Skip rows with errors and continue import</span>
|
||||
<span className="text-sm text-brand-purple ">Skip rows with errors and continue import</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<CheckCircle className="h-5 w-5 text-green-600" />
|
||||
<span className="text-sm text-[var(--purple-lavender)]">Full rollback capability available after import</span>
|
||||
<span className="text-sm text-brand-purple ">Full rollback capability available after import</span>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
@@ -751,7 +751,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2">
|
||||
{importing ? 'Import in Progress...' : 'Ready to Import'}
|
||||
</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
{importing
|
||||
? 'Please wait while users are imported. This may take a few minutes.'
|
||||
: 'Click "Start Import" to begin importing users.'}
|
||||
@@ -761,7 +761,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
{importing && (
|
||||
<div className="space-y-4">
|
||||
<Progress value={importProgress} className="w-full" />
|
||||
<p className="text-center text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-center text-sm text-brand-purple ">
|
||||
{importProgress.toFixed(1)}% complete
|
||||
</p>
|
||||
</div>
|
||||
@@ -770,7 +770,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
{!importing && !importResults && (
|
||||
<Button
|
||||
onClick={handleExecuteImport}
|
||||
className="w-full bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)] py-6 text-lg"
|
||||
className="w-full bg-brand-purple hover:bg-[var(--purple-ink)] py-6 text-lg"
|
||||
>
|
||||
<Play className="mr-2 h-5 w-5" />
|
||||
Start Import
|
||||
@@ -787,7 +787,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div className="space-y-6">
|
||||
<div>
|
||||
<h3 className="text-lg font-semibold text-[var(--purple-ink)] mb-2">Import Complete</h3>
|
||||
<p className="text-sm text-[var(--purple-lavender)]">
|
||||
<p className="text-sm text-brand-purple ">
|
||||
Review the import results and download error reports if needed.
|
||||
</p>
|
||||
</div>
|
||||
@@ -854,7 +854,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
Confirm Rollback
|
||||
</DialogTitle>
|
||||
</div>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]">
|
||||
<DialogDescription className="text-brand-purple ">
|
||||
This will permanently delete{' '}
|
||||
<strong>{importResults?.successful_rows} users</strong> that were imported.
|
||||
This action cannot be undone.
|
||||
@@ -901,7 +901,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<DialogTitle className="text-2xl font-semibold text-[var(--purple-ink)]">
|
||||
WordPress Import Wizard
|
||||
</DialogTitle>
|
||||
<DialogDescription className="text-[var(--purple-lavender)]">
|
||||
<DialogDescription className="text-brand-purple ">
|
||||
Import WordPress users with interactive status review and full rollback capability
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
@@ -919,7 +919,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<div
|
||||
className={`
|
||||
w-10 h-10 rounded-full flex items-center justify-center
|
||||
${isCurrent ? 'bg-[var(--purple-lavender)] text-white' : ''}
|
||||
${isCurrent ? 'bg-brand-purple text-white' : ''}
|
||||
${isCompleted ? 'bg-green-600 text-white' : ''}
|
||||
${!isCurrent && !isCompleted ? 'bg-gray-200 text-gray-600' : ''}
|
||||
`}
|
||||
@@ -962,7 +962,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
<Button
|
||||
onClick={handleNext}
|
||||
disabled={!canProceed()}
|
||||
className="bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)]"
|
||||
className="bg-brand-purple hover:bg-[var(--purple-ink)]"
|
||||
>
|
||||
Next
|
||||
<ChevronRight className="h-4 w-4 ml-2" />
|
||||
@@ -975,7 +975,7 @@ export default function WordPressImportWizard({ open, onOpenChange, onSuccess })
|
||||
onOpenChange(false);
|
||||
if (onSuccess) onSuccess();
|
||||
}}
|
||||
className="bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)]"
|
||||
className="bg-brand-purple hover:bg-[var(--purple-ink)]"
|
||||
>
|
||||
Close
|
||||
</Button>
|
||||
|
||||
@@ -40,7 +40,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.first_name}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="first-name-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -52,7 +52,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.last_name}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="last-name-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -69,7 +69,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.phone}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="phone-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -82,7 +82,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.date_of_birth}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="dob-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -112,7 +112,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.city}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="city-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -124,7 +124,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.state}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="state-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -136,7 +136,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
required
|
||||
value={formData.zipcode}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="zipcode-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -179,7 +179,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
name="partner_first_name"
|
||||
value={formData.partner_first_name}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="partner-first-name-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -190,7 +190,7 @@ const RegistrationStep1 = ({ formData, setFormData, handleInputChange }) => {
|
||||
name="partner_last_name"
|
||||
value={formData.partner_last_name}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="partner-last-name-input"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -36,7 +36,7 @@ const RegistrationStep2 = ({ formData, setFormData, handleInputChange }) => {
|
||||
<h2 className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
Newsletter Publication Preferences *
|
||||
</h2>
|
||||
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Please check what information may be published in LOAF Newsletter
|
||||
</p>
|
||||
|
||||
@@ -110,10 +110,10 @@ const RegistrationStep2 = ({ formData, setFormData, handleInputChange }) => {
|
||||
value={formData.referred_by_member_name}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Enter member name or email"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="referral-input"
|
||||
/>
|
||||
<p className="text-sm text-[var(--purple-lavender)] mt-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple mt-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
If referred by a current member, you may skip the event attendance requirement.
|
||||
</p>
|
||||
</div>
|
||||
@@ -124,7 +124,7 @@ const RegistrationStep2 = ({ formData, setFormData, handleInputChange }) => {
|
||||
<h2 className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
|
||||
Volunteer Interests (Optional)
|
||||
</h2>
|
||||
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
I may at some time be interested in volunteering with LOAF in the following ways (training is provided)
|
||||
</p>
|
||||
|
||||
@@ -158,7 +158,7 @@ const RegistrationStep2 = ({ formData, setFormData, handleInputChange }) => {
|
||||
I am requesting for scholarship
|
||||
</Label>
|
||||
</div>
|
||||
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Scholarship information is kept confidential
|
||||
</p>
|
||||
|
||||
@@ -174,7 +174,7 @@ const RegistrationStep2 = ({ formData, setFormData, handleInputChange }) => {
|
||||
onChange={handleInputChange}
|
||||
placeholder="Tell us why you're requesting a scholarship..."
|
||||
rows={4}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -27,7 +27,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
Members Directory
|
||||
</h2>
|
||||
|
||||
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Would you like to be displayed on our private members directory? (optional and you can change the answer later)
|
||||
</p>
|
||||
|
||||
@@ -38,7 +38,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
p-4 rounded-xl border-2 cursor-pointer transition-all
|
||||
${formData.show_in_directory
|
||||
? 'border-[var(--orange-light)] bg-[var(--orange-light)]/5'
|
||||
: 'border-[var(--neutral-800)] hover:border-[var(--purple-lavender)]'
|
||||
: 'border-[var(--neutral-800)] hover:border-brand-purple '
|
||||
}
|
||||
`}
|
||||
onClick={() => setFormData(prev => ({ ...prev, show_in_directory: true }))}
|
||||
@@ -63,7 +63,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
p-4 rounded-xl border-2 cursor-pointer transition-all
|
||||
${!formData.show_in_directory
|
||||
? 'border-[var(--orange-light)] bg-[var(--orange-light)]/5'
|
||||
: 'border-[var(--neutral-800)] hover:border-[var(--purple-lavender)]'
|
||||
: 'border-[var(--neutral-800)] hover:border-brand-purple '
|
||||
}
|
||||
`}
|
||||
onClick={() => setFormData(prev => ({ ...prev, show_in_directory: false }))}
|
||||
@@ -88,7 +88,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
{/* Conditional Directory Fields */}
|
||||
{formData.show_in_directory && (
|
||||
<div className="space-y-4 mt-6 p-6 bg-background rounded-xl border border-[var(--neutral-800)]">
|
||||
<p className="text-[var(--purple-lavender)] text-sm" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple text-sm" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Below, choose what information you would like include in the Members Only Directory.
|
||||
(If you ever want to update this information, remember the Directory Section and Account Section are separate)
|
||||
</p>
|
||||
@@ -101,7 +101,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
type="email"
|
||||
value={formData.directory_email}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -114,7 +114,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
onChange={handleInputChange}
|
||||
placeholder="Tell other members about yourself..."
|
||||
rows={4}
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -125,7 +125,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
name="directory_address"
|
||||
value={formData.directory_address}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -137,7 +137,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
type="tel"
|
||||
value={formData.directory_phone}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -149,7 +149,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
type="date"
|
||||
value={formData.directory_dob}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -162,7 +162,7 @@ const RegistrationStep3 = ({ formData, setFormData, handleInputChange }) => {
|
||||
name="directory_partner_name"
|
||||
value={formData.directory_partner_name}
|
||||
onChange={handleInputChange}
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,7 +11,7 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
Account Credentials
|
||||
</h2>
|
||||
|
||||
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Your email is also your username that you can use to login.
|
||||
Please note you can only login after your application is validated.
|
||||
</p>
|
||||
@@ -28,7 +28,7 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
value={formData.email}
|
||||
onChange={handleInputChange}
|
||||
placeholder="your.email@example.com"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="email-input"
|
||||
/>
|
||||
</div>
|
||||
@@ -43,10 +43,10 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
value={formData.password}
|
||||
onChange={handleInputChange}
|
||||
placeholder="At least 6 characters"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="password-input"
|
||||
/>
|
||||
<p className="text-sm text-[var(--purple-lavender)] mt-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-sm text-brand-purple mt-2" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Must be at least 6 characters long
|
||||
</p>
|
||||
</div>
|
||||
@@ -60,7 +60,7 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
value={formData.confirmPassword}
|
||||
onChange={handleInputChange}
|
||||
placeholder="Re-enter your password"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-[var(--purple-lavender)]"
|
||||
className="h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
|
||||
data-testid="confirm-password-input"
|
||||
/>
|
||||
{formData.confirmPassword && formData.password !== formData.confirmPassword && (
|
||||
@@ -79,7 +79,7 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
name="accepts_tos"
|
||||
checked={formData.accepts_tos || false}
|
||||
onChange={handleInputChange}
|
||||
className="mt-1 w-4 h-4 text-[var(--purple-lavender)] border-gray-300 rounded focus:ring-[var(--purple-lavender)]"
|
||||
className="mt-1 w-4 h-4 text-brand-purple border-gray-300 rounded focus:ring-brand-purple "
|
||||
required
|
||||
data-testid="tos-checkbox"
|
||||
/>
|
||||
@@ -89,7 +89,7 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
href="/become-a-member/terms-of-service"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-[var(--purple-lavender)] hover:text-[var(--purple-ink)] font-semibold underline"
|
||||
className="text-brand-purple hover:text-[var(--purple-ink)] font-semibold underline"
|
||||
>
|
||||
Terms of Service
|
||||
</a>
|
||||
@@ -98,7 +98,7 @@ const RegistrationStep4 = ({ formData, handleInputChange }) => {
|
||||
href="become-a-member/privacy-policy"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="text-[var(--purple-lavender)] hover:text-[var(--purple-ink)] font-semibold underline"
|
||||
className="text-brand-purple hover:text-[var(--purple-ink)] font-semibold underline"
|
||||
>
|
||||
Privacy Policy
|
||||
</a>
|
||||
|
||||
@@ -23,14 +23,14 @@ const RegistrationStepIndicator = ({ currentStep, totalSteps = 4 }) => {
|
||||
? 'bg-[var(--orange-light)] text-white scale-110 shadow-lg'
|
||||
: currentStep > step.number
|
||||
? 'bg-[var(--green-light)] text-white'
|
||||
: 'bg-[var(--neutral-800)] text-[var(--purple-lavender)]'
|
||||
: 'bg-[var(--neutral-800)] text-brand-purple '
|
||||
}
|
||||
`}>
|
||||
{currentStep > step.number ? '✓' : step.number}
|
||||
</div>
|
||||
<span className={`
|
||||
text-sm mt-2 font-medium transition-colors
|
||||
${currentStep === step.number ? 'text-[var(--orange-light)]' : 'text-[var(--purple-lavender)]'}
|
||||
${currentStep === step.number ? 'text-[var(--orange-light)]' : 'text-brand-purple '}
|
||||
`} style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
{step.title}
|
||||
</span>
|
||||
@@ -52,7 +52,7 @@ const RegistrationStepIndicator = ({ currentStep, totalSteps = 4 }) => {
|
||||
</div>
|
||||
|
||||
{/* Step Counter */}
|
||||
<p className="text-center text-[var(--purple-lavender)] mt-6 text-lg" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
<p className="text-center text-brand-purple mt-6 text-lg" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
|
||||
Step <span className="font-semibold text-[var(--orange-light)]">{currentStep}</span> of {totalSteps}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -1,47 +1,42 @@
|
||||
import * as React from "react"
|
||||
import { Slot } from "@radix-ui/react-slot"
|
||||
import { cva } from "class-variance-authority";
|
||||
import { cva } from "class-variance-authority"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default:
|
||||
"bg-primary text-primary-foreground shadow hover:bg-primary/90",
|
||||
destructive:
|
||||
"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",
|
||||
outline:
|
||||
"border border-input shadow-sm hover:bg-accent hover:text-accent-foreground",
|
||||
secondary:
|
||||
"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",
|
||||
ghost: "hover:bg-accent hover:text-accent-foreground",
|
||||
link: "text-primary underline-offset-4 hover:underline",
|
||||
},
|
||||
size: {
|
||||
default: "h-9 px-4 py-2",
|
||||
sm: "h-8 rounded-md px-3 text-xs",
|
||||
lg: "h-10 rounded-md px-8",
|
||||
icon: "h-9 w-9",
|
||||
},
|
||||
const buttonVariants = cva("btn", {
|
||||
variants: {
|
||||
variant: {
|
||||
default: "btn-primary",
|
||||
secondary: "btn-secondary",
|
||||
ghost: "btn-ghost",
|
||||
outline: "btn-outline",
|
||||
accent: "btn-accent",
|
||||
destructive: "btn-destructive",
|
||||
link: "btn-link",
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
size: {
|
||||
default: "btn-md",
|
||||
sm: "btn-sm",
|
||||
lg: "btn-lg",
|
||||
icon: "btn-icon",
|
||||
},
|
||||
}
|
||||
)
|
||||
},
|
||||
defaultVariants: {
|
||||
variant: "default",
|
||||
size: "default",
|
||||
},
|
||||
})
|
||||
|
||||
const Button = React.forwardRef(({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : "button"
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
className={cn(buttonVariants({ variant, size }), className)}
|
||||
ref={ref}
|
||||
{...props} />
|
||||
);
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
})
|
||||
Button.displayName = "Button"
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap hover:bg-[var(--lavender-300)] border-2 border-[var(--purple-lavender)] rounded-2xl px-3 py-1 text-[var(--purple-lavender)] text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-foreground data-[state=active]:text-background data-[state=active]:border-foreground data-[state=active]:shadow",
|
||||
"inline-flex items-center justify-center whitespace-nowrap hover:bg-[var(--lavender-300)] border-2 border-brand-purple rounded-2xl px-3 py-1 text-brand-purple text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-foreground data-[state=active]:text-background data-[state=active]:border-foreground data-[state=active]:shadow",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user