import { useCallback, useEffect, useState } from "react"; import { aethexUserService, aethexBadgeService, aethexTierService, type AethexUserProfile, type AethexBadge, type AethexUserBadge, } from "@/lib/aethex-database-adapter"; import { aethexToast } from "@/lib/aethex-toast"; import { Button } from "@/components/ui/button"; import { Badge } from "@/components/ui/badge"; import { Card, CardContent, CardHeader, CardTitle, CardDescription, } from "@/components/ui/card"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Input } from "@/components/ui/input"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Crown, Star, Sparkles, Search, Loader2, Plus, X, Shield, } from "lucide-react"; interface AdminTierBadgeManagerProps { profiles?: AethexUserProfile[]; onProfilesChange?: () => void; } export default function AdminTierBadgeManager({ profiles: externalProfiles, onProfilesChange, }: AdminTierBadgeManagerProps) { const [profiles, setProfiles] = useState([]); const [allBadges, setAllBadges] = useState([]); const [loading, setLoading] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [selectedUserId, setSelectedUserId] = useState(null); const [selectedUserBadges, setSelectedUserBadges] = useState([]); const [selectedUserTier, setSelectedUserTier] = useState<"free" | "pro" | "council">("free"); const [loadingUserData, setLoadingUserData] = useState(false); const [updatingTier, setUpdatingTier] = useState(false); const [updatingBadge, setUpdatingBadge] = useState(null); const loadData = useCallback(async () => { setLoading(true); try { const [profileList, badgeList] = await Promise.all([ externalProfiles ? Promise.resolve(externalProfiles) : aethexUserService.listProfiles(200), aethexBadgeService.getAllBadges(), ]); setProfiles(profileList); setAllBadges(badgeList); } catch (err) { console.warn("Failed to load data:", err); aethexToast.error({ description: "Failed to load user data" }); } finally { setLoading(false); } }, [externalProfiles]); useEffect(() => { loadData(); }, [loadData]); const loadSelectedUserData = useCallback(async (userId: string) => { setLoadingUserData(true); try { const [tier, badges] = await Promise.all([ aethexTierService.getUserTier(userId), aethexBadgeService.getUserBadges(userId), ]); setSelectedUserTier(tier); setSelectedUserBadges(badges); } catch (err) { console.warn("Failed to load user tier/badges:", err); } finally { setLoadingUserData(false); } }, []); useEffect(() => { if (selectedUserId) { loadSelectedUserData(selectedUserId); } }, [selectedUserId, loadSelectedUserData]); const handleTierChange = async (newTier: "free" | "pro" | "council") => { if (!selectedUserId) return; setUpdatingTier(true); try { const success = await aethexTierService.setUserTier(selectedUserId, newTier); if (success) { setSelectedUserTier(newTier); aethexToast.success({ description: `Tier updated to ${newTier.charAt(0).toUpperCase() + newTier.slice(1)}` }); onProfilesChange?.(); } else { aethexToast.error({ description: "Failed to update tier" }); } } catch (err) { console.warn("Failed to update tier:", err); aethexToast.error({ description: "Failed to update tier" }); } finally { setUpdatingTier(false); } }; const handleAwardBadge = async (badgeSlug: string) => { if (!selectedUserId) return; setUpdatingBadge(badgeSlug); try { const success = await aethexBadgeService.awardBadge(selectedUserId, badgeSlug); if (success) { await loadSelectedUserData(selectedUserId); aethexToast.success({ description: "Badge awarded successfully" }); } else { aethexToast.error({ description: "Failed to award badge" }); } } catch (err) { console.warn("Failed to award badge:", err); aethexToast.error({ description: "Failed to award badge" }); } finally { setUpdatingBadge(null); } }; const handleRevokeBadge = async (badgeSlug: string) => { if (!selectedUserId) return; setUpdatingBadge(badgeSlug); try { const success = await aethexBadgeService.revokeBadge(selectedUserId, badgeSlug); if (success) { await loadSelectedUserData(selectedUserId); aethexToast.success({ description: "Badge revoked" }); } else { aethexToast.error({ description: "Failed to revoke badge" }); } } catch (err) { console.warn("Failed to revoke badge:", err); aethexToast.error({ description: "Failed to revoke badge" }); } finally { setUpdatingBadge(null); } }; const filteredProfiles = profiles.filter((p) => { const query = searchQuery.toLowerCase(); return ( (p.username?.toLowerCase() || "").includes(query) || (p.full_name?.toLowerCase() || "").includes(query) || (p.email?.toLowerCase() || "").includes(query) ); }); const selectedProfile = profiles.find((p) => p.id === selectedUserId); const userBadgeSlugs = selectedUserBadges.map((ub) => ub.badge?.slug).filter(Boolean); const availableBadges = allBadges.filter((b) => !userBadgeSlugs.includes(b.slug)); if (loading) { return (
); } return (
Select User Search and select a user to manage their tier and badges.
setSearchQuery(e.target.value)} className="pl-10" />
{filteredProfiles.slice(0, 50).map((profile) => ( ))} {filteredProfiles.length === 0 && (

No users found

)}
{selectedProfile ? ( <>
{(selectedProfile.username || selectedProfile.full_name || "U") .slice(0, 2) .toUpperCase()}
{selectedProfile.username || selectedProfile.full_name || "Unknown User"} {selectedProfile.email || selectedProfile.id}

Subscription Tier

{loadingUserData ? (
Loading...
) : (
{selectedUserTier === "council" ? ( ) : selectedUserTier === "pro" ? ( ) : ( )} {selectedUserTier}
{updatingTier && }
)}
User Badges Manage badges for this user. Some badges unlock AI personas. {loadingUserData ? (
Loading badges...
) : ( <>

Earned Badges ({selectedUserBadges.length})

{selectedUserBadges.length > 0 ? (
{selectedUserBadges.map((ub) => (
{ub.badge?.icon || "🏆"}

{ub.badge?.name || "Badge"}

{new Date(ub.earned_at).toLocaleDateString()}

))}
) : (

No badges earned yet.

)}

Award New Badge

{availableBadges.length > 0 ? (
{availableBadges.map((badge) => (
{badge.icon || "🏅"}

{badge.name}

{badge.unlocks_persona && ( Unlocks AI )}
))}
) : (

{allBadges.length === 0 ? "No badges defined in the system yet." : "User has all available badges."}

)}
)}
) : (

Select a user from the list to manage their tier and badges.

)}
); }