-
Notifications
You must be signed in to change notification settings - Fork 51
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Feat]: Add time Entry Modal and Update Timesheet Status based on API response #3365
Changes from 4 commits
34256ca
a85d119
313f891
cb05f87
c4ad2e9
4028c8b
c586bff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -336,7 +336,7 @@ export const FilterCalendar = memo(function FuturePlansCalendar<T extends { date | |||||||||||||
toYear={ | ||||||||||||||
endYear || | ||||||||||||||
new Date(sortedPlansByDateDesc?.[sortedPlansByDateDesc?.length - 1]?.date ?? Date.now()).getFullYear() + | ||||||||||||||
10 | ||||||||||||||
10 | ||||||||||||||
} | ||||||||||||||
Comment on lines
338
to
340
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Handle edge case when no plans exist The Consider this safer implementation: - endYear ||
- new Date(sortedPlansByDateDesc?.[sortedPlansByDateDesc?.length - 1]?.date ?? Date.now()).getFullYear() +
- 10
+ endYear || new Date().getFullYear() + 10 📝 Committable suggestion
Suggested change
|
||||||||||||||
/> | ||||||||||||||
); | ||||||||||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { ID } from "@/app/interfaces"; | ||
import { authenticatedGuard } from "@/app/services/server/guards/authenticated-guard-app"; | ||
import { updateStatusTimesheetRequest } from "@/app/services/server/requests"; | ||
import { NextResponse } from "next/server"; | ||
|
||
export async function PUT(req: Request) { | ||
const res = new NextResponse(); | ||
const { | ||
$res, | ||
user, | ||
tenantId, | ||
organizationId, | ||
access_token | ||
} = await authenticatedGuard(req, res); | ||
if (!user) return $res('Unauthorized'); | ||
Innocent-Akim marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
try { | ||
const { searchParams } = new URL(req.url); | ||
|
||
const rawIds = searchParams.get('ids'); | ||
const status = searchParams.get('status'); | ||
|
||
if (!rawIds || !status) { | ||
return $res({ | ||
success: false, | ||
message: 'Missing required parameters' | ||
}); | ||
} | ||
let ids: ID[]; | ||
try { | ||
ids = JSON.parse(rawIds); | ||
if (!Array.isArray(ids) || !ids.length) { | ||
throw new Error('Invalid ids format'); | ||
} | ||
} catch (error) { | ||
return $res({ | ||
success: false, | ||
message: 'Invalid ids format' | ||
}); | ||
} | ||
const validStatuses = ['pending', 'approved', 'rejected']; | ||
if (!validStatuses.includes(status)) { | ||
return $res({ | ||
success: false, | ||
message: 'Invalid status value' | ||
}); | ||
} | ||
const { data } = await updateStatusTimesheetRequest( | ||
{ | ||
ids, | ||
organizationId, | ||
status, | ||
tenantId | ||
}, | ||
access_token | ||
); | ||
|
||
return $res({ | ||
success: true, | ||
data | ||
}); | ||
} catch (error) { | ||
console.error('Error updating timesheet status:', error); | ||
return $res({ | ||
success: false, | ||
message: 'Failed to update timesheet status' | ||
}); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,4 +1,4 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||
import { timesheetDeleteState, timesheetGroupByDayState, timesheetFilterEmployeeState, timesheetFilterProjectState, timesheetFilterStatusState, timesheetFilterTaskState } from '@/app/stores'; | ||||||||||||||||||||||||||||||||||||||||||||||||
import { timesheetDeleteState, timesheetGroupByDayState, timesheetFilterEmployeeState, timesheetFilterProjectState, timesheetFilterStatusState, timesheetFilterTaskState, timesheetUpdateStatus } from '@/app/stores'; | ||||||||||||||||||||||||||||||||||||||||||||||||
import { useAtom } from 'jotai'; | ||||||||||||||||||||||||||||||||||||||||||||||||
import React from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -8,12 +8,21 @@ export function useTimelogFilterOptions() { | |||||||||||||||||||||||||||||||||||||||||||||||
const [statusState, setStatusState] = useAtom(timesheetFilterStatusState); | ||||||||||||||||||||||||||||||||||||||||||||||||
const [taskState, setTaskState] = useAtom(timesheetFilterTaskState); | ||||||||||||||||||||||||||||||||||||||||||||||||
const [selectTimesheet, setSelectTimesheet] = useAtom(timesheetDeleteState); | ||||||||||||||||||||||||||||||||||||||||||||||||
const [timesheetGroupByDays, setTimesheetGroupByDays] = useAtom(timesheetGroupByDayState) | ||||||||||||||||||||||||||||||||||||||||||||||||
const [timesheetGroupByDays, setTimesheetGroupByDays] = useAtom(timesheetGroupByDayState); | ||||||||||||||||||||||||||||||||||||||||||||||||
const [puTimesheetStatus, setPuTimesheetStatus] = useAtom(timesheetUpdateStatus) | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
const employee = employeeState; | ||||||||||||||||||||||||||||||||||||||||||||||||
const project = projectState; | ||||||||||||||||||||||||||||||||||||||||||||||||
const task = taskState | ||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||
const generateTimeOptions = (interval = 15) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
const totalSlots = (24 * 60) / interval; // Total intervals in a day | ||||||||||||||||||||||||||||||||||||||||||||||||
return Array.from({ length: totalSlots }, (_, i) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
const hour = Math.floor((i * interval) / 60).toString().padStart(2, '0'); | ||||||||||||||||||||||||||||||||||||||||||||||||
const minutes = ((i * interval) % 60).toString().padStart(2, '0'); | ||||||||||||||||||||||||||||||||||||||||||||||||
return `${hour}:${minutes}`; | ||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||
const handleSelectRowTimesheet = (items: string) => { | ||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+18
to
+25
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider optimizing the time generation function While the implementation is functional, there are several opportunities for improvement:
Consider applying these improvements: +const MINUTES_IN_DAY = 24 * 60;
+
+const generateTimeOptions = React.useMemo(() => (interval = 15) => {
+ if (interval <= 0 || interval > MINUTES_IN_DAY) {
+ throw new Error('Invalid interval value');
+ }
+ const totalSlots = MINUTES_IN_DAY / interval;
return Array.from({ length: totalSlots }, (_, i) => {
const hour = Math.floor((i * interval) / 60).toString().padStart(2, '0');
const minutes = ((i * interval) % 60).toString().padStart(2, '0');
- return `${hour}:${minutes}`;
+ const period = hour >= 12 ? 'PM' : 'AM';
+ const displayHour = hour % 12 || 12;
+ return `${displayHour}:${minutes} ${period}`;
});
-};
+}, []); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||
setSelectTimesheet((prev) => prev.includes(items) ? prev.filter((filter) => filter !== items) : [...prev, items]) | ||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -34,6 +43,9 @@ export function useTimelogFilterOptions() { | |||||||||||||||||||||||||||||||||||||||||||||||
selectTimesheet, | ||||||||||||||||||||||||||||||||||||||||||||||||
setSelectTimesheet, | ||||||||||||||||||||||||||||||||||||||||||||||||
timesheetGroupByDays, | ||||||||||||||||||||||||||||||||||||||||||||||||
setTimesheetGroupByDays | ||||||||||||||||||||||||||||||||||||||||||||||||
setTimesheetGroupByDays, | ||||||||||||||||||||||||||||||||||||||||||||||||
generateTimeOptions, | ||||||||||||||||||||||||||||||||||||||||||||||||
setPuTimesheetStatus, | ||||||||||||||||||||||||||||||||||||||||||||||||
puTimesheetStatus | ||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -3,9 +3,9 @@ import { useAtom } from 'jotai'; | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { timesheetRapportState } from '@/app/stores/time-logs'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useQuery } from '../useQuery'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useCallback, useEffect, useMemo } from 'react'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { deleteTaskTimesheetLogsApi, getTaskTimesheetLogsApi } from '@/app/services/client/api/timer/timer-log'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { deleteTaskTimesheetLogsApi, getTaskTimesheetLogsApi, updateStatusTimesheetFromApi } from '@/app/services/client/api/timer/timer-log'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import moment from 'moment'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { TimesheetLog, TimesheetStatus } from '@/app/interfaces'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { ID, TimesheetLog, TimesheetStatus } from '@/app/interfaces'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
import { useTimelogFilterOptions } from './useTimelogFilterOptions'; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
interface TimesheetParams { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -100,9 +100,10 @@ export function useTimesheet({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}: TimesheetParams) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { user } = useAuthenticateUser(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const [timesheet, setTimesheet] = useAtom(timesheetRapportState); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { employee, project, task, statusState, selectTimesheet: logIds, timesheetGroupByDays } = useTimelogFilterOptions(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { employee, project, task, statusState, selectTimesheet: logIds, timesheetGroupByDays, puTimesheetStatus } = useTimelogFilterOptions(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Potential typo in variable name 'puTimesheetStatus' The variable |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { loading: loadingTimesheet, queryCall: queryTimesheet } = useQuery(getTaskTimesheetLogsApi); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { loading: loadingDeleteTimesheet, queryCall: queryDeleteTimesheet } = useQuery(deleteTaskTimesheetLogsApi) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { loading: loadingDeleteTimesheet, queryCall: queryDeleteTimesheet } = useQuery(deleteTaskTimesheetLogsApi); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const { loading: loadingUpdateTimesheetStatus, queryCall: queryUpdateTimesheetStatus } = useQuery(updateStatusTimesheetFromApi) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const getTaskTimesheet = useCallback( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -137,6 +138,31 @@ export function useTimesheet({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const updateTimesheetStatus = useCallback( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
({ status, ids }: { status: TimesheetStatus, ids: ID[] | ID }) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (!user) return; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
queryUpdateTimesheetStatus({ ids, status }) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.then((response) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const updatedData = timesheet.map(item => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const newItem = response.data.find(newItem => newItem.id === item.timesheet.id); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
if (newItem) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
...item, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
timesheet: { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
...item.timesheet, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
status: newItem.status | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return item; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
setTimesheet(updatedData); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
.catch((error) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
console.error('Error fetching timesheet:', error); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, [queryUpdateTimesheetStatus]) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+141
to
+165
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Incomplete dependency array in The Apply this diff to fix the dependency array: }, [queryUpdateTimesheetStatus
+ , user, timesheet, setTimesheet
]) 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const getStatusTimesheet = (items: TimesheetLog[] = []) => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
const STATUS_MAP: Record<TimesheetStatus, TimesheetLog[]> = { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
PENDING: [], | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -212,7 +238,7 @@ export function useTimesheet({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
useEffect(() => { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getTaskTimesheet({ startDate, endDate }); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, [getTaskTimesheet, startDate, endDate, timesheetGroupByDays]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}, [getTaskTimesheet, startDate, endDate, timesheetGroupByDays, timesheet]); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possible infinite loop due to Including Consider removing Apply this diff: }, [getTaskTimesheet, startDate, endDate, timesheetGroupByDays
- , timesheet
]); 📝 Committable suggestion
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
return { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
loadingTimesheet, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
@@ -222,6 +248,9 @@ export function useTimesheet({ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
deleteTaskTimesheet, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
getStatusTimesheet, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
timesheetGroupByDays, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
statusTimesheet: getStatusTimesheet(timesheet.flat()) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
statusTimesheet: getStatusTimesheet(timesheet.flat()), | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
updateTimesheetStatus, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
loadingUpdateTimesheetStatus, | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
puTimesheetStatus | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
Comment on lines
+251
to
+254
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Inconsistent variable naming: 'puTimesheetStatus' The variable |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -108,3 +108,32 @@ export interface TimesheetLog extends BaseEntity { | |
duration: number; | ||
isEdited: boolean; | ||
} | ||
|
||
|
||
|
||
export interface UpdateTimesheetStatus extends BaseEntity { | ||
isActive: boolean; | ||
isArchived: boolean; | ||
archivedAt: string | null; | ||
duration: number; | ||
keyboard: number; | ||
mouse: number; | ||
overall: number; | ||
startedAt: string; | ||
stoppedAt: string; | ||
approvedAt: string | null; | ||
submittedAt: string | null; | ||
lockedAt: string | null; | ||
editedAt: string | null; | ||
isBilled: boolean; | ||
status: | ||
| "DRAFT" | ||
| "PENDING" | ||
| "IN REVIEW" | ||
| "DENIED" | ||
| "APPROVED"; | ||
employeeId: string; | ||
approvedById: string | null; | ||
employee: Employee; | ||
isEdited: boolean; | ||
} | ||
Comment on lines
+114
to
+139
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Refactor to reduce code duplication with existing Timesheet interface The new -export interface UpdateTimesheetStatus extends BaseEntity {
- isActive: boolean;
- isArchived: boolean;
- archivedAt: string | null;
- duration: number;
- keyboard: number;
- mouse: number;
- overall: number;
- startedAt: string;
- stoppedAt: string;
- approvedAt: string | null;
- submittedAt: string | null;
- lockedAt: string | null;
- editedAt: string | null;
- isBilled: boolean;
- status:
- | "DRAFT"
- | "PENDING"
- | "IN REVIEW"
- | "DENIED"
- | "APPROVED";
- employeeId: string;
- approvedById: string | null;
- employee: Employee;
- isEdited: boolean;
-}
+type TimesheetStatus = "DRAFT" | "PENDING" | "IN REVIEW" | "DENIED" | "APPROVED";
+
+export interface UpdateTimesheetStatus extends Omit<Timesheet, 'status'> {
+ status: TimesheetStatus;
+}
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion
Enhance accessibility for toggle buttons
While the dark mode styling is improved, the toggle buttons could benefit from better accessibility support.
Consider these accessibility improvements:
Usage example: