diff --git a/SHARED_TASK_NOTES.md b/SHARED_TASK_NOTES.md new file mode 100644 index 0000000..0fa25c9 --- /dev/null +++ b/SHARED_TASK_NOTES.md @@ -0,0 +1,47 @@ +# Template Gallery — Shared Task Notes + +## What's Done (Phase 1 + Phase 2 start) + +### Template Data Architecture (Phase 1) +- `src/lib/template-registry.ts` — Template schema with rich metadata: categories, subcategories, tags, packages, accent colors, bibliography flag. 12 templates total (was 8). New: IEEE, ACM, Technical Report, Newsletter. Registry API: `getAllTemplates()`, `getTemplateById()`, `searchTemplates()`, `getTemplatesByCategory()`. +- `src/stores/template-store.ts` — Zustand store for gallery state: search query, category filter, template selection, preview state. `computeFiltered()` handles combined search+category filtering. + +### Visual Gallery UI (Phase 2 start) +- `src/components/template-gallery/` — New component directory: + - `template-gallery.tsx` — Main gallery: search bar (⌘K), category sidebar + grid layout, grouped view when no filter active, empty state + - `template-card.tsx` — Cards with CSS-based document thumbnail placeholders (9 distinct layouts: paper, slides, poster, CV, letter, book, report, newsletter, blank). Hover reveals "Preview" button + - `category-sidebar.tsx` — Category navigation with template counts + - `template-preview.tsx` — Dialog showing LaTeX source, package list, tags, metadata, "Use Template" CTA + - `index.ts` — Barrel export + +### Wizard Refactor +- `project-wizard.tsx` — Now uses `TemplateGallery` for step 1 instead of old inline `TemplateGrid`. Step 2 (project details) unchanged. All project creation logic preserved. Uses `template.hasBibliography` instead of hardcoded ID check. + +## Next Priorities + +### Phase 2 completion +- **Keyboard navigation** — Arrow keys to navigate grid, Enter to select, Tab between sections +- **Animations** — Consider adding `framer-motion` (not currently installed) for card entrance animations and page transitions +- **Responsive grid** — Test and tune grid breakpoints for various window sizes + +### Phase 3: Template Preview System +- **PDF thumbnail generation** — Compile templates to PDF, render first page as image using pdfjs-dist (already a dependency). Store as cached images. Replace CSS placeholders with actual rendered thumbnails +- **Live preview in modal** — Show rendered PDF in the preview dialog instead of just source code +- **Multi-page preview** — For templates like presentations/books +- **Side-by-side compare** — Allow comparing two templates + +### Phase 4: Package Integration +- **Package browser** — Curated CTAN package list +- **Package adding** — Let users add packages before project creation +- **Compatibility checker** — Warn about conflicting packages + +### Phase 5: More Templates +- **Springer, APA, MLA, Chicago** style templates +- **User template library** — Save customized templates +- **Template import** — From .tex files or Overleaf + +## Technical Notes +- No `framer-motion` installed — animations use Tailwind CSS `tw-animate-css`. Install if needed for gallery transitions +- `line-clamp-2` used in template-card.tsx — may need `@tailwindcss/line-clamp` if not natively supported (TW4 may include it) +- Template IDs changed: `paper` → `paper-standard`, `cv` → `cv-modern`, etc. Old IDs no longer exist +- `react-pdf` and `pdfjs-dist` already installed — ready for thumbnail generation work diff --git a/apps/desktop/src/components/project-wizard.tsx b/apps/desktop/src/components/project-wizard.tsx index f150f80..0c79bfe 100644 --- a/apps/desktop/src/components/project-wizard.tsx +++ b/apps/desktop/src/components/project-wizard.tsx @@ -3,20 +3,10 @@ import { open } from "@tauri-apps/plugin-dialog"; import { mkdir, writeTextFile } from "@tauri-apps/plugin-fs"; import { ArrowLeftIcon, - ArrowRightIcon, - FileTextIcon, - UserIcon, - LayoutIcon, - BookOpenIcon, - MailIcon, - MonitorIcon, - BookIcon, - FileIcon, FolderOpenIcon, PaperclipIcon, XIcon, SparklesIcon, - GraduationCapIcon, } from "lucide-react"; import { Button } from "@/components/ui/button"; import { Textarea } from "@/components/ui/textarea"; @@ -25,341 +15,8 @@ import { useProjectStore } from "@/stores/project-store"; import { useDocumentStore } from "@/stores/document-store"; import { useClaudeChatStore } from "@/stores/claude-chat-store"; import { exists, join } from "@/lib/tauri/fs"; - -// ─── Template Definitions ─── - -interface Template { - id: string; - name: string; - description: string; - icon: React.ReactNode; - documentClass: string; - mainFileName: string; - content: string; -} - -const TEMPLATES: Template[] = [ - { - id: "paper", - name: "Research Paper", - description: "Academic paper with abstract, sections, references", - icon: , - documentClass: "article", - mainFileName: "main.tex", - content: `\\documentclass[12pt]{article} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage{amsmath,amssymb} -\\usepackage{graphicx} -\\usepackage[margin=1in]{geometry} -\\usepackage{hyperref} -\\usepackage{booktabs} -\\usepackage{natbib} - -\\title{Title} -\\author{Author Name} -\\date{\\today} - -\\begin{document} - -\\maketitle - -\\begin{abstract} -Your abstract here. -\\end{abstract} - -\\section{Introduction} - -\\section{Related Work} - -\\section{Method} - -\\section{Results} - -\\section{Conclusion} - -\\bibliographystyle{plainnat} -\\bibliography{references} - -\\end{document} -`, - }, - { - id: "cv", - name: "CV / Resume", - description: "Professional curriculum vitae", - icon: , - documentClass: "article", - mainFileName: "main.tex", - content: `\\documentclass[11pt,a4paper]{article} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage[margin=0.8in]{geometry} -\\usepackage{hyperref} -\\usepackage{enumitem} -\\usepackage{titlesec} - -\\titleformat{\\section}{\\large\\bfseries}{}{0em}{}[\\titlerule] -\\titlespacing{\\section}{0pt}{12pt}{6pt} - -\\pagestyle{empty} - -\\begin{document} - -\\begin{center} - {\\LARGE\\bfseries Your Name}\\\\[4pt] - your.email@example.com \\quad | \\quad City, Country -\\end{center} - -\\section{Education} - -\\section{Experience} - -\\section{Skills} - -\\section{Publications} - -\\end{document} -`, - }, - { - id: "poster", - name: "Poster", - description: "Conference or research poster", - icon: , - documentClass: "a0poster", - mainFileName: "main.tex", - content: `\\documentclass[a1paper,portrait]{a0poster} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage{amsmath,amssymb} -\\usepackage{graphicx} -\\usepackage{multicol} -\\usepackage[margin=2cm]{geometry} -\\usepackage{xcolor} - -\\begin{document} - -\\begin{center} - {\\VERYHuge\\bfseries Poster Title}\\\\[1cm] - {\\LARGE Author Name \\quad Institution} -\\end{center} - -\\vspace{1cm} - -\\begin{multicols}{2} - -\\section*{Introduction} - -\\section*{Methods} - -\\section*{Results} - -\\section*{Conclusions} - -\\section*{References} - -\\end{multicols} - -\\end{document} -`, - }, - { - id: "thesis", - name: "Thesis", - description: "Dissertation or thesis with chapters", - icon: , - documentClass: "report", - mainFileName: "main.tex", - content: `\\documentclass[12pt,a4paper]{report} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage{amsmath,amssymb} -\\usepackage{graphicx} -\\usepackage[margin=1in]{geometry} -\\usepackage{hyperref} -\\usepackage{booktabs} -\\usepackage{natbib} -\\usepackage{setspace} - -\\onehalfspacing - -\\title{Thesis Title} -\\author{Author Name} -\\date{\\today} - -\\begin{document} - -\\maketitle - -\\begin{abstract} -Your abstract here. -\\end{abstract} - -\\tableofcontents - -\\chapter{Introduction} - -\\chapter{Literature Review} - -\\chapter{Methodology} - -\\chapter{Results} - -\\chapter{Discussion} - -\\chapter{Conclusion} - -\\bibliographystyle{plainnat} -\\bibliography{references} - -\\end{document} -`, - }, - { - id: "presentation", - name: "Presentation", - description: "Beamer slides for talks and lectures", - icon: , - documentClass: "beamer", - mainFileName: "main.tex", - content: `\\documentclass{beamer} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage{amsmath,amssymb} -\\usepackage{graphicx} - -\\usetheme{Madrid} - -\\title{Presentation Title} -\\author{Author Name} -\\institute{Institution} -\\date{\\today} - -\\begin{document} - -\\begin{frame} - \\titlepage -\\end{frame} - -\\begin{frame}{Outline} - \\tableofcontents -\\end{frame} - -\\section{Introduction} -\\begin{frame}{Introduction} - Content here. -\\end{frame} - -\\section{Main Content} -\\begin{frame}{Main Content} - Content here. -\\end{frame} - -\\section{Conclusion} -\\begin{frame}{Conclusion} - Content here. -\\end{frame} - -\\end{document} -`, - }, - { - id: "letter", - name: "Letter", - description: "Formal or cover letter", - icon: , - documentClass: "letter", - mainFileName: "main.tex", - content: `\\documentclass[12pt]{letter} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage[margin=1in]{geometry} -\\usepackage{hyperref} - -\\signature{Your Name} -\\address{Your Address \\\\ City, Country} - -\\begin{document} - -\\begin{letter}{Recipient Name \\\\ Recipient Address \\\\ City, Country} - -\\opening{Dear Recipient,} - -Your letter content here. - -\\closing{Sincerely,} - -\\end{letter} - -\\end{document} -`, - }, - { - id: "book", - name: "Book", - description: "Multi-chapter book or manuscript", - icon: , - documentClass: "book", - mainFileName: "main.tex", - content: `\\documentclass[12pt,a4paper]{book} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} -\\usepackage{amsmath,amssymb} -\\usepackage{graphicx} -\\usepackage[margin=1in]{geometry} -\\usepackage{hyperref} - -\\title{Book Title} -\\author{Author Name} -\\date{\\today} - -\\begin{document} - -\\frontmatter -\\maketitle -\\tableofcontents - -\\mainmatter - -\\chapter{First Chapter} - -\\chapter{Second Chapter} - -\\backmatter - -\\end{document} -`, - }, - { - id: "blank", - name: "Blank", - description: "Minimal template to start from scratch", - icon: , - documentClass: "article", - mainFileName: "main.tex", - content: `\\documentclass[12pt]{article} -\\usepackage[utf8]{inputenc} -\\usepackage[T1]{fontenc} - -\\begin{document} - -% Start writing here. - -\\end{document} -`, - }, -]; - -const BIB_TEMPLATE = `% Add your references here -% Example: -% @article{key, -% author = {Author Name}, -% title = {Article Title}, -% journal = {Journal Name}, -% year = {2024}, -% } -`; +import { getTemplateById, BIB_TEMPLATE } from "@/lib/template-registry"; +import { TemplateGallery } from "@/components/template-gallery"; // ─── Wizard Component ─── @@ -369,7 +26,7 @@ interface ProjectWizardProps { export function ProjectWizard({ onBack }: ProjectWizardProps) { const [step, setStep] = useState<1 | 2>(1); - const [selectedTemplate, setSelectedTemplate] = useState(null); + const [selectedTemplateId, setSelectedTemplateId] = useState(null); const [purpose, setPurpose] = useState(""); const [attachments, setAttachments] = useState([]); const [projectFolder, setProjectFolder] = useState(null); @@ -379,10 +36,10 @@ export function ProjectWizard({ onBack }: ProjectWizardProps) { const addRecentProject = useProjectStore((s) => s.addRecentProject); const openProject = useDocumentStore((s) => s.openProject); - const template = TEMPLATES.find((t) => t.id === selectedTemplate); + const template = selectedTemplateId ? getTemplateById(selectedTemplateId) : undefined; const handleSelectTemplate = (id: string) => { - setSelectedTemplate(id); + setSelectedTemplateId(id); setStep(2); }; @@ -442,7 +99,7 @@ export function ProjectWizard({ onBack }: ProjectWizardProps) { } // Write references.bib for templates that use bibliography - if (["paper", "thesis"].includes(template.id)) { + if (template.hasBibliography) { const bibPath = await join(projectPath, "references.bib"); const bibExists = await exists(bibPath); if (!bibExists) { @@ -509,154 +166,123 @@ export function ProjectWizard({ onBack }: ProjectWizardProps) { {/* Content */} -
+
{step === 1 ? ( - + ) : ( -
- {/* Selected template indicator */} - {template && ( - - )} - - {/* Purpose */} -
- -