Skip to content

Commit

Permalink
fix: simplify and improve readability of conditional rendering in tim…
Browse files Browse the repository at this point in the history
…esheet display
  • Loading branch information
Innocent-Akim committed Nov 22, 2024
1 parent 01e6109 commit 01199b0
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,31 +22,34 @@ import { DatePicker } from "@components/ui/DatePicker";
import { cn } from "@/lib/utils";
import { format } from "date-fns";
import { PiCalendarDotsThin } from "react-icons/pi";
import { useLocalStorageState, useTimelogFilterOptions } from "@/app/hooks";
import { TimesheetFilterByDays } from "@/app/interfaces";

interface DatePickerInputProps {
date: Date | null;
label: string;
}

export function FrequencySelect() {
const [selectedValue, setSelectedValue] = React.useState<string | undefined>(undefined);
const [] = useLocalStorageState<TimesheetFilterByDays>('timesheet-group-by-day', 'Daily')

const { setTimesheetGroupByDays, timesheetGroupByDays } = useTimelogFilterOptions();
const handleSelectChange = (value: string) => {
setSelectedValue(value);
setTimesheetGroupByDays(value as TimesheetFilterByDays);
};

return (
<Select
value={selectedValue}
value={timesheetGroupByDays}
onValueChange={handleSelectChange}>
<SelectTrigger className="w-36 overflow-hidden h-[2.2rem] text-clip border border-gray-200 dark:border-gray-700 bg-white dark:bg-dark--theme-light focus:ring-2 focus:ring-transparent">
<SelectValue placeholder="Select a daily" />
</SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectItem value="daily">Daily</SelectItem>
<SelectItem value="weekly">Weekly</SelectItem>
<SelectItem value="monthly">Monthly</SelectItem>
<SelectItem value="Daily">Daily</SelectItem>
<SelectItem value="Weekly">Weekly</SelectItem>
<SelectItem value="Monthly">Monthly</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
Expand Down
36 changes: 20 additions & 16 deletions apps/web/app/[locale]/timesheet/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { withAuthentication } from 'lib/app/authenticator';
import { Breadcrumb, Container } from 'lib/components';
import { MainLayout } from 'lib/layout';

import { useAuthenticateUser, useLocalStorageState, useModal, useOrganizationTeams } from '@app/hooks';
import { useAuthenticateUser, useLocalStorageState, useModal, useOrganizationTeams, useTimelogFilterOptions } from '@app/hooks';
import { clsxm } from '@app/utils';
import { fullWidthState } from '@app/stores/fullWidth';
import { useAtomValue } from 'jotai';
Expand Down Expand Up @@ -43,25 +43,30 @@ const TimeSheet = React.memo(function TimeSheetPage({ params }: { params: { memb
from: startOfDay(new Date()),
to: endOfDay(new Date())
});

const { timesheet, statusTimesheet, timesheetGroupByMonth, timesheetGroupByWeek } = useTimesheet({
const { timesheet, statusTimesheet } = useTimesheet({
startDate: dateRange.from ?? '',
endDate: dateRange.to ?? ''
});

const lowerCaseSearch = useMemo(() => search?.toLowerCase() ?? '', [search]);
const filterDataTimesheet = useMemo(
() =>
timesheetGroupByWeek.filter((v) =>
v.tasks.some(
(task) =>
task.task?.title?.toLowerCase()?.includes(lowerCaseSearch) ||
task.employee?.fullName?.toLowerCase()?.includes(lowerCaseSearch) ||
task.project?.name?.toLowerCase()?.includes(lowerCaseSearch)
)
),
[timesheet, timesheetGroupByMonth, timesheetGroupByWeek, lowerCaseSearch]
);
const filterDataTimesheet = useMemo(() => {
const filteredTimesheet =
timesheet
.filter((v) =>
v.tasks.some(
(task) =>
task.task?.title?.toLowerCase()?.includes(lowerCaseSearch) ||
task.employee?.fullName?.toLowerCase()?.includes(lowerCaseSearch) ||
task.project?.name?.toLowerCase()?.includes(lowerCaseSearch)
)
);

return filteredTimesheet;
}, [
timesheet,
lowerCaseSearch,
]);


const {
isOpen: isManualTimeModalOpen,
Expand Down Expand Up @@ -166,7 +171,6 @@ const TimeSheet = React.memo(function TimeSheetPage({ params }: { params: { memb
/>
</div>
</div>

<TimesheetFilter
data={statusTimesheet}
onChangeStatus={setFilterStatus}
Expand Down
5 changes: 4 additions & 1 deletion apps/web/app/hooks/features/useTimelogFilterOptions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { timesheetDeleteState, timesheetFilterEmployeeState, timesheetFilterProjectState, timesheetFilterStatusState, timesheetFilterTaskState } from '@/app/stores';
import { timesheetDeleteState, timesheetGroupByDayState, timesheetFilterEmployeeState, timesheetFilterProjectState, timesheetFilterStatusState, timesheetFilterTaskState } from '@/app/stores';
import { useAtom } from 'jotai';
import React from 'react';

Expand All @@ -8,6 +8,7 @@ export function useTimelogFilterOptions() {
const [statusState, setStatusState] = useAtom(timesheetFilterStatusState);
const [taskState, setTaskState] = useAtom(timesheetFilterTaskState);
const [selectTimesheet, setSelectTimesheet] = useAtom(timesheetDeleteState);
const [timesheetGroupByDays, setTimesheetGroupByDays] = useAtom(timesheetGroupByDayState)

const employee = employeeState;
const project = projectState;
Expand All @@ -32,5 +33,7 @@ export function useTimelogFilterOptions() {
handleSelectRowTimesheet,
selectTimesheet,
setSelectTimesheet,
timesheetGroupByDays,
setTimesheetGroupByDays
};
}
26 changes: 15 additions & 11 deletions apps/web/app/hooks/features/useTimesheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useAuthenticateUser } from './useAuthenticateUser';
import { useAtom } from 'jotai';
import { timesheetRapportState } from '@/app/stores/time-logs';
import { useQuery } from '../useQuery';
import { useCallback, useEffect } from 'react';
import { useCallback, useEffect, useMemo } from 'react';
import { deleteTaskTimesheetLogsApi, getTaskTimesheetLogsApi } from '@/app/services/client/api/timer/timer-log';
import moment from 'moment';
import { TimesheetLog, TimesheetStatus } from '@/app/interfaces';
Expand All @@ -29,7 +29,6 @@ interface DeleteTimesheetParams {
const groupByDate = (items: TimesheetLog[]): GroupedTimesheet[] => {
if (!items?.length) return [];
type GroupedMap = Record<string, TimesheetLog[]>;

const groupedByDate = items.reduce<GroupedMap>((acc, item) => {
if (!item?.timesheet?.createdAt) {
console.warn('Skipping item with missing timesheet or createdAt:', item);
Expand Down Expand Up @@ -115,15 +114,13 @@ const groupByMonth = (items: TimesheetLog[]): GroupedTimesheet[] => {
.sort((a, b) => b.date.localeCompare(a.date));
};



export function useTimesheet({
startDate,
endDate,
}: TimesheetParams) {
const { user } = useAuthenticateUser();
const [timesheet, setTimesheet] = useAtom(timesheetRapportState);
const { employee, project, task, statusState, selectTimesheet: logIds } = useTimelogFilterOptions();
const { employee, project, task, statusState, selectTimesheet: logIds, timesheetGroupByDays } = useTimelogFilterOptions();
const { loading: loadingTimesheet, queryCall: queryTimesheet } = useQuery(getTaskTimesheetLogsApi);
const { loading: loadingDeleteTimesheet, queryCall: queryDeleteTimesheet } = useQuery(deleteTaskTimesheetLogsApi)

Expand Down Expand Up @@ -222,22 +219,29 @@ export function useTimesheet({
},
[user, queryDeleteTimesheet, logIds, handleDeleteTimesheet] // deepscan-disable-line
);
const timesheetElementGroup = useMemo(() => {
if (timesheetGroupByDays === 'Daily') {
return groupByDate(timesheet);
}
if (timesheetGroupByDays === 'Weekly') {
return groupByWeek(timesheet);
}
return groupByMonth(timesheet);
}, [timesheetGroupByDays, timesheet]);


useEffect(() => {
getTaskTimesheet({ startDate, endDate });
}, [getTaskTimesheet, startDate, endDate]);


}, [getTaskTimesheet, startDate, endDate, timesheetGroupByDays]);

return {
loadingTimesheet,
timesheet: groupByDate(timesheet),
timesheetGroupByWeek: groupByWeek(timesheet),
timesheetGroupByMonth: groupByMonth(timesheet),
timesheet: timesheetElementGroup,
getTaskTimesheet,
loadingDeleteTimesheet,
deleteTaskTimesheet,
getStatusTimesheet,
timesheetGroupByDays,
statusTimesheet: getStatusTimesheet(timesheet.flatMap((data) => data))
};
}
5 changes: 3 additions & 2 deletions apps/web/app/stores/time-logs.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ITimerLogsDailyReport } from '@app/interfaces/timer/ITimerLogs';
import { atom } from 'jotai';
import { IProject, ITeamTask, OT_Member, TimesheetLog } from '../interfaces';
import { IProject, ITeamTask, OT_Member, TimesheetFilterByDays, TimesheetLog } from '../interfaces';

interface IFilterOption {
value: string;
Expand All @@ -16,4 +16,5 @@ export const timesheetFilterProjectState = atom<IProject[]>([]);
export const timesheetFilterTaskState = atom<ITeamTask[]>([]);

export const timesheetFilterStatusState = atom<IFilterOption[]>([]);
export const timesheetDeleteState = atom<string[]>([])
export const timesheetDeleteState = atom<string[]>([]);
export const timesheetGroupByDayState = atom<TimesheetFilterByDays>('Daily')
25 changes: 18 additions & 7 deletions apps/web/lib/features/integrations/calendar/table-time-sheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ export const columns: ColumnDef<TimeSheet>[] = [
export function DataTableTimeSheet({ data }: { data?: GroupedTimesheet[] }) {
const { isOpen, openModal, closeModal } = useModal();
const { deleteTaskTimesheet, loadingDeleteTimesheet, getStatusTimesheet } = useTimesheet({});
const { handleSelectRowTimesheet, selectTimesheet, setSelectTimesheet } = useTimelogFilterOptions();
const { handleSelectRowTimesheet, selectTimesheet, setSelectTimesheet, timesheetGroupByDays } = useTimelogFilterOptions();
const [isDialogOpen, setIsDialogOpen] = React.useState(false);
const handleConfirm = () => {
try {
Expand Down Expand Up @@ -235,20 +235,29 @@ export function DataTableTimeSheet({ data }: { data?: GroupedTimesheet[] }) {
isOpen={isOpen}
/>
<div className="rounded-md">
{data?.map((plan, index) => (
<div key={index}>
{data?.map((plan, index) => {
return <div key={index}>
<div
className={clsxm(
'h-[48px] flex justify-between items-center w-full',
'bg-[#ffffffcc] dark:bg-dark--theme rounded-md border-1',
'border-gray-400 px-5 text-[#71717A] font-medium'
)}>
<span>{formatDate(plan.date)}</span>
<div className='flex gap-x-3'>
<span>
{timesheetGroupByDays === 'Daily'
? ''
: timesheetGroupByDays === 'Weekly'
? `Week ${index + 1}`
: ''}
</span>
<span>{formatDate(plan.date)}</span>
</div>
<TotalDurationByDate
timesheetLog={plan.tasks}
createdAt={formatDate(plan.date)} />
createdAt={formatDate(plan.date)}
/>
</div>

<Accordion type="single" collapsible>
{Object.entries(getStatusTimesheet(plan.tasks)).map(([status, rows]) => (
<AccordionItem
Expand Down Expand Up @@ -344,7 +353,9 @@ export function DataTableTimeSheet({ data }: { data?: GroupedTimesheet[] }) {
))}
</Accordion>
</div>
))}
}

)}
</div>
<div className="flex items-center justify-end p-4 space-x-2">
<div className="flex-1 text-sm text-muted-foreground">
Expand Down

0 comments on commit 01199b0

Please sign in to comment.