From 1a8604f7e6ebbdbb1faa7d150ea8032253b9104f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 27 Sep 2026 16:01:12 +0000 Subject: [PATCH] Finanzen nur noch anzeigen, Dashboard und Admin-Konfiguration entfernt (Paket D) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Finanzen: Liste, Zahlen, PDF und Link zu InvoiceNinja bleiben. Das Formular "Rechnung erstellen" (auf der Seite und als "Rechnung aus Ticket erstellen" im Ticket) ist weg; Rechnungen entstehen direkt in InvoiceNinja. Das Verknüpfen von Kunden mit InvoiceNinja bleibt. - Filter "Bezahlt" repariert: InvoiceNinja liefert status_id als Text. - FinancePage.jsx und InvoicePanel.jsx waren Windows-1252 kodiert und zeigten live "�"; jetzt UTF-8, dazu Umlaute in den Texten. - Dashboard entfernt (doppelte Finanzzahlen, "Offen" zählte falsch); alte Links führen zu den Tickets. - Admin: Reiter "Konfiguration" (nur noch Prioritäten, die seit Paket B niemand liest) mit useAdminConfig entfernt; Admin startet bei Kunden. Co-Authored-By: Claude Opus 5.5 --- README.md | 10 +- src/App.jsx | 2 - src/components/InvoicePanel.jsx | 117 ++++-------------------- src/components/Navbar.jsx | 7 -- src/hooks/useAdminConfig.js | 156 -------------------------------- src/hooks/useInvoices.js | 15 +-- src/lib/appwrite.js | 1 - src/lib/integrationsApi.js | 1 - src/pages/AdminPage.css | 40 -------- src/pages/AdminPage.jsx | 124 +------------------------ src/pages/DashboardPage.jsx | 98 -------------------- src/pages/FinancePage.jsx | 86 +++--------------- 12 files changed, 40 insertions(+), 617 deletions(-) delete mode 100644 src/hooks/useAdminConfig.js delete mode 100644 src/pages/DashboardPage.jsx diff --git a/README.md b/README.md index 5c37060..5599a96 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ # WOMS – Ticketsystem von WEBklar Internes Ticketsystem unter https://ticket.webklar.com: Tickets, Arbeitsblätter mit -Zeiterfassung, Kunden und Leads, Website-Projekte, Planboard und Rechnungen. +Zeiterfassung, Kunden und Leads, Website-Projekte, Planboard und Rechnungen (nur +anzeigen; Rechnungen werden in InvoiceNinja geschrieben). React/Vite im Browser, Daten in Appwrite (Projekt `6a1058610003c5a13a05`, Datenbank `woms-database`, API unter `https://ticket.webklar.com/v1`). @@ -27,7 +28,7 @@ Datum speichert WOMS als Text `dd.mm.yyyy`, Uhrzeiten als `hhmm` (z. B. `0930`). | `websiteProjects` | Website-Projekte und Vorschauen | `customerId` (steuert, was der Kunde im Portal sieht), `ticketId` (Ziel der Git-Push-Arbeitsblätter), Subdomain, Repo | | `leads`, `leadPipeline`, `leadSettings` | Lead-Automatik | Recherche-Ergebnisse, Pipeline-Schritte, Sucheinstellungen | | `roadmaps`, `roadmapNodes` | Projektpläne | Plan mit Schritten, verknüpft mit einem Ticket | -| `config` | Einstellungen | Prioritäten (dazu alte Listen, die nichts mehr liest) | +| `config` | alte Einstellungen | wird von WOMS nicht mehr gelesen (Prioritäten, alte Listen) | Zusammenspiel mit anderen Systemen: @@ -36,5 +37,6 @@ Zusammenspiel mit anderen Systemen: nachgetragen, danach zählt sie als Arbeitszeit. Termine aus der Rechnungsanalyse landen am Akquise-Ticket des Kunden und erscheinen im Planboard. Kunden-, Mitarbeiter- und Projektverwaltung laufen über die Admin-API des Portals. -- **ticket-integrations** (`/api/integrations`): Proxy zu InvoiceNinja (Rechnungen) - und Paperless (Dokumente). +- **ticket-integrations** (`/api/integrations`): Proxy zu InvoiceNinja (Rechnungen + anzeigen, Kunden verknüpfen). Die Paperless-Routen dort nutzt WOMS nicht mehr; + Paperless selbst ist gestoppt. diff --git a/src/App.jsx b/src/App.jsx index 7705546..4b93d00 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,7 +4,6 @@ import Sidebar from './components/Navbar' import Footer from './components/Footer' import LoginPage from './pages/LoginPage' import TicketsPage from './pages/TicketsPage' -import DashboardPage from './pages/DashboardPage' import PlanboardPage from './pages/PlanboardPage' import ProjectsPage from './pages/ProjectsPage' import RoadmapsPage from './pages/RoadmapsPage' @@ -46,7 +45,6 @@ function AppRoutes() { } /> } /> } /> - } /> } /> } /> } /> diff --git a/src/components/InvoicePanel.jsx b/src/components/InvoicePanel.jsx index bd2f6f1..93d508f 100644 --- a/src/components/InvoicePanel.jsx +++ b/src/components/InvoicePanel.jsx @@ -41,7 +41,7 @@ export default function InvoicePanel({ ticket }) { }, [loadCustomer]) const clientId = customer?.invoiceNinjaClientId || null - const { invoices, loading, error, refresh, createInvoice } = useInvoices(clientId) + const { invoices, loading, error, refresh } = useInvoices(clientId) if (customerLoading) { return ( @@ -54,7 +54,7 @@ export default function InvoicePanel({ ticket }) { if (!ticket.customerId) { return (
-

