import { useEffect, useState, useCallback } from "react"; import { useDiscordActivity } from "@/contexts/DiscordActivityContext"; import LoadingScreen from "@/components/LoadingScreen"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent } from "@/components/ui/card"; import { Progress } from "@/components/ui/progress"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { ScrollArea } from "@/components/ui/scroll-area"; import { Heart, MessageCircle, Trophy, Zap, Gamepad2, Briefcase, BookOpen, Network, Sparkles, Shield, RefreshCw, ExternalLink, Flame, Star, Target, Gift, CheckCircle, AlertCircle, Loader2, } from "lucide-react"; const APP_URL = "https://aethex.dev"; type ArmType = "labs" | "gameforge" | "corp" | "foundation" | "devlink" | "nexus" | "staff"; const ARM_CONFIG: Record = { labs: { label: "Labs", icon: Zap, color: "text-yellow-400", bgClass: "bg-yellow-500/20", borderClass: "border-yellow-500" }, gameforge: { label: "GameForge", icon: Gamepad2, color: "text-green-400", bgClass: "bg-green-500/20", borderClass: "border-green-500" }, corp: { label: "Corp", icon: Briefcase, color: "text-blue-400", bgClass: "bg-blue-500/20", borderClass: "border-blue-500" }, foundation: { label: "Foundation", icon: BookOpen, color: "text-red-400", bgClass: "bg-red-500/20", borderClass: "border-red-500" }, devlink: { label: "Dev-Link", icon: Network, color: "text-cyan-400", bgClass: "bg-cyan-500/20", borderClass: "border-cyan-500" }, nexus: { label: "Nexus", icon: Sparkles, color: "text-purple-400", bgClass: "bg-purple-500/20", borderClass: "border-purple-500" }, staff: { label: "Staff", icon: Shield, color: "text-indigo-400", bgClass: "bg-indigo-500/20", borderClass: "border-indigo-500" }, }; interface Post { id: string; title: string; content: string; arm_affiliation: ArmType; author_id: string; created_at: string; likes_count: number; comments_count: number; tags?: string[]; user_profiles?: { id: string; username?: string; full_name?: string; avatar_url?: string; }; } interface Opportunity { id: string; title: string; description: string; job_type: string; arm_affiliation: ArmType; salary_min?: number; salary_max?: number; } interface Quest { id: string; title: string; description: string; xp_reward: number; completed: boolean; progress: number; total: number; type: "daily" | "weekly"; } interface Achievement { id: string; name: string; description: string; icon: string; xp_reward: number; unlocked: boolean; progress?: number; total?: number; } interface LeaderboardEntry { rank: number; user_id: string; username: string; avatar_url?: string; xp: number; level: number; streak?: number; } function ErrorMessage({ message, onRetry }: { message: string; onRetry?: () => void }) { return (

{message}

{onRetry && ( )}
); } function LoadingSpinner() { return (
); } function FeedTab({ openExternalLink }: { openExternalLink: (url: string) => Promise }) { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [needsAuth, setNeedsAuth] = useState(false); const fetchPosts = useCallback(async () => { setLoading(true); setError(null); setNeedsAuth(false); try { const response = await fetch("/api/feed?limit=10"); if (response.status === 401 || response.status === 403) { setNeedsAuth(true); return; } if (!response.ok) { const errorData = await response.json().catch(() => ({})); throw new Error(errorData.error || `Failed to fetch posts (${response.status})`); } const data = await response.json(); setPosts(data.posts || []); } catch (err: any) { console.error("[Activity Feed] Error:", err); setError(err.message || "Failed to load feed"); } finally { setLoading(false); } }, []); useEffect(() => { fetchPosts(); }, [fetchPosts]); if (loading) return ; if (needsAuth) { return (

Sign in on the web to view the community feed

); } if (error) return ; return (
{posts.length === 0 ? (

No posts yet. Be the first to share!

) : ( posts.map((post) => { const config = ARM_CONFIG[post.arm_affiliation] || ARM_CONFIG.labs; const Icon = config.icon; return (
{post.user_profiles?.avatar_url && ( )}
{post.user_profiles?.full_name || post.user_profiles?.username || "Anonymous"} {config.label}

{post.title}

{post.content}

{post.likes_count || 0} {post.comments_count || 0}
); }) )} {posts.length > 0 && ( )}
); } function RealmSwitcher({ currentRealm, openExternalLink, }: { currentRealm: ArmType; openExternalLink: (url: string) => Promise; }) { const realms = Object.entries(ARM_CONFIG) as [ArmType, typeof ARM_CONFIG.labs][]; return (

Your Realms

Explore the different realms of AeThex

Your current realm: {ARM_CONFIG[currentRealm]?.label || "Labs"}

{realms.map(([key, config]) => { const Icon = config.icon; const isActive = currentRealm === key; return ( ); })}
); } function AchievementsTab({ openExternalLink }: { openExternalLink: (url: string) => Promise }) { const achievements: Achievement[] = [ { id: "1", name: "First Post", description: "Create your first community post", icon: "πŸ“", xp_reward: 50, unlocked: true }, { id: "2", name: "Social Butterfly", description: "Follow 5 different realms", icon: "πŸ¦‹", xp_reward: 100, unlocked: true }, { id: "3", name: "Realm Explorer", description: "Visit all 7 realms", icon: "πŸ—ΊοΈ", xp_reward: 150, unlocked: false, progress: 5, total: 7 }, { id: "4", name: "Community Leader", description: "Get 100 likes on your posts", icon: "πŸ‘‘", xp_reward: 500, unlocked: false, progress: 42, total: 100 }, { id: "5", name: "Mentor", description: "Complete 10 mentorship sessions", icon: "πŸŽ“", xp_reward: 300, unlocked: false, progress: 3, total: 10 }, { id: "6", name: "Hot Streak", description: "Log in 7 days in a row", icon: "πŸ”₯", xp_reward: 200, unlocked: false, progress: 4, total: 7 }, ]; const unlockedCount = achievements.filter((a) => a.unlocked).length; return (
{unlockedCount}/{achievements.length} Unlocked
Preview
{achievements.slice(0, 5).map((achievement) => (
{achievement.icon}

{achievement.name}

{achievement.unlocked && }
+{achievement.xp_reward}

{achievement.description}

{!achievement.unlocked && achievement.progress !== undefined && (
{achievement.progress}/{achievement.total}
)}
))}
); } function LeaderboardTab({ openExternalLink }: { openExternalLink: (url: string) => Promise }) { const leaderboard: LeaderboardEntry[] = [ { rank: 1, user_id: "1", username: "CodeMaster", xp: 12500, level: 25, streak: 14 }, { rank: 2, user_id: "2", username: "DevNinja", xp: 11200, level: 23, streak: 7 }, { rank: 3, user_id: "3", username: "BuilderX", xp: 9800, level: 21, streak: 21 }, { rank: 4, user_id: "4", username: "CreatorPro", xp: 8500, level: 19, streak: 5 }, { rank: 5, user_id: "5", username: "ForgeHero", xp: 7200, level: 17, streak: 3 }, ]; const getRankBadge = (rank: number) => { if (rank === 1) return { color: "text-yellow-400", bg: "bg-yellow-500/20", icon: "πŸ₯‡" }; if (rank === 2) return { color: "text-gray-300", bg: "bg-gray-400/20", icon: "πŸ₯ˆ" }; if (rank === 3) return { color: "text-orange-400", bg: "bg-orange-500/20", icon: "πŸ₯‰" }; return { color: "text-gray-400", bg: "bg-gray-700/50", icon: null }; }; return (
Top Creators This Week
Preview
{leaderboard.map((entry) => { const badge = getRankBadge(entry.rank); return (
{badge.icon || `#${entry.rank}`}

{entry.username}

Lvl {entry.level} {entry.streak && entry.streak > 0 && ( {entry.streak}d )}

{entry.xp.toLocaleString()}

XP

); })}
); } function OpportunitiesTab({ openExternalLink }: { openExternalLink: (url: string) => Promise }) { return (
Open Opportunities

Browse job opportunities, contracts, and gigs from the AeThex community.

Quick categories:

{[ { label: "Full-Time", icon: Briefcase }, { label: "Contract", icon: Target }, { label: "Freelance", icon: Star }, ].map(({ label, icon: Icon }) => ( ))}
); } function QuestsTab({ openExternalLink }: { openExternalLink: (url: string) => Promise }) { const quests: Quest[] = [ { id: "1", title: "Share Your Work", description: "Post an update to the community feed", xp_reward: 25, completed: false, progress: 0, total: 1, type: "daily" }, { id: "2", title: "Engage & Support", description: "Like 5 posts from other creators", xp_reward: 15, completed: false, progress: 3, total: 5, type: "daily" }, { id: "3", title: "Realm Hopper", description: "Visit 3 different realm feeds", xp_reward: 20, completed: true, progress: 3, total: 3, type: "daily" }, { id: "4", title: "Weekly Contributor", description: "Make 7 posts this week", xp_reward: 150, completed: false, progress: 4, total: 7, type: "weekly" }, ]; const dailyQuests = quests.filter((q) => q.type === "daily"); const weeklyQuests = quests.filter((q) => q.type === "weekly"); const QuestCard = ({ quest }: { quest: Quest }) => (
{quest.completed ? : }

{quest.title}

+{quest.xp_reward} XP

{quest.description}

{!quest.completed && (
{quest.progress}/{quest.total}
)}
); return (
Preview - Quest system coming soon
{dailyQuests.map((quest) => )}
Weekly Quests
{weeklyQuests.map((quest) => )}
); } export default function Activity() { const { isActivity, isLoading, user, error, openExternalLink } = useDiscordActivity(); const [showContent, setShowContent] = useState(false); const [activeTab, setActiveTab] = useState("feed"); const currentRealm: ArmType = (user?.primary_arm as ArmType) || "labs"; useEffect(() => { if (isActivity && !isLoading) { setShowContent(true); } }, [isActivity, isLoading]); if (isLoading) { return ; } if (error) { return (

Activity Error

{error}

Troubleshooting:

  1. Clear your browser cache
  2. Close Discord completely
  3. Reopen Discord and try again
); } if (!isActivity && !isLoading) { return (

Discord Activity

This page is designed to run as a Discord Activity. Open it within Discord to get started!

Visit aethex.dev
); } if (user && showContent) { const realmConfig = ARM_CONFIG[currentRealm]; const RealmIcon = realmConfig.icon; return (
{user.avatar_url && }

{user.full_name || user.username}

{realmConfig.label}
Feed Realms Badges Top Jobs Quests
); } return ; }