From 200d68f20d6952c6a7df77fd196efb06dbe059ea Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 5 Oct 2026 11:15:29 +0000 Subject: [PATCH] Tickets: vier Ticket-Dialoge auf Dialog (Esc, Sperre beim Speichern), Unterstuetzung als Feldblock Co-Authored-By: Claude Opus 5.5 --- src/components/CreateTicketModal.jsx | 276 +++++++++++----------- src/components/CreateWorksheetModal.jsx | 302 ++++++++++++------------ src/components/OwnSupportModal.jsx | 95 ++++---- src/components/SupportersEditor.jsx | 46 ++-- src/components/WorksheetTimesModal.jsx | 154 ++++++------ src/styles/global.css | 2 + 6 files changed, 439 insertions(+), 436 deletions(-) diff --git a/src/components/CreateTicketModal.jsx b/src/components/CreateTicketModal.jsx index 4839200..1a50330 100644 --- a/src/components/CreateTicketModal.jsx +++ b/src/components/CreateTicketModal.jsx @@ -1,6 +1,5 @@ -import { useState, useEffect, useMemo } from 'react' -import { FaTimes } from 'react-icons/fa' -import { useEmployees } from '../hooks/useEmployees' +import { useState, useEffect, useMemo, useRef } from 'react' +import { useScrollIntoView } from '../hooks/useScrollIntoView' import { databases, DATABASE_ID, COLLECTIONS, Query } from '../lib/appwrite' import { SERVICE_TYPES, @@ -11,7 +10,7 @@ import { rankSuggestions, } from '../lib/ticketForm' import { priorityFor } from '../lib/ticketStatus' -import { AutocompleteInput, DateTimeInput } from './ui' +import { AutocompleteInput, Button, DateTimeInput, Dialog, Field } from './ui' // Neue Tickets gibt es aktuell nur fuer diese Arten; alte Tickets behalten ihre Art. // Migration = ein Kunde, den wir von einem anderen Anbieter uebernehmen. @@ -36,14 +35,18 @@ const emptyForm = () => ({ details: '' }) -export default function CreateTicketModal({ isOpen, onClose, onCreate, customers = [] }) { - const { employees } = useEmployees() +// Stabile Vorgabe, damit die Vorschlagsliste nicht bei jedem Render neu entsteht +const NO_EMPLOYEES = [] +// `employees` kommt von der Seite (useEmployees laeuft dort einmal), der Dialog ruft den Hook nicht selbst auf +export default function CreateTicketModal({ isOpen, onClose, onCreate, customers = [], employees = NO_EMPLOYEES }) { const [formData, setFormData] = useState(emptyForm) const [recentTickets, setRecentTickets] = useState([]) const [loading, setLoading] = useState(false) const [error, setError] = useState('') + const errorRef = useRef(null) + useScrollIntoView(errorRef, error) // Reset error when modal opens useEffect(() => { @@ -122,145 +125,132 @@ export default function CreateTicketModal({ isOpen, onClose, onCreate, customers if (!isOpen) return null return ( -
- - - -
-

Neues Ticket

+ + + + + } + > + {error && ( +
+ {error} +
+ )} - {error && ( -
- {error} -
- )} +
+ + + -
-
-
-
- - -
- -
- - -
- -
- -
- -
- -

- {employees.length > 0 - ? `Automatisch an den Mitarbeiter mit der geringsten Anzahl offener Tickets (${employees.length} verfügbar).` - : 'Es ist noch kein Mitarbeiter verfügbar. Das Ticket bleibt zunächst offen.'} -

-
-
- -
-
- - handleChange('topic', e.target.value)} - required - /> -
- -
- - handleChange('requestedBy', value)} - getSuggestions={getSuggestions} - required - /> -
- -
- - handleChange('startTime', value)} - /> -
- -
- - handleChange('deadline', value)} - onTimeChange={(value) => handleChange('endTime', value)} - /> -
-
-
- -
- -