Updated reports components.

This commit is contained in:
Mike Cao 2025-03-26 21:54:23 -07:00
parent f5bc3dc6c2
commit 0f6cdf8b80
95 changed files with 580 additions and 698 deletions

View file

@ -0,0 +1,15 @@
import { Row, Column, Text } from '@umami/react-zen';
export function ActionForm({ label, description, children }) {
return (
<Row padding="6" border borderRadius="3" justifyContent="space-between" shadow="2">
<Column>
<Text weight="bold">{label}</Text>
<Text>{description}</Text>
</Column>
<Row gap="3" alignItems="center">
{children}
</Row>
</Row>
);
}

View file

@ -0,0 +1,23 @@
import { Grid } from '@umami/react-zen';
const LAYOUTS = {
one: { columns: '1fr' },
two: { columns: { xs: '1fr', sm: '1fr', md: '1fr 1fr', lg: '1fr 1fr' } },
three: { columns: { xs: '1fr', sm: '1fr', md: '1fr 1fr 1fr', lg: '1fr 2fr' } },
'one-two': { columns: { xs: '1fr', sm: '1fr', md: '1fr 2fr', lg: '1fr 2fr' } },
'two-one': { columns: { xs: '1fr', sm: '1fr', md: '2fr 1fr', lg: '2fr 1fr', xl: '2fr 1fr' } },
};
export function GridRow(props: {
[x: string]: any;
layout?: 'one' | 'two' | 'three' | 'one-two' | 'two-one' | 'compare';
className?: string;
children?: any;
}) {
const { layout = 'two', children, ...otherProps } = props;
return (
<Grid gap="3" {...LAYOUTS[layout]} {...otherProps}>
{children}
</Grid>
);
}

View file

@ -0,0 +1,10 @@
.page {
flex: 1;
display: flex;
flex-direction: column;
position: relative;
width: 100%;
max-width: 1320px;
margin: 0 auto;
padding: 0 20px;
}

View file

@ -0,0 +1,32 @@
'use client';
import { ReactNode } from 'react';
import { AlertBanner, Loading, Column } from '@umami/react-zen';
import { useMessages } from '@/components/hooks';
export function Page({
error,
isLoading,
children,
...props
}: {
className?: string;
error?: unknown;
isLoading?: boolean;
children?: ReactNode;
}) {
const { formatMessage, messages } = useMessages();
if (error) {
return <AlertBanner title={formatMessage(messages.error)} variant="error" />;
}
if (isLoading) {
return <Loading position="page" />;
}
return (
<Column {...props} width="100%" maxWidth="1320px" margin="auto" paddingBottom="9">
{children}
</Column>
);
}

View file

@ -0,0 +1,48 @@
.header {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
align-content: center;
align-self: stretch;
flex-wrap: wrap;
height: 100px;
}
.header a {
color: var(--base600);
}
.header a:hover {
color: var(--base900);
}
.title {
display: flex;
align-items: center;
font-size: 24px;
font-weight: 700;
gap: 20px;
height: 60px;
flex: 1;
}
.breadcrumb {
padding-top: 20px;
}
.icon {
color: var(--base700);
margin-inline-end: 1rem;
}
.actions {
display: flex;
justify-content: flex-end;
}
@media only screen and (max-width: 992px) {
.header {
margin-bottom: 10px;
}
}

View file

@ -0,0 +1,27 @@
import { ReactNode } from 'react';
import { Heading, Icon, Row, Text } from '@umami/react-zen';
export function PageHeader({
title,
description,
icon,
children,
}: {
title: string;
description?: string;
icon?: ReactNode;
allowEdit?: boolean;
className?: string;
children?: ReactNode;
}) {
return (
<Row justifyContent="space-between" alignItems="center" marginY="6">
<Row gap="3">
{icon && <Icon size="lg">{icon}</Icon>}
{title && <Heading size="2">{title}</Heading>}
{description && <Text color="muted">{description}</Text>}
</Row>
<Row justifyContent="flex-end">{children}</Row>
</Row>
);
}

View file

@ -0,0 +1,6 @@
import { Box } from '@umami/react-zen';
import type { BoxProps } from '@umami/react-zen/Box';
export function Panel(props: BoxProps) {
return <Box padding="6" border borderRadius="3" backgroundColor="solid" shadow="4" {...props} />;
}

View file

@ -0,0 +1,20 @@
import { Text, List, ListItem } from '@umami/react-zen';
export interface MenuNavProps {
items: any[];
selectedKey?: string;
}
export function SideBar({ items, selectedKey }: MenuNavProps) {
return (
<List>
{items.map(({ key, label, url }) => {
return (
<ListItem key={key} href={url}>
<Text weight={key === selectedKey ? 'bold' : 'regular'}>{label}</Text>
</ListItem>
);
})}
</List>
);
}