Download src/components/landing/WorkspaceInteractiveDemo.tsx from asnannp/DocDoeAI: direct link, hf CLI and curl.
- Browser
- Download file 18.9 kB
-
https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/landing/WorkspaceInteractiveDemo.tsx
- Command line
-
hf download hf://spaces/asnannp/DocDoeAI/src/components/landing/WorkspaceInteractiveDemo.tsx
-
curl -L -o WorkspaceInteractiveDemo.tsx https://huggingface.co/spaces/asnannp/DocDoeAI/resolve/main/src/components/landing/WorkspaceInteractiveDemo.tsx
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'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'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'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'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'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> | |
| ); | |
| } | |