import { useState, useEffect } from 'react'; import { adminData } from '@/lib/adminApi'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; import { Target, Users, MessageSquare, Flame, Heart, Smile, Shield, TrendingUp, PieChart } from 'lucide-react'; import { Bar, BarChart, ResponsiveContainer, XAxis, YAxis, Tooltip, Cell, Pie, PieChart as RechartsPieChart } from 'recharts'; type UsageReason = 'improve_communication' | 'spice_up_intimacy' | 'deeper_connection' | 'have_fun' | 'strengthen_relationship'; interface UsageReasonStat { reason: UsageReason | null; count: number; percentage: number; } interface GenderStat { gender: string | null; count: number; percentage: number; } const usageReasonConfig: Record = { improve_communication: { label: 'Improve communication', icon: , color: '#3b82f6', }, spice_up_intimacy: { label: 'Spice up intimacy', icon: , color: '#ef4444', }, deeper_connection: { label: 'Build deeper connection', icon: , color: '#ec4899', }, have_fun: { label: 'Have fun together', icon: , color: '#f59e0b', }, strengthen_relationship: { label: 'Strengthen relationship', icon: , color: '#10b981', }, }; const genderConfig: Record = { male: { label: 'Male', color: '#3b82f6' }, female: { label: 'Female', color: '#ec4899' }, 'non-binary': { label: 'Non-binary', color: '#8b5cf6' }, 'prefer-not-to-say': { label: 'Prefer not to say', color: '#6b7280' }, }; export function UsageInsightsPage() { const [usageStats, setUsageStats] = useState([]); const [genderStats, setGenderStats] = useState([]); const [totalUsers, setTotalUsers] = useState(0); const [onboardedUsers, setOnboardedUsers] = useState(0); const [loading, setLoading] = useState(true); useEffect(() => { const fetchStats = async () => { try { // Get total users count const { count: total } = await adminData .from('profiles') .select('*', { count: 'exact', head: true }); setTotalUsers(total || 0); // Get onboarded users count const { count: onboarded } = await adminData .from('profiles') .select('*', { count: 'exact', head: true }) .eq('onboarding_completed', true); setOnboardedUsers(onboarded || 0); // Get usage reason breakdown const { data: usageData } = await adminData .from('profiles') .select('usage_reason') .not('usage_reason', 'is', null); const usageCounts: Record = {}; usageData?.forEach(profile => { const reason = profile.usage_reason as string; usageCounts[reason] = (usageCounts[reason] || 0) + 1; }); const totalWithReason = Object.values(usageCounts).reduce((a, b) => a + b, 0); const usageStatsArray: UsageReasonStat[] = Object.entries(usageCounts) .map(([reason, count]) => ({ reason: reason as UsageReason, count, percentage: totalWithReason > 0 ? Math.round((count / totalWithReason) * 100) : 0, })) .sort((a, b) => b.count - a.count); setUsageStats(usageStatsArray); // Get gender breakdown const { data: genderData } = await adminData .from('profiles') .select('gender') .not('gender', 'is', null); const genderCounts: Record = {}; genderData?.forEach(profile => { const gender = profile.gender as string; genderCounts[gender] = (genderCounts[gender] || 0) + 1; }); const totalWithGender = Object.values(genderCounts).reduce((a, b) => a + b, 0); const genderStatsArray: GenderStat[] = Object.entries(genderCounts) .map(([gender, count]) => ({ gender, count, percentage: totalWithGender > 0 ? Math.round((count / totalWithGender) * 100) : 0, })) .sort((a, b) => b.count - a.count); setGenderStats(genderStatsArray); } catch (error) { console.error('Failed to fetch usage stats:', error); } finally { setLoading(false); } }; fetchStats(); }, []); const chartData = usageStats.map(stat => ({ name: stat.reason ? usageReasonConfig[stat.reason]?.label || stat.reason : 'Unknown', value: stat.count, color: stat.reason ? usageReasonConfig[stat.reason]?.color : '#6b7280', })); const pieData = genderStats.map(stat => ({ name: stat.gender ? genderConfig[stat.gender]?.label || stat.gender : 'Unknown', value: stat.count, color: stat.gender ? genderConfig[stat.gender]?.color : '#6b7280', })); return (

Usage Insights

Understand why users are using Sauci based on onboarding responses

{/* Quick Stats */}
Total Users {loading ? ( ) : (
{totalUsers.toLocaleString()}
)}
Completed Onboarding {loading ? ( ) : ( <>
{onboardedUsers.toLocaleString()}

{totalUsers > 0 ? Math.round((onboardedUsers / totalUsers) * 100) : 0}% of total users

)}
Response Rate {loading ? ( ) : ( <>
{usageStats.reduce((sum, s) => sum + s.count, 0).toLocaleString()}

users provided usage reason

)}
{/* Usage Reasons Chart */} Why Users Join Sauci Distribution of user motivations from onboarding {loading ? ( ) : usageStats.length === 0 ? (
No usage data available yet
) : (
{chartData.map((entry, index) => ( ))}
)}
{/* Gender Distribution */} Gender Distribution User demographics from onboarding {loading ? ( ) : genderStats.length === 0 ? (
No gender data available yet
) : (
`${name}: ${((percent ?? 0) * 100).toFixed(0)}%` } > {pieData.map((entry, index) => ( ))}
)}
{/* Detailed Breakdown */} Detailed Breakdown Individual statistics for each usage reason {loading ? (
{[1, 2, 3, 4, 5].map(i => ( ))}
) : usageStats.length === 0 ? (
No usage data available yet
) : (
{usageStats.map(stat => { const config = stat.reason ? usageReasonConfig[stat.reason] : null; return (
{config?.icon}

{config?.label || stat.reason}

{stat.percentage}%

{stat.count}

users

); })}
)}
); }