revert(frontend): Frontend auf letzten funktionierenden Stand 5680179 zurückgesetzt — i18n-Massen-Batch brach Dashboard-Shell in Produktion; Render-Loop-Fix und DSGVO-Antrags-UI liegen sicher in Historie für kontrollierten Wiedereinspiel

This commit is contained in:
Agent Zero
2026-08-27 09:14:21 +02:00
parent bea479bfad
commit 66c11d3d64
119 changed files with 925 additions and 1477 deletions
+11 -13
View File
@@ -1,33 +1,31 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
export function HelpApiDocsPage() {
const { t } = useTranslation();
return (
<div className="max-w-4xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">{t('helpApiDocs.apidokumentation')}</h1>
<h1 className="text-2xl font-bold text-secondary-900 mb-4">API Dokumentation</h1>
<p className="text-secondary-600 mb-4">
{t('helpApiDocs.dievollständigeapidokumentationfindensie')} <a href="/docs" target="_blank" rel="noopener noreferrer" className="text-primary-600 hover:underline">/docs</a> {t('helpApiDocs.swaggerui')}
Die vollständige API-Dokumentation finden Sie unter <a href="/docs" target="_blank" rel="noopener noreferrer" className="text-primary-600 hover:underline">/docs</a> (Swagger UI).
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Übersicht</h2>
<p className="text-secondary-600 mb-4">
{t('helpApiDocs.leocrmbieteteinerestapimit')}
LeoCRM bietet eine REST-API mit über 224 Endpoints. Die API verwendet JSON für Request- und Response-Bodies.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Authentifizierung</h2>
<p className="text-secondary-600 mb-4">
{t('helpApiDocs.dieapiverwendetsessionbasierteauthentifi')} <code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">{t('helpApiDocs.postapiv1authlogin')}</code> {t('helpApiDocs.wirdeinsessioncookiegesetzt')}
Die API verwendet Session-basierte Authentifizierung mit HttpOnly-Cookies. Nach dem Login über <code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">POST /api/v1/auth/login</code> wird ein Session-Cookie gesetzt.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpApiDocs.wichtigeendpoints')}</h2>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Wichtige Endpoints</h2>
<ul className="list-disc list-inside text-secondary-600 space-y-1">
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">{t('helpApiDocs.getapiv1contacts')}</code> {t('helpApiDocs.kontakteabrufen')}</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">{t('helpApiDocs.postapiv1contacts')}</code> {t('helpApiDocs.kontakterstellen')}</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">{t('helpApiDocs.getapiv1calendarentries')}</code> {t('helpApiDocs.kalendereinträge')}</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">{t('helpApiDocs.getapiv1mailaccounts')}</code> {t('helpApiDocs.mailkonten')}</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">{t('helpApiDocs.getapiv1pluginsactivemanifests')}</code> {t('helpApiDocs.pluginmanifeste')}</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">GET /api/v1/contacts</code> Kontakte abrufen</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">POST /api/v1/contacts</code> Kontakt erstellen</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">GET /api/v1/calendar/entries</code> Kalendereinträge</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">GET /api/v1/mail/accounts</code> Mail-Konten</li>
<li><code className="bg-secondary-100 px-1.5 py-0.5 rounded text-sm">GET /api/v1/plugins/active-manifests</code> Plugin-Manifeste</li>
</ul>
<div className="mt-6 p-4 bg-primary-50 rounded-lg border border-primary-200">
<p className="text-sm text-primary-700">
📖 <strong>{t('helpApiDocs.vollständigedoku')}</strong> <a href="/docs" target="_blank" rel="noopener noreferrer" className="underline">{t('helpApiDocs.swaggeruiöffnen')}</a>
📖 <strong>Vollständige Doku:</strong> <a href="/docs" target="_blank" rel="noopener noreferrer" className="underline">Swagger UI öffnen</a>
</p>
</div>
</div>
+6 -8
View File
@@ -1,26 +1,24 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
export function HelpContactsPage() {
const { t } = useTranslation();
return (
<div className="max-w-3xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">{t('helpContacts.kontakteverwalten')}</h1>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpContacts.kontakteerstellen')}</h2>
<h1 className="text-2xl font-bold text-secondary-900 mb-4">Kontakte verwalten</h1>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Kontakte erstellen</h2>
<p className="text-secondary-600 mb-4">
{t('helpContacts.gehensiezukontakteundklicken')}
Gehen Sie zu Kontakte und klicken Sie auf "Neuer Kontakt". Füllen Sie die Felder aus und speichern Sie. Sie können Firmen und Personen anlegen.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Kontaktpersonen</h2>
<p className="text-secondary-600 mb-4">
{t('helpContacts.jederfirmakönnenmehrerekontaktpersonenzu')}
Jeder Firma können mehrere Kontaktpersonen zugeordnet werden. Öffnen Sie eine Firma und fügen Sie Personen hinzu.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Tags</h2>
<p className="text-secondary-600 mb-4">
{t('helpContacts.verwendensietagsumkontaktezu')}
Verwenden Sie Tags um Kontakte zu kategorisieren. Tags können frei vergeben werden und helfen bei der Filterung.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Ordner</h2>
<p className="text-secondary-600 mb-4">
{t('helpContacts.organisierensiekontakteinordnernordner')}
Organisieren Sie Kontakte in Ordnern. Ordner können verschachtelt werden und eigene Berechtigungen haben.
</p>
</div>
);
+7 -9
View File
@@ -1,24 +1,22 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
export function HelpLoginPage() {
const { t } = useTranslation();
return (
<div className="max-w-3xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">{t('helpLogin.loginanmeldung')}</h1>
<h1 className="text-2xl font-bold text-secondary-900 mb-4">Login & Anmeldung</h1>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Anmeldung</h2>
<p className="text-secondary-600 mb-4">
{t('helpLogin.rufensiedieleocrmurlauf')}
Rufen Sie die LeoCRM-URL auf (z.B. https://crm.media-on.de) und melden Sie sich mit Ihrer E-Mail-Adresse und Ihrem Passwort an.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpLogin.passwortvergessen')}</h2>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Passwort vergessen?</h2>
<p className="text-secondary-600 mb-4">
{t('helpLogin.klickensieaufderloginseite')}
Klicken Sie auf der Login-Seite auf "Passwort vergessen". Sie erhalten eine E-Mail mit einem Link zum Zurücksetzen Ihres Passworts.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Sicherheit</h2>
<ul className="list-disc list-inside text-secondary-600 space-y-1">
<li>{t('helpLogin.ihresitzungwirdübereinsicheres')}</li>
<li>{t('helpLogin.nachinaktivitätwirddiesitzungautomatisch')}</li>
<li>{t('helpLogin.passwörterwerdenmitbcryptcost12')}</li>
<li>Ihre Sitzung wird über ein sicheres HttpOnly-Cookie verwaltet</li>
<li>Nach Inaktivität wird die Sitzung automatisch beendet</li>
<li>Passwörter werden mit bcrypt (cost=12) verschlüsselt gespeichert</li>
</ul>
</div>
);
+10 -12
View File
@@ -1,26 +1,24 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
export function HelpMailSetupPage() {
const { t } = useTranslation();
return (
<div className="max-w-3xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">{t('helpMailSetup.postfacheinrichten')}</h1>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpMailSetup.imapkontohinzufügen')}</h2>
<h1 className="text-2xl font-bold text-secondary-900 mb-4">Postfach einrichten</h1>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">IMAP-Konto hinzufügen</h2>
<p className="text-secondary-600 mb-4">
{t('helpMailSetup.gehensiezueinstellungenemailund')}
Gehen Sie zu Einstellungen Email und klicken Sie auf "Konto hinzufügen". Geben Sie Ihre IMAP- und SMTP-Serverdaten ein.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpMailSetup.benötigtedaten')}</h2>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Benötigte Daten</h2>
<ul className="list-disc list-inside text-secondary-600 space-y-1">
<li>{t('helpMailSetup.imapserverzbimapexample')}</li>
<li>{t('helpMailSetup.imapportmeist993fürssl')}</li>
<li>{t('helpMailSetup.smtpserverzbsmtpexample')}</li>
<li>{t('helpMailSetup.smtpportmeist587fürtls')}</li>
<li>{t('helpMailSetup.emailadresseundpasswort')}</li>
<li>IMAP-Server (z.B. imap.example.com)</li>
<li>IMAP-Port (meist 993 für SSL)</li>
<li>SMTP-Server (z.B. smtp.example.com)</li>
<li>SMTP-Port (meist 587 für TLS)</li>
<li>E-Mail-Adresse und Passwort</li>
</ul>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Synchronisation</h2>
<p className="text-secondary-600 mb-4">
{t('helpMailSetup.nachdemeinrichtenwirdihrpostfach')}
Nach dem Einrichten wird Ihr Postfach automatisch synchronisiert. Neue E-Mails werden im Hintergrund abgerufen.
</p>
</div>
);
+6 -8
View File
@@ -1,30 +1,28 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
export function HelpNavigationPage() {
const { t } = useTranslation();
return (
<div className="max-w-3xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">Navigation</h1>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Startseite</h2>
<p className="text-secondary-600 mb-4">
{t('helpNavigation.nachdemlogingelangensiezur')}
Nach dem Login gelangen Sie zur Startseite. Hier können Sie einen Workspace auswählen oder zu den Einstellungen und der Hilfe navigieren.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Workspace</h2>
<p className="text-secondary-600 mb-4">
{t('helpNavigation.einworkspaceistihrarbeitsbereichmit')}
Ein Workspace ist Ihr Arbeitsbereich mit Sidebar-Navigation. Hier finden Sie Kontakte, Kalender, E-Mail und alle anderen Module.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Sidebar</h2>
<p className="text-secondary-600 mb-4">
{t('helpNavigation.dashamburgermenüobenlinksblendet')}
Das Hamburger-Menü oben links blendet die Seitenleiste ein und aus. Die Sidebar zeigt alle verfügbaren Module.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Zurück-Pfeil</h2>
<p className="text-secondary-600 mb-4">
{t('helpNavigation.rechtsnebendemhamburgermenüfinden')}
Rechts neben dem Hamburger-Menü finden Sie einen Zurück-Pfeil, der Sie zurück zur Startseite bringt.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpNavigation.globalesuche')}</h2>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Globale Suche</h2>
<p className="text-secondary-600 mb-4">
{t('helpNavigation.verwendensiedielupeobenoder')}
Verwenden Sie die Lupe oben oder Strg+K um das Kommando-Palette zu öffnen und schnell nach Kontakten, Mails oder Dateien zu suchen.
</p>
</div>
);
+2 -4
View File
@@ -1,18 +1,16 @@
import React from 'react';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
export function HelpPlaceholderPage() {
const { t } = useTranslation();
const params = useParams();
return (
<div className="max-w-3xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">Hilfe</h1>
<p className="text-secondary-600">
{t('helpPlaceholder.diesehilfeseite')}{params['*'] || 'unbekannt'}{t('helpPlaceholder.wirdgeradeerstelltschauensiespäter')}
Diese Hilfeseite ({params['*'] || 'unbekannt'}) wird gerade erstellt. Schauen Sie später wieder vorbei.
</p>
<p className="text-secondary-400 text-sm mt-4">
{t('helpPlaceholder.wählensieeinthemaausdem')}
Wählen Sie ein Thema aus dem Menü links um weitere Hilfe-Artikel zu lesen.
</p>
</div>
);
+14 -16
View File
@@ -1,33 +1,31 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
export function HelpWelcomePage() {
const { t } = useTranslation();
return (
<div className="max-w-3xl mx-auto prose prose-secondary">
<h1 className="text-2xl font-bold text-secondary-900 mb-4">{t('helpWelcome.willkommenbeileocrm')}</h1>
<h1 className="text-2xl font-bold text-secondary-900 mb-4">Willkommen bei LeoCRM</h1>
<p className="text-secondary-600 mb-4">
{t('helpWelcome.leocrmisteinselbstgehostetescrm')}
LeoCRM ist ein selbst-gehostetes CRM-System für kleine Vertriebsteams. Es bietet Kontakte, Kalender, E-Mail, Dateiverwaltung und mehr alles in einer Anwendung.
</p>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Hauptfunktionen</h2>
<ul className="list-disc list-inside text-secondary-600 space-y-1">
<li><strong>{t('helpWelcome.kontakteverwalten')}</strong> {t('helpWelcome.firmenpersonenkontaktdatenzentralspeiche')}</li>
<li><strong>Kalender</strong> {t('helpWelcome.termineaufgabenunderinnerungen')}</li>
<li><strong>E-Mail</strong> {t('helpWelcome.imappostfächersynchronisierendirektantwo')}</li>
<li><strong>{t('helpWelcome.dateiendms')}</strong> {t('helpWelcome.dokumentehochladenteilenundverwalten')}</li>
<li><strong>KI-Assistent</strong> {t('helpWelcome.intelligentehilfebeiderarbeit')}</li>
<li><strong>Workflows</strong> {t('helpWelcome.automatisierteprozesse')}</li>
<li><strong>Kontakte verwalten</strong> Firmen, Personen, Kontaktdaten zentral speichern</li>
<li><strong>Kalender</strong> Termine, Aufgaben und Erinnerungen</li>
<li><strong>E-Mail</strong> IMAP-Postfächer synchronisieren, direkt antworten</li>
<li><strong>Dateien (DMS)</strong> Dokumente hochladen, teilen und verwalten</li>
<li><strong>KI-Assistent</strong> Intelligente Hilfe bei der Arbeit</li>
<li><strong>Workflows</strong> Automatisierte Prozesse</li>
</ul>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">{t('helpWelcome.ersteschritte')}</h2>
<h2 className="text-lg font-semibold text-secondary-800 mt-6 mb-2">Erste Schritte</h2>
<ol className="list-decimal list-inside text-secondary-600 space-y-1">
<li>{t('helpWelcome.meldensiesichmitihrenzugangsdaten')}</li>
<li>{t('helpWelcome.wählensieeinenworkspaceaufder')}</li>
<li>{t('helpWelcome.beginnensiemitdemanlegenvon')}</li>
<li>{t('helpWelcome.richtensieihremailpostfach')}</li>
<li>Melden Sie sich mit Ihren Zugangsdaten an</li>
<li>Wählen Sie einen Workspace auf der Startseite</li>
<li>Beginnen Sie mit dem Anlegen von Kontakten</li>
<li>Richten Sie Ihr E-Mail-Postfach unter Einstellungen Email ein</li>
</ol>
<div className="mt-6 p-4 bg-primary-50 rounded-lg border border-primary-200">
<p className="text-sm text-primary-700">
💡 <strong>Tipp:</strong> {t('helpWelcome.nutzensiedieglobalesuchelupe')}
💡 <strong>Tipp:</strong> Nutzen Sie die globale Suche (Lupe oben) oder das Kommando-Palette (Strg+K) um schnell zu finden was Sie brauchen.
</p>
</div>
</div>