DocDoeAI / src /components /study-chat /StructuredStudyResponseCard.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
4.33 kB
"use client";
import { BookOpen, ChevronRight, Layers3, ShieldCheck } from "lucide-react";
import type { StructuredStudyResponse } from "@/lib/phase3-learning";
import type { StudyIntent } from "@/lib/study-intents";
type StructuredStudyResponseCardProps = {
data: StructuredStudyResponse;
onAction: (intent: StudyIntent, prompt: string) => void;
};
export function StructuredStudyResponseCard({ data, onAction }: StructuredStudyResponseCardProps) {
return (
<article className="animate-msg-assistant w-full rounded-[1.25rem] border border-white/[0.085] bg-white/[0.028] p-4 shadow-[0_14px_50px_rgba(0,0,0,0.22)] sm:p-5">
<div className="flex flex-wrap items-start justify-between gap-3 border-b border-white/[0.07] pb-4">
<div className="min-w-0">
<p className="text-[10px] font-bold uppercase tracking-[0.14em] text-white/36">Study Chat response</p>
<h2 className="mt-1 text-lg font-semibold text-white sm:text-xl">{data.topic}</h2>
<p className="mt-2 max-w-2xl text-sm leading-6 text-white/58">{data.contextNote}</p>
</div>
<span className="inline-flex items-center gap-1.5 rounded-full border border-white/[0.1] bg-black px-2.5 py-1 text-[11px] font-semibold text-white/62">
<ShieldCheck className="size-3.5" />
Separate practice
</span>
</div>
<div className="mt-4 grid gap-3 md:grid-cols-2">
{data.sections.map((section) => (
<section key={section.title} className="rounded-xl border border-white/[0.07] bg-[#0B0B0B] p-4">
<div className="flex items-start gap-3">
<span className="grid size-8 shrink-0 place-items-center rounded-lg border border-white/[0.08] bg-white/[0.04] text-white/66">
{section.title === "Flashcards" || section.title === "Smart Notes" ? (
<Layers3 className="size-4" />
) : (
<BookOpen className="size-4" />
)}
</span>
<div className="min-w-0">
<h3 className="text-sm font-semibold text-white">{section.title}</h3>
<p className="mt-1 text-xs leading-5 text-white/52">{section.summary}</p>
</div>
</div>
<ul className="mt-3 space-y-1.5">
{section.points.slice(0, 4).map((point, index) => (
<li key={`${section.title}-${point}-${index}`} className="flex gap-2 text-xs leading-5 text-white/68">
<span className="mt-2 size-1 shrink-0 rounded-full bg-white/38" />
<span>{point}</span>
</li>
))}
</ul>
{section.action ? (
<button
type="button"
onClick={() => onAction(section.action!.intent, section.action!.prompt)}
className="mt-3 inline-flex min-h-8 items-center gap-1.5 rounded-lg border border-white/[0.1] bg-white/[0.04] px-2.5 text-[11px] font-semibold text-white/66 transition hover:border-white/[0.2] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/22"
>
{section.action.label}
<ChevronRight className="size-3.5" />
</button>
) : null}
</section>
))}
</div>
<div className="mt-4 flex flex-wrap gap-2 rounded-xl border border-white/[0.07] bg-black/30 p-3">
{data.footerActions.map((action) => {
const disabled = action.label === "Add to Tuition Plan";
return (
<button
key={action.label}
type="button"
disabled={disabled}
title={disabled ? "Backend tuition-plan handoff is not wired yet." : undefined}
onClick={() => onAction(action.intent, action.prompt)}
className="inline-flex min-h-9 items-center gap-1.5 rounded-lg border border-white/[0.1] bg-white/[0.04] px-3 text-xs font-semibold text-white/68 transition hover:border-white/[0.2] hover:text-white focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-white/22 disabled:cursor-not-allowed disabled:opacity-45"
>
{action.label}
</button>
);
})}
</div>
</article>
);
}