Kein Kunde am Ticket verknuepft - keine Rechnungen verfuegbar.

+

Kein Kunde am Ticket verknüpft, keine Rechnungen verfügbar.

) } @@ -77,23 +77,16 @@ export default function InvoicePanel({ ticket }) { {customer && customerStage(customer) === 'lead' ? (

- Dieser Kunde ist noch ein Lead. Erst zum festen Kunden machen (im Kunden-Bereich, vollstaendige Daten noetig) - dann sind Rechnungen moeglich. + Dieser Kunde ist noch ein Lead. Erst zum festen Kunden machen (im Kunden-Bereich, vollständige Daten nötig), dann sind Rechnungen möglich.

) : !clientId && !isInvoiceReady(customer) ? (

- Rechnungsdaten unvollstaendig. Bitte im Kunden-Bereich Unternehmen, E-Mail, Strasse, PLZ und Stadt ergaenzen. + Rechnungsdaten unvollständig. Bitte im Kunden-Bereich Unternehmen, E-Mail, Straße, PLZ und Stadt ergänzen.

) : !clientId ? ( ) : ( - + )} ) @@ -163,13 +156,13 @@ function LinkClient({ customer, onLinked }) { return (

- Dieser Kunde ist noch nicht mit InvoiceNinja verknuepft. + Dieser Kunde ist noch nicht mit InvoiceNinja verknüpft.

setSearch(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && doSearch()} @@ -186,11 +179,11 @@ function LinkClient({ customer, onLinked }) {
{c.name} - {c.number ? � {c.number} : null} + {c.number ? · {c.number} : null} {c.email ?
{c.email}
: null}
))} @@ -200,15 +193,15 @@ function LinkClient({ customer, onLinked }) {
) } // ---------------------------------------------------- Rechnungsliste --------- -function InvoiceList({ ticket, clientId, invoices, loading, error, createInvoice }) { - const [showCreate, setShowCreate] = useState(false) +// Nur anzeigen: neue Rechnungen entstehen direkt in InvoiceNinja +function InvoiceList({ invoices, loading, error }) { const [openingId, setOpeningId] = useState(null) const openPdf = async (id) => { @@ -216,7 +209,7 @@ function InvoiceList({ ticket, clientId, invoices, loading, error, createInvoice try { await integrationsApi.openInvoicePdf(id) } catch (err) { - alert('PDF konnte nicht geoeffnet werden: ' + err.message) + alert('PDF konnte nicht geöffnet werden: ' + err.message) } finally { setOpeningId(null) } @@ -224,40 +217,23 @@ function InvoiceList({ ticket, clientId, invoices, loading, error, createInvoice return (
- - - {showCreate && ( - setShowCreate(false)} - onSubmit={async (payload) => { - const r = await createInvoice(payload) - if (r.success) setShowCreate(false) - return r - }} - /> - )} - {error &&
{error}
} {loading ? (

Rechnungen werden geladen...

) : invoices.length === 0 ? ( -

Noch keine Rechnungen fuer diesen Kunden.

+

Noch keine Rechnungen für diesen Kunden.

) : (
- + {invoices.map((inv) => { - const st = INVOICE_STATUS[inv.status_id] || { label: '�', color: '#a0aec0' } + const st = INVOICE_STATUS[inv.status_id] || { label: '–', color: '#a0aec0' } const overdue = Number(inv.balance) > 0 && inv.due_date && new Date(inv.due_date) < new Date() return ( @@ -266,9 +242,9 @@ function InvoiceList({ ticket, clientId, invoices, loading, error, createInvoice - +
Nr.DatumFaelligBetragOffenStatusNr.DatumFälligBetragOffenStatus
{inv.due_date || '-'} {formatMoney(inv.amount)} 0 ? '#f59e0b' : '#10b981' }}>{formatMoney(inv.balance)}{st.label}{overdue ? ' (ueberfaellig)' : ''}{st.label}{overdue ? ' (überfällig)' : ''} -