Skip to content

Commit

Permalink
[M1_TR-206] Frontend for M1_TR-5
Browse files Browse the repository at this point in the history
  • Loading branch information
nicoleamber committed Sep 18, 2023
1 parent 926dafd commit c42f0dd
Show file tree
Hide file tree
Showing 15 changed files with 242 additions and 106 deletions.
3 changes: 2 additions & 1 deletion web/src/app/job/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { JobTable } from '@/utils/types/job';
import { JobQuery, JobTable } from '@/utils/types/job';
import { createContext } from 'react';

export const JobListContext = createContext<JobTable | undefined>(undefined);
export const JobQueryContext = createContext<JobQuery | undefined>(undefined);
60 changes: 52 additions & 8 deletions web/src/app/job/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { axiosInstance } from '@/utils/services/axios';
import { JobSchema, JobTable, JobTableRow } from '@/utils/types/job';
import { JobQuery, JobSchema, JobTable, JobTableRow } from '@/utils/types/job';
import { ScheduleSchema } from '@/utils/types/schedule';
import { Moment } from 'moment';
import { useContext, useEffect, useState } from 'react';
import { JobListContext } from './context';
import { JobListContext, JobQueryContext } from './context';

export const useJobListContext = (): JobTable => {
const jobs = useContext(JobListContext);
Expand All @@ -14,6 +15,16 @@ export const useJobListContext = (): JobTable => {
return jobs;
};

export const useJobQueryContext = (): JobQuery => {
const query = useContext(JobQueryContext);

if (query === undefined) {
throw new Error('Missing JobQueryContext');
}

return query;
};

export const useHooks = () => {
const [page, setPage] = useState(1);
const [perPage] = useState(12);
Expand All @@ -23,13 +34,36 @@ export const useHooks = () => {
const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string | undefined>();

const [isFilter, setIsFilter] = useState(false);
const [tag, setTag] = useState('');
const [status, setStatus] = useState('');
const [startDate, setStartDate] = useState<Moment | null>(null);
const [endDate, setEndDate] = useState<Moment | null>(null);

const params: { page: number, perPage: number, tag?: string, status?: string, startDate?: string,
endDate?: string } = {
page, perPage,
};

if(isFilter) {
if (tag) {
params.tag = tag;
}

if (status) {
params.status = status;
}

if (startDate && endDate) {
params.startDate = startDate.format("MM-DD-YYYY");
params.endDate = endDate.format("MM-DD-YYYY");
}
}

useEffect(() => {
axiosInstance
.get('/jobs', {
params: {
page,
perPage
}
params
})
.then((response) => {
setCount(response?.data.count);
Expand All @@ -42,7 +76,7 @@ export const useHooks = () => {
setIsLoading(false);
setError('Something went wrong.');
});
}, [page, perPage]);
}, [page, perPage, tag, status, startDate, endDate, isFilter]);

return {
jobs,
Expand All @@ -52,6 +86,16 @@ export const useHooks = () => {
isLoading,
error,
setPage,
tag,
setTag,
status,
setStatus,
startDate,
setStartDate,
endDate,
setEndDate,
isFilter,
setIsFilter
};
};

Expand Down Expand Up @@ -81,7 +125,7 @@ const formatSchedules = (schedules: ScheduleSchema[]): string[] => {
return scheduleData;
};

const formatEnum = (value: string): string => {
export const formatEnum = (value: string): string => {
let words = value.split('_');
words = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase());
return words.join(' ');
Expand Down
121 changes: 76 additions & 45 deletions web/src/app/job/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,61 +7,92 @@ import SearchFilterHeader from '@/components/organisms/SearchFilterHeader';
import { JobColumns } from '@/utils/constants/jobTableData';
import { Grid, Typography } from '@mui/material';
import { Fragment } from 'react';
import { JobListContext } from './context';
import { JobListContext, JobQueryContext } from './context';
import { useHooks } from './hooks';

const JobList = (): JSX.Element => {
const { page, jobs, count, pageCount, setPage, isLoading, error } =
useHooks();
const {
page,
jobs,
count,
pageCount,
setPage,
isLoading,
error,
tag,
setTag,
status,
setStatus,
startDate,
setStartDate,
endDate,
setEndDate,
isFilter,
setIsFilter
} = useHooks();

return (
<main>
<JobListContext.Provider
value={{ columns: JobColumns, data: jobs }}>
{isLoading ? (
<StatusDisplay isLoading={isLoading} />
) : error ? (
<StatusDisplay error={error} />
) : (
<Grid
container
sx={{
padding: 3,
gap: 3,
flexDirection: 'column'
}}>
<Grid item>
<SearchFilterHeader />
</Grid>
{!count ? (
<Grid
item
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '60vh'
}}>
<Typography variant='label1r'>
No jobs found
</Typography>
<JobQueryContext.Provider
value={{
tag,
setTag,
status,
setStatus,
startDate,
setStartDate,
endDate,
setEndDate,
isFilter,
setIsFilter
}}>
{isLoading ? (
<StatusDisplay isLoading={isLoading} />
) : error ? (
<StatusDisplay error={error} />
) : (
<Grid
container
sx={{
padding: 3,
gap: 3,
flexDirection: 'column'
}}>
<Grid item>
<SearchFilterHeader />
</Grid>
) : (
<Fragment>
<Grid item>
<JobListTable />
</Grid>
<Grid item sx={{ alignSelf: 'center' }}>
<Pagination
count={pageCount}
page={page}
onChange={setPage}
/>
{!count ? (
<Grid
item
sx={{
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
height: '60vh'
}}>
<Typography variant='label1r'>
No jobs found
</Typography>
</Grid>
</Fragment>
)}
</Grid>
)}
) : (
<Fragment>
<Grid item>
<JobListTable />
</Grid>
<Grid item sx={{ alignSelf: 'center' }}>
<Pagination
count={pageCount}
page={page}
onChange={setPage}
/>
</Grid>
</Fragment>
)}
</Grid>
)}
</JobQueryContext.Provider>
</JobListContext.Provider>
</main>
);
Expand Down
42 changes: 30 additions & 12 deletions web/src/components/molecules/CreatedDateRangeFilter/hooks.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,48 @@
import moment, { type Moment } from 'moment';
import { useJobQueryContext } from '@/app/job/hooks';
import { type Moment } from 'moment';
import { useEffect, useState } from 'react';

export const useHooks = () => {
const [startDate, setStartDate] = useState<Moment | null>(moment().startOf('month'));
const [endDate, setEndDate] = useState<Moment | null>(moment());
const [isInvalidDate, setIsInvalidDate] = useState(false);
const { setStartDate, setEndDate } = useJobQueryContext();
const [initialStartDate, setInitialStartDate] = useState<Moment | null>(null);
const [initialEndDate, setInitialEndDate] = useState<Moment | null>(null);
const [error, setError] = useState('');

const handleStartDateChange = (date: Moment | null): void => {
setStartDate(date);
setInitialStartDate(date);
};

const handleEndDateChange = (date: Moment | null): void => {
setEndDate(date);
setInitialEndDate(date);
};

useEffect(() => {
if (startDate && endDate) {
setIsInvalidDate(endDate <= startDate);
if (initialStartDate && !initialEndDate || initialEndDate && !initialStartDate) {
setError('Both start and end dates must be set');
}
}, [startDate, endDate]);

if(!initialStartDate && !initialEndDate) {
setError('');
setStartDate(null);
setEndDate(null);
}

if (initialStartDate && initialEndDate) {
if (initialEndDate < initialStartDate) {
setError('Please set a vaild date');
} else {
setError('');
setStartDate(initialStartDate);
setEndDate(initialEndDate);
}
}
}, [initialStartDate, initialEndDate]);

return {
startDate,
error,
initialStartDate,
handleStartDateChange,
endDate,
initialEndDate,
handleEndDateChange,
isInvalidDate
};
};
31 changes: 16 additions & 15 deletions web/src/components/molecules/CreatedDateRangeFilter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import { useHooks } from './hooks';

const CreateDateRangeFilter = () => {
const {
startDate,
error,
initialStartDate,
handleStartDateChange,
endDate,
handleEndDateChange,
isInvalidDate
initialEndDate,
handleEndDateChange
} = useHooks();

return (
Expand All @@ -21,7 +21,7 @@ const CreateDateRangeFilter = () => {
<DatePicker
disableFuture
label='Created at - Start Date'
value={startDate}
value={initialStartDate}
onChange={handleStartDateChange}
sx={{
'& .MuiInputBase-root': {
Expand All @@ -32,23 +32,23 @@ const CreateDateRangeFilter = () => {
}
}}
slotProps={{
actionBar: {
actions: ['clear']
},
textField: {
size: 'small',
color: 'secondary',
id: 'created-start',
name: 'created-start',
error: isInvalidDate,
helperText: isInvalidDate
? 'Please set a valid date'
: ''
error: !!error,
helperText: error
}
}}
/>
{' - '}
<DatePicker
disableFuture
label='Created at - End Date'
value={endDate}
value={initialEndDate}
onChange={handleEndDateChange}
sx={{
'& .MuiInputBase-root': {
Expand All @@ -59,15 +59,16 @@ const CreateDateRangeFilter = () => {
}
}}
slotProps={{
actionBar: {
actions: ['clear']
},
textField: {
size: 'small',
color: 'secondary',
id: 'created-end',
name: 'created-end',
error: isInvalidDate,
helperText: isInvalidDate
? 'Please set a valid date.'
: ''
error: !!error,
helperText: error
}
}}
/>
Expand Down
Loading

0 comments on commit c42f0dd

Please sign in to comment.