Skip to content

Commit

Permalink
Refactor mock data fetching
Browse files Browse the repository at this point in the history
  • Loading branch information
alexwkleung committed Dec 30, 2024
1 parent 50415c0 commit 9727bdf
Show file tree
Hide file tree
Showing 6 changed files with 175 additions and 55 deletions.
14 changes: 9 additions & 5 deletions src/components/Chart/Chart.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { CircularProgress } from '@mui/material';
import { getTotalStatus } from '../../utils/get-mock-data';
import { useDateRange } from '../../hooks/useDateRange';
import dayjs from 'dayjs';
import { mockFetch } from '../../utils/mock-fetch';
import { mockFetchDelay } from '../../utils/mock-fetch';

import type { Options, SeriesOptionsType } from 'highcharts';
import type { TotalStatus } from '../../types/status';
Expand All @@ -19,17 +19,21 @@ const Chart = () => {
useEffect(() => {
let isMounted: boolean = true;

const fetchData = async () => {
// fetch chart data
const fetchChartData = async (): Promise<void> => {
try {
await mockFetch(1100);
await mockFetchDelay(1000);

if (!isMounted) return;

const chartTitle: string = 'Status Totals';
const chartCategoriesX: string[] = ['Open', 'Closed', 'In Progress'];
const chartTitleY: string = 'Total';

const totalStatus: TotalStatus = getTotalStatus(dayjs(date.startDate), dayjs(date.endDate));
const totalStatus: TotalStatus = await getTotalStatus(
dayjs(date.startDate),
dayjs(date.endDate)
);

const chartSeries: SeriesOptionsType[] = [
{
Expand Down Expand Up @@ -86,7 +90,7 @@ const Chart = () => {
}
};

fetchData();
fetchChartData();

return () => {
isMounted = false;
Expand Down
36 changes: 25 additions & 11 deletions src/components/DataGridTable/DataGridTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import { useDateRange } from '../../hooks/useDateRange';
import { isBetween } from '../../utils/is-between';
import dayjs from 'dayjs';
import { CircularProgress } from '@mui/material';
import { mockFetch } from '../../utils/mock-fetch';
import { mockFetchDelay } from '../../utils/mock-fetch';
import { Typography } from '@mui/material';

import type { GridTable } from '../../types/gridtable';

Expand All @@ -15,23 +16,32 @@ const DataGridTable = () => {

const [filterRows, setFilterRows] = useState<GridTable['rows']>();

const [gridTableData, setGridTableData] = useState<GridTable>();

const [isLoading, setIsLoading] = useState<boolean>(true);

useEffect(() => {
let isMounted: boolean = true;

const fetchData = async () => {
// fetch table data
const fetchTableData = async (): Promise<void> => {
try {
await mockFetch(1100);
await mockFetchDelay(1000);

const data: GridTable = await gridTable();

setGridTableData(data);

if (!isMounted) return;

// filter rows based on date range
const filtered: GridTable['rows'] = gridTable.rows.filter((field) =>
isBetween(dayjs(field.DateCreated), dayjs(date.startDate), dayjs(date.endDate))
);
if (data && data.rows) {
// filter rows based on date range
const filtered: GridTable['rows'] = data.rows.filter((field) =>
isBetween(dayjs(field.dateCreated), dayjs(date.startDate), dayjs(date.endDate))
);

setFilterRows(filtered);
setFilterRows(filtered);
}
} catch (err) {
console.error(err);
} finally {
Expand All @@ -41,7 +51,7 @@ const DataGridTable = () => {
}
};

fetchData();
fetchTableData();

// clean up
return () => {
Expand All @@ -55,11 +65,11 @@ const DataGridTable = () => {
<div className="flex h-full items-center justify-center">
<CircularProgress />
</div>
) : (
) : gridTableData && gridTableData.columns && filterRows ? (
<DataGrid
sx={{ width: '90%', margin: 'auto' }}
rows={filterRows}
columns={gridTable.columns}
columns={gridTableData.columns}
initialState={{
pagination: {
paginationModel: {
Expand All @@ -71,6 +81,10 @@ const DataGridTable = () => {
checkboxSelection
disableRowSelectionOnClick
/>
) : (
<div className="flex h-full items-center justify-center">
<Typography>No table data available</Typography>
</div>
)}
</Box>
);
Expand Down
58 changes: 40 additions & 18 deletions src/data/grid-table.ts
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
import { mockData } from './data';
import { parseMockFetch } from '../utils/mock-fetch';

import type { MockData } from '../types/mockdata';
import type { GridTable } from '../types/gridtable';

/**
* Generate rows
*
* @returns Generated rows for grid table
*/
function generateRows(): GridTable['rows'] {
return mockData.map((data) => {
return {
id: data.id,
Title: data.title,
Description: data.description,
DateCreated: data.dateCreated,
Comments: data.comments,
};
});
async function generateRows(): Promise<GridTable['rows']> {
const data: MockData[] = await parseMockFetch();

const parse: GridTable['rows'] = [];

for (const obj in data) {
parse.push({
id: data[obj].id,
title: data[obj].title,
description: data[obj].description,
dateCreated: data[obj].dateCreated,
status: data[obj].status,
comments: data[obj].comments,
});
}

return parse;
}

/**
Expand All @@ -27,25 +36,31 @@ function generateColumns(): GridTable['columns'] {
return [
{ field: 'id', headerName: 'ID', width: 90 },
{
field: 'Title',
field: 'title',
headerName: 'Title',
width: 150,
editable: false,
},
{
field: 'Description',
field: 'description',
headerName: 'Description',
width: 150,
editable: false,
},
{
field: 'DateCreated',
field: 'dateCreated',
headerName: 'Date Created',
width: 150,
editable: false,
},
{
field: 'Comments',
field: 'status',
headerName: 'Status',
width: 150,
editable: false,
},
{
field: 'comments',
headerName: 'Comments',
width: 150,
editable: false,
Expand All @@ -58,7 +73,14 @@ function generateColumns(): GridTable['columns'] {
*
* Holds the rows and columns for the grid table
*/
export const gridTable: GridTable = {
rows: generateRows(),
columns: generateColumns(),
// export const gridTable: GridTable = {
// rows: await generateRows(),
// columns: generateColumns(),
// };

export const gridTable = async (): Promise<GridTable> => {
return {
rows: await generateRows(),
columns: generateColumns(),
};
};
19 changes: 8 additions & 11 deletions src/types/gridtable.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import type { GridColDef } from '@mui/x-data-grid';
import type { MockData } from './mockdata';
import type { Status } from './status';

export interface GridTable {
rows: {
id: number;
Title: string;
Description: string;
DateCreated: string;
Comments: string;
}[];
rows: MockData[];
columns: GridColDef<{
id: number;
Title: string;
Description: string;
DateCreated: string;
Comments: string;
title: string;
description: string;
dateCreated: string;
status: Status;
comments: string;
}>[];
}
28 changes: 20 additions & 8 deletions src/utils/get-mock-data.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { mockData } from '../data/data';
import dayjs from 'dayjs';
import { parseMockFetch } from './mock-fetch';

import type { Dayjs } from 'dayjs';
import type { MockData } from '../types/mockdata';
Expand All @@ -8,12 +8,18 @@ import type { TotalStatus } from '../types/status';
/**
* Filter by date range.
*
* @async
* @param start Start date
* @param end End date
* @returns
* @returns A promise containing the filtered mock data according to the specified date range
*/
export function filterByDateRange(start: string | Dayjs, end: string | Dayjs): MockData[] {
const filter: MockData[] = mockData.filter(
export async function filterByDateRange(
start: string | Dayjs,
end: string | Dayjs
): Promise<MockData[]> {
const parse: MockData[] = await parseMockFetch();

const filter: MockData[] = parse.filter(
(props) => dayjs(props.dateCreated) >= dayjs(start) && dayjs(props.dateCreated) <= dayjs(end)
);

Expand All @@ -23,26 +29,32 @@ export function filterByDateRange(start: string | Dayjs, end: string | Dayjs): M
/**
* Get total mock data entries
*
* @async
* @returns Total number of mock data entries
*/
export function getTotalMockData(): number {
return mockData?.length;
export async function getTotalMockData(): Promise<number> {
const parse: MockData[] = await parseMockFetch();

return parse?.length;
}

/**
* Get total data entries by status.
*
* @async
* @param status Status to filter by
* @param start Start of date range
* @param end End of date range
* @returns Object with the total of each status
*/
export function getTotalStatus(start: Dayjs, end: Dayjs): TotalStatus {
export async function getTotalStatus(start: Dayjs, end: Dayjs): Promise<TotalStatus> {
let openCount: number = 0;
let closedCount: number = 0;
let inProgressCount: number = 0;

filterByDateRange(start, end).map((props) => {
const filter: MockData[] = await filterByDateRange(start, end);

filter.map((props) => {
switch (props.status) {
case 'Open':
openCount++;
Expand Down
Loading

0 comments on commit 9727bdf

Please sign in to comment.