feat: Introduce StatusBadge component for consistent status representation

- Added StatusBadge component to standardize the display of user and membership statuses across various admin pages.
- Refactored AdminMembers, AdminPlans, AdminStaff, AdminSubscriptions, AdminUserView, AdminValidations, and MembersDirectory to utilize the new StatusBadge component.
- Removed redundant status badge logic from AdminMembers, AdminStaff, and AdminValidations.
- Updated AdminLayout to include a mobile-friendly sidebar toggle button with Menu icon.
- Created MemberCard component to encapsulate member display logic, improving code reusability.
- Adjusted various components to enhance user experience and maintain consistent styling.
This commit is contained in:
2026-01-22 14:20:02 -06:00
parent 6c844c0e19
commit ac879b69b4
11 changed files with 372 additions and 361 deletions

View File

@@ -4,7 +4,6 @@ import { useAuth } from '../../context/AuthContext';
import api from '../../utils/api';
import { Card } from '../../components/ui/card';
import { Button } from '../../components/ui/button';
import { Badge } from '../../components/ui/badge';
import { Input } from '../../components/ui/input';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components/ui/select';
import {
@@ -20,6 +19,7 @@ import ConfirmationDialog from '../../components/ConfirmationDialog';
import CreateMemberDialog from '../../components/CreateMemberDialog';
import InviteStaffDialog from '../../components/InviteStaffDialog';
import WordPressImportWizard from '../../components/WordPressImportWizard';
import StatusBadge from '../../components/StatusBadge';
import { StatCard } from '@/components/StatCard';
const AdminMembers = () => {
@@ -200,27 +200,6 @@ const AdminMembers = () => {
};
};
const getStatusBadge = (status) => {
const config = {
pending_email: { label: 'Pending Email', variant: 'orange2' },
pending_validation: { label: 'Pending Validation', variant: 'gray' },
pre_validated: { label: 'Pre-Validated', variant: 'green' },
payment_pending: { label: 'Payment Pending', variant: 'orange' },
active: { label: 'Active', variant: 'green' },
inactive: { label: 'Inactive', variant: 'gray2' },
canceled: { label: 'Canceled', variant: 'red' },
expired: { label: 'Expired', variant: 'red2' },
abandoned: { label: 'Abandoned', variant: 'gray3' }
};
const statusConfig = config[status] || config.inactive;
return (
<Badge variant={statusConfig.variant} className={` px-3 py-1 rounded-full text-sm`}>
{statusConfig.label}
</Badge>
);
};
const getReminderInfo = (user) => {
const emailReminders = user.email_verification_reminders_sent || 0;
const eventReminders = user.event_attendance_reminders_sent || 0;
@@ -325,8 +304,6 @@ const AdminMembers = () => {
Quick Overview
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-4 gap-4">
<StatCard
title="Total Members"
value={users.length}
@@ -355,9 +332,6 @@ const AdminMembers = () => {
iconBgClass=" text-brand-pink"
dataTestId="stat-inactive-members"
/>
</div>
</div>
@@ -401,7 +375,8 @@ const AdminMembers = () => {
) : filteredUsers.length > 0 ? (
<div className="space-y-4">
{filteredUsers.map((user) => {
const joinedDate = user.member_since || user.created_at;
const joinedDate = user.created_at;
const memberDate = user.member_since;
return (
<Card
key={user.id}
@@ -421,12 +396,13 @@ const AdminMembers = () => {
<h3 className="text-xl font-semibold text-[var(--purple-ink)] " style={{ fontFamily: "'Inter', sans-serif" }}>
{user.first_name} {user.last_name}
</h3>
{getStatusBadge(user.status)}
<StatusBadge status={user.status} />
</div>
<div className="grid md:grid-cols-2 gap-2 text-sm text-brand-purple dark:text-brand-lavender " style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p>Email: {user.email}</p>
<p>Phone: {user.phone}</p>
<p>Joined: {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'}</p>
<p>Registered: {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'}</p>
<p>Member Since: {memberDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'}</p>
{user.referred_by_member_name && (
<p>Referred by: {user.referred_by_member_name}</p>
)}