styling consistency

This commit is contained in:
2026-02-04 19:12:37 -06:00
parent 6720b16056
commit 2fa1fa903f
9 changed files with 94 additions and 63 deletions

View File

@@ -13,11 +13,9 @@ const MemberFooter = () => {
<div className="grid md:grid-cols-5 gap-8">
{/* Logo & About */}
<div>
<div className="w-40 sm:w-40 md:w-48 lg:w-[180px] flex-shrink-0">
<img src={loafLogo} alt="LOAF Logo" className="w-full h-auto aspect-square object-contain" />
</div>
</div>
{/* Member Resources */}
<div>
@@ -104,7 +102,7 @@ const MemberFooter = () => {
</div>
{/* donate button */}
<div className="flex flex-col gap-2 items-center self-start justify-center md:items-start text-left w-full sm:w-auto sm:min-w-[200px] md:min-w-[200px] lg:min-w-[220px]">
<div className="flex flex-col gap-2 items-center self-start justify-center md:items-start text-left w-full sm:w-auto sm:min-w-[200px] md:min-w-[200px] ">
<div className="pb-4 w-full flex justify-center lg:justify-start">
<Link to="/donate" className="block">
<Button className="bg-[var(--orange-light)] hover:bg-[var(--orange-coral)] text-[var(--purple-deep)] rounded-full px-12 lg:px-16 py-6 text-lg sm:text-lg font-medium ">
@@ -123,13 +121,14 @@ const MemberFooter = () => {
{/* Bottom Bar */}
<div className="bg-gradient-to-r from-[var(--purple-deep)] to-[var(--purple-amethyst)] border-t border-[rgba(0,0,0,0.1)]">
<div className="max-w-7xl mx-auto px-6 py-4">
<div className="max-w-7xl mx-auto px-8 py-4 grid-cols-3">
<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="/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>© {new Date().getFullYear()} LOAF. All rights reserved.</p>
<p>Designed and Managed by <a href='https://konceptkit.com' target='_blank' className='font-bold text-white hover:underline cursor-pointer'>Konceptkit</a></p>
</div>
</div>
</div>

View File

@@ -7,7 +7,7 @@ import { cn } from "@/lib/utils";
const buttonVariants = cva("btn", {
variants: {
variant: {
default: "btn-primary",
default: "btn-purple",
secondary: "btn-secondary",
ghost: "btn-ghost",
outline: "btn-outline",
@@ -15,6 +15,7 @@ const buttonVariants = cva("btn", {
accent: "btn-accent",
destructive: "btn-destructive",
link: "btn-link",
green: 'btn-green'
},
size: {
default: "btn-md",

View File

@@ -298,7 +298,7 @@ const AdminDonations = () => {
placeholder="Search by donor name or email..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-10 rounded-full border-2 border-[var(--neutral-800)] focus:border-brand-purple "
className="pl-10 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
/>
</div>
{hasPermission('donations.export') && (
@@ -336,7 +336,7 @@ const AdminDonations = () => {
<div className="grid grid-cols-1 md:grid-cols-4 gap-4">
<div>
<Select value={typeFilter} onValueChange={setTypeFilter}>
<SelectTrigger className="rounded-full border-2 border-[var(--neutral-800)]">
<SelectTrigger className="rounded-xl border-2 border-[var(--neutral-800)]">
<SelectValue placeholder="All Types" />
</SelectTrigger>
<SelectContent>
@@ -349,7 +349,7 @@ const AdminDonations = () => {
<div>
<Select value={statusFilter} onValueChange={setStatusFilter}>
<SelectTrigger className="rounded-full border-2 border-[var(--neutral-800)]">
<SelectTrigger className="rounded-xl border-2 border-[var(--neutral-800)]">
<SelectValue placeholder="All Statuses" />
</SelectTrigger>
<SelectContent>
@@ -366,7 +366,7 @@ const AdminDonations = () => {
type="date"
value={startDate}
onChange={(e) => setStartDate(e.target.value)}
className="rounded-full border-2 border-[var(--neutral-800)]"
className="rounded-xl border-2 border-[var(--neutral-800)]"
placeholder="Start Date"
/>
</div>
@@ -376,7 +376,7 @@ const AdminDonations = () => {
type="date"
value={endDate}
onChange={(e) => setEndDate(e.target.value)}
className="rounded-full border-2 border-[var(--neutral-800)]"
className="rounded-xl border-2 border-[var(--neutral-800)]"
placeholder="End Date"
/>
</div>

View File

@@ -354,42 +354,11 @@ const AdminMembers = () => {
</p>
</div>
<div className="flex gap-3 flex-wrap ">
{hasPermission('users.export') && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
className="btn-util-purple "
disabled={exporting}
>
{exporting ? (
<>
<Download className="h-5 w-5 mr-2 animate-bounce" />
Exporting...
</>
) : (
<>
<FileDown className="h-5 w-5 mr-2" />
Export
<ChevronDown className="h-4 w-4 ml-2" />
</>
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="rounded-xl">
<DropdownMenuItem onClick={() => handleExport('all')} className="cursor-pointer">
Export All Members
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExport('current')} className="cursor-pointer">
Export Current View
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
{hasPermission('users.import') && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button className="btn-util-green">
<Button className="">
<Upload className="h-5 w-5 mr-2" />
Import
<ChevronDown className="h-4 w-4 ml-2" />
@@ -440,7 +409,9 @@ const AdminMembers = () => {
{hasPermission('users.invite') && (
<Button
onClick={() => setInviteDialogOpen(true)}
className="btn-util-purple "
className=" "
variant='outline'
>
<Mail className="h-5 w-5 mr-2" />
Invite Member
@@ -450,7 +421,8 @@ const AdminMembers = () => {
{hasPermission('users.create') && (
<Button
onClick={() => setCreateDialogOpen(true)}
className="btn-util-green "
className=""
variant='outline'
>
<UserPlus className="h-5 w-5 mr-2" />
Create Member
@@ -499,19 +471,20 @@ const AdminMembers = () => {
{/* Filters */}
<Card className="p-6 bg-background rounded-2xl border border-[var(--neutral-800)] mb-8">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div className="relative">
<Search className="absolute left-4 top-1/2 transform -translate-y-1/2 h-5 w-5 text-brand-purple " />
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-brand-purple " />
<Input
placeholder="Search by name or email..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-12 h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
className="pl-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
data-testid="search-members-input"
/>
</div>
<Select value={statusFilter} onValueChange={setStatusFilter}>
<SelectTrigger className="h-14 rounded-xl border-2 border-[var(--neutral-800)]" data-testid="status-filter-select">
<SelectTrigger className=" rounded-xl border-2 border-[var(--neutral-800)]" data-testid="status-filter-select">
<SelectValue placeholder="Filter by status" />
</SelectTrigger>
<SelectContent>
@@ -525,6 +498,41 @@ const AdminMembers = () => {
</SelectContent>
</Select>
</div>
<div className='mt-4 flex items-center justify-between'>
<div className='text-sm text-brand-purple pl-2'>Showing {filteredUsers.length} of {users.length} </div>
{hasPermission('users.export') && (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
className="btn-green "
disabled={exporting}
>
{exporting ? (
<>
<Download className=" b h-5 w-5 mr-2 animate-bounce" />
Exporting...
</>
) : (
<>
<Download className="h-5 w-5 mr-2" />
Export
<ChevronDown className=" h-4 w-4 ml-2" />
</>
)}
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="rounded-xl">
<DropdownMenuItem onClick={() => handleExport('all')} className="cursor-pointer">
Export All Members
</DropdownMenuItem>
<DropdownMenuItem onClick={() => handleExport('current')} className="cursor-pointer">
Export Current View
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
)}
</div>
</Card>
{/* Import Job Quick Select */}
@@ -654,11 +662,10 @@ const AdminMembers = () => {
return (
<Card
key={user.id}
className={`p-6 bg-background rounded-2xl border hover:shadow-md transition-shadow ${
selectedUsers.has(user.id)
? 'border-brand-purple bg-[var(--lavender-500)]'
: 'border-[var(--neutral-800)]'
}`}
className={`p-6 bg-background rounded-2xl border hover:shadow-md transition-shadow ${selectedUsers.has(user.id)
? 'border-brand-purple bg-[var(--lavender-500)]'
: 'border-[var(--neutral-800)]'
}`}
data-testid={`member-card-${user.id}`}
>
<div className="flex justify-between items-start flex-wrap gap-4">

View File

@@ -195,11 +195,11 @@ const AdminPlans = () => {
placeholder="Search plans..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-12 h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
className="pl-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
/>
</div>
<Select value={activeFilter} onValueChange={setActiveFilter}>
<SelectTrigger className="h-14 rounded-xl border-2 border-[var(--neutral-800)]">
<SelectTrigger className="rounded-xl border-2 border-[var(--neutral-800)]">
<SelectValue placeholder="Filter by status" />
</SelectTrigger>
<SelectContent>
@@ -208,6 +208,13 @@ const AdminPlans = () => {
<SelectItem value="inactive">Inactive Only</SelectItem>
</SelectContent>
</Select>
<div className="mt-4 flex items-center justify-between">
<div className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Showing {filteredPlans.length} of {plans.length} plans
</div>
</div>
</div>
</Card>

View File

@@ -83,7 +83,7 @@ const AdminStaff = () => {
{hasPermission('users.create') && (
<Button
onClick={() => setInviteDialogOpen(true)}
className="btn-util-purple h-12 px-6"
className="btn-purple px-6"
>
<Mail className="h-5 w-5 mr-2" />
Invite Staff
@@ -92,7 +92,7 @@ const AdminStaff = () => {
{hasPermission('users.create') && (
<Button
onClick={() => setCreateDialogOpen(true)}
className="btn-util-green h-12 px-6"
className="btn-green px-6"
>
<UserPlus className="h-5 w-5 mr-2" />
Create Staff
@@ -163,12 +163,12 @@ const AdminStaff = () => {
placeholder="Search by name or email..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-12 h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
className="pl-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
data-testid="search-staff-input"
/>
</div>
<Select value={roleFilter} onValueChange={setRoleFilter}>
<SelectTrigger className="h-14 rounded-xl border-2 border-[var(--neutral-800)]" data-testid="role-filter-select">
<SelectTrigger className=" rounded-xl border-2 border-[var(--neutral-800)]" data-testid="role-filter-select">
<SelectValue placeholder="Filter by role" />
</SelectTrigger>
<SelectContent>
@@ -180,6 +180,11 @@ const AdminStaff = () => {
<SelectItem value="media">Media</SelectItem>
</SelectContent>
</Select>
<div className="mt-4 flex items-center justify-between">
<div className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Showing {filteredUsers.length} of {users.length} subscriptions
</div>
</div>
</div>
</Card>

View File

@@ -338,7 +338,7 @@ Proceed with activation?`;
{hasPermission('users.create') && (
<Button
onClick={() => setCreateDialogOpen(true)}
className="btn-util-green "
className="btn-green "
>
<Repeat className="h-5 w-5 mr-2" />
Create Subscription
@@ -459,7 +459,7 @@ Proceed with activation?`;
</Select>
</div>
</div>
{/* second row */}
<div className="mt-4 flex items-center justify-between">
<div className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Showing {filteredSubscriptions.length} of {subscriptions.length} subscriptions
@@ -496,6 +496,7 @@ Proceed with activation?`;
</DropdownMenu>
)}
</div>
</Card>
{/* Subscriptions Table */}

View File

@@ -407,12 +407,12 @@ const AdminValidations = () => {
placeholder="Search by name, email, or phone..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-12 h-14 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
className="pl-12 rounded-xl border-2 border-[var(--neutral-800)] focus:border-brand-purple "
/>
</div>
<Select value={statusFilter} onValueChange={setStatusFilter}>
<SelectTrigger className="h-14 rounded-xl border-2 border-[var(--neutral-800)]">
<SelectTrigger className=" rounded-xl border-2 border-[var(--neutral-800)]">
<SelectValue placeholder="Filter by status" />
</SelectTrigger>
<SelectContent className="">
@@ -423,6 +423,13 @@ const AdminValidations = () => {
<SelectItem value="rejected" >Rejected</SelectItem>
</SelectContent>
</Select>
<div className="mt-4 flex items-center justify-between">
<div className="text-sm text-brand-purple " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Showing {filteredUsers.length} of {pendingUsers.length} pending validations
</div>
{/*TODO: <div>Export button here?</div> */}
</div>
</div>
</Card>

View File

@@ -21,7 +21,7 @@
}
.btn-outline {
@apply border border-primary border-2 text-primary shadow-sm hover:bg-primary/10 rounded-full disabled:opacity-50 px-6 transition-transform;
@apply border-brand-purple border-2 text-brand-purple shadow-sm hover:bg-brand-purple/10 rounded-full disabled:opacity-50 px-6 transition-transform;
}
.btn-accent {
@@ -58,6 +58,10 @@
.btn-green {
@apply bg-[var(--green-light)] hover:bg-[var(--green-forest)] text-white transition-transform rounded-full px-6;
}
.btn-purple {
@apply bg-brand-purple text-background shadow hover:bg-brand-purple/90 rounded-full px-6 disabled:opacity-50 px-6 transition-transform
}
.btn-util-green {
@apply bg-[var(--green-light)] hover:bg-[var(--green-forest)] text-white transition-transform rounded-xl h-12 px-6;
}