DocDoeAI / src /components /student-os /ChapterLibrary.tsx
asnannp's picture
deploy: sync backend to Space root (learn-lesson HF cache fix)
65d68f5
Raw History Blame Contribute Delete
3.72 kB
"use client";
import { useState } from "react";
import Link from "next/link";
import { ArrowRight, Search } from "lucide-react";
import coverage from "@/content/sslc/coverage-index.json";
const subjects = ["All subjects", "Physics", "Mathematics", "Chemistry", "Biology", "Social Science", "History", "Geography"];
export function ChapterLibrary() {
const [subject, setSubject] = useState("All subjects");
const [query, setQuery] = useState("");
const chapters = coverage.chapters.filter((chapter) => {
const discipline = "discipline" in chapter ? chapter.discipline : "";
return (subject === "All subjects" || chapter.subject === subject || discipline === subject) &&
`${chapter.name} ${chapter.subject} ${discipline}`.toLowerCase().includes(query.trim().toLowerCase());
});
return (
<section id="chapter-library" aria-labelledby="chapter-library-title" className="mb-8 scroll-mt-6">
<div className="mb-4">
<p className="student-eyebrow-accent">Kerala SCERT · Class 10</p>
<h2 id="chapter-library-title" className="mt-1 text-xl font-semibold text-[#202127]">Chapter library</h2>
<p className="mt-2 text-sm text-[#77756f]">Browse all {coverage.chapters.length} chapters. Open notes, formulas and sample practice for your subject.</p>
</div>
<div className="mb-4 flex flex-col gap-3 sm:flex-row">
<label className="flex min-h-11 flex-1 items-center gap-2 rounded-lg border border-[#deddd7] bg-white px-3 focus-within:ring-2 focus-within:ring-[#171716]/35">
<Search className="size-4 shrink-0" aria-hidden="true" />
<span className="sr-only">Search chapters</span>
<input value={query} onChange={(event) => setQuery(event.target.value)} placeholder="Search chapters…" className="min-w-0 flex-1 bg-transparent py-3 text-sm outline-none" />
</label>
<label className="flex items-center gap-2 text-sm">
<span className="sr-only">Filter chapter subject</span>
<select value={subject} onChange={(event) => setSubject(event.target.value)} className="min-h-11 w-full rounded-lg border border-[#deddd7] bg-white px-3 sm:w-auto">
{subjects.map((name) => <option key={name}>{name}</option>)}
</select>
</label>
</div>
<div className="mb-2 flex items-center justify-between gap-3">
<p aria-live="polite" aria-atomic="true" className="text-xs text-[#6f6e68]">{chapters.length} chapters{subject !== "All subjects" ? ` · ${subject}` : ""}</p>
{(query || subject !== "All subjects") && <button type="button" onClick={() => { setQuery(""); setSubject("All subjects"); }} className="min-h-11 px-2 text-sm underline focus-visible:outline-2 focus-visible:outline-offset-2">Clear filters</button>}
</div>
<div className="grid gap-x-6 sm:grid-cols-2">
{chapters.map((chapter) => (
<Link key={chapter.chapterId} href={`/classes/chapters/${chapter.chapterId}`} className="group flex min-h-20 items-center justify-between gap-3 border-t border-[#e3e1da] py-4 focus-visible:outline-2 focus-visible:outline-offset-2">
<span className="min-w-0">
<span className="block text-xs text-[#77756f]">{chapter.subject}{"discipline" in chapter ? ` · ${chapter.discipline}` : ""}</span>
<span className="mt-1 block text-sm font-semibold text-[#202127] group-hover:underline">{chapter.name}</span>
</span>
<ArrowRight className="size-4 shrink-0" aria-hidden="true" />
</Link>
))}
</div>
{!chapters.length && <p className="py-6 text-sm text-[#77756f]">No chapters match. Try another name or subject.</p>}
</section>
);
}