Files
MoneyMgr/moneymgr_web/src/routes/AccountsRoute.tsx
2025-04-14 23:25:45 +02:00

206 lines
5.5 KiB
TypeScript

import AddIcon from "@mui/icons-material/Add";
import RefreshIcon from "@mui/icons-material/Refresh";
import { IconButton, Tooltip } from "@mui/material";
import { DataGrid, GridActionsCellItem, GridColDef } from "@mui/x-data-grid";
import { Account, AccountApi } from "../api/AccountApi";
import { useAccounts } from "../hooks/AccountsListProvider";
import { useAlert } from "../hooks/context_providers/AlertDialogProvider";
import { useSnackbar } from "../hooks/context_providers/SnackbarProvider";
import { MoneyMgrWebRouteContainer } from "../widgets/MoneyMgrWebRouteContainer";
import { TimeWidget } from "../widgets/TimeWidget";
import DeleteIcon from "@mui/icons-material/DeleteOutlined";
import { useConfirm } from "../hooks/context_providers/ConfirmDialogProvider";
import { AccountWidget } from "../widgets/AccountWidget";
import { ServerApi } from "../api/ServerApi";
export function AccountsRoute(): React.ReactElement {
const alert = useAlert();
const confirm = useConfirm();
const snackbar = useSnackbar();
const accounts = useAccounts();
const list = accounts.list.list;
const createAccount = async () => {
try {
await AccountApi.Create(`New account #${list.length + 1}`);
snackbar("New account successfully created!");
await accounts.reload();
} catch (e) {
console.error("Failed to create new account!", e);
alert(`Failed to create new account! ${e}`);
}
};
const setDefaultAccount = async (account: Account) => {
try {
await AccountApi.SetDefaultAccount(account);
snackbar("Default account successfully updated!");
await accounts.reload();
return accounts.get(account.id);
} catch (e) {
console.error("Failed to change default account!", e);
alert(`Failed to change default account! ${e}`);
return account;
}
};
const updateAccount = async (account: Account) => {
try {
await AccountApi.Update(account);
snackbar("Account successfully updated!");
await accounts.reload();
return accounts.get(account.id);
} catch (e) {
console.error("Failed to update account!", e);
alert(`Failed to update account! ${e}`);
return account;
}
};
const deleteAccount = async (account: Account) => {
try {
if (
!(await confirm(
`Do you really want to delete account ${account.name}?`,
"Delete account"
))
)
return;
await AccountApi.Delete(account);
snackbar("Account successfully deleted!");
await accounts.reload();
} catch (e) {
console.error(`Failed to delete account!`, e);
alert(`Failed to delete account! ${e}`);
}
};
const columns: GridColDef<(typeof list)[number]>[] = [
{ field: "id", headerName: "ID", flex: 1 },
{
field: "type",
headerName: "Type",
flex: 2,
editable: true,
type: "singleSelect",
valueOptions: ServerApi.Config.accounts_types.map((v) => {
return { label: v.label, value: v.code };
}),
renderCell(params) {
return (
<span
style={{
display: "flex",
flexDirection: "row",
justifyContent: "start",
alignItems: "center",
}}
>
<AccountWidget account={params.row} />
{
ServerApi.Config.accounts_types.find(
(t) => t.code === params.row.type
)!.label
}
</span>
);
},
},
{ field: "name", headerName: "Name", flex: 6, editable: true },
{
field: "time_create",
headerName: "Time created",
flex: 2,
renderCell(params) {
return <TimeWidget time={params.row.time_create} />;
},
},
{
field: "time_update",
headerName: "Time updated",
flex: 2,
renderCell(params) {
return <TimeWidget time={params.row.time_update} />;
},
},
{
field: "default_account",
headerName: "Default",
flex: 1,
type: "boolean",
editable: true,
},
{
field: "actions",
type: "actions",
headerName: "",
flex: 1,
cellClassName: "actions",
getActions: ({ row }) => {
return [
<GridActionsCellItem
key={row.id}
icon={<DeleteIcon />}
label="Delete account"
onClick={() => deleteAccount(row)}
color="inherit"
/>,
];
},
},
];
return (
<MoneyMgrWebRouteContainer
label="Accounts"
actions={
<span>
<Tooltip title="Create a new account">
<IconButton onClick={createAccount}>
<AddIcon />
</IconButton>
</Tooltip>
<Tooltip title="Refresh accounts list">
<IconButton onClick={() => accounts.reload()}>
<RefreshIcon />
</IconButton>
</Tooltip>
</span>
}
>
<DataGrid<Account>
rows={list}
columns={columns}
disableRowSelectionOnClick
processRowUpdate={(updated, original) => {
if (updated.default_account && !original.default_account) {
return setDefaultAccount(updated);
}
if (
updated.name !== original.name ||
updated.type !== original.type
) {
return updateAccount(updated);
}
return original as any;
}}
/>
</MoneyMgrWebRouteContainer>
);
}