Skip to content

Commit

Permalink
feat(1-3262): begin impl of new month/range picker
Browse files Browse the repository at this point in the history
  • Loading branch information
thomasheartman committed Jan 20, 2025
1 parent 54aebe7 commit ebc283f
Show file tree
Hide file tree
Showing 5 changed files with 343 additions and 5 deletions.
Empty file.
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useMemo, type VFC, useState, useEffect } from 'react';
import { useMemo, useState, useEffect, type FC } from 'react';
import useTheme from '@mui/material/styles/useTheme';
import styled from '@mui/material/styles/styled';
import { usePageTitle } from 'hooks/usePageTitle';
Expand Down Expand Up @@ -34,6 +34,7 @@ import { formatTickValue } from 'component/common/Chart/formatTickValue';
import { useTrafficLimit } from './hooks/useTrafficLimit';
import { BILLING_TRAFFIC_BUNDLE_PRICE } from 'component/admin/billing/BillingDashboard/BillingPlan/BillingPlan';
import { useLocationSettings } from 'hooks/useLocationSettings';
import { PeriodSelector } from './PeriodSelector';

const StyledBox = styled(Box)(({ theme }) => ({
display: 'grid',
Expand Down Expand Up @@ -139,7 +140,7 @@ const createBarChartOptions = (
},
});

export const NetworkTrafficUsage: VFC = () => {
export const NetworkTrafficUsage: FC = () => {
usePageTitle('Network - Data Usage');
const theme = useTheme();

Expand Down Expand Up @@ -278,6 +279,7 @@ export const NetworkTrafficUsage: VFC = () => {
estimatedMonthlyCost={estimatedMonthlyCost}
/>
</Grid>
<PeriodSelector />
<Grid item xs={12} md={2}>
<Select
id='dataperiod-select'
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { styled } from '@mui/material';
import { ScreenReaderOnly } from 'component/common/ScreenReaderOnly/ScreenReaderOnly';

export type Period = {
key: string;
dayCount: number;
label: string;
year: number;
month: number;
selectable: boolean;
shortLabel: string;
};

export const toSelectablePeriod = (
date: Date,
label?: string,
selectable = true,
): Period => {
// const { locationSettings } = useLocationSettings();
const year = date.getFullYear();
const month = date.getMonth();
const period = `${year}-${(month + 1).toString().padStart(2, '0')}`;
const dayCount = new Date(year, month + 1, 0).getDate();
return {
key: period,
year,
month,
dayCount,
shortLabel: date.toLocaleString('en-US', {
month: 'short',
}),
label:
label ||
date.toLocaleString('en-US', { month: 'long', year: 'numeric' }),
selectable,
};
};

const currentDate = new Date(Date.now());
const currentPeriod = toSelectablePeriod(currentDate, 'Current month');

const getSelectablePeriods = (): Period[] => {
const selectablePeriods = [currentPeriod];
for (
let subtractMonthCount = 1;
subtractMonthCount < 12;
subtractMonthCount++
) {
// JavaScript wraps around the year, so we don't need to handle that.
const date = new Date(
currentDate.getFullYear(),
currentDate.getMonth() - subtractMonthCount,
1,
);
selectablePeriods.push(
toSelectablePeriod(date, undefined, date > new Date('2024-03-31')),
);
}
return selectablePeriods;
};

const Wrapper = styled('article')(({ theme }) => ({
marginTop: '2rem', // temporary
borderRadius: theme.shape.borderRadiusLarge,
border: `1px solid ${theme.palette.divider}`,
paddingInline: theme.spacing(1),
paddingBlock: theme.spacing(2.5),
}));

const Selector = styled('fieldset')(({ theme }) => ({
'&:focus-within': {
bakgroundColor: 'blue',
},
label: {
cursor: 'pointer',
},
'label:focus-within': {
backgroundColor: 'red',
},
'label:has(input:checked)': {
backgroundColor: theme.palette.secondary.light,
},
'label:has(input:disabled)': {
color: theme.palette.text.disabled,
cursor: 'default',
},
input: {
display: 'none',
},
border: 'none',
// borderRadius: theme.shape.borderRadiusLarge,
// borderColor: theme.palette.divider,
legend: {
h3: {
margin: 0,
fontSize: theme.typography.h3.fontSize,
},
p: {
color: theme.palette.text.secondary,
fontSize: theme.typography.body2.fontSize,
},
// position: 'absolute',
// top: '-.6em',
},
}));

const MonthGrid = styled('div')(({ theme }) => ({
display: 'grid',
gridTemplateColumns: 'repeat(4, 1fr)',
rowGap: theme.spacing(1),
columnGap: theme.spacing(2),
label: {
textAlign: 'center',
padding: theme.spacing(0.2),
borderRadius: theme.shape.borderRadius,
},
}));

type Selection =
| {
type: 'month';
value: string;
}
| {
type: 'range';
monthsBack: number;
};

export const PeriodSelector = () => {
const selectablePeriods = getSelectablePeriods();
console.log(selectablePeriods);
return (
<Wrapper>
<Selector>
<legend>
<h3>Select month</h3>
<p>Last 12 months</p>
</legend>
<MonthGrid>
{selectablePeriods.map((period, index) => (
<label
key={period.label}
className={period.selectable ? '' : 'disabled'}
>
{period.shortLabel}
<ScreenReaderOnly>
<input
type='radio'
name='period'
value={period.label}
disabled={!period.selectable}
onClick={(e) =>
console.log(
'clicked',
e,
e.target.value,
)
}
/>
</ScreenReaderOnly>
</label>
))}
</MonthGrid>
</Selector>
</Wrapper>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const useInstanceTrafficMetrics = (

return useMemo(
() => ({
usage: data,
usage: useInstanceTrafficMetricsMonths2(4),
loading: !error && !data,
refetch: () => mutate(),
error,
Expand All @@ -38,3 +38,173 @@ const fetcher = (path: string) => {
.then(handleErrorResponses('Instance Metrics'))
.then((res) => res.json());
};

export const useInstanceTrafficMetricsMonths2 = (_monthsBack: number) => {
const mockMonthData = [
{
apiPath: '/api/admin',
months: [
{
month: '2025-01',
trafficTypes: [
{
group: 'successful-requests',
count: 535,
},
],
},
{
month: '2024-12',
trafficTypes: [
{
group: 'successful-requests',
count: 240,
},
],
},
{
month: '2024-11',
trafficTypes: [
{
group: 'successful-requests',
count: 180, // Example count
},
],
},
{
month: '2024-10',
trafficTypes: [
{
group: 'successful-requests',
count: 200, // Example count
},
],
},
],
},
{
apiPath: '/edge',
months: [
{
month: '2025-01',
trafficTypes: [
{
group: 'successful-requests',
count: 535,
},
],
},
{
month: '2024-12',
trafficTypes: [
{
group: 'successful-requests',
count: 240,
},
],
},
{
month: '2024-11',
trafficTypes: [
{
group: 'successful-requests',
count: 180, // Example count
},
],
},
{
month: '2024-10',
trafficTypes: [
{
group: 'successful-requests',
count: 200, // Example count
},
],
},
],
},
{
apiPath: '/api/frontend',
months: [
{
month: '2025-01',
trafficTypes: [
{
group: 'successful-requests',
count: 535,
},
],
},
{
month: '2024-12',
trafficTypes: [
{
group: 'successful-requests',
count: 240,
},
],
},
{
month: '2024-11',
trafficTypes: [
{
group: 'successful-requests',
count: 180, // Example count
},
],
},
{
month: '2024-10',
trafficTypes: [
{
group: 'successful-requests',
count: 200, // Example count
},
],
},
],
},
{
apiPath: '/api/client',
months: [
{
month: '2025-01',
trafficTypes: [
{
group: 'successful-requests',
count: 535,
},
],
},
{
month: '2024-12',
trafficTypes: [
{
group: 'successful-requests',
count: 240,
},
],
},
{
month: '2024-11',
trafficTypes: [
{
group: 'successful-requests',
count: 180, // Example count
},
],
},
{
month: '2024-10',
trafficTypes: [
{
group: 'successful-requests',
count: 200, // Example count
},
],
},
],
},
];
return mockMonthData;
};
3 changes: 1 addition & 2 deletions frontend/src/hooks/useTrafficData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ const calculateTrafficDataCost = (
return unitCount * trafficUnitCost;
};

const padMonth = (month: number): string =>
month < 10 ? `0${month}` : `${month}`;
const padMonth = (month: number): string => month.toString().padStart(2, '0');

export const toSelectablePeriod = (
date: Date,
Expand Down

0 comments on commit ebc283f

Please sign in to comment.