diff --git a/package.json b/package.json index 36ed4ca..abd6011 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "lageplan", - "version": "1.2.0", + "version": "1.2.1", "description": "Feuerwehr Lageplan - Krokier-App für Einsatzdokumentation", "private": true, "scripts": { diff --git a/src/app/admin/page.tsx b/src/app/admin/page.tsx index 4454698..2bdd6af 100644 --- a/src/app/admin/page.tsx +++ b/src/app/admin/page.tsx @@ -330,47 +330,64 @@ export default function AdminPage() { const fetchData = async () => { setIsLoading(true) try { - const [catRes, iconRes, userRes, tenantRes, projRes] = await Promise.all([ + const isServerAdmin = user?.role === 'SERVER_ADMIN' + + // Common fetches for all admins + const fetches: Promise[] = [ fetch('/api/admin/categories'), - fetch('/api/admin/icons'), fetch('/api/admin/users'), - fetch('/api/admin/tenants'), fetch('/api/projects'), - ]) + ] + // SERVER_ADMIN-only fetches + if (isServerAdmin) { + fetches.push(fetch('/api/admin/icons')) + fetches.push(fetch('/api/admin/tenants')) + } + + const results = await Promise.all(fetches) + const [catRes, userRes, projRes] = results + if (catRes.ok) setCategories((await catRes.json()).categories || []) - if (iconRes.ok) setIcons((await iconRes.json()).icons || []) if (userRes.ok) setUsers((await userRes.json()).users || []) - if (tenantRes.ok) setTenants((await tenantRes.json()).tenants || []) if (projRes.ok) { const projData = await projRes.json() setAllProjects((projData.projects || []).map((p: any) => ({ id: p.id, title: p.title, location: p.location }))) } - // Load SMTP settings - try { - const smtpRes = await fetch('/api/admin/settings') - if (smtpRes.ok) { - const smtpData = await smtpRes.json() - if (smtpData.smtp) { - setSmtpHost(smtpData.smtp.host || '') - setSmtpPort(String(smtpData.smtp.port || 587)) - setSmtpSecure(smtpData.smtp.secure || false) - setSmtpUser(smtpData.smtp.user || '') - setSmtpPass(smtpData.smtp.pass || '') - setSmtpFromName(smtpData.smtp.fromName || 'Lageplan') - setSmtpFromEmail(smtpData.smtp.fromEmail || '') + if (isServerAdmin) { + const iconRes = results[3] + const tenantRes = results[4] + if (iconRes.ok) setIcons((await iconRes.json()).icons || []) + if (tenantRes.ok) setTenants((await tenantRes.json()).tenants || []) + } + + // Load settings (SERVER_ADMIN only) + if (isServerAdmin) { + try { + const smtpRes = await fetch('/api/admin/settings') + if (smtpRes.ok) { + const smtpData = await smtpRes.json() + if (smtpData.smtp) { + setSmtpHost(smtpData.smtp.host || '') + setSmtpPort(String(smtpData.smtp.port || 587)) + setSmtpSecure(smtpData.smtp.secure || false) + setSmtpUser(smtpData.smtp.user || '') + setSmtpPass(smtpData.smtp.pass || '') + setSmtpFromName(smtpData.smtp.fromName || 'Lageplan') + setSmtpFromEmail(smtpData.smtp.fromEmail || '') + } + if (smtpData.contactEmail) setContactEmail(smtpData.contactEmail) + if (smtpData.notifyRegistrationEmail) setNotifyRegistrationEmail(smtpData.notifyRegistrationEmail) + if (smtpData.demoProjectId) setDemoProjectId(smtpData.demoProjectId) + if (smtpData.defaultSymbolScale) setDefaultSymbolScale(smtpData.defaultSymbolScale) + if (smtpData.stripe) { + setStripePublicKey(smtpData.stripe.publicKey || '') + setStripeSecretKey(smtpData.stripe.secretKey || '') + setStripeWebhookSecret(smtpData.stripe.webhookSecret || '') + } } - if (smtpData.contactEmail) setContactEmail(smtpData.contactEmail) - if (smtpData.notifyRegistrationEmail) setNotifyRegistrationEmail(smtpData.notifyRegistrationEmail) - if (smtpData.demoProjectId) setDemoProjectId(smtpData.demoProjectId) - if (smtpData.defaultSymbolScale) setDefaultSymbolScale(smtpData.defaultSymbolScale) - if (smtpData.stripe) { - setStripePublicKey(smtpData.stripe.publicKey || '') - setStripeSecretKey(smtpData.stripe.secretKey || '') - setStripeWebhookSecret(smtpData.stripe.webhookSecret || '') - } - } - } catch {} + } catch {} + } } catch (error) { console.error('Error fetching data:', error) } finally { @@ -947,22 +964,22 @@ export default function AdminPage() { {catName} ({syms.length}) -
+
{syms.map(sym => { const selected = selectedSymbolIds.has(sym.id) return (
toggleSelect(sym.id)} - className={`relative cursor-pointer border-2 rounded-lg p-2 transition-all hover:shadow-sm ${ + className={`relative cursor-pointer border-2 rounded-lg p-3 transition-all hover:shadow-sm ${ selected ? 'border-blue-500 bg-blue-50 dark:bg-blue-950/30' : sym.isActive ? 'border-transparent hover:border-border' : 'border-transparent opacity-40' }`} > -
- {sym.name} +
+ {sym.name}
-

{sym.name}

+

{sym.name}

{/* Status dot */}
@@ -1819,24 +1836,41 @@ export default function AdminPage() { {user?.role === 'TENANT_ADMIN' && tenant && (
-

Lageplan unterstützen

-

- Lageplan ist ein kostenloses Herzensprojekt. Wenn du die Weiterentwicklung unterstützen möchtest, - kannst du auf unserer Spendenseite einen freiwilligen Beitrag leisten. -

- -
diff --git a/src/app/app/page.tsx b/src/app/app/page.tsx index 2a396dc..cea321c 100644 --- a/src/app/app/page.tsx +++ b/src/app/app/page.tsx @@ -1087,10 +1087,11 @@ export default function AppPage() { return } - // Ctrl/Cmd shortcuts (CH keyboard: Z and Y are swapped) + // Ctrl/Cmd shortcuts if (e.ctrlKey || e.metaKey) { - if (e.key === 'z') { e.preventDefault(); handleRedo(); return } - if (e.key === 'y') { e.preventDefault(); handleUndo(); return } + if (e.key === 'z' && e.shiftKey) { e.preventDefault(); handleRedo(); return } + if (e.key === 'z') { e.preventDefault(); handleUndo(); return } + if (e.key === 'y') { e.preventDefault(); handleRedo(); return } if (e.key === 's') { e.preventDefault(); handleSaveProject(); return } return } @@ -1707,7 +1708,7 @@ export default function AppPage() { ))}
Aktionen
{[ - ['Ctrl+Y', 'Rückgängig'], ['Ctrl+Z', 'Wiederholen'], + ['Ctrl+Z', 'Rückgängig'], ['Ctrl+Y', 'Wiederholen'], ['Ctrl+S', 'Speichern'], ['Del', 'Auswahl löschen'], ['Esc', 'Abbrechen'], ['?', 'Diese Hilfe'], ].map(([key, label]) => (