Mobile Dropdowns und Aktionen vereinheitlichen
All checks were successful
CI / Build and Deploy (push) Successful in 2m17s
All checks were successful
CI / Build and Deploy (push) Successful in 2m17s
This commit is contained in:
@@ -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 (
|
||||
<Card
|
||||
@@ -441,6 +466,7 @@ export function BudgetColumn({
|
||||
value={selectedBudget?.id ?? ""}
|
||||
onChange={(event) => setSelectedBudgetId(event.target.value)}
|
||||
fullWidth
|
||||
sx={mobilePrimarySelectSx}
|
||||
>
|
||||
{group.budgets.map((budget) => (
|
||||
<MenuItem key={budget.id} value={budget.id}>
|
||||
|
||||
@@ -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<DashboardMessage | null>(null);
|
||||
const [busy, setBusy] = useState(false);
|
||||
const [mobileSection, setMobileSection] = useState<MobileSection>("overview");
|
||||
const [selectedMobileAction, setSelectedMobileAction] = useState<MobileAction>("expense");
|
||||
const [desktopSection, setDesktopSection] = useState<DesktopSection>("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 ? (
|
||||
<Stack spacing={2}>
|
||||
<Box>
|
||||
@@ -1655,7 +1719,24 @@ export function DashboardShell({
|
||||
: null)
|
||||
}}
|
||||
>
|
||||
{isCompactLayout || desktopSection === "overview" ? (
|
||||
{isCompactLayout ? (
|
||||
<TextField
|
||||
select
|
||||
label="Aktion auswählen"
|
||||
value={selectedMobileAction}
|
||||
onChange={(event) => setSelectedMobileAction(event.target.value as MobileAction)}
|
||||
fullWidth
|
||||
sx={mobilePrimarySelectSx}
|
||||
>
|
||||
{mobileActions.map((action) => (
|
||||
<MenuItem key={action.value} value={action.value}>
|
||||
{action.label}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
) : null}
|
||||
|
||||
{(isCompactLayout ? selectedMobileAction === "expense" : desktopSection === "overview") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2.5}>
|
||||
@@ -1777,7 +1858,7 @@ export function DashboardShell({
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{canManagePeriods && (isCompactLayout || desktopSection === "overview") ? (
|
||||
{canManagePeriods && (isCompactLayout ? selectedMobileAction === "budgetRelease" : desktopSection === "overview") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2.5}>
|
||||
@@ -1869,7 +1950,7 @@ export function DashboardShell({
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{canManageBudgets(viewer.role) && (isCompactLayout || desktopSection === "budgetGroups") ? (
|
||||
{canManageBudgets(viewer.role) && (isCompactLayout ? selectedMobileAction === "workingGroup" : desktopSection === "budgetGroups") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2.5}>
|
||||
@@ -1902,7 +1983,7 @@ export function DashboardShell({
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{canManageBudgets(viewer.role) && (isCompactLayout || desktopSection === "budgetGroups") ? (
|
||||
{canManageBudgets(viewer.role) && (isCompactLayout ? selectedMobileAction === "budget" : desktopSection === "budgetGroups") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2.5}>
|
||||
@@ -1983,13 +2064,13 @@ export function DashboardShell({
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{canManagePeriods && isCompactLayout ? (
|
||||
{canManagePeriods && isCompactLayout && selectedMobileAction === "periods" ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>{periodManagementPanel}</CardContent>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{canManageAccounts && (isCompactLayout || desktopSection === "logs") ? (
|
||||
{canManageAccounts && (isCompactLayout ? selectedMobileAction === "backup" : desktopSection === "logs") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2}>
|
||||
@@ -2038,8 +2119,12 @@ export function DashboardShell({
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{canManageAccounts && (isCompactLayout || desktopSection === "users") ? (
|
||||
{canManageAccounts &&
|
||||
(isCompactLayout
|
||||
? selectedMobileAction === "userCreate" || selectedMobileAction === "approvalThreshold"
|
||||
: desktopSection === "users") ? (
|
||||
<Stack spacing={3}>
|
||||
{!isCompactLayout || selectedMobileAction === "userCreate" ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2.5}>
|
||||
@@ -2141,7 +2226,9 @@ export function DashboardShell({
|
||||
</Stack>
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : null}
|
||||
|
||||
{!isCompactLayout || selectedMobileAction === "approvalThreshold" ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2}>
|
||||
@@ -2168,9 +2255,10 @@ export function DashboardShell({
|
||||
</Stack>
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : null}
|
||||
</Stack>
|
||||
) : null}
|
||||
{canManageAccounts && (isCompactLayout || desktopSection === "users") ? (
|
||||
{canManageAccounts && (isCompactLayout ? selectedMobileAction === "users" : desktopSection === "users") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2}>
|
||||
@@ -2412,7 +2500,7 @@ export function DashboardShell({
|
||||
</CardContent>
|
||||
</Card>
|
||||
) : null}
|
||||
{canManageAccounts && (isCompactLayout || desktopSection === "logs") ? (
|
||||
{canManageAccounts && (isCompactLayout ? selectedMobileAction === "logs" : desktopSection === "logs") ? (
|
||||
<Card sx={islandCardSx}>
|
||||
<CardContent sx={{ p: 3 }}>
|
||||
<Stack spacing={2}>
|
||||
@@ -2532,6 +2620,7 @@ export function DashboardShell({
|
||||
setFocusedBudgetId(null);
|
||||
}}
|
||||
fullWidth
|
||||
sx={mobilePrimarySelectSx}
|
||||
>
|
||||
{visibleGroups.map((group) => (
|
||||
<MenuItem key={group.id} value={group.id}>
|
||||
|
||||
Reference in New Issue
Block a user