Zen components conversion.

This commit is contained in:
Mike Cao 2025-03-07 03:11:58 -08:00
parent aac1a12e51
commit 5999bf6256
142 changed files with 1235 additions and 1454 deletions

View file

@ -1,5 +1,15 @@
import { useState } from 'react';
import { Icon, Modal, Dropdown, Item, Text, Flexbox } from 'react-basics';
import { useState, Key } from 'react';
import {
Icon,
Modal,
Select,
Text,
Block,
Row,
ListItem,
ListSeparator,
Dialog,
} from '@umami/react-zen';
import { endOfYear, isSameDay } from 'date-fns';
import { DatePickerForm } from '@/components/metrics/DatePickerForm';
import { useLocale, useMessages } from '@/components/hooks';
@ -39,19 +49,19 @@ export function DateFilter({
label: formatMessage(labels.lastHours, { x: 24 }),
value: '24hour',
},
{ divider: true },
{
label: formatMessage(labels.thisWeek),
value: '0week',
divider: true,
},
{
label: formatMessage(labels.lastDays, { x: 7 }),
value: '7day',
},
{ divider: true },
{
label: formatMessage(labels.thisMonth),
value: '0month',
divider: true,
},
{
label: formatMessage(labels.lastDays, { x: 30 }),
@ -61,7 +71,8 @@ export function DateFilter({
label: formatMessage(labels.lastDays, { x: 90 }),
value: '90day',
},
{ label: formatMessage(labels.thisYear), value: '0year', divider: true },
{ divider: true },
{ label: formatMessage(labels.thisYear), value: '0year' },
{
label: formatMessage(labels.lastMonths, { x: 6 }),
value: '6month',
@ -70,29 +81,31 @@ export function DateFilter({
label: formatMessage(labels.lastMonths, { x: 12 }),
value: '12month',
},
{ divider: true },
showAllTime && {
label: formatMessage(labels.allTime),
value: 'all',
divider: true,
},
{ divider: true },
{
label: formatMessage(labels.customRange),
value: 'custom',
divider: true,
},
].filter(n => n);
]
.filter(n => n)
.map((a, id) => ({ ...a, id }));
const handleChange = (value: string) => {
const handleChange = (value: Key) => {
if (value === 'custom') {
setShowPicker(true);
return;
}
onChange(value);
onChange(value.toString());
};
const handlePickerChange = (value: string) => {
setShowPicker(false);
onChange(value);
onChange(value.toString());
};
const handleClose = () => setShowPicker(false);
@ -122,33 +135,37 @@ export function DateFilter({
return options.find(e => e.value === value)?.label;
};
console.log({ showPicker });
return (
<>
<Dropdown
<Select
className={classNames(className, styles.dropdown)}
items={options}
renderValue={renderValue}
value={value}
alignment={alignment}
placeholder={formatMessage(labels.selectDate)}
onChange={key => handleChange(key as any)}
onSelectionChange={handleChange}
>
{({ label, value, divider }) => (
<Item key={value} divider={divider}>
{label}
</Item>
)}
</Dropdown>
{({ label, value, divider }: any) => {
if (divider) {
return <ListSeparator />;
}
return <ListItem id={value}>{label}</ListItem>;
}}
</Select>
{showPicker && (
<Modal onClose={handleClose}>
<DatePickerForm
startDate={startDate}
endDate={endDate}
minDate={new Date(2000, 0, 1)}
maxDate={endOfYear(new Date())}
onChange={handlePickerChange}
onClose={() => setShowPicker(false)}
/>
<Modal isOpen={true}>
<Dialog>
<DatePickerForm
startDate={startDate}
endDate={endDate}
minDate={new Date(2000, 0, 1)}
maxDate={endOfYear(new Date())}
onChange={handlePickerChange}
onClose={() => setShowPicker(false)}
/>
</Dialog>
</Modal>
)}
</>
@ -167,8 +184,8 @@ const CustomRange = ({ startDate, endDate, unit, onClick }) => {
}
return (
<Flexbox gap={10} alignItems="center" wrap="nowrap">
<Icon className="mr-2" onClick={handleClick}>
<Row gap="3" alignItems="center" wrap="nowrap">
<Icon onClick={handleClick}>
<Icons.Calendar />
</Icon>
<Text>
@ -181,6 +198,6 @@ const CustomRange = ({ startDate, endDate, unit, onClick }) => {
</>
)}
</Text>
</Flexbox>
</Row>
);
};

View file

@ -1,46 +0,0 @@
.menu {
display: grid;
grid-template-columns: repeat(3, 1fr);
padding: 10px;
background: var(--base50);
z-index: var(--z-index-popup);
border-radius: 5px;
border: 1px solid var(--border-color);
margin-inline-start: 10px;
}
.item {
display: flex;
align-items: center;
justify-content: space-between;
min-width: 200px;
border-radius: 5px;
padding: 5px 10px;
}
.item:hover {
background: var(--base75);
cursor: pointer;
}
.selected {
color: var(--font-color);
font-weight: 700;
background: var(--blue100);
}
.icon {
color: var(--primary400);
}
@media screen and (max-width: 992px) {
.menu {
grid-template-columns: repeat(2, 1fr);
}
}
@media screen and (max-width: 768px) {
.menu {
transform: translateX(40px);
}
}

View file

@ -1,4 +1,4 @@
import { Button, Icon, Icons, TooltipPopup } from 'react-basics';
import { Button, Icon, Icons, TooltipPopup } from '@umami/react-zen';
import Link from 'next/link';
import { useMessages } from '@/components/hooks';

View file

@ -1,14 +1,6 @@
import { useRef } from 'react';
import {
Text,
Icon,
CalendarMonthSelect,
CalendarYearSelect,
Button,
PopupTrigger,
Popup,
} from 'react-basics';
import { startOfMonth, endOfMonth } from 'date-fns';
import { Row, Text, Icon, Button, MenuTrigger, Popover, Menu, MenuItem } from '@umami/react-zen';
import { startOfMonth, endOfMonth, startOfYear, addMonths, subYears } from 'date-fns';
import { Icons } from '@/components/icons';
import { useLocale } from '@/components/hooks';
import { formatDate } from '@/lib/date';
@ -25,40 +17,48 @@ export function MonthSelect({ date = new Date(), onChange }) {
close();
};
const start = startOfYear(date);
const months: Date[] = [];
for (let i = 0; i < 12; i++) {
months.push(addMonths(start, i));
}
const years: number[] = [];
for (let i = 0; i < 10; i++) {
years.push(subYears(start, 10 - i).getFullYear());
}
return (
<>
<div ref={ref} className={styles.container}>
<PopupTrigger>
<Button className={styles.input} variant="quiet">
<Text>{month}</Text>
<Icon size="sm">
<Icons.ChevronDown />
</Icon>
</Button>
<Popup className={styles.popup} alignment="start">
{close => (
<CalendarMonthSelect
date={date}
locale={dateLocale}
onSelect={handleChange.bind(null, close)}
/>
)}
</Popup>
</PopupTrigger>
<PopupTrigger>
<Button className={styles.input} variant="quiet">
<Text>{year}</Text>
<Icon size="sm">
<Icons.ChevronDown />
</Icon>
</Button>
<Popup className={styles.popup} alignment="start">
{(close: any) => (
<CalendarYearSelect date={date} onSelect={handleChange.bind(null, close)} />
)}
</Popup>
</PopupTrigger>
</div>
</>
<Row>
<MenuTrigger>
<Button className={styles.input} variant="quiet">
<Text>{month}</Text>
<Icon size="sm">
<Icons.Chevron />
</Icon>
</Button>
<Popover>
<Menu items={months}>
{month => {
return <MenuItem id={month}>{month.getDay()}</MenuItem>;
}}
</Menu>
</Popover>
</MenuTrigger>
<MenuTrigger>
<Button className={styles.input} variant="quiet">
<Text>{year}</Text>
<Icon size="sm">
<Icons.Chevron />
</Icon>
</Button>
<Popover>
<Menu items={years}>
{year => {
return <MenuItem id={year}>{year}</MenuItem>;
}}
</Menu>
</Popover>
</MenuTrigger>
</Row>
);
}

View file

@ -1,4 +1,4 @@
import { LoadingButton, Icon, TooltipPopup } from 'react-basics';
import { LoadingButton, Icon, TooltipPopup } from '@umami/react-zen';
import { setWebsiteDateRange } from '@/store/websites';
import { useDateRange } from '@/components/hooks';
import { Icons } from '@/components/icons';

View file

@ -1,4 +1,4 @@
import { Button, Icon, PopupTrigger, Popup, Form, FormRow } from 'react-basics';
import { Button, Icon, PopupTrigger, Popup, Form, FormRow } from '@umami/react-zen';
import { TimezoneSetting } from '@/app/(main)/profile/TimezoneSetting';
import { DateRangeSetting } from '@/app/(main)/profile/DateRangeSetting';
import { Icons } from '@/components/icons';

View file

@ -1,7 +1,7 @@
import { useDateRange, useLocale } from '@/components/hooks';
import { isAfter } from 'date-fns';
import { getOffsetDateRange } from '@/lib/date';
import { Button, Icon, Icons } from 'react-basics';
import { Button, Icon, Icons } from '@umami/react-zen';
import { DateFilter } from './DateFilter';
import styles from './WebsiteDateFilter.module.css';
import { DateRange } from '@/lib/types';
@ -40,14 +40,14 @@ export function WebsiteDateFilter({
/>
{value !== 'all' && !value.startsWith('range') && (
<div className={styles.buttons}>
<Button onClick={() => handleIncrement(-1)}>
<Icon rotate={dir === 'rtl' ? 270 : 90}>
<Icons.ChevronDown />
<Button onPress={() => handleIncrement(-1)}>
<Icon size="sm" rotate={180}>
<Icons.Chevron />
</Icon>
</Button>
<Button onClick={() => handleIncrement(1)} disabled={disableForward}>
<Icon rotate={dir === 'rtl' ? 90 : 270}>
<Icons.ChevronDown />
<Button onPress={() => handleIncrement(1)} isDisabled={disableForward}>
<Icon size="sm">
<Icons.Chevron />
</Icon>
</Button>
</div>

View file

@ -1,5 +1,5 @@
import { useState, Key } from 'react';
import { Dropdown, Item } from 'react-basics';
import { Dropdown, Item } from '@umami/react-zen';
import { useWebsite, useWebsites, useMessages } from '@/components/hooks';
import { Empty } from '@/components/common/Empty';
import styles from './WebsiteSelect.module.css';