DocDoeAI / src /components /study-chat /ExplanationNotesCards.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
4.39 kB
"use client";
import { FileText, MessageCircle } from "lucide-react";
import { EvidenceBadge } from "@/components/dashboard/EvidenceBadge";
import { studyIntentConfig, type StudyIntent } from "@/lib/study-intents";
import type { StudyCard } from "./types";
import { cleanLegacySourceSafetyText, isLegacySourceSafetyText, safeList } from "./utils";
import { BulletList, CitationBlock, FollowUpActions, Prose, RichStudyCard, Section, TrustFooter } from "./StudyCardPrimitives";
type CardAction = (intent: StudyIntent, prompt: string) => void;
export function ExplanationCard({ card, onAction }: { card: Extract<StudyCard, { kind: "explanation" }>; onAction: CardAction }) {
const isLegacySourceSafety =
isLegacySourceSafetyText(card.data.answer) ||
safeList(card.data.sections).some((section) => isLegacySourceSafetyText(`${section.title} ${section.body}`));
const answer = cleanLegacySourceSafetyText(card.data.answer);
const sections = isLegacySourceSafety
? []
: safeList(card.data.sections)
.filter((section) => !isLegacySourceSafetyText(`${section.title} ${section.body}`))
.slice(0, 8);
const citations = safeList(card.data.citations).slice(0, 3);
return (
<RichStudyCard icon={MessageCircle} title={studyIntentConfig[card.intent].label} eyebrow="Study Chat">
{card.meta?.evidenceLabel || card.data.evidence_label ? (
<div className="mb-3">
<EvidenceBadge label={card.meta?.evidenceLabel ?? card.data.evidence_label} />
</div>
) : null}
<div className="text-sm leading-7 text-white/74">
<Prose>{answer}</Prose>
</div>
{sections.length > 0 ? (
<div className="mt-4 grid gap-3 md:grid-cols-2">
{sections.map((section) => (
<Section key={section.title} title={section.title}>
<Prose>{section.body}</Prose>
</Section>
))}
</div>
) : null}
<CitationBlock citations={citations} />
<FollowUpActions topic={card.topic} onAction={onAction} meta={card.meta} />
<TrustFooter meta={card.meta} />
</RichStudyCard>
);
}
export function NotesCard({ card, onAction }: { card: Extract<StudyCard, { kind: "notes" }>; onAction: CardAction }) {
const data = card.data;
const formulaAndDefinitionItems = [
...safeList(data.important_definitions),
...safeList(data.formulas),
...safeList(data.diagrams_to_practice).map((item) => `Diagram: ${item}`),
];
const examFocusItems = [
...safeList(data.exam_focus),
...safeList(data.possible_exam_questions).map((item) => `Question: ${item}`),
];
const quickRecallItems = [
...safeList(data.quick_check),
...safeList(data.memory_tricks).map((item) => `Memory: ${item}`),
];
return (
<RichStudyCard icon={FileText} title={data.title || "Exam-ready notes"} eyebrow="Study notes">
{data.source_summary || data.summary || data.simple_explanation ? (
<div className="text-sm leading-7 text-white/74">
<Prose>{data.source_summary || data.summary || data.simple_explanation}</Prose>
</div>
) : null}
<div className="mt-4 grid gap-3 md:grid-cols-2">
<Section title="Key points">
<BulletList items={data.key_points} />
</Section>
<Section title="Scoring keywords">
<BulletList items={data.scoring_keywords || data.exam_keywords || data.important_keywords || []} />
</Section>
<Section title="Definitions, formulas, diagrams">
<BulletList items={formulaAndDefinitionItems} />
</Section>
<Section title="Exam focus">
<BulletList items={examFocusItems} />
</Section>
<Section title="Common mistakes">
<BulletList items={data.common_mistakes || []} limit={5} />
</Section>
<Section title="Quick recall">
<BulletList items={quickRecallItems} limit={6} />
</Section>
<Section title="10-minute revision">
<BulletList items={data.ten_minute_revision || data.last_minute_revision || []} limit={5} />
</Section>
</div>
{data.next_study_action ? <p className="mt-4 text-sm font-semibold text-white/70">{data.next_study_action}</p> : null}
<FollowUpActions topic={card.topic} onAction={onAction} meta={card.meta} />
<TrustFooter meta={card.meta} />
</RichStudyCard>
);
}