+
+ Quick Overview
+
+
+ ['admin', 'superadmin', 'finance', 'staff', 'media', 'moderator'].includes(u.role)).length}
+ icon={Users}
+ iconBgClass="bg-[var(--blue-light)] text-[var(--blue-dark)]"
+ dataTestId="stat-total-members"
+ />
+ ['admin', 'superadmin'].includes(u.role)).length}
+ icon={Shield}
+ iconBgClass="text-[var(--green-light)]"
+ dataTestId="stat-active-members"
+ />
+ u.role === 'moderator').length}
+ icon={CreditCard}
+ iconBgClass="text-brand-light-orange"
+ dataTestId="stat-payment-pending-members"
+ />
+ ['admin', 'superadmin'].includes(u.role)).length && users.filter(u => u.status !== 'inactive').length}
+ icon={CircleMinus}
+ iconBgClass=" text-brand-pink"
+ dataTestId="stat-inactive-members"
+ />
+
{/* Tabs */}
@@ -250,79 +235,79 @@ const AdminStaff = () => {
className="p-6 bg-background rounded-2xl border border-[var(--neutral-800)] hover:shadow-md transition-shadow"
data-testid={`staff-card-${user.id}`}
>
-
-
- {/* Avatar */}
-
- {user.first_name?.[0]}{user.last_name?.[0]}
-
-
- {/* Info */}
-
-
-
- {user.first_name} {user.last_name}
-
- {getRoleBadge(user.role)}
- {getStatusBadge(user.status)}
+
+
+ {/* Avatar */}
+
+ {user.first_name?.[0]}{user.last_name?.[0]}
-
-
Email: {user.email}
-
Phone: {user.phone}
-
Joined: {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'}
- {user.last_login && (
-
Last Login: {new Date(user.last_login).toLocaleDateString()}
- )}
+
+ {/* Info */}
+
+
+
+ {user.first_name} {user.last_name}
+
+
+
+
+
+
Email: {user.email}
+
Phone: {user.phone}
+
Joined: {joinedDate ? new Date(joinedDate).toLocaleDateString() : 'N/A'}
+ {user.last_login && (
+
Last Login: {new Date(user.last_login).toLocaleDateString()}
+ )}
+
-
- {/* Actions */}
-
-
-
- {hasPermission('users.status') && (
+ {/* Actions */}
+
- )}
- {hasPermission('users.delete') && (
-
- )}
+ {hasPermission('users.status') && (
+
+ )}
+
+ {hasPermission('users.delete') && (
+
+ )}
+
-
);
})}
diff --git a/src/pages/admin/AdminSubscriptions.js b/src/pages/admin/AdminSubscriptions.js
index 815580d..dc6c14c 100644
--- a/src/pages/admin/AdminSubscriptions.js
+++ b/src/pages/admin/AdminSubscriptions.js
@@ -19,7 +19,6 @@ import {
DialogHeader,
DialogTitle,
} from '../../components/ui/dialog';
-import { Badge } from '../../components/ui/badge';
import api from '../../utils/api';
import { toast } from 'sonner';
import {
@@ -47,6 +46,7 @@ import {
DropdownMenuItem,
DropdownMenuTrigger,
} from '../../components/ui/dropdown-menu';
+import StatusBadge from '@/components/StatusBadge';
const AdminSubscriptions = () => {
const { hasPermission } = useAuth();
@@ -302,14 +302,7 @@ Proceed with activation?`;
}
};
- const getStatusBadgeVariant = (status) => {
- const variants = {
- active: 'default',
- cancelled: 'destructive',
- expired: 'secondary'
- };
- return variants[status] || 'outline';
- };
+
if (loading) {
return (
@@ -501,7 +494,7 @@ Proceed with activation?`;
{sub.user.email}
-
{sub.status}
+
{/* Plan & Period */}
@@ -635,9 +628,8 @@ Proceed with activation?`;
-
- {sub.status}
-
+
+
|
diff --git a/src/pages/admin/AdminUserView.js b/src/pages/admin/AdminUserView.js
index 350880a..f47b64c 100644
--- a/src/pages/admin/AdminUserView.js
+++ b/src/pages/admin/AdminUserView.js
@@ -10,6 +10,7 @@ import { ArrowLeft, Mail, Phone, MapPin, Calendar, Lock, AlertTriangle, Camera,
import { toast } from 'sonner';
import ConfirmationDialog from '../../components/ConfirmationDialog';
import ChangeRoleDialog from '../../components/ChangeRoleDialog';
+import StatusBadge from '../../components/StatusBadge';
const AdminUserView = () => {
const { userId } = useParams();
@@ -277,7 +278,7 @@ const AdminUserView = () => {
if (loading) return Loading... ;
if (!user) return null;
- const joinedDate = user.member_since || user.created_at;
+ const joinedDate = user.created_at;
const memberSinceBaseline = formatDateInputValue(user.member_since);
const memberSinceHasChanges = memberSince !== memberSinceBaseline;
@@ -311,8 +312,9 @@ const AdminUserView = () => {
{user.first_name} {user.last_name}
{/* Status & Role Badges */}
- {user.status}
- {user.role}
+
+
+
{/* Contact Info */}
@@ -331,7 +333,7 @@ const AdminUserView = () => {
- Joined {formatDateDisplayValue(joinedDate)}
+ Registered: {formatDateDisplayValue(joinedDate)}
@@ -506,13 +508,7 @@ const AdminUserView = () => {
{sub.plan.billing_cycle}
-
- {sub.status}
-
+
diff --git a/src/pages/admin/AdminValidations.js b/src/pages/admin/AdminValidations.js
index d2ab17c..c26a5fd 100644
--- a/src/pages/admin/AdminValidations.js
+++ b/src/pages/admin/AdminValidations.js
@@ -3,7 +3,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,
@@ -34,6 +33,7 @@ import { CheckCircle, Clock, Search, ArrowUp, ArrowDown, X } from 'lucide-react'
import PaymentActivationDialog from '../../components/PaymentActivationDialog';
import ConfirmationDialog from '../../components/ConfirmationDialog';
import RejectionDialog from '../../components/RejectionDialog';
+import StatusBadge from '@/components/StatusBadge';
const AdminValidations = () => {
const { hasPermission } = useAuth();
@@ -235,22 +235,7 @@ const AdminValidations = () => {
}
};
- const getStatusBadge = (status) => {
- const config = {
- pending_email: { label: 'Awaiting Email', className: 'bg-orange-100 text-orange-700' },
- pending_validation: { label: 'Pending Validation', className: 'bg-gray-200 text-gray-700' },
- pre_validated: { label: 'Pre-Validated', className: 'bg-[var(--green-light)] text-white' },
- payment_pending: { label: 'Payment Pending', className: 'bg-orange-500 text-white' },
- rejected: { label: 'Rejected', className: 'bg-red-100 text-red-700' }
- };
-
- const statusConfig = config[status];
- return (
-
- {statusConfig.label}
-
- );
- };
+
const handleSort = (column) => {
if (sortBy === column) {
@@ -401,7 +386,7 @@ const AdminValidations = () => {
{user.email}
{user.phone}
- {getStatusBadge(user.status)}
+
{new Date(user.created_at).toLocaleDateString()}
diff --git a/src/pages/members/MembersDirectory.js b/src/pages/members/MembersDirectory.js
index 31bd3d3..161e56a 100644
--- a/src/pages/members/MembersDirectory.js
+++ b/src/pages/members/MembersDirectory.js
@@ -15,6 +15,8 @@ import {
} from '../../components/ui/dialog';
import { User, Search, Mail, MapPin, Phone, Heart, Facebook, Instagram, Twitter, Linkedin, UserCircle, Calendar } from 'lucide-react';
import { useToast } from '../../hooks/use-toast';
+import StatusBadge from '@/components/StatusBadge';
+import MemberCard from '../../components/MemberCard';
const MembersDirectory = () => {
const [members, setMembers] = useState([]);
@@ -80,9 +82,7 @@ const MembersDirectory = () => {
const totalMembers = members.length;
- const getInitials = (firstName, lastName) => {
- return `${firstName.charAt(0)}${lastName.charAt(0)}`.toUpperCase();
- };
+
const getSocialMediaLink = (url) => {
if (!url) return null;
@@ -118,168 +118,6 @@ const MembersDirectory = () => {
:
)
}
- const MemberCard = ({ member }) => {
- const joinedDate = member.member_since || member.created_at;
- return (
-
- {/* Profile Photo */}
-
- {member.profile_photo_url ? (
- 
- ) : (
-
-
- {getInitials(member.first_name, member.last_name)}
-
-
- )}
-
-
- {/* Name */}
-
- {member.first_name} {member.last_name}
-
-
- {/* Partner Name */}
- {member.directory_partner_name && (
-
-
-
- Partner: {member.directory_partner_name}
-
-
- )}
-
- {/* Bio */}
- {member.directory_bio && (
-
- {member.directory_bio}
-
- )}
-
- {/* Member Since */}
- {joinedDate && (
-
-
-
- Member since {new Date(joinedDate).toLocaleDateString('en-US', {
- month: 'long',
- year: 'numeric'
- })}
-
-
- )}
-
- {/* Contact Information */}
-
- {member.directory_email && (
-
- )}
-
- {member.directory_phone && (
-
- )}
-
- {member.directory_address && (
-
-
-
- {member.directory_address}
-
-
- )}
-
-
- {/* Social Media Links */}
- {(member.social_media_facebook || member.social_media_instagram || member.social_media_twitter || member.social_media_linkedin) && (
-
-
- {member.social_media_facebook && (
-
-
-
- )}
-
- {member.social_media_instagram && (
-
-
-
- )}
-
- {member.social_media_twitter && (
-
-
-
- )}
-
- {member.social_media_linkedin && (
-
-
-
- )}
-
-
- )}
-
- {/* View Profile Button */}
-
-
-
-
- );
- };
return (
@@ -354,7 +192,7 @@ const MembersDirectory = () => {
{/* Border Decoration */}
-
+ {/* todo: use badge to display if member */}
{/* Info Card */}
{!loading && members.length > 0 && (
@@ -377,15 +215,16 @@ const MembersDirectory = () => {
)}
-
{/* Profile Detail Dialog */}
-
-
{/* Pagination */}
{!loading && filteredMembers.length > 0 && (
|