import React, { useEffect, useState } from 'react'; import { useParams, useNavigate } from 'react-router-dom'; import api from '../../utils/api'; import { Card } from '../../components/ui/card'; import { Button } from '../../components/ui/button'; import { Badge } from '../../components/ui/badge'; import { ArrowLeft, Mail, Phone, MapPin, Calendar, Lock, AlertTriangle } from 'lucide-react'; import { toast } from 'sonner'; import ConfirmationDialog from '../../components/ConfirmationDialog'; const AdminUserView = () => { const { userId } = useParams(); const navigate = useNavigate(); const [user, setUser] = useState(null); const [loading, setLoading] = useState(true); const [resetPasswordLoading, setResetPasswordLoading] = useState(false); const [resendVerificationLoading, setResendVerificationLoading] = useState(false); const [subscriptions, setSubscriptions] = useState([]); const [subscriptionsLoading, setSubscriptionsLoading] = useState(true); const [confirmDialogOpen, setConfirmDialogOpen] = useState(false); const [pendingAction, setPendingAction] = useState(null); useEffect(() => { fetchUserProfile(); fetchSubscriptions(); }, [userId]); const fetchUserProfile = async () => { try { const response = await api.get(`/admin/users/${userId}`); setUser(response.data); } catch (error) { toast.error('Failed to load user profile'); navigate('/admin/members'); } finally { setLoading(false); } }; const fetchSubscriptions = async () => { try { const response = await api.get(`/admin/subscriptions?user_id=${userId}`); setSubscriptions(response.data); } catch (error) { console.error('Failed to fetch subscriptions:', error); } finally { setSubscriptionsLoading(false); } }; const handleResetPasswordRequest = () => { setPendingAction({ type: 'reset_password' }); setConfirmDialogOpen(true); }; const handleResendVerificationRequest = () => { setPendingAction({ type: 'resend_verification' }); setConfirmDialogOpen(true); }; const confirmAction = async () => { if (!pendingAction) return; const { type } = pendingAction; setConfirmDialogOpen(false); if (type === 'reset_password') { setResetPasswordLoading(true); try { await api.put(`/admin/users/${userId}/reset-password`, { force_change: true }); toast.success(`Password reset email sent to ${user.email}`); } catch (error) { const errorMessage = error.response?.data?.detail || 'Failed to reset password'; toast.error(errorMessage); } finally { setResetPasswordLoading(false); setPendingAction(null); } } else if (type === 'resend_verification') { setResendVerificationLoading(true); try { await api.post(`/admin/users/${userId}/resend-verification`); toast.success(`Verification email sent to ${user.email}`); // Refresh user data to get updated email_verified status if changed await fetchUserProfile(); } catch (error) { const errorMessage = error.response?.data?.detail || 'Failed to send verification email'; toast.error(errorMessage); } finally { setResendVerificationLoading(false); setPendingAction(null); } } }; const getActionMessage = () => { if (!pendingAction || !user) return {}; const { type } = pendingAction; const userName = `${user.first_name} ${user.last_name}`; if (type === 'reset_password') { return { title: 'Reset Password?', description: `This will send a temporary password to ${user.email}. ${userName} will be required to change it on their next login.`, variant: 'warning', confirmText: 'Yes, Reset Password', }; } if (type === 'resend_verification') { return { title: 'Resend Verification Email?', description: `This will send a new verification email to ${user.email}. ${userName} will need to click the link to verify their email address.`, variant: 'info', confirmText: 'Yes, Resend Email', }; } return {}; }; if (loading) return
{user.address}
{new Date(user.date_of_birth).toLocaleDateString()}
{user.partner_first_name} {user.partner_last_name}
{user.referred_by_member_name}
Loading subscriptions...
) : subscriptions.length === 0 ? (No subscriptions found for this member.
) : ({sub.plan.billing_cycle}
{new Date(sub.start_date).toLocaleDateString()}
{new Date(sub.end_date).toLocaleDateString()}
${(sub.base_subscription_cents / 100).toFixed(2)}
${(sub.donation_cents / 100).toFixed(2)}
${(sub.amount_paid_cents / 100).toFixed(2)}
{sub.payment_method}
{sub.stripe_subscription_id}