Skip to content

Commit

Permalink
[Feat]:Timesheet Skeleton Calendar-View (#3419)
Browse files Browse the repository at this point in the history
* feat:timesheet skeleton calendar-view

* coderabbitai

* feat: optimize SelectionBar component with reusable ActionButton and improved class handling

* coderabbitai

* coderabbitai
  • Loading branch information
Innocent-Akim authored Dec 12, 2024
1 parent 8f94a71 commit 1bbb370
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import MonthlyTimesheetCalendar from "./MonthlyTimesheetCalendar";
import { useTimelogFilterOptions } from "@/app/hooks";
import WeeklyTimesheetCalendar from "./WeeklyTimesheetCalendar";
import { IUser } from "@/app/interfaces";
import TimesheetSkeleton from "@components/shared/skeleton/TimesheetSkeleton";
interface BaseCalendarDataViewProps {
t: TranslationHooks
data: GroupedTimesheet[];
Expand All @@ -32,31 +33,40 @@ export function CalendarView({ data, loading, user }: { data?: GroupedTimesheet[
t("common.DAYS.fri"),
t("common.DAYS.sat")
];

if (loading || !data) {
return (
<div className="grow h-full w-full bg-[#FFFFFF] dark:bg-dark--theme">
{Array.from({ length: 10 }).map((_, index) => (
<TimesheetSkeleton key={index} />
))}
</div>
);
}

if (data.length === 0) {
return (
<div className="grow w-full bg-[#FFFFFF] dark:bg-dark--theme flex flex-col items-center justify-center h-full min-h-[280px]">
<p>{t('pages.timesheet.NO_ENTRIES_FOUND')}</p>
</div>
);
}

return (
<div className="grow h-full bg-[#FFFFFF] dark:bg-dark--theme">
{data ? (
data.length > 0 ? (
<>
{timesheetGroupByDays === 'Monthly' ? (
<MonthlyCalendarDataView data={data} daysLabels={defaultDaysLabels} t={t} />
) : timesheetGroupByDays === 'Weekly' ? (
<WeeklyCalendarDataView data={data} daysLabels={defaultDaysLabels} t={t} />
) : (
<CalendarDataView data={data} t={t} />
)}
</>
) : (
<div className="flex items-center justify-center h-full min-h-[280px]">
<p>{t('pages.timesheet.NO_ENTRIES_FOUND')}</p>
</div>
)
) : (
<div className="flex items-center justify-center h-full">
<p>{t('pages.timesheet.LOADING')}</p>
</div>
)}
<div className="grow h-full w-full bg-[#FFFFFF] dark:bg-dark--theme">
{(() => {
switch (timesheetGroupByDays) {
case 'Monthly':
return <MonthlyCalendarDataView data={data} daysLabels={defaultDaysLabels} t={t} />;
case 'Weekly':
return <WeeklyCalendarDataView data={data} daysLabels={defaultDaysLabels} t={t} />;
default:
return <CalendarDataView data={data} t={t} />;
}
})()}
</div>
);

}

const CalendarDataView = ({ data, t }: { data?: GroupedTimesheet[], t: TranslationHooks }) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { cn } from "@/lib/utils";
import { useTranslations } from "next-intl";

type ActionButtonProps = {
label: string;
onClick?: (event: React.MouseEvent<HTMLButtonElement>) => void;
};

const ActionButton = ({ label, onClick }: ActionButtonProps) => (
<button
className="bg-white font-semibold h-8 px-3 rounded-lg text-[#282048] dark:text-white dark:bg-primary-light"
onClick={onClick}
>
{label}
</button>
);

interface SelectionBarProps {
fullWidth: boolean;
selectedCount: number;
onApprove: () => void;
onReject: () => void;
onDelete: () => void;
onClearSelection: () => void;
}

export const SelectionBar = ({
fullWidth,
selectedCount,
onApprove,
onReject,
onDelete,
onClearSelection
}: SelectionBarProps) => {
const t = useTranslations()
return (
<div
className={cn(
"bg-[#E2E2E2CC] fixed dark:bg-slate-800 opacity-85 h-16 z-50 bottom-5 left-1/2 transform -translate-x-1/2 shadow-lg rounded-2xl flex items-center justify-between gap-x-4 px-4",
fullWidth && "x-container"
)}
>
<div className="flex items-center justify-start gap-x-4">
<div className="flex items-center justify-center gap-x-2 text-[#282048] dark:text-[#7a62d8]">
<div className="bg-primary dark:bg-primary-light text-white rounded-full h-7 w-7 flex items-center justify-center font-bold">
<span>{selectedCount}</span>
</div>
<span>selected</span>
</div>
<ActionButton
label={t("pages.timesheet.TIMESHEET_ACTION_APPROVE_SELECTED")}
onClick={onApprove}
/>
<ActionButton
label={t("pages.timesheet.TIMESHEET_ACTION_REJECT_SELECTED")}
onClick={onReject}
/>
<ActionButton
label={t("pages.timesheet.TIMESHEET_ACTION_DELETE_SELECTED")}
onClick={onDelete}
/>
</div>
<button
onClick={onClearSelection}
className="font-semibold h-8 px-3 rounded-lg text-[#3826A6] dark:text-primary-light"
aria-label="Clear Selection"
>
Clear Selection
</button>
</div>
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ export const TimesheetCardDetail = ({ data }: { data?: Record<TimesheetStatus, T
<TaskNameInfoDisplay
task={task.task}
className={cn(
'rounded-sm h-auto !px-[0.3312rem] py-[0.2875rem] shadow-[0px_0px_15px_0px_#e2e8f0] dark:shadow-transparent'
'rounded-sm !h-auto !px-[0.3312rem] py-[0.2875rem] shadow-[0px_0px_15px_0px_#e2e8f0] dark:shadow-transparent'
)}
taskTitleClassName={cn(
'text-sm !text-ellipsis !overflow-hidden text-sm'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ export * from './RejectSelectedModal';
export * from './EditTaskModal';
export * from './CompactTimesheetComponent';
export * from './TimesheetLoader';

export * from './SelectionBar'
4 changes: 2 additions & 2 deletions apps/web/app/[locale]/timesheet/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -221,9 +221,8 @@ const TimeSheet = React.memo(function TimeSheetPage({ params }: { params: { memb
</div>
}
>
<div className="flex flex-col w-full border-1 rounded-lg bg-[#FFFFFF] dark:bg-dark--theme px-4">
<div className="flex flex-col w-full border-1 rounded-lg bg-[#FFFFFF] dark:bg-dark--theme px-4">
<Container fullWidth={fullWidth} className="h-full py-5 mt-3">
{/* <DropdownMenuDemo /> */}
<div className="border border-gray-200 rounded-lg dark:border-gray-800">
{timesheetNavigator === 'ListView' ? (
<TimesheetView
Expand All @@ -239,6 +238,7 @@ const TimeSheet = React.memo(function TimeSheetPage({ params }: { params: { memb
/>
)}
</div>

</Container>
</div>
</MainLayout>
Expand Down

0 comments on commit 1bbb370

Please sign in to comment.