diff --git a/src/app/api/og/dashboard/route.tsx b/src/app/api/og/dashboard/route.tsx index 990ab73..829850a 100644 --- a/src/app/api/og/dashboard/route.tsx +++ b/src/app/api/og/dashboard/route.tsx @@ -18,6 +18,13 @@ export async function GET(req: NextRequest) { const target = searchParams.get('target') || 'JEE'; const plan = searchParams.get('plan') || 'Free'; + // Read date (if passed, otherwise use current date/time) + const exportDate = searchParams.get('date') || new Intl.DateTimeFormat('en-IN', { + dateStyle: 'medium', + timeStyle: 'short', + timeZone: 'Asia/Kolkata', + }).format(new Date()); + // Load logo from disk and convert to base64 const logoPath = join(process.cwd(), 'public', 'PragatiVeer_Logo', 'PNG_Logos', 'Rectangular_dark_background.png'); let logoUrl = ''; @@ -110,6 +117,7 @@ export async function GET(req: NextRequest) {
{name}
+
Generated: {exportDate}
{`${target} Aspirant`}
•
@@ -118,10 +126,10 @@ export async function GET(req: NextRequest) {
-
-
- pragativeer.com -
+
+
pragativeer.com
+
contact@pragativeer.com
+
+91 9079337961
diff --git a/src/app/dashboard/cbt/page.tsx b/src/app/dashboard/cbt/page.tsx index c4c3256..87c702e 100644 --- a/src/app/dashboard/cbt/page.tsx +++ b/src/app/dashboard/cbt/page.tsx @@ -134,7 +134,7 @@ export default function CBTPage() { - Computer Based Tests (CBT) + Mock Tests (CBT)

Real exam environment simulations to conquer {selectedPattern === "NEET" ? "NEET" : (targetExam || "JEE")}. diff --git a/src/app/dashboard/layout.tsx b/src/app/dashboard/layout.tsx index 55663ad..5386d19 100644 --- a/src/app/dashboard/layout.tsx +++ b/src/app/dashboard/layout.tsx @@ -1,7 +1,7 @@ "use client" import { ReactNode, useState, useEffect, useRef } from "react" -import { BookOpen, LayoutDashboard, Settings, FileText, Activity, LineChart, Trophy, User, ChevronUp, Lock, ShieldAlert, Flame, Target, Gauge, Zap, Calendar, Clock, BrainCircuit, BarChart3, School, CheckSquare } from "lucide-react" +import { BookOpen, LayoutDashboard, Settings, FileText, Activity, LineChart, Trophy, User, ChevronUp, Lock, ShieldAlert, Flame, Target, Gauge, Zap, Calendar, Clock, BrainCircuit, BarChart3, School, CheckSquare, MessageSquare } from "lucide-react" import Link from "next/link" import { usePathname } from "next/navigation" import { LanguageToggle } from "@/components/LanguageToggle" @@ -145,7 +145,7 @@ export default function DashboardLayout({ children }: { children: ReactNode }) { } + icon={} label="Doubt Forum" active={pathname.startsWith("/dashboard/community")} isLocked={!hasAccessTo("doubt-resolution-community")} diff --git a/src/app/dashboard/page.tsx b/src/app/dashboard/page.tsx index b6ff07a..a049510 100644 --- a/src/app/dashboard/page.tsx +++ b/src/app/dashboard/page.tsx @@ -4,7 +4,7 @@ import { useRef, useState, useEffect } from "react" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Badge } from "@/components/ui/badge" import { Button } from "@/components/ui/button" -import { BrainCircuit, Play, ChevronRight, Activity, Target, CheckCircle2, AlertTriangle, TrendingUp, Calendar, Zap, LayoutDashboard, Share2, Trophy, Lock, ArrowRight, Clock } from "lucide-react" +import { BrainCircuit, Play, ChevronRight, Activity, Target, CheckCircle2, AlertTriangle, TrendingUp, Calendar, Zap, LayoutDashboard, Share2, Trophy, Lock, ArrowRight, Clock, Facebook, Download, MessageCircle } from "lucide-react" import { MistakeHeatmap } from "@/components/AI/MistakeHeatmap" import { AdaptiveStudyPlan } from "@/components/AI/AdaptiveStudyPlan" import { useActiveUser } from "@/hooks/useActiveUser" @@ -14,6 +14,7 @@ export default function DashboardPage() { const [userStats, setUserStats] = useState(null) const [loading, setLoading] = useState(true) const [downloading, setDownloading] = useState(false) + const [shareMenuOpen, setShareMenuOpen] = useState(false) const progressRef = useRef(null) useEffect(() => { @@ -39,20 +40,28 @@ export default function DashboardPage() { fetchStats() }, [userLoading, user?.id, userId]) - const handleExport = async () => { + const getShareUrl = () => { + const score = isNew ? "0 / 0" : `${userStats?.today_score || 0} / ${userStats?.today_max_score || 60}` + const accuracy = isNew ? "0%" : `${userStats?.overall_accuracy || 0}%` + const qs = isNew ? "0" : (userStats?.total_questions_attempted || 0).toLocaleString() + const rank = isNew ? "#--" : `#${userStats?.city_rank || 1} / ${userStats?.city_total || 50}` + + const target = user?.target_exam === "NEET" ? "NEET" : "JEE" + const plan = user?.tier === "Al_Coach" ? "AI Coach" : user?.tier || "Free" + const name = user?.name || "Student" + const date = new Intl.DateTimeFormat('en-IN', { + dateStyle: 'medium', + timeStyle: 'short', + timeZone: 'Asia/Kolkata', + }).format(new Date()); + + return `/api/og/dashboard?score=${encodeURIComponent(score)}&accuracy=${encodeURIComponent(accuracy)}&qs=${encodeURIComponent(qs)}&rank=${encodeURIComponent(rank)}&name=${encodeURIComponent(name)}&target=${target}&plan=${encodeURIComponent(plan)}&date=${encodeURIComponent(date)}` + } + + const handleDownload = async () => { try { setDownloading(true) - const score = isNew ? "0 / 0" : `${userStats?.today_score || 0} / ${userStats?.today_max_score || 60}` - const accuracy = isNew ? "0%" : `${userStats?.overall_accuracy || 0}%` - const qs = isNew ? "0" : (userStats?.total_questions_attempted || 0).toLocaleString() - const rank = isNew ? "#--" : `#${userStats?.city_rank || 1} / ${userStats?.city_total || 50}` - - const target = user?.target_exam === "NEET" ? "NEET" : "JEE" - const plan = user?.tier === "Al_Coach" ? "AI Coach" : user?.tier || "Free" - const name = user?.name || "Student" - - const url = `/api/og/dashboard?score=${encodeURIComponent(score)}&accuracy=${encodeURIComponent(accuracy)}&qs=${encodeURIComponent(qs)}&rank=${encodeURIComponent(rank)}&name=${encodeURIComponent(name)}&target=${target}&plan=${encodeURIComponent(plan)}` - + const url = getShareUrl() const res = await fetch(url) const blob = await res.blob() const blobUrl = window.URL.createObjectURL(blob) @@ -68,9 +77,23 @@ export default function DashboardPage() { console.error("Failed to export image", err) } finally { setDownloading(false) + setShareMenuOpen(false) } } + const handleShareFacebook = () => { + const fullUrl = window.location.origin + getShareUrl() + window.open(`https://www.facebook.com/sharer/sharer.php?u=${encodeURIComponent(fullUrl)}`, '_blank') + setShareMenuOpen(false) + } + + const handleShareWhatsApp = () => { + const fullUrl = window.location.origin + getShareUrl() + const text = `Check out my performance on PragatiVeer!\n\n${fullUrl}` + window.open(`https://wa.me/?text=${encodeURIComponent(text)}`, '_blank') + setShareMenuOpen(false) + } + if (loading) { return (

@@ -100,10 +123,28 @@ export default function DashboardPage() { Your overall progress, scores, and active study plan at a glance.

- +
+ + {shareMenuOpen && ( +
+ + + +
+ )} +
{/* Today's Score */}