feat: popover

This commit is contained in:
TrèsAbhi committed 2024-06-10 13:06:02 -05:00
1 parent 0523619aee
commit e2cef42667
3 files changed
+117 -34

No files matched your search

+26 -6
View File
@@ -1,10 +1,19 @@
'use client'; 'use client';
import { ExclamationTriangleIcon } from '@radix-ui/react-icons'; import { ExclamationTriangleIcon } from '@radix-ui/react-icons';
import { Box, Callout, Flex, Heading, Tabs, Text } from '@radix-ui/themes'; import {
Box,
Callout,
Flex,
Heading,
Popover,
Tabs,
Text,
} from '@radix-ui/themes';
import { use, useMemo, useState } from 'react'; import { use, useMemo, useState } from 'react';
import { BkniIndicator } from '../../../../components/BkniIndicator'; import { BkniIndicator } from '../../../../components/BkniIndicator';
import { DatePicker } from '../../../../components/DatePicker'; import { DatePicker } from '../../../../components/DatePicker';
import { DummyLink } from '../../../../components/DummyLink';
import PageWrapper from '../../../../components/PageWrapper'; import PageWrapper from '../../../../components/PageWrapper';
import { getAccountInfo } from '../../../../core/blitz/getAccountInfo'; import { getAccountInfo } from '../../../../core/blitz/getAccountInfo';
import { getClanAccountInfo } from '../../../../core/blitz/getClanAccountInfo'; import { getClanAccountInfo } from '../../../../core/blitz/getClanAccountInfo';
@@ -23,8 +32,7 @@ export default function Page({ params }: { params: { id: string } }) {
[id], [id],
); );
const clanAccountInfo = use(clanAccountInfoPromise); const clanAccountInfo = use(clanAccountInfoPromise);
const bkni = Math.random() * 2 - 1; const bkni = ((Math.round(Date.now() / 1000 / 60) / 100) % 2) - 1;
// const bkni = 0.87;
const [period, setPeriod] = useState<'custom' | number>(30); const [period, setPeriod] = useState<'custom' | number>(30);
const { bkniColor } = parseBkni(bkni); const { bkniColor } = parseBkni(bkni);
const isTracking = false; const isTracking = false;
@@ -100,10 +108,22 @@ export default function Page({ params }: { params: { id: string } }) {
<FlippedTrigger value="custom">Custom</FlippedTrigger> <FlippedTrigger value="custom">Custom</FlippedTrigger>
</Tabs.List> </Tabs.List>
</Tabs.Root> </Tabs.Root>
</PageWrapper>
<PageWrapper color={bkniColor} noFlex1> {period === 'custom' && (
<DatePicker /> <Text>
From{' '}
<Popover.Root>
<Popover.Trigger>
<DummyLink underline="always">June 1, 2021</DummyLink>
</Popover.Trigger>
<Popover.Content>
<DatePicker />
</Popover.Content>
</Popover.Root>{' '}
to <DummyLink underline="always">June 7, 2024</DummyLink>
</Text>
)}
</PageWrapper> </PageWrapper>
{!isTracking && ( {!isTracking && (
+84 -28
View File
@@ -17,25 +17,48 @@ import {
} from '@radix-ui/themes'; } from '@radix-ui/themes';
import { times } from 'lodash'; import { times } from 'lodash';
import { useState } from 'react'; import { useState } from 'react';
import { Vector3Tuple } from 'three';
const DAY_TITLES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; const DAY_TITLES = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
const YEAR_OPTIONS = 7; const YEAR_OPTIONS = 7;
export function DatePicker() { interface DatePickerProps {
onDateChange?: (date: Vector3Tuple) => void;
defaultDate?: Vector3Tuple;
}
export function DatePicker({ onDateChange, defaultDate }: DatePickerProps) {
const initialDate = new Date(); const initialDate = new Date();
const [year, setYear] = useState(initialDate.getFullYear()); const [year, setYear] = useState(
const [month, setMonth] = useState(initialDate.getMonth()); defaultDate?.[2] ?? initialDate.getFullYear(),
const [day, setDay] = useState(initialDate.getDate()); );
const [month, setMonth] = useState(
defaultDate?.[1] ?? initialDate.getMonth(),
);
const [day, setDay] = useState(defaultDate?.[0] ?? initialDate.getDate());
const [yearScroll, setYearScroll] = useState(0);
const [yearOffset, setYearOffset] = useState(0); const [yearOffset, setYearOffset] = useState(0);
const [monthOffset, setMonthOffset] = useState(0); const [monthOffset, setMonthOffset] = useState(0);
const date = new Date(year + yearOffset, month + monthOffset, day); const date = new Date(year + yearOffset, month + monthOffset, day);
const daysInLastMonth = new Date(year, month + monthOffset, 0).getDate(); const daysInLastMonth = new Date(
const daysInMonth = new Date(year, month + monthOffset + 1, 0).getDate(); year + yearOffset,
const firstDayOfMonth = new Date(year, month + monthOffset, 1).getDay(); month + monthOffset,
0,
).getDate();
const daysInMonth = new Date(
year + yearOffset,
month + monthOffset + 1,
0,
).getDate();
const firstDayOfMonth = new Date(
year + yearOffset,
month + monthOffset,
1,
).getDay();
const lastDayOfMonth = new Date( const lastDayOfMonth = new Date(
year, year + yearOffset,
month + monthOffset, month + monthOffset,
daysInMonth, daysInMonth,
).getDay(); ).getDay();
@@ -50,7 +73,14 @@ export function DatePicker() {
<IconButton <IconButton
size="3" size="3"
variant="ghost" variant="ghost"
onClick={() => setMonthOffset((state) => state - 1)} onClick={() => {
if (monthOffset === 0) {
setYearOffset((state) => state - 1);
setMonthOffset(11);
} else {
setMonthOffset((state) => state - 1);
}
}}
ml="2" ml="2"
> >
<ChevronLeftIcon /> <ChevronLeftIcon />
@@ -72,9 +102,13 @@ export function DatePicker() {
</IconButton> </IconButton>
<Flex gap="1"> <Flex gap="1">
<Text>{date.toLocaleString(undefined, { month: 'long' })} </Text> <Text>
{date.toLocaleString(undefined, {
month: 'long',
})}
</Text>
<Popover.Root onOpenChange={() => setYearOffset(0)}> <Popover.Root onOpenChange={() => setYearScroll(0)}>
<Popover.Trigger> <Popover.Trigger>
<Link underline="always" href="#"> <Link underline="always" href="#">
{date.getFullYear()} {date.getFullYear()}
@@ -85,7 +119,7 @@ export function DatePicker() {
<Flex direction="column" gap="1"> <Flex direction="column" gap="1">
<IconButton <IconButton
variant="ghost" variant="ghost"
onClick={() => setYearOffset((state) => state + 1)} onClick={() => setYearScroll((state) => state + 1)}
mb="2" mb="2"
> >
<ChevronUpIcon /> <ChevronUpIcon />
@@ -93,22 +127,31 @@ export function DatePicker() {
{times(YEAR_OPTIONS, (index) => { {times(YEAR_OPTIONS, (index) => {
const thisYear = const thisYear =
year - index + Math.floor(YEAR_OPTIONS / 2) + yearOffset; year +
yearOffset -
index +
Math.floor(YEAR_OPTIONS / 2) +
yearScroll;
const selected = year + yearOffset === thisYear;
return ( return (
<Button <Popover.Close key={thisYear}>
variant={year === thisYear ? 'solid' : 'soft'} <Button
radius="large" variant={selected ? 'solid' : 'soft'}
onClick={() => setYear(thisYear)} radius="large"
> onClick={() => {
{thisYear} setYearOffset(thisYear - year);
</Button> }}
>
{thisYear}
</Button>
</Popover.Close>
); );
})} })}
<IconButton <IconButton
variant="ghost" variant="ghost"
onClick={() => setYearOffset((state) => state - 1)} onClick={() => setYearScroll((state) => state - 1)}
mt="2" mt="2"
> >
<ChevronDownIcon /> <ChevronDownIcon />
@@ -122,7 +165,14 @@ export function DatePicker() {
<IconButton <IconButton
size="3" size="3"
variant="ghost" variant="ghost"
onClick={() => setMonthOffset((state) => state + 1)} onClick={() => {
if (monthOffset === 11) {
setYearOffset((state) => state + 1);
setMonthOffset(0);
} else {
setMonthOffset((state) => state + 1);
}
}}
mr="2" mr="2"
> >
<ChevronRightIcon /> <ChevronRightIcon />
@@ -153,7 +203,8 @@ export function DatePicker() {
))} ))}
{times(daysInMonth, (index) => { {times(daysInMonth, (index) => {
const selected = index === day - 1 && monthOffset === 0; const selected =
index === day - 1 && monthOffset === 0 && yearOffset === 0;
return ( return (
<IconButton <IconButton
@@ -161,11 +212,18 @@ export function DatePicker() {
key={index} key={index}
variant={selected ? 'solid' : 'soft'} variant={selected ? 'solid' : 'soft'}
onClick={() => { onClick={() => {
setYear(year + yearOffset); const newYear =
setMonth((month + monthOffset) % 12); year + yearOffset + Math.floor((month + monthOffset) / 12);
setDay(index + 1); const newMonth = (month + monthOffset) % 12;
const newDay = index + 1;
setYear(newYear);
setMonth(newMonth);
setDay(newDay);
setYearOffset(0); setYearOffset(0);
setMonthOffset(0); setMonthOffset(0);
onDateChange?.([newDay, newMonth, newYear]);
}} }}
> >
{index + 1} {index + 1}
@@ -179,8 +237,6 @@ export function DatePicker() {
</IconButton> </IconButton>
))} ))}
</Grid> </Grid>
{/* {`${day} ${month} ${year}`} */}
</Card> </Card>
); );
} }
+7
View File
@@ -0,0 +1,7 @@
import { Link, LinkProps } from '@radix-ui/themes';
export function DummyLink({ href = '#', onClick, ...props }: LinkProps) {
return (
<Link href={href} onClick={(event) => event.preventDefault()} {...props} />
);
}