"use client"; import { Suspense, useEffect, useState } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { Award, CalendarDays, HeartHandshake, MessageSquareHeart, Sparkles } from "lucide-react"; import { useQuery } from "@tanstack/react-query"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { PageHeader } from "@/components/page-header"; import { EventsPanel } from "@/components/events-panel"; import { LeaderboardPanel } from "@/components/leaderboard-panel"; import { CommunityPanel } from "@/components/community-panel"; import { Button } from "@/components/ui/button"; import { UserAvatar, avatarPropsOf } from "@/components/ui/user-avatar"; import { Skeleton, SkeletonAvatar } from "@/components/ui/skeleton"; import { Panel } from "@/components/panel"; import { Badge } from "@/components/ui/badge"; import type { Mentor } from "@/lib/types"; import { http } from "@/lib/api"; import type { ChatMessage, Conversation } from "@/lib/types"; import { cn } from "@/lib/utils"; type Tab = "events" | "chats" | "leagues" | "community"; const TABS: Tab[] = ["events", "chats", "leagues", "community"]; function parseTab(raw: string | null): Tab { if (raw && (TABS as string[]).includes(raw)) { return raw as Tab; } return "events"; } export default function UnwrapPage() { return ( ); } function HubTabs() { const router = useRouter(); const params = useSearchParams(); const [tab, setTab] = useState(() => parseTab(params.get("tab"))); useEffect(() => { const raw = params.get("tab"); const next = parseTab(raw); setTab(next); // Invalid / unknown ?tab=… → clean URL so content isn't blank. if (raw != null && raw !== next) { router.replace(next === "events" ? "/unwrap" : `/unwrap?tab=${next}`, { scroll: false }); } }, [params, router]); const onTab = (value: string) => { const next = parseTab(value); setTab(next); const url = next === "events" ? "/unwrap" : `/unwrap?tab=${next}`; router.replace(url, { scroll: false }); }; return (
جامعه، استمرار و منتورها } description="رویدادهای زنده برای تقویت مهارت، لیگ‌های هفتگی برای ثبات، گفتگو با منتور، و هماهنگی حمایت مالی." className="mb-0" /> رویدادها گفتگو با منتور لیگ‌ها حمایت
); } function openChat(withId?: number) { window.dispatchEvent(new CustomEvent("pargar:chat", { detail: { open: true, with: withId } })); } function ChatsLauncher() { const { data, isLoading } = useQuery({ queryKey: ["mentors"], queryFn: () => http.get<{ mentors: Mentor[] }>("/api/mentors"), }); const { data: convData, isLoading: convLoading } = useQuery({ queryKey: ["conversations"], queryFn: () => http.get<{ conversations: Conversation[] }>("/api/chats/conversations"), }); const mentors = data?.mentors ?? []; const conversations = convData?.conversations ?? []; return (

گفتگو همیشه در دکمهٔ شناور پایین صفحه در دسترس شماست؛ گفتگوها خصوصی هستند و پاسخ منتورها معمولاً کمتر از یک روز طول می‌کشد.

{convLoading && (
{[0, 1, 2].map((i) => (
))}
)} {conversations.map((c) => ( ))} {!convLoading && conversations.length === 0 && (

هنوز گفتگویی ندارید — از «شروع سریع» یک منتور انتخاب کنید.

)}
{isLoading && (
{[0, 1, 2, 3].map((i) => (
))}
)} {mentors.map((m) => ( ))} {!isLoading && mentors.length === 0 && (

هنوز منتوری در دسترس نیست.

)}
); } function messagePreview(m: ChatMessage) { if (m.body) return m.body; if (m.attachment) { const labels: Record = { image: "📷 عکس", video: "🎬 ویدیو", audio: "🎵 پیام صوتی" }; return labels[m.attachment.type] ?? `📎 ${m.attachment.name}`; } return ""; } function timeAgo(iso: string) { const diff = Date.now() - new Date(iso).getTime(); const m = Math.floor(diff / 60_000); if (m < 1) return "الان"; if (m < 60) return `${m} دقیقه قبل`; const h = Math.floor(m / 60); if (h < 24) return `${h} ساعت قبل`; return new Date(iso).toLocaleDateString("fa-IR"); }