diff --git a/src/components/dashboard/budget-column.tsx b/src/components/dashboard/budget-column.tsx index d0c8b92..e7e6de1 100644 --- a/src/components/dashboard/budget-column.tsx +++ b/src/components/dashboard/budget-column.tsx @@ -271,6 +271,31 @@ export function BudgetColumn({ const selectedBudget = group.budgets.find((budget) => budget.id === selectedBudgetId) ?? group.budgets[0] ?? null; const visibleBudgets = isCompactLayout && selectedBudget ? [selectedBudget] : group.budgets; + const mobilePrimarySelectSx = { + width: "100%", + "& .MuiOutlinedInput-root": { + minHeight: 64, + borderRadius: "28px", + backgroundColor: alpha(theme.palette.background.paper, isDark ? 0.72 : 0.96), + "& fieldset": { + borderColor: alpha(theme.palette.primary.main, isDark ? 0.54 : 0.38) + }, + "&:hover fieldset": { + borderColor: alpha(theme.palette.primary.main, 0.72) + }, + "&.Mui-focused fieldset": { + borderWidth: 2, + borderColor: theme.palette.primary.main + } + }, + "& .MuiInputLabel-root": { + color: theme.palette.text.secondary + }, + "& .MuiInputBase-input": { + fontSize: "1.08rem", + fontWeight: 600 + } + } as const; return ( setSelectedBudgetId(event.target.value)} fullWidth + sx={mobilePrimarySelectSx} > {group.budgets.map((budget) => ( diff --git a/src/components/dashboard/dashboard-shell.tsx b/src/components/dashboard/dashboard-shell.tsx index 2eb723d..aca0b84 100644 --- a/src/components/dashboard/dashboard-shell.tsx +++ b/src/components/dashboard/dashboard-shell.tsx @@ -175,6 +175,17 @@ function sortManagedUsersList(users: DashboardManagedUser[]) { type MobileSection = "overview" | "actions"; +type MobileAction = + | "expense" + | "budgetRelease" + | "workingGroup" + | "budget" + | "periods" + | "backup" + | "userCreate" + | "approvalThreshold" + | "users" + | "logs"; type DesktopSection = "overview" | "budgetGroups" | "periods" | "users" | "logs"; const currencyFormatter = new Intl.NumberFormat("de-DE", { style: "currency", @@ -300,6 +311,26 @@ export function DashboardShell({ ...(canManageAccounts ? [{ value: "users" as const, label: "Nutzerverwaltung" }] : []), ...(canManageAccounts ? [{ value: "logs" as const, label: "Backup & Log" }] : []) ]; + const mobileActions = [ + { value: "expense" as const, label: "Neue Ausgabe" }, + ...(canManagePeriods ? [{ value: "budgetRelease" as const, label: "Bereits an AG übergeben" }] : []), + ...(canManageBudgets(viewer.role) + ? [ + { value: "workingGroup" as const, label: "AG anlegen" }, + { value: "budget" as const, label: "Budget anlegen" } + ] + : []), + ...(canManagePeriods ? [{ value: "periods" as const, label: "Zeitraum" }] : []), + ...(canManageAccounts + ? [ + { value: "backup" as const, label: "CSV-Backup" }, + { value: "userCreate" as const, label: "Nutzer anlegen" }, + { value: "approvalThreshold" as const, label: "Freigabe-Schwelle" }, + { value: "users" as const, label: "Nutzer verwalten" }, + { value: "logs" as const, label: "Änderungsverlauf" } + ] + : []) + ]; const showDesktopSectionTabs = !isCompactLayout && desktopSections.length > 1; const defaultEditableGroup = @@ -340,6 +371,7 @@ export function DashboardShell({ const [message, setMessage] = useState(null); const [busy, setBusy] = useState(false); const [mobileSection, setMobileSection] = useState("overview"); + const [selectedMobileAction, setSelectedMobileAction] = useState("expense"); const [desktopSection, setDesktopSection] = useState("overview"); const [selectedCurrentPeriodId, setSelectedCurrentPeriodId] = useState(currentPeriodId); const [selectedMobileGroupId, setSelectedMobileGroupId] = useState(visibleGroups[0]?.id ?? ""); @@ -377,6 +409,12 @@ export function DashboardShell({ } }, [desktopSection, desktopSections]); + useEffect(() => { + if (!mobileActions.some((action) => action.value === selectedMobileAction)) { + setSelectedMobileAction(mobileActions[0]?.value ?? "expense"); + } + }, [mobileActions, selectedMobileAction]); + useEffect(() => { const directGroupId = searchParams.get("group"); const budgetId = searchParams.get("budget"); @@ -1450,6 +1488,32 @@ export function DashboardShell({ overflow: "hidden" }; + const mobilePrimarySelectSx = { + width: "100%", + "& .MuiOutlinedInput-root": { + minHeight: 64, + borderRadius: "28px", + backgroundColor: alpha(theme.palette.background.paper, isDark ? 0.72 : 0.96), + "& fieldset": { + borderColor: alpha(theme.palette.primary.main, isDark ? 0.54 : 0.38) + }, + "&:hover fieldset": { + borderColor: alpha(theme.palette.primary.main, 0.72) + }, + "&.Mui-focused fieldset": { + borderWidth: 2, + borderColor: theme.palette.primary.main + } + }, + "& .MuiInputLabel-root": { + color: theme.palette.text.secondary + }, + "& .MuiInputBase-input": { + fontSize: "1.08rem", + fontWeight: 600 + } + } as const; + const periodManagementPanel = canManagePeriods ? ( @@ -1655,7 +1719,24 @@ export function DashboardShell({ : null) }} > - {isCompactLayout || desktopSection === "overview" ? ( + {isCompactLayout ? ( + setSelectedMobileAction(event.target.value as MobileAction)} + fullWidth + sx={mobilePrimarySelectSx} + > + {mobileActions.map((action) => ( + + {action.label} + + ))} + + ) : null} + + {(isCompactLayout ? selectedMobileAction === "expense" : desktopSection === "overview") ? ( @@ -1777,7 +1858,7 @@ export function DashboardShell({ ) : null} - {canManagePeriods && (isCompactLayout || desktopSection === "overview") ? ( + {canManagePeriods && (isCompactLayout ? selectedMobileAction === "budgetRelease" : desktopSection === "overview") ? ( @@ -1869,7 +1950,7 @@ export function DashboardShell({ ) : null} - {canManageBudgets(viewer.role) && (isCompactLayout || desktopSection === "budgetGroups") ? ( + {canManageBudgets(viewer.role) && (isCompactLayout ? selectedMobileAction === "workingGroup" : desktopSection === "budgetGroups") ? ( @@ -1902,7 +1983,7 @@ export function DashboardShell({ ) : null} - {canManageBudgets(viewer.role) && (isCompactLayout || desktopSection === "budgetGroups") ? ( + {canManageBudgets(viewer.role) && (isCompactLayout ? selectedMobileAction === "budget" : desktopSection === "budgetGroups") ? ( @@ -1983,13 +2064,13 @@ export function DashboardShell({ ) : null} - {canManagePeriods && isCompactLayout ? ( + {canManagePeriods && isCompactLayout && selectedMobileAction === "periods" ? ( {periodManagementPanel} ) : null} - {canManageAccounts && (isCompactLayout || desktopSection === "logs") ? ( + {canManageAccounts && (isCompactLayout ? selectedMobileAction === "backup" : desktopSection === "logs") ? ( @@ -2038,8 +2119,12 @@ export function DashboardShell({ ) : null} - {canManageAccounts && (isCompactLayout || desktopSection === "users") ? ( + {canManageAccounts && + (isCompactLayout + ? selectedMobileAction === "userCreate" || selectedMobileAction === "approvalThreshold" + : desktopSection === "users") ? ( + {!isCompactLayout || selectedMobileAction === "userCreate" ? ( @@ -2141,7 +2226,9 @@ export function DashboardShell({ + ) : null} + {!isCompactLayout || selectedMobileAction === "approvalThreshold" ? ( @@ -2168,9 +2255,10 @@ export function DashboardShell({ + ) : null} ) : null} - {canManageAccounts && (isCompactLayout || desktopSection === "users") ? ( + {canManageAccounts && (isCompactLayout ? selectedMobileAction === "users" : desktopSection === "users") ? ( @@ -2412,7 +2500,7 @@ export function DashboardShell({ ) : null} - {canManageAccounts && (isCompactLayout || desktopSection === "logs") ? ( + {canManageAccounts && (isCompactLayout ? selectedMobileAction === "logs" : desktopSection === "logs") ? ( @@ -2532,6 +2620,7 @@ export function DashboardShell({ setFocusedBudgetId(null); }} fullWidth + sx={mobilePrimarySelectSx} > {visibleGroups.map((group) => (