DocDoeAI / src /components /landing /WorkspaceInteractiveDemo.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
18.9 kB
"use client";
import { useState } from "react";
import {
ArrowRight,
BookOpen,
CheckCircle2,
Circle,
Clock3,
FileText,
GraduationCap,
Home,
MessageSquareText,
Play,
Search,
Sparkles,
} from "lucide-react";
import { DocDoeLogoMark } from "./DocDoeLogoMark";
import { cn } from "@/lib/utils";
export type WorkspaceView = "home" | "tuition" | "studychat" | "learn";
const nav = [
{ id: "home" as const, label: "Home", icon: Home },
{ id: "tuition" as const, label: "Tuition", icon: GraduationCap },
{ id: "learn" as const, label: "Learn Anything", icon: BookOpen },
{ id: "studychat" as const, label: "StudyChat", icon: MessageSquareText },
];
const tasks = [
"Sound Waves: Oscillation, amplitude, period",
"Sound Waves: Natural frequency & resonance",
"Sound Waves: Wave motion and types",
"Sound Waves: Frequency, wavelength, v = fλ",
];
const routeSteps = [
"Learn today's concept",
"Read the key notes",
"Pass the checkpoints",
"Fix weak areas",
"Save revision",
];
const chatTools = [
{ title: "Solve a PYQ", desc: "Method, marks and final answer" },
{ title: "Explain a derivation", desc: "Steps, formula and exam method" },
{ title: "Make study notes", desc: "Clean notes from a topic or PDF" },
{ title: "Correct my answer", desc: "Marks, mistakes and improved answer" },
];
/**
* Live-looking DocDoe workspace. Tabs switch real product surfaces
* (Home / Tuition / StudyChat / Learn Anything) — not screenshots.
*/
export function WorkspaceInteractiveDemo({
className,
defaultView = "home",
}: {
className?: string;
defaultView?: WorkspaceView;
}) {
const [view, setView] = useState<WorkspaceView>(defaultView);
return (
<div
className={cn(
"overflow-hidden rounded-[22px] border border-[#E6E8EE] bg-white shadow-[0_28px_80px_-24px_rgba(21,23,31,0.18)]",
className,
)}
>
{/* Window chrome */}
<div className="flex items-center gap-2 border-b border-[#EEF0F4] bg-[#FAFBFC] px-4 py-2.5">
<span className="size-2.5 rounded-full bg-[#E4E6EC]" />
<span className="size-2.5 rounded-full bg-[#E4E6EC]" />
<span className="size-2.5 rounded-full bg-[#E4E6EC]" />
<span className="ml-2 text-[11px] font-medium text-[#8B90A0]">
app.docdoe.in · live workspace
</span>
</div>
<div className="grid min-h-[420px] grid-cols-1 sm:min-h-[480px] sm:grid-cols-[200px_1fr]">
{/* Sidebar */}
<aside className="hidden flex-col bg-[#0A0A0B] text-white sm:flex">
<div className="flex items-center gap-2.5 px-4 py-4">
<span className="grid size-8 place-items-center rounded-lg bg-white text-[#0A0A0B]">
<DocDoeLogoMark className="size-4" />
</span>
<div>
<p className="text-[13px] font-semibold tracking-tight">DocDoe</p>
<p className="text-[10px] text-white/40">AI tuition partner</p>
</div>
</div>
<nav className="flex flex-1 flex-col gap-0.5 px-2.5 pb-4" aria-label="Workspace demo">
{nav.map((item) => {
const Icon = item.icon;
const active = view === item.id;
return (
<button
key={item.id}
type="button"
onClick={() => setView(item.id)}
className={cn(
"flex items-center gap-2.5 rounded-xl px-3 py-2.5 text-left text-[13px] font-medium transition-colors",
active
? "bg-white text-[#0A0A0B]"
: "text-white/55 hover:bg-white/[0.06] hover:text-white",
)}
>
<Icon className="size-4 shrink-0" strokeWidth={1.8} />
{item.label}
{active ? (
<span className="ml-auto size-1.5 rounded-full bg-violet-500" />
) : null}
</button>
);
})}
</nav>
<div className="border-t border-white/10 p-3">
<div className="rounded-xl border border-white/10 bg-white/[0.04] px-3 py-2.5">
<p className="text-[10px] font-semibold uppercase tracking-[0.12em] text-white/35">
Student
</p>
<p className="mt-1 text-[12px] font-medium text-white/80">SSLC · 10th · Kerala</p>
</div>
</div>
</aside>
{/* Mobile tab bar */}
<div className="flex gap-1 overflow-x-auto border-b border-[#EEF0F4] bg-[#FAFBFC] p-2 sm:hidden">
{nav.map((item) => (
<button
key={item.id}
type="button"
onClick={() => setView(item.id)}
className={cn(
"shrink-0 rounded-full px-3 py-1.5 text-[12px] font-semibold",
view === item.id
? "bg-[#111] text-white"
: "bg-white text-[#5B5B66] ring-1 ring-[#E6E8EE]",
)}
>
{item.label}
</button>
))}
</div>
{/* Main content */}
<div className="min-w-0 bg-[#F7F8FA]">
<div className="flex items-center justify-between border-b border-[#EEF0F4] bg-white px-4 py-3">
<p className="text-[13px] font-semibold text-[#111]">
{nav.find((n) => n.id === view)?.label}
</p>
<div className="flex items-center gap-2 text-[11px] text-[#8B90A0]">
<Search className="size-3.5" />
<span className="hidden sm:inline">Search workspace</span>
</div>
</div>
<div className="p-4 sm:p-5">
{view === "home" ? (
<HomeView
onOpenTuition={() => setView("tuition")}
onOpenLearn={() => setView("learn")}
onOpenChat={() => setView("studychat")}
/>
) : null}
{view === "tuition" ? <TuitionView /> : null}
{view === "studychat" ? <StudyChatView /> : null}
{view === "learn" ? <LearnView /> : null}
</div>
</div>
</div>
</div>
);
}
function HomeView({
onOpenTuition,
onOpenLearn,
onOpenChat,
}: {
onOpenTuition: () => void;
onOpenLearn: () => void;
onOpenChat: () => void;
}) {
return (
<div className="space-y-4">
<div>
<p className="text-[12px] text-[#8B90A0]">Good evening</p>
<h3 className="mt-0.5 text-xl font-semibold tracking-tight text-[#111]">
Let&apos;s make today productive
</h3>
<p className="mt-1 text-[12px] text-[#6B7080]">SSLC / 10th · Kerala State Board</p>
</div>
<div className="grid gap-3 sm:grid-cols-[1.3fr_0.9fr]">
<div className="relative overflow-hidden rounded-2xl bg-gradient-to-br from-[#1a1035] via-[#2b1654] to-[#0f0a1c] p-5 text-white">
<p className="text-[10px] font-semibold uppercase tracking-[0.16em] text-white/50">
Today&apos;s focus
</p>
<p className="mt-3 text-lg font-semibold tracking-tight">Sound Waves · Mission 01</p>
<p className="mt-1 text-[12px] text-white/60">
Oscillation, amplitude, period and frequency · 35 min
</p>
<button
type="button"
onClick={onOpenTuition}
className="mt-5 inline-flex items-center gap-1.5 rounded-full bg-white px-4 py-2 text-[12px] font-semibold text-[#111]"
>
Continue learning
<ArrowRight className="size-3.5" />
</button>
<div className="pointer-events-none absolute -right-6 -top-6 size-28 rounded-full bg-violet-400/20 blur-2xl" />
</div>
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-4">
<div className="flex items-center justify-between">
<p className="text-[11px] font-semibold uppercase tracking-[0.12em] text-[#8B90A0]">
Today&apos;s plan
</p>
<span className="rounded-full bg-violet-50 px-2 py-0.5 text-[10px] font-semibold text-violet-700">
0/4
</span>
</div>
<ul className="mt-3 space-y-2.5">
{tasks.map((task, i) => (
<li key={task} className="flex items-start gap-2 text-[12px] text-[#3A3F4B]">
<Circle className="mt-0.5 size-3.5 shrink-0 text-[#C5C9D4]" />
<span className="leading-snug">
<span className="font-medium">{task}</span>
<span className="mt-0.5 block text-[10px] text-[#8B90A0]">Physics · 35 min</span>
</span>
{i === 0 ? (
<button
type="button"
onClick={onOpenTuition}
className="ml-auto shrink-0 text-[11px] font-semibold text-violet-600"
>
Start
</button>
) : null}
</li>
))}
</ul>
</div>
</div>
<div className="grid grid-cols-3 gap-2">
{[
{ label: "Tuition", color: "from-violet-50 to-white", icon: GraduationCap, onClick: onOpenTuition },
{ label: "Learn Anything", color: "from-emerald-50 to-white", icon: BookOpen, onClick: onOpenLearn },
{ label: "StudyChat", color: "from-blue-50 to-white", icon: MessageSquareText, onClick: onOpenChat },
].map((card) => {
const Icon = card.icon;
return (
<button
key={card.label}
type="button"
onClick={card.onClick}
className={cn(
"rounded-xl border border-[#E6E8EE] bg-gradient-to-b p-3 text-left transition-colors hover:border-[#D0D4DE]",
card.color,
)}
>
<Icon className="size-4 text-[#3A3F4B]" strokeWidth={1.8} />
<p className="mt-2 text-[11px] font-semibold text-[#111]">{card.label}</p>
</button>
);
})}
</div>
</div>
);
}
function TuitionView() {
return (
<div className="space-y-4">
<div className="rounded-2xl bg-gradient-to-br from-[#1a1035] via-[#2b1654] to-[#120c22] p-5 text-white">
<p className="text-[10px] font-semibold uppercase tracking-[0.16em] text-white/50">
Today&apos;s tuition
</p>
<h3 className="mt-2 text-lg font-semibold tracking-tight sm:text-xl">
Oscillation, Amplitude, Period and Frequency
</h3>
<p className="mt-1.5 max-w-md text-[12px] leading-relaxed text-white/60">
Understand the basic terms of oscillatory motion using a pendulum and swing.
</p>
<div className="mt-3 flex flex-wrap items-center gap-3 text-[11px] text-white/55">
<span className="inline-flex items-center gap-1">
<Clock3 className="size-3" /> 20 mins
</span>
<span>Sound Waves · p.7</span>
</div>
<button
type="button"
className="mt-5 inline-flex items-center gap-1.5 rounded-full bg-white px-4 py-2 text-[12px] font-semibold text-[#111]"
>
<Play className="size-3 fill-current" />
Start today&apos;s class
</button>
</div>
<div className="grid gap-3 sm:grid-cols-[1fr_0.85fr]">
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-4">
<div className="flex items-center justify-between">
<p className="text-[11px] font-semibold uppercase tracking-[0.12em] text-violet-600">
Your class route
</p>
<span className="rounded-full bg-violet-50 px-2 py-0.5 text-[10px] font-semibold text-violet-700">
5 steps
</span>
</div>
<ul className="mt-3 space-y-0">
{routeSteps.map((step, i) => (
<li
key={step}
className="flex items-center gap-3 border-b border-[#F0F1F5] py-2.5 last:border-0"
>
{i === 0 ? (
<span className="grid size-6 place-items-center rounded-full bg-violet-100 text-violet-700">
<Play className="size-3 fill-current" />
</span>
) : (
<Circle className="size-5 text-[#D0D3DC]" />
)}
<span className="text-[13px] font-medium text-[#222]">{step}</span>
<span className="ml-auto text-[10px] text-[#8B90A0]">Step {i + 1}</span>
</li>
))}
</ul>
</div>
<div className="space-y-3">
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-4">
<p className="text-[11px] font-semibold text-[#111]">Class summary</p>
<dl className="mt-3 space-y-2 text-[12px]">
{[
["Chapter", "Sound Waves"],
["Mission", "M1"],
["Time", "20 mins"],
["Source", "Textbook p.7"],
].map(([k, v]) => (
<div key={k} className="flex justify-between gap-2">
<dt className="text-[#8B90A0]">{k}</dt>
<dd className="font-medium text-[#222]">{v}</dd>
</div>
))}
</dl>
</div>
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-4">
<p className="text-[11px] font-semibold text-[#111]">Why this class</p>
<p className="mt-2 text-[12px] leading-relaxed text-[#5B5B66]">
Next unfinished task in your saved plan. Aim: write exam keywords in your own words.
</p>
</div>
</div>
</div>
</div>
);
}
function StudyChatView() {
return (
<div className="space-y-4">
<div className="text-center">
<div className="mx-auto grid size-10 place-items-center rounded-xl bg-[#111] text-white">
<DocDoeLogoMark className="size-5" />
</div>
<h3 className="mt-3 text-lg font-semibold tracking-tight text-[#111]">
What do you need to understand?
</h3>
<p className="mt-1 text-[12px] text-[#8B90A0]">SSLC / 10th · Kerala · Physics</p>
</div>
<div className="grid gap-2 sm:grid-cols-2">
{chatTools.map((tool) => (
<button
key={tool.title}
type="button"
className="flex items-start gap-3 rounded-xl border border-[#E6E8EE] bg-white p-3.5 text-left transition-colors hover:border-[#D0D4DE]"
>
<FileText className="mt-0.5 size-4 shrink-0 text-[#6B7080]" />
<span>
<span className="block text-[13px] font-semibold text-[#111]">{tool.title}</span>
<span className="mt-0.5 block text-[11px] text-[#8B90A0]">{tool.desc}</span>
</span>
<ArrowRight className="ml-auto size-3.5 shrink-0 text-[#C5C9D4]" />
</button>
))}
</div>
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-3">
<div className="flex items-center gap-2 rounded-xl bg-[#F7F8FA] px-3 py-2.5">
<span className="flex-1 text-[12px] text-[#8B90A0]">
Ask a doubt, paste a PYQ, or tell DocDoe what to teach…
</span>
<span className="grid size-8 place-items-center rounded-full bg-[#111] text-white">
<ArrowRight className="size-3.5" />
</span>
</div>
<p className="mt-2 text-center text-[10px] text-[#A0A4B0]">
Answers can make mistakes. Check important exam facts against your source.
</p>
</div>
</div>
);
}
function LearnView() {
return (
<div className="space-y-4">
<div>
<h3 className="text-lg font-semibold tracking-tight text-[#111]">
Learn Anything
</h3>
<p className="mt-1 text-[12px] text-[#6B7080]">
Turn any topic into a clear roadmap with sessions, notes, and practice.
</p>
</div>
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-4">
<p className="text-[12px] font-semibold text-[#111]">What do you want to learn?</p>
<div className="mt-3 flex items-center gap-2 rounded-xl border border-[#E6E8EE] bg-[#FAFBFC] px-3 py-2.5">
<Sparkles className="size-4 text-violet-500" />
<span className="text-[12px] text-[#8B90A0]">I want to learn…</span>
</div>
<div className="mt-3 flex flex-wrap gap-2">
{["Beginner", "3 months", "Career skill"].map((chip) => (
<span
key={chip}
className="rounded-full border border-[#E6E8EE] bg-white px-2.5 py-1 text-[11px] font-medium text-[#5B5B66]"
>
{chip}
</span>
))}
</div>
<div className="mt-3 flex flex-wrap gap-1.5">
{["Data Science", "Python", "UI/UX", "Public Speaking"].map((t) => (
<span
key={t}
className="rounded-full bg-violet-50 px-2.5 py-1 text-[10px] font-semibold text-violet-700"
>
{t}
</span>
))}
</div>
</div>
<div className="rounded-2xl border border-[#E6E8EE] bg-white p-4">
<div className="flex items-center justify-between">
<p className="text-[12px] font-semibold text-[#111]">Your learning roadmap</p>
<span className="rounded-full bg-violet-50 px-2 py-0.5 text-[10px] font-semibold text-violet-700">
Ready when you are
</span>
</div>
<div className="mt-4 grid grid-cols-3 gap-2 sm:grid-cols-6">
{["Goal", "Foundations", "Core ideas", "Practice", "Project", "Revision"].map(
(stage, i) => (
<div
key={stage}
className="rounded-xl border border-[#EEF0F4] bg-[#FAFBFC] px-2 py-3 text-center"
>
<span className="mx-auto grid size-6 place-items-center rounded-full border border-[#E0E3EA] text-[10px] font-semibold text-[#8B90A0]">
{i + 1}
</span>
<p className="mt-2 text-[10px] font-medium text-[#5B5B66]">{stage}</p>
</div>
),
)}
</div>
</div>
<div className="flex items-start gap-2 rounded-xl border border-[#E6E8EE] bg-white p-3">
<CheckCircle2 className="mt-0.5 size-4 shrink-0 text-emerald-500" />
<p className="text-[12px] leading-relaxed text-[#5B5B66]">
Name a skill, set your pace, start one session. Same student profile as Tuition and StudyChat.
</p>
</div>
</div>
);
}