Add Help & Documentation system under Settings
This commit is contained in:
702
src/views/HelpView.vue
Normal file
702
src/views/HelpView.vue
Normal file
@@ -0,0 +1,702 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from 'vue'
|
||||
|
||||
const searchQuery = ref('')
|
||||
const activeCategory = ref<string | null>(null)
|
||||
const activeArticle = ref<string | null>(null)
|
||||
|
||||
interface Article {
|
||||
id: string
|
||||
title: string
|
||||
icon: string
|
||||
content: string
|
||||
}
|
||||
|
||||
interface Category {
|
||||
id: string
|
||||
name: string
|
||||
icon: string
|
||||
description: string
|
||||
articles: Article[]
|
||||
}
|
||||
|
||||
const categories: Category[] = [
|
||||
{
|
||||
id: 'getting-started',
|
||||
name: 'Erste Schritte',
|
||||
icon: '🚀',
|
||||
description: 'Grundlagen und Einrichtung',
|
||||
articles: [
|
||||
{
|
||||
id: 'overview',
|
||||
title: 'Übersicht',
|
||||
icon: '📋',
|
||||
content: `
|
||||
## Was ist SeCu?
|
||||
|
||||
SeCu ist eine modulare Mitarbeiterverwaltung speziell für Sicherheitsunternehmen. Die Software hilft Ihnen bei:
|
||||
|
||||
- **Mitarbeiterverwaltung** – Alle Mitarbeiter zentral verwalten
|
||||
- **Auftragsverwaltung** – Aufträge erstellen und zuweisen
|
||||
- **Stundenzettel** – Arbeitszeiten erfassen und genehmigen
|
||||
- **Verfügbarkeiten** – Wer ist wann einsetzbar?
|
||||
- **Partnerschaften** – Zusammenarbeit mit Subunternehmern
|
||||
|
||||
### Rollen im System
|
||||
|
||||
**Chef** – Vollzugriff auf alle Funktionen, kann Disponenten und Mitarbeiter anlegen
|
||||
|
||||
**Disponent** – Kann Mitarbeiter anlegen, Aufträge erstellen, Stundenzettel einsehen
|
||||
|
||||
**Mitarbeiter** – Kann eigene Aufträge sehen, Verfügbarkeit melden, Stundenzettel hochladen
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'first-login',
|
||||
title: 'Erster Login',
|
||||
icon: '🔐',
|
||||
content: `
|
||||
## Erster Login
|
||||
|
||||
Nach der Registrierung Ihrer Organisation erhalten Sie Zugangsdaten per E-Mail.
|
||||
|
||||
### Anmeldung
|
||||
|
||||
1. Öffnen Sie die SeCu-Webseite
|
||||
2. Geben Sie Ihre E-Mail-Adresse ein
|
||||
3. Geben Sie Ihr Passwort ein
|
||||
4. Klicken Sie auf "Anmelden"
|
||||
|
||||
### Passwort ändern
|
||||
|
||||
Wir empfehlen, Ihr Passwort nach dem ersten Login zu ändern:
|
||||
|
||||
1. Gehen Sie zu **Einstellungen**
|
||||
2. Scrollen Sie zu "Passwort ändern"
|
||||
3. Geben Sie Ihr aktuelles Passwort ein
|
||||
4. Geben Sie ein neues Passwort ein (mind. 8 Zeichen)
|
||||
5. Bestätigen Sie das neue Passwort
|
||||
6. Klicken Sie auf "Passwort ändern"
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'users',
|
||||
name: 'Benutzerverwaltung',
|
||||
icon: '👥',
|
||||
description: 'Mitarbeiter und Disponenten verwalten',
|
||||
articles: [
|
||||
{
|
||||
id: 'create-user',
|
||||
title: 'Benutzer anlegen',
|
||||
icon: '➕',
|
||||
content: `
|
||||
## Neuen Benutzer anlegen
|
||||
|
||||
**Berechtigung:** Chef oder Disponent
|
||||
|
||||
### Schritt für Schritt
|
||||
|
||||
1. Navigieren Sie zu **Benutzer** im Menü
|
||||
2. Klicken Sie auf **"+ Neuer Benutzer"**
|
||||
3. Füllen Sie das Formular aus:
|
||||
- **Vorname** und **Nachname**
|
||||
- **E-Mail-Adresse** (wird für Login verwendet)
|
||||
- **Passwort** (mind. 8 Zeichen)
|
||||
- **Rolle** auswählen (Disponent oder Mitarbeiter)
|
||||
4. Klicken Sie auf **"Erstellen"**
|
||||
|
||||
### Rollen-Unterschiede
|
||||
|
||||
- **Disponent**: Kann selbst Mitarbeiter anlegen und Aufträge verwalten
|
||||
- **Mitarbeiter**: Kann nur eigene Daten sehen und bearbeiten
|
||||
|
||||
> **Hinweis:** Als Disponent können Sie nur Mitarbeiter anlegen, keine weiteren Disponenten.
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'edit-user',
|
||||
title: 'Benutzer bearbeiten',
|
||||
icon: '✏️',
|
||||
content: `
|
||||
## Benutzer bearbeiten
|
||||
|
||||
### Benutzerdaten ändern
|
||||
|
||||
1. Gehen Sie zu **Benutzer**
|
||||
2. Klicken Sie auf den Namen des Benutzers
|
||||
3. Ändern Sie die gewünschten Felder
|
||||
4. Klicken Sie auf **"Speichern"**
|
||||
|
||||
### Benutzer deaktivieren
|
||||
|
||||
Statt einen Benutzer zu löschen, können Sie ihn deaktivieren:
|
||||
|
||||
1. Öffnen Sie das Benutzerprofil
|
||||
2. Setzen Sie den Status auf **"Inaktiv"**
|
||||
3. Der Benutzer kann sich nicht mehr anmelden
|
||||
|
||||
> **Tipp:** Deaktivierte Benutzer bleiben in der Historie erhalten.
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'orders',
|
||||
name: 'Auftragsverwaltung',
|
||||
icon: '📋',
|
||||
description: 'Aufträge erstellen und verwalten',
|
||||
articles: [
|
||||
{
|
||||
id: 'create-order',
|
||||
title: 'Auftrag erstellen',
|
||||
icon: '➕',
|
||||
content: `
|
||||
## Neuen Auftrag erstellen
|
||||
|
||||
**Berechtigung:** Chef oder Disponent
|
||||
|
||||
### Auftrag anlegen
|
||||
|
||||
1. Navigieren Sie zu **Aufträge**
|
||||
2. Klicken Sie auf **"+ Neuer Auftrag"**
|
||||
3. Füllen Sie die Pflichtfelder aus:
|
||||
- **Titel** – Kurze Beschreibung des Auftrags
|
||||
- **Kunde** – Name des Auftraggebers
|
||||
- **Standort** – Einsatzort
|
||||
- **Datum/Zeit** – Wann findet der Einsatz statt?
|
||||
4. Optional: Beschreibung hinzufügen
|
||||
5. Klicken Sie auf **"Erstellen"**
|
||||
|
||||
### Mitarbeiter zuweisen
|
||||
|
||||
Nach dem Erstellen können Sie Mitarbeiter zuweisen:
|
||||
|
||||
1. Öffnen Sie den Auftrag
|
||||
2. Klicken Sie auf **"Mitarbeiter zuweisen"**
|
||||
3. Wählen Sie verfügbare Mitarbeiter aus
|
||||
4. Bestätigen Sie die Zuweisung
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'order-status',
|
||||
title: 'Auftragsstatus',
|
||||
icon: '🔄',
|
||||
content: `
|
||||
## Auftragsstatus verstehen
|
||||
|
||||
Jeder Auftrag durchläuft verschiedene Status:
|
||||
|
||||
🟡 **Offen** – Auftrag erstellt, noch nicht begonnen
|
||||
|
||||
🔵 **In Bearbeitung** – Auftrag läuft aktuell
|
||||
|
||||
🟢 **Abgeschlossen** – Auftrag erfolgreich beendet
|
||||
|
||||
🔴 **Storniert** – Auftrag wurde abgebrochen
|
||||
|
||||
### Status ändern
|
||||
|
||||
1. Öffnen Sie den Auftrag
|
||||
2. Klicken Sie auf den aktuellen Status
|
||||
3. Wählen Sie den neuen Status
|
||||
4. Optional: Kommentar hinzufügen
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'timesheets',
|
||||
name: 'Stundenzettel',
|
||||
icon: '⏱️',
|
||||
description: 'Arbeitszeiten erfassen und verwalten',
|
||||
articles: [
|
||||
{
|
||||
id: 'submit-timesheet',
|
||||
title: 'Stundenzettel einreichen',
|
||||
icon: '📤',
|
||||
content: `
|
||||
## Stundenzettel einreichen
|
||||
|
||||
**Für Mitarbeiter**
|
||||
|
||||
### Arbeitszeit erfassen
|
||||
|
||||
1. Gehen Sie zu **Stundenzettel**
|
||||
2. Klicken Sie auf **"+ Neue Erfassung"**
|
||||
3. Wählen Sie den **Auftrag** aus
|
||||
4. Geben Sie ein:
|
||||
- **Startzeit** und **Endzeit**
|
||||
- **Pausenzeit** (falls vorhanden)
|
||||
5. Optional: Foto des Stundenzettels hochladen
|
||||
6. Klicken Sie auf **"Einreichen"**
|
||||
|
||||
### Foto hochladen
|
||||
|
||||
Sie können ein Foto Ihres handschriftlichen Stundenzettels anhängen:
|
||||
|
||||
1. Klicken Sie auf **"Foto hinzufügen"**
|
||||
2. Wählen Sie das Foto aus oder machen Sie ein neues
|
||||
3. Das Foto wird automatisch hochgeladen
|
||||
|
||||
> **Tipp:** Stellen Sie sicher, dass das Foto gut lesbar ist.
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'approve-timesheet',
|
||||
title: 'Stundenzettel genehmigen',
|
||||
icon: '✅',
|
||||
content: `
|
||||
## Stundenzettel genehmigen
|
||||
|
||||
**Für Disponenten und Chefs**
|
||||
|
||||
### Übersicht
|
||||
|
||||
Offene Stundenzettel werden im Dashboard angezeigt. Sie können diese genehmigen oder ablehnen.
|
||||
|
||||
### Genehmigungsprozess
|
||||
|
||||
1. Gehen Sie zu **Stundenzettel**
|
||||
2. Filtern Sie nach **"Ausstehend"**
|
||||
3. Prüfen Sie die Einträge:
|
||||
- Stimmen die Zeiten mit dem Auftrag überein?
|
||||
- Ist das hochgeladene Foto lesbar?
|
||||
4. Klicken Sie auf **✓ Genehmigen** oder **✗ Ablehnen**
|
||||
5. Bei Ablehnung: Grund angeben
|
||||
|
||||
### Massenbearbeitung
|
||||
|
||||
Sie können mehrere Stundenzettel gleichzeitig bearbeiten:
|
||||
|
||||
1. Aktivieren Sie die Checkboxen
|
||||
2. Klicken Sie auf **"Ausgewählte genehmigen"**
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'availability',
|
||||
name: 'Verfügbarkeiten',
|
||||
icon: '📅',
|
||||
description: 'Einsatzbereitschaft verwalten',
|
||||
articles: [
|
||||
{
|
||||
id: 'set-availability',
|
||||
title: 'Verfügbarkeit melden',
|
||||
icon: '🗓️',
|
||||
content: `
|
||||
## Verfügbarkeit melden
|
||||
|
||||
**Für Mitarbeiter**
|
||||
|
||||
### Warum Verfügbarkeit melden?
|
||||
|
||||
Damit Disponenten wissen, wann Sie einsetzbar sind, sollten Sie Ihre Verfügbarkeit regelmäßig aktualisieren.
|
||||
|
||||
### Verfügbarkeit eintragen
|
||||
|
||||
1. Gehen Sie zu **Verfügbarkeit**
|
||||
2. Klicken Sie auf einen Tag im Kalender
|
||||
3. Wählen Sie:
|
||||
- ✅ **Verfügbar** – Sie können eingesetzt werden
|
||||
- ❌ **Nicht verfügbar** – Sie sind verhindert
|
||||
- 🕐 **Teilweise** – Nur zu bestimmten Zeiten
|
||||
4. Bei "Teilweise": Zeitfenster angeben
|
||||
5. Speichern Sie die Eingabe
|
||||
|
||||
### Regelmäßige Muster
|
||||
|
||||
Sie können wiederkehrende Verfügbarkeiten einrichten:
|
||||
|
||||
1. Klicken Sie auf **"Muster erstellen"**
|
||||
2. Wählen Sie die Wochentage
|
||||
3. Geben Sie die Zeiten ein
|
||||
4. Das Muster wird automatisch angewendet
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'view-availability',
|
||||
title: 'Verfügbarkeiten einsehen',
|
||||
icon: '👁️',
|
||||
content: `
|
||||
## Verfügbarkeiten einsehen
|
||||
|
||||
**Für Disponenten und Chefs**
|
||||
|
||||
### Team-Übersicht
|
||||
|
||||
1. Gehen Sie zu **Verfügbarkeit**
|
||||
2. Wählen Sie **"Team-Ansicht"**
|
||||
3. Sie sehen alle Mitarbeiter im Kalender
|
||||
|
||||
### Nach Datum filtern
|
||||
|
||||
- Klicken Sie auf ein Datum, um zu sehen, wer verfügbar ist
|
||||
- Grün = verfügbar, Rot = nicht verfügbar, Gelb = teilweise
|
||||
|
||||
### Für Auftrag nutzen
|
||||
|
||||
Beim Erstellen eines Auftrags werden automatisch nur verfügbare Mitarbeiter vorgeschlagen.
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'partnerships',
|
||||
name: 'Partnerschaften',
|
||||
icon: '🤝',
|
||||
description: 'Zusammenarbeit mit Subunternehmern',
|
||||
articles: [
|
||||
{
|
||||
id: 'partnership-overview',
|
||||
title: 'Übersicht',
|
||||
icon: '📋',
|
||||
content: `
|
||||
## Partnerschaften in SeCu
|
||||
|
||||
Das Partnerschaftsmodul ermöglicht die Zusammenarbeit mit anderen Sicherheitsunternehmen.
|
||||
|
||||
### Anwendungsfälle
|
||||
|
||||
- **Subunternehmer einsetzen** – Personal bei Partnerfirmen anfordern
|
||||
- **Personal verleihen** – Eigene Mitarbeiter an Partner ausleihen
|
||||
- **Abrechnung** – Stundenzettel und Rechnungen austauschen
|
||||
|
||||
### Beziehungsarten
|
||||
|
||||
**Auftraggeber** – Sie beauftragen den Partner (Subunternehmer)
|
||||
|
||||
**Subunternehmer** – Sie werden vom Partner beauftragt
|
||||
|
||||
**Bilateral** – Beide Seiten können Aufträge teilen
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
- Beide Unternehmen müssen in SeCu registriert sein
|
||||
- Partnerschaftsmodul muss aktiviert sein
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'create-partnership',
|
||||
title: 'Partnerschaft anfragen',
|
||||
icon: '➕',
|
||||
content: `
|
||||
## Partnerschaft anfragen
|
||||
|
||||
**Berechtigung:** Chef
|
||||
|
||||
### Neue Partnerschaft
|
||||
|
||||
1. Gehen Sie zu **Partnerschaften**
|
||||
2. Klicken Sie auf **"+ Neue Partnerschaft"**
|
||||
3. Suchen Sie das Partnerunternehmen
|
||||
4. Wählen Sie die **Beziehungsart**:
|
||||
- Auftraggeber (Sie beauftragen)
|
||||
- Subunternehmer (Sie werden beauftragt)
|
||||
- Bilateral (beidseitig)
|
||||
5. Klicken Sie auf **"Anfrage senden"**
|
||||
|
||||
### Anfrage annehmen
|
||||
|
||||
Wenn Sie eine Anfrage erhalten:
|
||||
|
||||
1. Sie sehen eine Benachrichtigung
|
||||
2. Prüfen Sie die Details
|
||||
3. Klicken Sie auf **"Annehmen"** oder **"Ablehnen"**
|
||||
|
||||
> **Hinweis:** Nach Annahme können beide Seiten Aufträge teilen.
|
||||
`
|
||||
},
|
||||
{
|
||||
id: 'share-orders',
|
||||
title: 'Aufträge teilen',
|
||||
icon: '📤',
|
||||
content: `
|
||||
## Aufträge mit Partnern teilen
|
||||
|
||||
### Auftrag an Subunternehmer
|
||||
|
||||
1. Erstellen oder öffnen Sie einen Auftrag
|
||||
2. Klicken Sie auf **"Mit Partner teilen"**
|
||||
3. Wählen Sie den **Partner** aus
|
||||
4. Geben Sie Details an:
|
||||
- Benötigte Mitarbeiteranzahl
|
||||
- Stundensatz (falls vereinbart)
|
||||
5. Partner erhält Benachrichtigung
|
||||
|
||||
### Geteilte Aufträge verwalten
|
||||
|
||||
Geteilte Aufträge werden mit einem 🤝 Symbol markiert.
|
||||
|
||||
- **Blau**: Von Ihnen geteilt
|
||||
- **Orange**: An Sie geteilt
|
||||
|
||||
### Stundenzettel vom Partner
|
||||
|
||||
Wenn der Partner Stundenzettel einreicht:
|
||||
|
||||
1. Sie erhalten eine Benachrichtigung
|
||||
2. Prüfen Sie die Zeiten
|
||||
3. Genehmigen oder lehnen Sie ab
|
||||
4. Genehmigte Zeiten fließen in die Abrechnung
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'modules',
|
||||
name: 'Module',
|
||||
icon: '🧩',
|
||||
description: 'Funktionen aktivieren/deaktivieren',
|
||||
articles: [
|
||||
{
|
||||
id: 'module-overview',
|
||||
title: 'Module verwalten',
|
||||
icon: '⚙️',
|
||||
content: `
|
||||
## Module in SeCu
|
||||
|
||||
SeCu ist modular aufgebaut. Sie können Funktionen nach Bedarf aktivieren oder deaktivieren.
|
||||
|
||||
### Verfügbare Module
|
||||
|
||||
**Stundenzettel** – Arbeitszeiterfassung
|
||||
|
||||
**Verfügbarkeit** – Einsatzplanung
|
||||
|
||||
**Dokumente** – Dateiverwaltung
|
||||
|
||||
**Partnerschaften** – Subunternehmer-Management
|
||||
|
||||
**Abrechnung** – Rechnungserstellung
|
||||
|
||||
### Modul aktivieren
|
||||
|
||||
1. Gehen Sie zu **Module** (nur für Chefs)
|
||||
2. Finden Sie das gewünschte Modul
|
||||
3. Klicken Sie auf den Schalter
|
||||
4. Das Modul ist sofort verfügbar
|
||||
|
||||
### Modul deaktivieren
|
||||
|
||||
> **Achtung:** Beim Deaktivieren werden keine Daten gelöscht, aber die Funktionen sind nicht mehr zugänglich.
|
||||
|
||||
1. Klicken Sie auf den Schalter des aktiven Moduls
|
||||
2. Bestätigen Sie die Deaktivierung
|
||||
`
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
id: 'faq',
|
||||
name: 'Häufige Fragen',
|
||||
icon: '❓',
|
||||
description: 'Antworten auf häufige Fragen',
|
||||
articles: [
|
||||
{
|
||||
id: 'faq-general',
|
||||
title: 'Allgemeine Fragen',
|
||||
icon: '💬',
|
||||
content: `
|
||||
## Häufige Fragen
|
||||
|
||||
### Ich habe mein Passwort vergessen
|
||||
|
||||
1. Klicken Sie auf der Login-Seite auf **"Passwort vergessen"**
|
||||
2. Geben Sie Ihre E-Mail-Adresse ein
|
||||
3. Sie erhalten einen Link zum Zurücksetzen
|
||||
|
||||
---
|
||||
|
||||
### Kann ich mehrere Organisationen haben?
|
||||
|
||||
Nein, jeder Benutzer gehört zu genau einer Organisation. Für die Zusammenarbeit nutzen Sie das Partnerschaftsmodul.
|
||||
|
||||
---
|
||||
|
||||
### Werden meine Daten gesichert?
|
||||
|
||||
Ja, es werden regelmäßig automatische Backups erstellt. Bei Datenverlust kontaktieren Sie den Support.
|
||||
|
||||
---
|
||||
|
||||
### Wie kann ich Support kontaktieren?
|
||||
|
||||
- **E-Mail:** support@kronos-soulution.de
|
||||
- **Telefon:** Siehe Ihre Vertragsdaten
|
||||
|
||||
---
|
||||
|
||||
### Gibt es eine Mobile App?
|
||||
|
||||
SeCu ist als Web-App optimiert und funktioniert auf allen Geräten. Eine native App ist in Planung.
|
||||
`
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
// Simple markdown renderer
|
||||
function renderMarkdown(text: string): string {
|
||||
return text
|
||||
// Headers
|
||||
.replace(/^### (.+)$/gm, '<h3 class="text-lg font-semibold mt-6 mb-2 text-gray-900 dark:text-white">$1</h3>')
|
||||
.replace(/^## (.+)$/gm, '<h2 class="text-xl font-bold mt-8 mb-4 text-gray-900 dark:text-white">$1</h2>')
|
||||
// Bold
|
||||
.replace(/\*\*(.+?)\*\*/g, '<strong class="font-semibold">$1</strong>')
|
||||
// Italic
|
||||
.replace(/\*(.+?)\*/g, '<em>$1</em>')
|
||||
// Code
|
||||
.replace(/`(.+?)`/g, '<code class="bg-gray-100 dark:bg-gray-700 px-1.5 py-0.5 rounded text-sm">$1</code>')
|
||||
// Blockquote
|
||||
.replace(/^> (.+)$/gm, '<blockquote class="border-l-4 border-blue-500 pl-4 italic text-gray-600 dark:text-gray-400 my-4 bg-blue-50 dark:bg-blue-900/20 py-2 pr-4 rounded-r">$1</blockquote>')
|
||||
// Horizontal rule
|
||||
.replace(/^---$/gm, '<hr class="my-6 border-gray-200 dark:border-gray-700">')
|
||||
// Lists
|
||||
.replace(/^(\d+)\. (.+)$/gm, '<li class="ml-6 list-decimal my-1 text-gray-700 dark:text-gray-300">$2</li>')
|
||||
.replace(/^- (.+)$/gm, '<li class="ml-6 list-disc my-1 text-gray-700 dark:text-gray-300">$1</li>')
|
||||
// Wrap consecutive list items
|
||||
.replace(/(<li class="ml-6 list-decimal[^>]*>.*<\/li>\n?)+/g, (match) => `<ol class="my-4">${match}</ol>`)
|
||||
.replace(/(<li class="ml-6 list-disc[^>]*>.*<\/li>\n?)+/g, (match) => `<ul class="my-4">${match}</ul>`)
|
||||
// Paragraphs (lines that don't start with HTML tags)
|
||||
.split('\n\n')
|
||||
.map(p => {
|
||||
p = p.trim()
|
||||
if (!p) return ''
|
||||
if (p.startsWith('<')) return p
|
||||
return `<p class="my-3 text-gray-700 dark:text-gray-300">${p}</p>`
|
||||
})
|
||||
.join('\n')
|
||||
}
|
||||
|
||||
const filteredCategories = computed(() => {
|
||||
if (!searchQuery.value) return categories
|
||||
|
||||
const query = searchQuery.value.toLowerCase()
|
||||
return categories.map(cat => ({
|
||||
...cat,
|
||||
articles: cat.articles.filter(art =>
|
||||
art.title.toLowerCase().includes(query) ||
|
||||
art.content.toLowerCase().includes(query)
|
||||
)
|
||||
})).filter(cat => cat.articles.length > 0)
|
||||
})
|
||||
|
||||
function selectCategory(catId: string) {
|
||||
activeCategory.value = catId
|
||||
activeArticle.value = null
|
||||
}
|
||||
|
||||
function selectArticle(catId: string, artId: string) {
|
||||
activeCategory.value = catId
|
||||
activeArticle.value = artId
|
||||
}
|
||||
|
||||
function goBack() {
|
||||
if (activeArticle.value) {
|
||||
activeArticle.value = null
|
||||
} else {
|
||||
activeCategory.value = null
|
||||
}
|
||||
}
|
||||
|
||||
const currentCategory = computed(() =>
|
||||
categories.find(c => c.id === activeCategory.value)
|
||||
)
|
||||
|
||||
const currentArticle = computed(() =>
|
||||
currentCategory.value?.articles.find(a => a.id === activeArticle.value)
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="space-y-6">
|
||||
<div class="flex items-center justify-between">
|
||||
<div class="flex items-center gap-3">
|
||||
<button
|
||||
v-if="activeCategory"
|
||||
@click="goBack"
|
||||
class="p-2 hover:bg-gray-100 dark:hover:bg-gray-700 rounded-lg transition-colors text-xl"
|
||||
>
|
||||
←
|
||||
</button>
|
||||
<h1 class="text-2xl font-bold text-gray-900 dark:text-white">
|
||||
📚 Hilfe & Dokumentation
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Search -->
|
||||
<div class="relative">
|
||||
<input
|
||||
v-model="searchQuery"
|
||||
type="text"
|
||||
placeholder="🔍 Suche in der Dokumentation..."
|
||||
class="input pl-4 pr-10 w-full"
|
||||
/>
|
||||
<span
|
||||
v-if="searchQuery"
|
||||
@click="searchQuery = ''"
|
||||
class="absolute right-3 top-1/2 -translate-y-1/2 cursor-pointer text-gray-400 hover:text-gray-600 text-lg"
|
||||
>
|
||||
✕
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Category Grid -->
|
||||
<div v-if="!activeCategory" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div
|
||||
v-for="category in filteredCategories"
|
||||
:key="category.id"
|
||||
@click="selectCategory(category.id)"
|
||||
class="card cursor-pointer hover:shadow-lg transition-all hover:scale-[1.02] border-2 border-transparent hover:border-blue-500"
|
||||
>
|
||||
<div class="text-3xl mb-3">{{ category.icon }}</div>
|
||||
<h3 class="text-lg font-semibold mb-1 text-gray-900 dark:text-white">{{ category.name }}</h3>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ category.description }}</p>
|
||||
<p class="text-xs text-gray-400 mt-2">{{ category.articles.length }} Artikel</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Article List -->
|
||||
<div v-else-if="!activeArticle" class="space-y-4">
|
||||
<div class="card bg-gray-50 dark:bg-gray-800">
|
||||
<div class="flex items-center gap-3">
|
||||
<span class="text-3xl">{{ currentCategory?.icon }}</span>
|
||||
<div>
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">{{ currentCategory?.name }}</h2>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">{{ currentCategory?.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-3">
|
||||
<div
|
||||
v-for="article in currentCategory?.articles"
|
||||
:key="article.id"
|
||||
@click="selectArticle(currentCategory!.id, article.id)"
|
||||
class="card cursor-pointer hover:shadow-md transition-all flex items-center gap-3 hover:bg-gray-50 dark:hover:bg-gray-700"
|
||||
>
|
||||
<span class="text-2xl">{{ article.icon }}</span>
|
||||
<span class="font-medium text-gray-900 dark:text-white">{{ article.title }}</span>
|
||||
<span class="ml-auto text-gray-400">→</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Article Content -->
|
||||
<div v-else class="card">
|
||||
<div class="flex items-center gap-3 mb-6 pb-4 border-b dark:border-gray-700">
|
||||
<span class="text-3xl">{{ currentArticle?.icon }}</span>
|
||||
<h2 class="text-xl font-semibold text-gray-900 dark:text-white">{{ currentArticle?.title }}</h2>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="prose dark:prose-invert max-w-none"
|
||||
v-html="renderMarkdown(currentArticle?.content || '')"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
Reference in New Issue
Block a user