fix: five dashboard improvements across booking, vehicles, profile, and UI
- fix(auth): guard extractNames() against Authentik sending full name in given_name field (e.g. "Matthias Hochmeister" + family_name "Hochmeister"); detect by checking given_name ends with family_name suffix, fall through to name-splitting so Vorname/Nachname display correctly in Profile - fix(db): add migration 018 to repair broken BEFORE UPDATE triggers on veranstaltungen and veranstaltung_kategorien; old triggers called update_updated_at_column() which references NEW.updated_at, but both tables use aktualisiert_am, causing every category/event edit to fail - feat(booking): open vehicle booking creation to all authenticated users; only dashboard_admin / dashboard_moderator can change the Buchungsart (type select disabled for regular members); edit and cancel still restricted to WRITE_GROUPS - feat(vehicles): VehicleDashboardCard now fetches equipment warnings via equipmentApi.getVehicleWarnings() in parallel and shows an alert when any vehicle equipment is not einsatzbereit - fix(ui): add MuiTextField defaultProps (InputLabelProps.shrink=true) and MuiOutlinedInput notch legend font-size override to theme to eliminate floating-label / border conflict on click Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,6 +81,7 @@ const EMPTY_FORM: CreateBuchungInput = {
|
||||
};
|
||||
|
||||
const WRITE_GROUPS = ['dashboard_admin', 'dashboard_fahrmeister', 'dashboard_moderator'];
|
||||
const MANAGE_ART_GROUPS = ['dashboard_admin', 'dashboard_moderator'];
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Main Page
|
||||
@@ -89,8 +90,11 @@ const WRITE_GROUPS = ['dashboard_admin', 'dashboard_fahrmeister', 'dashboard_mod
|
||||
function FahrzeugBuchungen() {
|
||||
const { user } = useAuth();
|
||||
const notification = useNotification();
|
||||
const canCreate = !!user; // All authenticated users can create bookings
|
||||
const canWrite =
|
||||
user?.groups?.some((g) => WRITE_GROUPS.includes(g)) ?? false;
|
||||
user?.groups?.some((g) => WRITE_GROUPS.includes(g)) ?? false; // Can edit/cancel
|
||||
const canChangeBuchungsArt =
|
||||
user?.groups?.some((g) => MANAGE_ART_GROUPS.includes(g)) ?? false; // Can change booking type
|
||||
|
||||
// ── Week navigation ────────────────────────────────────────────────────────
|
||||
const [currentWeekStart, setCurrentWeekStart] = useState<Date>(() =>
|
||||
@@ -194,7 +198,7 @@ function FahrzeugBuchungen() {
|
||||
};
|
||||
|
||||
const handleCellClick = (vehicleId: string, day: Date) => {
|
||||
if (!canWrite) return;
|
||||
if (!canCreate) return;
|
||||
const dateStr = format(day, "yyyy-MM-dd'T'08:00");
|
||||
const dateEndStr = format(day, "yyyy-MM-dd'T'17:00");
|
||||
setEditingBooking(null);
|
||||
@@ -339,7 +343,7 @@ function FahrzeugBuchungen() {
|
||||
>
|
||||
Kalender
|
||||
</Button>
|
||||
{canWrite && (
|
||||
{canCreate && (
|
||||
<Button
|
||||
startIcon={<Add />}
|
||||
onClick={openCreateDialog}
|
||||
@@ -442,8 +446,8 @@ function FahrzeugBuchungen() {
|
||||
}
|
||||
sx={{
|
||||
bgcolor: isFree ? 'success.50' : undefined,
|
||||
cursor: isFree && canWrite ? 'pointer' : 'default',
|
||||
'&:hover': isFree && canWrite
|
||||
cursor: isFree && canCreate ? 'pointer' : 'default',
|
||||
'&:hover': isFree && canCreate
|
||||
? { bgcolor: 'success.100' }
|
||||
: {},
|
||||
p: 0.5,
|
||||
@@ -534,7 +538,7 @@ function FahrzeugBuchungen() {
|
||||
)}
|
||||
|
||||
{/* ── FAB ── */}
|
||||
{canWrite && (
|
||||
{canCreate && (
|
||||
<Fab
|
||||
color="primary"
|
||||
aria-label="Buchung erstellen"
|
||||
@@ -706,6 +710,7 @@ function FahrzeugBuchungen() {
|
||||
<InputLabel>Buchungsart</InputLabel>
|
||||
<Select
|
||||
value={form.buchungsArt}
|
||||
disabled={!canChangeBuchungsArt}
|
||||
onChange={(e) =>
|
||||
setForm((f) => ({
|
||||
...f,
|
||||
|
||||
Reference in New Issue
Block a user