UI: Fix streak modal, light mode contrast, state datalist, and plan mapping
This commit is contained in:
@@ -32,15 +32,15 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
|
|||||||
return () => document.removeEventListener("mousedown", handleClickOutside)
|
return () => document.removeEventListener("mousedown", handleClickOutside)
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const userInitials = user ? user.name.split(" ").map(n => n[0]).join("").toUpperCase() : "DS"
|
const userInitials = user ? user.name.split(" ").filter(n => /^[a-zA-Z]/.test(n)).slice(0, 2).map(n => n[0]).join("").toUpperCase() : "DS"
|
||||||
const targetExamLabel = user?.target_exam === "JEE_Main" ? "JEE Main" : user?.target_exam === "JEE_Advanced" ? "JEE Advanced" : user?.target_exam === "NEET" ? "NEET" : "NEET/JEE"
|
const targetExamLabel = user?.target_exam === "JEE_Main" ? "JEE Main" : user?.target_exam === "JEE_Advanced" ? "JEE Advanced" : user?.target_exam === "NEET" ? "NEET" : "NEET/JEE"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-screen bg-background overflow-hidden text-foreground selection:bg-primary/20">
|
<div className="flex h-screen bg-background overflow-hidden text-foreground selection:bg-primary/20">
|
||||||
{/* Sidebar */}
|
{/* Sidebar */}
|
||||||
<aside className="w-64 border-r border-border bg-background flex flex-col hidden md:flex">
|
<aside className="w-64 border-r border-border bg-background flex flex-col hidden md:flex">
|
||||||
<div className="p-6">
|
<div className="px-5 py-4">
|
||||||
<Link href="/dashboard" className="block relative h-16 w-full hover:opacity-90 transition-opacity">
|
<Link href="/dashboard" className="block relative h-10 w-full hover:opacity-90 transition-opacity">
|
||||||
<div className="absolute inset-0 dark:hidden">
|
<div className="absolute inset-0 dark:hidden">
|
||||||
<Image
|
<Image
|
||||||
src="/PragatiVeer_Logo/SVG_Logos/Rectangular_light_background.svg"
|
src="/PragatiVeer_Logo/SVG_Logos/Rectangular_light_background.svg"
|
||||||
@@ -88,21 +88,21 @@ export default function DashboardLayout({ children }: { children: ReactNode }) {
|
|||||||
icon={<LineChart size={18} />}
|
icon={<LineChart size={18} />}
|
||||||
label="Performance Analytics"
|
label="Performance Analytics"
|
||||||
active={pathname.startsWith("/dashboard/analytics")}
|
active={pathname.startsWith("/dashboard/analytics")}
|
||||||
isLocked={!hasAccessTo("ai-mistake-tracking")}
|
isLocked={!hasAccessTo("detailed-performance-analytics")}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/dashboard/rank-predictor"
|
href="/dashboard/rank-predictor"
|
||||||
icon={<Trophy size={18} />}
|
icon={<Trophy size={18} />}
|
||||||
label="Rank Predictor"
|
label="Rank Predictor"
|
||||||
active={pathname.startsWith("/dashboard/rank-predictor")}
|
active={pathname.startsWith("/dashboard/rank-predictor")}
|
||||||
isLocked={!hasAccessTo("ai-mistake-tracking")}
|
isLocked={!hasAccessTo("college-predictor")}
|
||||||
/>
|
/>
|
||||||
<NavItem
|
<NavItem
|
||||||
href="/dashboard/ai-coach"
|
href="/dashboard/ai-coach"
|
||||||
icon={<BrainCircuitIcon />}
|
icon={<BrainCircuitIcon />}
|
||||||
label="AI Coach"
|
label="AI Coach"
|
||||||
active={pathname.startsWith("/dashboard/ai-coach")}
|
active={pathname.startsWith("/dashboard/ai-coach")}
|
||||||
isLocked={!hasAccessTo("ai-mistake-tracking")}
|
isLocked={!hasAccessTo("ai-tutor-chat")}
|
||||||
/>
|
/>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ import { Activity, BrainCircuit, ArrowRight, Clock, Target, CheckCircle2, Trendi
|
|||||||
import * as htmlToImage from 'html-to-image'
|
import * as htmlToImage from 'html-to-image'
|
||||||
import { MistakeHeatmap } from "@/components/AI/MistakeHeatmap"
|
import { MistakeHeatmap } from "@/components/AI/MistakeHeatmap"
|
||||||
import { AdaptiveStudyPlan } from "@/components/AI/AdaptiveStudyPlan"
|
import { AdaptiveStudyPlan } from "@/components/AI/AdaptiveStudyPlan"
|
||||||
|
import { useActiveUser } from "@/hooks/useActiveUser"
|
||||||
|
|
||||||
export default function DashboardPage() {
|
export default function DashboardPage() {
|
||||||
|
const { user, hasAccessTo } = useActiveUser()
|
||||||
const progressRef = useRef<HTMLDivElement>(null)
|
const progressRef = useRef<HTMLDivElement>(null)
|
||||||
|
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
@@ -29,7 +31,7 @@ export default function DashboardPage() {
|
|||||||
return (
|
return (
|
||||||
<div className="p-8 max-w-6xl mx-auto space-y-10 animate-in fade-in duration-500 slide-in-from-bottom-4">
|
<div className="p-8 max-w-6xl mx-auto space-y-10 animate-in fade-in duration-500 slide-in-from-bottom-4">
|
||||||
<header className="flex justify-end mb-2">
|
<header className="flex justify-end mb-2">
|
||||||
<Button size="lg" className="gap-2 shadow-sm bg-[#00F0FF] text-background hover:bg-[#00F0FF]/90 font-bold">
|
<Button size="lg" className="gap-2 shadow-sm bg-[#00F0FF] text-black hover:bg-[#00F0FF]/90 font-bold">
|
||||||
<BrainCircuit size={18} />
|
<BrainCircuit size={18} />
|
||||||
Generate AI Plan
|
Generate AI Plan
|
||||||
</Button>
|
</Button>
|
||||||
@@ -133,22 +135,41 @@ export default function DashboardPage() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
||||||
<Card className="relative opacity-60 cursor-not-allowed border-dashed">
|
{hasAccessTo("topic-wise-microtests-unlimited") ? (
|
||||||
<CardContent className="p-5 flex items-center justify-between">
|
<Card className="hover:border-primary/30 hover:shadow-md cursor-pointer transition-all duration-300 group">
|
||||||
<div className="flex gap-4 items-center">
|
<CardContent className="p-5 flex items-center justify-between">
|
||||||
<div className="p-3 bg-secondary rounded-xl text-muted-foreground">
|
<div className="flex gap-4 items-center">
|
||||||
<Lock size={20} />
|
<div className="p-3 bg-secondary rounded-xl text-foreground">
|
||||||
|
<BrainCircuit size={20} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-medium text-base group-hover:text-primary transition-colors">Biology: Human Physiology</h3>
|
||||||
|
<p className="text-sm text-muted-foreground mt-0.5">30 Questions • Medium Priority</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<Button variant="outline" size="sm" className="gap-2 rounded-xl group-hover:bg-primary group-hover:text-primary-foreground group-hover:border-primary transition-all">
|
||||||
<h3 className="font-medium text-base text-muted-foreground">Biology: Human Physiology</h3>
|
Start <ArrowRight size={14} />
|
||||||
<p className="text-sm text-muted-foreground mt-0.5 flex items-center gap-1"><Lock size={12}/> Pro Feature</p>
|
</Button>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
) : (
|
||||||
|
<Card className="relative opacity-60 cursor-not-allowed border-dashed">
|
||||||
|
<CardContent className="p-5 flex items-center justify-between">
|
||||||
|
<div className="flex gap-4 items-center">
|
||||||
|
<div className="p-3 bg-secondary rounded-xl text-muted-foreground">
|
||||||
|
<Lock size={20} />
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h3 className="font-medium text-base text-muted-foreground">Biology: Human Physiology</h3>
|
||||||
|
<p className="text-sm text-muted-foreground mt-0.5 flex items-center gap-1"><Lock size={12}/> Pro Feature</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<Button variant="outline" size="sm" disabled className="gap-2 rounded-xl">
|
||||||
<Button variant="outline" size="sm" disabled className="gap-2 rounded-xl">
|
Locked
|
||||||
Locked
|
</Button>
|
||||||
</Button>
|
</CardContent>
|
||||||
</CardContent>
|
</Card>
|
||||||
</Card>
|
)}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
@@ -171,13 +192,23 @@ export default function DashboardPage() {
|
|||||||
</div>
|
</div>
|
||||||
<Button variant="secondary" className="rounded-xl font-medium">Remind Me</Button>
|
<Button variant="secondary" className="rounded-xl font-medium">Remind Me</Button>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-5 bg-secondary/50 flex items-center justify-between transition-colors hover:bg-secondary/70">
|
{hasAccessTo("weekly-test-series") ? (
|
||||||
<div>
|
<div className="p-5 bg-secondary/50 flex items-center justify-between transition-colors hover:bg-secondary/70 cursor-pointer group">
|
||||||
<h3 className="font-medium text-sm text-foreground flex items-center gap-2"><Lock size={14} className="text-muted-foreground"/> Part Test 3: Mechanics</h3>
|
<div>
|
||||||
<p className="text-xs text-muted-foreground mt-0.5 font-medium ml-6">Oct 24, 2026</p>
|
<h3 className="font-medium text-sm text-foreground flex items-center gap-2"><Activity size={14} className="text-primary group-hover:animate-pulse"/> Part Test 3: Mechanics</h3>
|
||||||
|
<p className="text-xs text-muted-foreground mt-0.5 font-medium ml-6">Oct 24, 2026</p>
|
||||||
|
</div>
|
||||||
|
<Button variant="outline" size="sm" className="h-7 text-xs rounded-lg group-hover:bg-primary group-hover:text-primary-foreground group-hover:border-primary">Start <ArrowRight size={12} className="ml-1" /></Button>
|
||||||
</div>
|
</div>
|
||||||
<Badge variant="secondary" className="text-xs">Pro Only</Badge>
|
) : (
|
||||||
</div>
|
<div className="p-5 bg-secondary/50 flex items-center justify-between transition-colors hover:bg-secondary/70 opacity-75">
|
||||||
|
<div>
|
||||||
|
<h3 className="font-medium text-sm text-foreground flex items-center gap-2"><Lock size={14} className="text-muted-foreground"/> Part Test 3: Mechanics</h3>
|
||||||
|
<p className="text-xs text-muted-foreground mt-0.5 font-medium ml-6">Oct 24, 2026</p>
|
||||||
|
</div>
|
||||||
|
<Badge variant="secondary" className="text-xs">Pro Only</Badge>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</Card>
|
</Card>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ export default function SettingsPage() {
|
|||||||
className="hidden"
|
className="hidden"
|
||||||
disabled={uploading}
|
disabled={uploading}
|
||||||
/>
|
/>
|
||||||
<Button type="button" variant="outline" className="w-full gap-2 rounded-xl border-dashed" asChild>
|
<Button type="button" variant="outline" className="w-full gap-2 rounded-xl border-dashed">
|
||||||
<span>
|
<span>
|
||||||
<Upload size={16} /> {avatarUrl ? "Change Photo" : "Upload Photo"}
|
<Upload size={16} /> {avatarUrl ? "Change Photo" : "Upload Photo"}
|
||||||
</span>
|
</span>
|
||||||
@@ -182,14 +182,53 @@ export default function SettingsPage() {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label className="text-sm font-bold">State</label>
|
<label className="text-sm font-bold">State / Union Territory</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
value={state}
|
value={state}
|
||||||
placeholder="Enter your state (e.g. Rajasthan, Delhi)"
|
list="indian-states"
|
||||||
|
placeholder="Enter or select your state"
|
||||||
onChange={(e) => setState(e.target.value)}
|
onChange={(e) => setState(e.target.value)}
|
||||||
className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[#00F0FF]"
|
className="w-full bg-secondary/50 border border-border rounded-lg px-4 py-2 text-sm focus:outline-none focus:ring-2 focus:ring-[#00F0FF]"
|
||||||
/>
|
/>
|
||||||
|
<datalist id="indian-states">
|
||||||
|
<option value="Andhra Pradesh" />
|
||||||
|
<option value="Arunachal Pradesh" />
|
||||||
|
<option value="Assam" />
|
||||||
|
<option value="Bihar" />
|
||||||
|
<option value="Chhattisgarh" />
|
||||||
|
<option value="Goa" />
|
||||||
|
<option value="Gujarat" />
|
||||||
|
<option value="Haryana" />
|
||||||
|
<option value="Himachal Pradesh" />
|
||||||
|
<option value="Jharkhand" />
|
||||||
|
<option value="Karnataka" />
|
||||||
|
<option value="Kerala" />
|
||||||
|
<option value="Madhya Pradesh" />
|
||||||
|
<option value="Maharashtra" />
|
||||||
|
<option value="Manipur" />
|
||||||
|
<option value="Meghalaya" />
|
||||||
|
<option value="Mizoram" />
|
||||||
|
<option value="Nagaland" />
|
||||||
|
<option value="Odisha" />
|
||||||
|
<option value="Punjab" />
|
||||||
|
<option value="Rajasthan" />
|
||||||
|
<option value="Sikkim" />
|
||||||
|
<option value="Tamil Nadu" />
|
||||||
|
<option value="Telangana" />
|
||||||
|
<option value="Tripura" />
|
||||||
|
<option value="Uttar Pradesh" />
|
||||||
|
<option value="Uttarakhand" />
|
||||||
|
<option value="West Bengal" />
|
||||||
|
<option value="Andaman and Nicobar Islands" />
|
||||||
|
<option value="Chandigarh" />
|
||||||
|
<option value="Dadra and Nagar Haveli and Daman and Diu" />
|
||||||
|
<option value="Delhi" />
|
||||||
|
<option value="Jammu and Kashmir" />
|
||||||
|
<option value="Ladakh" />
|
||||||
|
<option value="Lakshadweep" />
|
||||||
|
<option value="Puducherry" />
|
||||||
|
</datalist>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<label className="text-sm font-bold">Email Address</label>
|
<label className="text-sm font-bold">Email Address</label>
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ export function StreakOnboardingModal() {
|
|||||||
<div className="pt-4">
|
<div className="pt-4">
|
||||||
<Button
|
<Button
|
||||||
onClick={handleEnter}
|
onClick={handleEnter}
|
||||||
className="w-full size-12 rounded-xl text-base font-black bg-[#00F0FF] text-background hover:bg-[#00F0FF]/90 shadow-[0_0_20px_-3px_#00F0FF] hover:shadow-[0_0_30px_#00F0FF] transition-all duration-300"
|
className="w-full h-14 rounded-xl text-lg font-black bg-[#00F0FF] text-black hover:bg-[#00F0FF]/90 shadow-[0_0_20px_-3px_#00F0FF] hover:shadow-[0_0_30px_#00F0FF] hover:-translate-y-1 transition-all duration-300"
|
||||||
>
|
>
|
||||||
Enter Workspace
|
Enter Workspace
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
({ className, variant = "default", size = "default", ...props }, ref) => {
|
({ className, variant = "default", size = "default", asChild, ...props }, ref) => {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
|||||||
Reference in New Issue
Block a user