125 lines
5.2 KiB
TypeScript
125 lines
5.2 KiB
TypeScript
import { ArrowUp, BookOpenCheck } from "lucide-react";
|
|
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Button } from "@/components/ui/button";
|
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
|
import { helpSections } from "../help-content";
|
|
import { cn } from "../lib/utils";
|
|
|
|
function WorkflowList({ items }: { items: string[] }) {
|
|
return (
|
|
<div>
|
|
<p className="mb-2 text-sm font-medium">Empfohlener Ablauf</p>
|
|
<ol className="space-y-2 text-sm text-muted-foreground">
|
|
{items.map((item, index) => (
|
|
<li key={item} className="flex gap-2">
|
|
<span className="grid size-5 shrink-0 place-items-center rounded-full bg-primary/10 text-xs font-semibold text-primary">{index + 1}</span>
|
|
<span>{item}</span>
|
|
</li>
|
|
))}
|
|
</ol>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
function FlowDiagram({ items }: { items: string[] }) {
|
|
return (
|
|
<div>
|
|
<p className="mb-2 text-sm font-medium">Ablaufdiagramm</p>
|
|
<div className="overflow-x-auto rounded-md border bg-muted/20 p-3">
|
|
<div className="flex min-w-[520px] flex-col items-center gap-2 text-center text-xs text-muted-foreground">
|
|
{items.map((item, index) => (
|
|
<div key={item} className="contents">
|
|
<div className="w-full max-w-[360px] rounded-md border bg-background px-3 py-2 font-medium text-foreground">{item}</div>
|
|
{index < items.length - 1 ? <div className="text-muted-foreground">↓</div> : null}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function FaqPage() {
|
|
return (
|
|
<div id="top" className="space-y-5">
|
|
<div className="flex flex-col gap-3 lg:flex-row lg:items-end lg:justify-between">
|
|
<div>
|
|
<h2 className="text-2xl font-semibold tracking-normal">FAQ und Anleitung</h2>
|
|
<p className="text-sm text-muted-foreground">Ausführliche Anleitung für Timer, Auswertung, Teamspace, fixe Abrechnungen, Monatsabschluss und Adminfunktionen.</p>
|
|
</div>
|
|
<Badge variant="outline">{helpSections.length} Abschnitt(e)</Badge>
|
|
</div>
|
|
|
|
<Card>
|
|
<CardHeader className="p-4">
|
|
<div className="flex items-center gap-2">
|
|
<BookOpenCheck className="size-5 text-muted-foreground" />
|
|
<CardTitle>Schnellnavigation</CardTitle>
|
|
</div>
|
|
<CardDescription>Die Fragezeichen in der App öffnen eine Kurzfassung. Von dort gelangst du direkt zum passenden ausführlichen Abschnitt.</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="flex flex-wrap gap-2 px-4 pb-4">
|
|
{helpSections.map((section) => (
|
|
<Button key={section.id} asChild variant="secondary" size="sm">
|
|
<a href={`#${section.id}`}>{section.title}</a>
|
|
</Button>
|
|
))}
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<div className="grid gap-3 xl:grid-cols-2">
|
|
{helpSections.map((section) => {
|
|
const isWide = section.id === "grundprinzip" || section.id === "monatsworkflow";
|
|
const isWorkflow = section.id === "monatsworkflow";
|
|
|
|
return (
|
|
<Card key={section.id} id={section.id} className={cn("scroll-mt-16", isWide ? "xl:col-span-2" : "")}>
|
|
<CardHeader className="p-4">
|
|
<CardTitle>{section.title}</CardTitle>
|
|
<CardDescription>{section.description}</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className={cn("px-4 pb-4", isWorkflow ? "grid gap-5 lg:grid-cols-[minmax(0,1fr)_minmax(320px,0.9fr)]" : "space-y-4")}>
|
|
<div className="space-y-4">
|
|
<div className="rounded-md border bg-muted/20 p-3">
|
|
<p className="mb-2 text-sm font-medium">Kurzfassung</p>
|
|
<ul className="space-y-2 text-sm text-muted-foreground">
|
|
{section.quickItems.map((item) => (
|
|
<li key={item} className="flex gap-2">
|
|
<span className="mt-2 size-1.5 shrink-0 rounded-full bg-primary" />
|
|
<span>{item}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
<div>
|
|
<p className="mb-2 text-sm font-medium">Details</p>
|
|
<ul className="space-y-2 text-sm text-muted-foreground">
|
|
{section.details.map((item) => (
|
|
<li key={item} className="flex gap-2">
|
|
<span className="mt-2 size-1.5 shrink-0 rounded-full bg-primary/70" />
|
|
<span>{item}</span>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
{section.workflow ? <WorkflowList items={section.workflow} /> : null}
|
|
</div>
|
|
{section.diagram ? <FlowDiagram items={section.diagram} /> : null}
|
|
<div className={cn("flex justify-end", isWorkflow ? "lg:col-span-2" : "")}>
|
|
<Button asChild variant="ghost" size="sm">
|
|
<a href="#top">
|
|
<ArrowUp className="size-4" />
|
|
Nach oben
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|