Frontend half of the rename: - New /admin/partner-units page (admin-partner-units.tsx + .ts) with full CRUD + member management. Mirrors /admin/team's aesthetic and uses the same modal pattern. Card on /admin flips from "Geplant" to "Verfügbar" with ICON_BUILDING and a /admin/partner-units link. - Sidebar gains a "Partner Units" admin nav item between Team and Audit. - Onboarding form replaces the free-text Dezernat input with a select populated from /api/partner-units; submits partner_unit_id which the backend uses to insert a membership row in the user-create tx. - Settings: dezernat tab removed entirely (TabName drops to 3). The read-only "Meine Partner Units" view now lives as a card on the profile tab. Free-text dezernat input removed from the profile form. ~250 lines of admin-CRUD removed; replaced by ~70 lines of read-only partner-units summary. - /admin/team: Dezernat column dropped from the table and the inline edit row; "Onboard existing account" modal no longer asks for one. Column count drops from 10 to 9. - /team directory: groups by structured partner_unit_members only; drops the free-text fallback grouping and the "Ohne Dezernat" loose bucket. Single "Ohne Partner Unit" orphan group catches users in no unit. - i18n: ~30 dezernat.* + onboarding.dezernat + admin.team.col.dezernat + admin.card.departments + team.* keys removed; ~30 partner_unit.* keys added in DE+EN. "Partner Unit" / "Partner Units" used as a loanword in DE. - /api/departments?include=members → /api/partner-units?include=members in team.ts (the only frontend-side fetch URL referencing the old endpoints). go build / vet / test clean. cd frontend && bun run build clean.
132 lines
6.4 KiB
TypeScript
132 lines
6.4 KiB
TypeScript
import { h } from "./jsx";
|
|
import { Sidebar } from "./components/Sidebar";
|
|
import { BottomNav } from "./components/BottomNav";
|
|
import { Footer } from "./components/Footer";
|
|
import { PWAHead } from "./components/PWAHead";
|
|
|
|
export function renderAdminPartnerUnits(): string {
|
|
return "<!DOCTYPE html>" + (
|
|
<html lang="de">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
|
<meta name="theme-color" content="#BFF355" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<PWAHead />
|
|
<title data-i18n="admin.partner_units.title">Partner Units — Paliad</title>
|
|
<link rel="stylesheet" href="/assets/global.css" />
|
|
</head>
|
|
<body className="has-sidebar">
|
|
<Sidebar currentPath="/admin/partner-units" />
|
|
<BottomNav currentPath="/admin/partner-units" />
|
|
|
|
<main>
|
|
<section className="tool-page">
|
|
<div className="container">
|
|
<div className="tool-header">
|
|
<div>
|
|
<h1 data-i18n="admin.partner_units.heading">Partner Units</h1>
|
|
<p className="tool-subtitle" data-i18n="admin.partner_units.subtitle">
|
|
Strukturelle Partnereinheiten verwalten und Mitglieder zuordnen.
|
|
</p>
|
|
</div>
|
|
<div className="admin-team-actions">
|
|
<button className="btn-primary" id="pu-new-btn" type="button" data-i18n="admin.partner_units.new">
|
|
Neue Partner Unit
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="pu-feedback" className="form-msg" style="display:none" />
|
|
|
|
<div className="akten-table-wrap admin-team-table-wrap">
|
|
<table className="akten-table admin-team-table">
|
|
<thead>
|
|
<tr>
|
|
<th data-i18n="admin.partner_units.col.name">Name</th>
|
|
<th data-i18n="admin.partner_units.col.office">Büro</th>
|
|
<th data-i18n="admin.partner_units.col.lead">Lead</th>
|
|
<th data-i18n="admin.partner_units.col.members">Mitglieder</th>
|
|
<th data-i18n="admin.partner_units.col.actions">Aktionen</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody id="pu-tbody">
|
|
<tr><td colspan={5} className="admin-team-loading" data-i18n="admin.partner_units.loading">Lade...</td></tr>
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
<div className="akten-empty" id="pu-empty" style="display:none">
|
|
<p data-i18n="admin.partner_units.empty">Noch keine Partner Units angelegt.</p>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
|
|
{/* Create / edit modal — same shape for both, "id" is empty when
|
|
creating. Office select is populated from /api/offices at init,
|
|
lead picker from /api/users (filtered to display_name+email). */}
|
|
<div className="modal-overlay" id="pu-edit-modal" style="display:none">
|
|
<div className="modal-card">
|
|
<div className="modal-header">
|
|
<h2 id="pu-edit-title" data-i18n="admin.partner_units.new.heading">Partner Unit anlegen</h2>
|
|
<button className="modal-close" id="pu-edit-close" type="button" aria-label="Close">×</button>
|
|
</div>
|
|
<form id="pu-edit-form" className="akten-form" autocomplete="off">
|
|
<input type="hidden" id="pu-edit-id" />
|
|
<div className="form-field">
|
|
<label htmlFor="pu-edit-name" data-i18n="admin.partner_units.col.name">Name</label>
|
|
<input type="text" id="pu-edit-name" required />
|
|
</div>
|
|
<div className="form-field">
|
|
<label htmlFor="pu-edit-office" data-i18n="admin.partner_units.col.office">Büro</label>
|
|
<select id="pu-edit-office" required />
|
|
</div>
|
|
<div className="form-field">
|
|
<label htmlFor="pu-edit-lead" data-i18n="admin.partner_units.col.lead">Lead</label>
|
|
<select id="pu-edit-lead">
|
|
<option value="">—</option>
|
|
</select>
|
|
</div>
|
|
<p className="form-msg" id="pu-edit-msg" />
|
|
<div className="form-actions">
|
|
<button type="button" className="btn-cancel" id="pu-edit-cancel" data-i18n="admin.partner_units.cancel">Abbrechen</button>
|
|
<button type="submit" className="btn-primary btn-cta-lime" data-i18n="admin.partner_units.create">Speichern</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Member-management modal — opens from the row's "Verwalten" button. */}
|
|
<div className="modal-overlay" id="pu-members-modal" style="display:none">
|
|
<div className="modal-card">
|
|
<div className="modal-header">
|
|
<h2 id="pu-members-title">Mitglieder verwalten</h2>
|
|
<button className="modal-close" id="pu-members-close" type="button" aria-label="Close">×</button>
|
|
</div>
|
|
<div id="pu-members-body">
|
|
<ul className="partner-unit-member-list" id="pu-members-list" />
|
|
<form id="pu-add-form" autocomplete="off" className="akten-form">
|
|
<div className="form-field">
|
|
<label htmlFor="pu-add-input" data-i18n="admin.partner_units.member.add">Mitglied hinzufügen</label>
|
|
<input type="text" id="pu-add-input" data-i18n-placeholder="admin.partner_units.member.placeholder" placeholder="Name oder E-Mail" />
|
|
<input type="hidden" id="pu-add-user-id" />
|
|
<div className="akten-collab-suggestions" id="pu-add-suggestions" />
|
|
</div>
|
|
<p className="form-msg" id="pu-add-msg" />
|
|
<div className="form-actions">
|
|
<button type="submit" className="btn-primary btn-cta-lime btn-small" data-i18n="admin.partner_units.member.add_btn">Hinzufügen</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<Footer />
|
|
<script src="/assets/admin-partner-units.js"></script>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|