fix(ui): align page layouts and add navigation icons

This commit is contained in:
2026-09-11 08:52:40 +03:00
parent 232d7f9990
commit d7e8963d1c
12 changed files with 61 additions and 22 deletions
+4 -4
View File
@@ -27,7 +27,7 @@ const AppBreadcrumbs: FC = () => {
return <StockBreadcrumbs identifier={stock.params.stockId ?? ""} />; return <StockBreadcrumbs identifier={stock.params.stockId ?? ""} />;
if (operations) if (operations)
return ( return (
<Stack gap="sm" mb="lg"> <Stack gap={0} mb="md">
<AccountBreadcrumbs <AccountBreadcrumbs
accountId={operations.params.accountId ?? ""} accountId={operations.params.accountId ?? ""}
section="operations" section="operations"
@@ -40,7 +40,7 @@ const AppBreadcrumbs: FC = () => {
); );
if (events) if (events)
return ( return (
<Stack gap="sm" mb="lg"> <Stack gap={0} mb="md">
<AccountBreadcrumbs <AccountBreadcrumbs
accountId={events.params.accountId ?? ""} accountId={events.params.accountId ?? ""}
section="events" section="events"
@@ -53,7 +53,7 @@ const AppBreadcrumbs: FC = () => {
); );
if (income) if (income)
return ( return (
<Stack gap="sm" mb="lg"> <Stack gap={0} mb="md">
<AccountBreadcrumbs <AccountBreadcrumbs
accountId={income.params.accountId ?? ""} accountId={income.params.accountId ?? ""}
section="income" section="income"
@@ -66,7 +66,7 @@ const AppBreadcrumbs: FC = () => {
); );
if (account) if (account)
return ( return (
<Stack gap="sm" mb="lg"> <Stack gap={0} mb="md">
<AccountBreadcrumbs accountId={account.params.accountId ?? ""} /> <AccountBreadcrumbs accountId={account.params.accountId ?? ""} />
<AccountScopeSwitch accountId={account.params.accountId ?? ""} /> <AccountScopeSwitch accountId={account.params.accountId ?? ""} />
</Stack> </Stack>
@@ -7,7 +7,7 @@ import type { EventsRefreshState } from "../AccountEventsPage.vm";
const AccountEventsPageEmpty: FC<EventsRefreshState> = (props) => { const AccountEventsPageEmpty: FC<EventsRefreshState> = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack maw={960} gap="lg"> <Stack gap="lg">
<Title order={1}>{t("events.title")}</Title> <Title order={1}>{t("events.title")}</Title>
{props.refreshing ? ( {props.refreshing ? (
<Progress value={100} animated aria-label={t("accounts.refreshing")} /> <Progress value={100} animated aria-label={t("accounts.refreshing")} />
@@ -14,7 +14,7 @@ type AccountEventsPageLoadedProps = EventsRefreshState & {
const AccountEventsPageLoaded: FC<AccountEventsPageLoadedProps> = (props) => { const AccountEventsPageLoaded: FC<AccountEventsPageLoadedProps> = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack maw={960} gap="lg"> <Stack gap="lg">
<Title order={1}>{t("events.title")}</Title> <Title order={1}>{t("events.title")}</Title>
{props.refreshing ? ( {props.refreshing ? (
<Progress value={100} animated aria-label={t("accounts.refreshing")} /> <Progress value={100} animated aria-label={t("accounts.refreshing")} />
@@ -33,7 +33,7 @@ const AccountIncomePageLoaded: FC<LoadedProps> = (props) => {
} = props; } = props;
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack maw={960} gap="lg" className={classes.page}> <Stack gap="lg" className={classes.page}>
<Title order={1}>{t("income.title")}</Title> <Title order={1}>{t("income.title")}</Title>
<FormProvider {...form}> <FormProvider {...form}>
<IncomePeriodForm <IncomePeriodForm
@@ -8,7 +8,7 @@ const AccountIncomePageLoading: FC = () => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<LoadingSkeleton label={t("states.loadingTitle")}> <LoadingSkeleton label={t("states.loadingTitle")}>
<Stack maw={960} gap="lg"> <Stack gap="lg">
<Skeleton height={32} width="40%" /> <Skeleton height={32} width="40%" />
<Paper p="md" radius="md" withBorder> <Paper p="md" radius="md" withBorder>
<Stack gap="sm"> <Stack gap="sm">
@@ -73,7 +73,7 @@ const AccountOperationsPageLoaded: FC<AccountOperationsPageLoadedProps> = (
})); }));
return ( return (
<Stack maw={960} gap="lg"> <Stack gap="lg">
<Title order={1}>{t("ledger.title")}</Title> <Title order={1}>{t("ledger.title")}</Title>
{props.refreshing ? ( {props.refreshing ? (
<Progress value={100} animated aria-label={t("accounts.refreshing")} /> <Progress value={100} animated aria-label={t("accounts.refreshing")} />
@@ -1,7 +1,3 @@
.page {
max-width: 960px;
}
.tile, .tile,
.cash { .cash {
border-color: var(--mantine-color-gray-3); border-color: var(--mantine-color-gray-3);
@@ -36,7 +36,7 @@ type AccountPageLoadedProps = {
const AccountPageLoaded: FC<AccountPageLoadedProps> = (props) => { const AccountPageLoaded: FC<AccountPageLoadedProps> = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack className={classes.page} gap="lg"> <Stack gap="lg">
<AccountHeading account={props.account} accountId={props.accountId} /> <AccountHeading account={props.account} accountId={props.accountId} />
<PortfolioRefreshState <PortfolioRefreshState
refreshing={props.refreshing ?? false} refreshing={props.refreshing ?? false}
+1 -1
View File
@@ -30,7 +30,7 @@ const BondsPageView: FC<BondsPageViewProps> = (props) => {
const { vm } = props; const { vm } = props;
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack maw={860} mx="auto" gap="lg"> <Stack gap="lg">
<div> <div>
<Title order={1}>{t("bond.searchTitle")}</Title> <Title order={1}>{t("bond.searchTitle")}</Title>
<Text c="dimmed" mt="xs"> <Text c="dimmed" mt="xs">
+1 -1
View File
@@ -25,7 +25,7 @@ const StocksPageView: FC<StocksPageViewProps> = (props) => {
const { vm } = props; const { vm } = props;
const { t } = useTranslation(); const { t } = useTranslation();
return ( return (
<Stack maw={860} mx="auto" gap="lg"> <Stack gap="lg">
<div> <div>
<Title order={1}>{t("stock.searchTitle")}</Title> <Title order={1}>{t("stock.searchTitle")}</Title>
<Text c="dimmed" mt="xs"> <Text c="dimmed" mt="xs">
+5
View File
@@ -1,3 +1,8 @@
.content {
max-width: 1120px;
margin-inline: auto;
}
.header { .header {
align-items: center; align-items: center;
display: flex; display: flex;
+44 -6
View File
@@ -13,10 +13,30 @@ const AppShell: FC<AppShellProps> = (props) => {
const { t } = useTranslation(); const { t } = useTranslation();
const { pathname } = useLocation(); const { pathname } = useLocation();
const items = [ const items = [
{ to: "/accounts", label: t("navigation.accounts") }, {
{ to: "/stocks", label: t("navigation.stocks") }, to: "/accounts",
{ to: "/bonds", label: t("navigation.bonds") }, label: t("navigation.accounts"),
{ to: "/settings", label: t("navigation.settings") }, icon: (
<path d="M8 6V4h8v2M3 10h18M9 10v3h6v-3M5 6h14a2 2 0 0 1 2 2v11H3V8a2 2 0 0 1 2-2Z" />
),
},
{
to: "/stocks",
label: t("navigation.stocks"),
icon: <path d="M3 3v18h18M7 14l5-5 4 3 5-7M16 5h5v5" />,
},
{
to: "/bonds",
label: t("navigation.bonds"),
icon: <path d="M6 3h12v18l-3-2-3 2-3-2-3 2V3ZM9 7h6M9 11h6M9 15h3" />,
},
{
to: "/settings",
label: t("navigation.settings"),
icon: (
<path d="M4 7h9m4 0h3M4 17h3m4 0h9M13 4v6h4V4h-4ZM7 14v6h4v-6H7Z" />
),
},
]; ];
return ( return (
@@ -35,13 +55,31 @@ const AppShell: FC<AppShellProps> = (props) => {
key={item.to} key={item.to}
to={item.to} to={item.to}
label={item.label} label={item.label}
leftSection={
<svg
width={20}
height={20}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
aria-hidden="true"
focusable="false"
>
{item.icon}
</svg>
}
active={pathname.startsWith(item.to)} active={pathname.startsWith(item.to)}
/> />
))} ))}
</MantineAppShell.Navbar> </MantineAppShell.Navbar>
<MantineAppShell.Main className={classes.main}> <MantineAppShell.Main className={classes.main}>
{contentAboveOutlet} <div className={classes.content}>
<Outlet /> {contentAboveOutlet}
<Outlet />
</div>
</MantineAppShell.Main> </MantineAppShell.Main>
<nav className={classes.bottomNav} aria-label={t("appName")}> <nav className={classes.bottomNav} aria-label={t("appName")}>
{items.map((item) => ( {items.map((item) => (