Refine help UX and monthly close layout
This commit is contained in:
+30
-172
@@ -3,163 +3,7 @@ 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";
|
||||
|
||||
type FaqSection = {
|
||||
id: string;
|
||||
title: string;
|
||||
description: string;
|
||||
items: string[];
|
||||
};
|
||||
|
||||
const faqSections: FaqSection[] = [
|
||||
{
|
||||
id: "grundprinzip",
|
||||
title: "Grundprinzip",
|
||||
description: "TicketTracker ersetzt weder Ticketsystem noch CRM. Die App misst Zeiten, bewertet Sessions und bereitet den Monatsabschluss vor.",
|
||||
items: [
|
||||
"Session-Zeit ist die gemessene oder manuell erfasste Arbeitszeit einer Tätigkeit.",
|
||||
"Teamspace-Zeit ist der Tageswert, der für ein Ticket wirklich im CRM eingetragen wurde.",
|
||||
"Abgeschlossen wird nur ein Monat. Tickets werden nicht geschlossen, sondern nur über ihre Sessions bewertet."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "timer",
|
||||
title: "Timer",
|
||||
description: "Timer sind für laufende Arbeit an Tickets gedacht.",
|
||||
items: [
|
||||
"Ticketnummer im Format Ticket#XXXXXX eingeben und Timer starten.",
|
||||
"Es können mehrere Timer vorbereitet sein, aber immer nur einer läuft aktiv.",
|
||||
"Wird ein Timer aktiviert, werden alle anderen automatisch pausiert.",
|
||||
"Beim Klick auf Beenden stoppt die Zeit sofort. Danach werden Tätigkeit und gegebenenfalls Organisation und Art gespeichert."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "session-nachtragen",
|
||||
title: "Session Nachtragen",
|
||||
description: "Vergessene Zeiten können nachträglich als Session angelegt werden.",
|
||||
items: [
|
||||
"Benutzer tragen eigene Sessions nach. Admins können Sessions auch anderen Benutzern zuweisen.",
|
||||
"Pflichtangaben sind Ticket, Organisation, Art, Datum, Von, Bis und Tätigkeit.",
|
||||
"Das Tätigkeitsfeld ist mehrzeilig. Zeilenumbrüche bleiben in den Auswertungen erhalten."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "ticketdaten",
|
||||
title: "Ticketdaten",
|
||||
description: "Ticketdaten können in der Ticketdetailansicht korrigiert werden.",
|
||||
items: [
|
||||
"Bearbeitbar sind Ticketnummer, Organisation und Art.",
|
||||
"Änderungen an Organisation und Art werden auf vorhandene manuelle Sessions des Tickets übernommen.",
|
||||
"Bei wiederkehrenden Sessions kommt die Art aus der Regel der fixen Abrechnung."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "organisationen",
|
||||
title: "Organisationen",
|
||||
description: "Organisationen werden aus Zammad synchronisiert und danach aus der lokalen Liste gewählt.",
|
||||
items: [
|
||||
"Freitext ist nicht mehr erlaubt, damit Auswertungen je Organisation sauber möglich sind.",
|
||||
"Alte Freitexte müssen manuell korrigiert werden.",
|
||||
"Der Zammad-Sync speichert nur interne ID, Zammad-ID, Name und Zeitstempel."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "auswertung",
|
||||
title: "Auswertung",
|
||||
description: "Die Auswertung zeigt Monats- oder Tageswerte und listet Tickets im gewählten Zeitraum.",
|
||||
items: [
|
||||
"Mit den Pfeilen neben Monat oder Datum wechselst du den Zeitraum. Die Daten aktualisieren sich automatisch.",
|
||||
"Tickets können gefiltert, gruppiert und sortiert werden. Diese Einstellungen bleiben gespeichert.",
|
||||
"Der Graph zeigt den Gesamtaufwand des gewählten Zeitraums."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "ticketdetail",
|
||||
title: "Ticketdetailansicht",
|
||||
description: "Hier werden alle Sessions eines Tickets im gewählten Monat oder Tag bearbeitet.",
|
||||
items: [
|
||||
"Sessions sind nach Tagen gruppiert.",
|
||||
"Pro Tag wird die getrackte Zeit angezeigt.",
|
||||
"Das Teamspace-Feld speichert die Stunden, die für diesen Ticket-Tag wirklich im CRM eingetragen wurden.",
|
||||
"Der Teamspace-Wert ist in Monats- und Tagesansicht derselbe."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "sessions-bewerten",
|
||||
title: "Sessions Bewerten",
|
||||
description: "Jede Session braucht eine Bewertung für die Abrechnung.",
|
||||
items: [
|
||||
"Möglich sind Abgerechnet und Nicht abrechenbar.",
|
||||
"Ein erneuter Klick auf die gewählte Bewertung nimmt sie zurück.",
|
||||
"Bewertungen können bei abgeschlossenem Monat erst geändert werden, nachdem der Monat wieder geöffnet wurde."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "sessions-bearbeiten",
|
||||
title: "Sessions Bearbeiten und Löschen",
|
||||
description: "Sessions können korrigiert oder gelöscht werden.",
|
||||
items: [
|
||||
"Bearbeitbar sind Datum, Von, Bis, Organisation, Tätigkeit und Art.",
|
||||
"Bei wiederkehrenden Sessions ist die Art gesperrt und wird über die Regel geändert.",
|
||||
"Wird die letzte Session eines Tickets gelöscht, wird das leere Ticket entfernt.",
|
||||
"Gelöschte wiederkehrende Sessions werden als Ausnahme gespeichert und nicht automatisch neu erzeugt."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "monatsabschluss",
|
||||
title: "Monatsabschluss",
|
||||
description: "Der Monatsabschluss bündelt offene Bewertungen und Teamspace-Prüfpunkte.",
|
||||
items: [
|
||||
"Ein Monat kann abgeschlossen werden, sobald alle Sessions des Monats bewertet sind.",
|
||||
"Tage ohne Teamspace-Wert können zur Kenntnis genommen werden, wenn sie bewusst nicht ins CRM gehören.",
|
||||
"Zur Kenntnis genommene Teamspace-Punkte können eingeblendet und zurückgenommen werden.",
|
||||
"Einen Tagesabschluss gibt es nicht."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "fixe-abrechnungen",
|
||||
title: "Fixe Abrechnungen",
|
||||
description: "Fixe Abrechnungen erzeugen wiederkehrende Sessions für den eigenen Account.",
|
||||
items: [
|
||||
"Ticket ist optional. Ohne Ticket wird automatisch Fix#ID verwendet.",
|
||||
"Muster können Wochentage oder alle X Wochen sein.",
|
||||
"Gültig bis ist optional. Wird es später gesetzt, werden nicht mehr gültige erzeugte Sessions entfernt.",
|
||||
"Bayerische Feiertage werden übersprungen."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "statistiken",
|
||||
title: "Statistiken",
|
||||
description: "Die Statistikseite vergleicht getrackte Sessions mit Teamspace-Zeiten.",
|
||||
items: [
|
||||
"Sessions und Teamspace haben eigene Farben.",
|
||||
"Eine positive oder ausgeglichene Differenz ist grün.",
|
||||
"Eine negative Differenz ist rot und bedeutet: in Teamspace ist weniger eingetragen als getrackt.",
|
||||
"Organisationen, Typen und Ticket-Hotspots helfen bei der Monatskontrolle."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "profil",
|
||||
title: "Profil",
|
||||
description: "Jeder Benutzer kann eigene Accountdaten pflegen.",
|
||||
items: [
|
||||
"Benutzername und voller Name können geändert werden.",
|
||||
"Passwortänderungen benötigen das aktuelle Passwort.",
|
||||
"Der volle Name wird in der App angezeigt."
|
||||
]
|
||||
},
|
||||
{
|
||||
id: "admin",
|
||||
title: "Adminbereich",
|
||||
description: "Admins verwalten Benutzer, Sessions und Zammad-Organisationen.",
|
||||
items: [
|
||||
"Admins legen Benutzer an und können deren Daten bearbeiten.",
|
||||
"Sessions können zwischen Benutzern umverteilt werden.",
|
||||
"Admins können Sessions für andere Benutzer nachtragen.",
|
||||
"Der Zammad-Zugang wird gespeichert und der Organisationssync aktualisiert die lokale Organisationsliste."
|
||||
]
|
||||
}
|
||||
];
|
||||
import { helpSections } from "../help-content";
|
||||
|
||||
export function FaqPage() {
|
||||
return (
|
||||
@@ -167,9 +11,9 @@ export function FaqPage() {
|
||||
<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">Kurzanleitung für Timer, Auswertung, Teamspace, fixe Abrechnungen und Adminfunktionen.</p>
|
||||
<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">{faqSections.length} Abschnitt(e)</Badge>
|
||||
<Badge variant="outline">{helpSections.length} Abschnitt(e)</Badge>
|
||||
</div>
|
||||
|
||||
<Card>
|
||||
@@ -178,10 +22,10 @@ export function FaqPage() {
|
||||
<BookOpenCheck className="size-5 text-muted-foreground" />
|
||||
<CardTitle>Schnellnavigation</CardTitle>
|
||||
</div>
|
||||
<CardDescription>Die Fragezeichen in der App springen direkt in diese Abschnitte.</CardDescription>
|
||||
<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">
|
||||
{faqSections.map((section) => (
|
||||
{helpSections.map((section) => (
|
||||
<Button key={section.id} asChild variant="secondary" size="sm">
|
||||
<a href={`#${section.id}`}>{section.title}</a>
|
||||
</Button>
|
||||
@@ -190,22 +34,36 @@ export function FaqPage() {
|
||||
</Card>
|
||||
|
||||
<div className="grid gap-3 xl:grid-cols-2">
|
||||
{faqSections.map((section) => (
|
||||
{helpSections.map((section) => (
|
||||
<Card key={section.id} id={section.id} className="scroll-mt-16">
|
||||
<CardHeader className="p-4">
|
||||
<CardTitle>{section.title}</CardTitle>
|
||||
<CardDescription>{section.description}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="px-4 pb-4">
|
||||
<ul className="space-y-2 text-sm text-muted-foreground">
|
||||
{section.items.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 className="mt-4 flex justify-end">
|
||||
<CardContent className="space-y-4 px-4 pb-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>
|
||||
<div className="flex justify-end">
|
||||
<Button asChild variant="ghost" size="sm">
|
||||
<a href="#top">
|
||||
<ArrowUp className="size-4" />
|
||||
|
||||
Reference in New Issue
Block a user