From 2b47ec0f558c5692d2867ff136d9966052afb3bf Mon Sep 17 00:00:00 2001 From: AKILIMAILI CIZUNGU Innocent <51681130+Innocent-Akim@users.noreply.github.com> Date: Sun, 11 Aug 2024 12:51:02 +0200 Subject: [PATCH] [Feat]: Implement Create Manual Time Modal Component (#2875) * feat: modal-manual-time * fix: timer picker component * fix: task is defined but never used. * fix: task is defined but never used. * feat: timer picker component * fix: Remove invalid HeadCalendar export field * feat: Customize AddManualTimeModal component * fix: customize AddManualTimeModal component * fix: property * fix: change project to task --- apps/web/app/[locale]/calendar/component.tsx | 31 ++ apps/web/app/[locale]/calendar/page.tsx | 73 +++-- .../lib/components/custom-select/index.tsx | 8 +- apps/web/lib/components/time-picker/index.tsx | 6 +- .../manual-time/add-manual-time-modal.tsx | 273 +++++++++++------- apps/web/lib/features/task/task-filters.tsx | 6 +- 6 files changed, 247 insertions(+), 150 deletions(-) create mode 100644 apps/web/app/[locale]/calendar/component.tsx diff --git a/apps/web/app/[locale]/calendar/component.tsx b/apps/web/app/[locale]/calendar/component.tsx new file mode 100644 index 000000000..0b8d6501c --- /dev/null +++ b/apps/web/app/[locale]/calendar/component.tsx @@ -0,0 +1,31 @@ +import { clsxm } from "@app/utils"; +import { QueueListIcon } from "@heroicons/react/20/solid"; +import { Button } from "lib/components"; +import { LuCalendarDays } from "react-icons/lu"; + +export function HeadCalendar({ openModal }: { openModal?: () => void }) { + return ( +
+

CALENDAR

+
+ + + +
+
+ ); +} diff --git a/apps/web/app/[locale]/calendar/page.tsx b/apps/web/app/[locale]/calendar/page.tsx index e805038f3..f149a2b18 100644 --- a/apps/web/app/[locale]/calendar/page.tsx +++ b/apps/web/app/[locale]/calendar/page.tsx @@ -1,24 +1,31 @@ -"use client" -import { useOrganizationTeams } from '@app/hooks'; +"use client"; + +import { useModal, useOrganizationTeams } from '@app/hooks'; import { fullWidthState } from '@app/stores/fullWidth'; import { clsxm } from '@app/utils'; import HeaderTabs from '@components/pages/main/header-tabs'; import { PeoplesIcon } from 'assets/svg'; import { withAuthentication } from 'lib/app/authenticator'; -import { Breadcrumb, Button, Container, Divider } from 'lib/components'; -import { SetupFullCalendar } from 'lib/features' +import { Breadcrumb, Container, Divider } from 'lib/components'; +import { SetupFullCalendar } from 'lib/features'; import { Footer, MainLayout } from 'lib/layout'; import { useTranslations } from 'next-intl'; import { useParams } from 'next/navigation'; -import React, { useMemo } from 'react' +import React, { useMemo } from 'react'; import { useRecoilValue } from 'recoil'; -import { LuCalendarDays } from "react-icons/lu"; - +import { HeadCalendar } from './component'; +import { AddManualTimeModal } from 'lib/features/manual-time/add-manual-time-modal'; const CalendarPage = () => { const t = useTranslations(); const fullWidth = useRecoilValue(fullWidthState); const { activeTeam, isTrackingEnabled } = useOrganizationTeams(); + const { + isOpen: isManualTimeModalOpen, + openModal: openManualTimeModal, + closeModal: closeManualTimeModal + } = useModal(); + const params = useParams<{ locale: string }>(); const currentLocale = params ? params.locale : null; const breadcrumbPath = useMemo( @@ -29,19 +36,24 @@ const CalendarPage = () => { ], [activeTeam?.name, currentLocale, t] ); + return ( <> + -
+ + +
@@ -49,44 +61,25 @@ const CalendarPage = () => {
-
+
-
-

- CALENDAR -

-
- - - -
-
+
-
+
-
+
- ) -} + ); +}; -export default withAuthentication(CalendarPage, { displayName: 'Calender' }); +export default withAuthentication(CalendarPage, { displayName: 'Calendar' }); diff --git a/apps/web/lib/components/custom-select/index.tsx b/apps/web/lib/components/custom-select/index.tsx index 046fff4de..0e56528b7 100644 --- a/apps/web/lib/components/custom-select/index.tsx +++ b/apps/web/lib/components/custom-select/index.tsx @@ -53,8 +53,8 @@ export function SelectItems({ onClick={() => setPopoverOpen(!isPopoverOpen)} variant="outline" className={cn( - 'w-full justify-between text-left font-normal h-9 rounded-lg dark:bg-dark--theme-light', - !selectedItem && 'text-muted-foreground', + 'w-full justify-between text-left font-normal h-10 rounded-lg dark:bg-dark--theme-light', + // !selectedItem && 'text-muted-foreground', triggerClassName )} > @@ -64,7 +64,7 @@ export function SelectItems({ Select an item )} @@ -82,7 +82,7 @@ export function SelectItems({ onClick(item)} key={itemId(item)} - className="truncate hover:cursor-pointer hover:bg-slate-50 w-full text-[13px] hover:rounded-lg p-1 hover:font-bold dark:text-white dark:hover:bg-primary" + className="truncate hover:cursor-pointer hover:bg-slate-50 w-full text-[13px] hover:rounded-lg p-1 hover:font-normal dark:text-white dark:hover:bg-primary" style={{ textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden' }} > {itemToString(item)} diff --git a/apps/web/lib/components/time-picker/index.tsx b/apps/web/lib/components/time-picker/index.tsx index dba5217c5..8104aef8a 100644 --- a/apps/web/lib/components/time-picker/index.tsx +++ b/apps/web/lib/components/time-picker/index.tsx @@ -39,13 +39,13 @@ export function TimePicker({ onChange, defaultValue }: IPopoverTimePicker) { diff --git a/apps/web/lib/features/manual-time/add-manual-time-modal.tsx b/apps/web/lib/features/manual-time/add-manual-time-modal.tsx index cf8c1b4b9..8f220c52b 100644 --- a/apps/web/lib/features/manual-time/add-manual-time-modal.tsx +++ b/apps/web/lib/features/manual-time/add-manual-time-modal.tsx @@ -3,25 +3,37 @@ import '../../../styles/style.css'; import { useOrganizationTeams, useTeamTasks } from '@app/hooks'; import { clsxm } from '@app/utils'; import { DatePicker } from '@components/ui/DatePicker'; -import { PencilSquareIcon } from '@heroicons/react/20/solid'; import { format } from 'date-fns'; import { useState, useEffect, FormEvent, useCallback } from 'react'; import { Button, SelectItems, Modal } from 'lib/components'; -import { FaRegCalendarAlt } from 'react-icons/fa'; -import { HiMiniClock } from 'react-icons/hi2'; import { manualTimeReasons } from '@app/constants'; import { useTranslations } from 'next-intl'; import { IOrganizationTeamList } from '@app/interfaces'; import { useManualTime } from '@app/hooks/features/useManualTime'; import { IAddManualTimeRequest } from '@app/interfaces/timer/ITimerLogs'; +import { cn } from 'lib/utils'; +import { CalendarDays } from 'lucide-react'; +import { IoTime } from 'react-icons/io5'; +/** + * Interface for the properties of the `AddManualTimeModal` component. + * + * This interface defines the properties expected by the `AddManualTimeModal` component. + * + * @interface IAddManualTimeModalProps + * + * @property {boolean} isOpen - Indicates whether the modal is open or closed. + * @property {"AddManuelTime" | "AddTime"} params - Determines the context in which the modal is used, either "AddManuelTime" for the Add Manuel Time view or "AddTime" for the Add time. + * @property {() => void} closeModal - Callback function to be called to close the modal. + */ interface IAddManualTimeModalProps { isOpen: boolean; + params: "AddManuelTime" | "AddTime"; closeModal: () => void; } export function AddManualTimeModal(props: IAddManualTimeModalProps) { - const { closeModal, isOpen } = props; + const { closeModal, isOpen, params } = props; const t = useTranslations(); const [isBillable, setIsBillable] = useState(false); const [description, setDescription] = useState(''); @@ -93,15 +105,20 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) { const endTotalMinutes = endHours * 60 + endMinutes; const diffMinutes = endTotalMinutes - startTotalMinutes; - if (diffMinutes < 0) { - return; - } + if (diffMinutes < 0) return; const hours = Math.floor(diffMinutes / 60); const minutes = diffMinutes % 60; - setTimeDifference(`${String(hours).padStart(2, '0')}h ${String(minutes).padStart(2, '0')}m`); + + const timeString = [ + hours > 0 ? `${String(hours).padStart(2, '0')}h` : '0h', + minutes > 0 ? `${String(minutes).padStart(2, '0')}m` : '' + ].filter(Boolean).join(' '); + + setTimeDifference(timeString); }, [endTime, startTime]); + useEffect(() => { calculateTimeDifference(); }, [calculateTimeDifference, endTime, startTime]); @@ -127,48 +144,38 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) {
-
+
-
- - {date ? ( -
- - {format(date, 'PPP')} -
- ) : ( - - )} -
- } - selected={date} - onSelect={(value) => { - value && setDate(value); - }} - mode={'single'} - /> -
+ + + + + } + selected={date} + onSelect={(value) => { + value && setDate(value); + }} + mode={'single'} + />
@@ -196,7 +203,7 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) { type="time" value={startTime} onChange={(e) => setStartTime(e.target.value)} - className="w-full p-2 border font-bold border-slate-100 dark:border-slate-600 dark:bg-dark--theme-light rounded-md" + className="w-full p-2 border font-normal border-slate-300 dark:border-slate-600 dark:bg-dark--theme-light rounded-md" required />
@@ -210,19 +217,19 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) { type="time" value={endTime} onChange={(e) => setEndTime(e.target.value)} - className="w-full p-2 border font-bold border-slate-100 dark:border-slate-600 dark:bg-dark--theme-light rounded-md" + className="w-full p-2 border font-normal border-slate-300 dark:border-slate-600 dark:bg-dark--theme-light rounded-md" required />
- -
-
- {`${params === 'AddManuelTime' ? 'Total hours' : 'Added hours'}`}: +
+
+
{timeDifference} @@ -239,65 +246,127 @@ export function AddManualTimeModal(props: IAddManualTimeModalProps) { onValueChange={(team) => setTeam(team)} itemId={(team) => (team ? team.id : '')} itemToString={(team) => (team ? team.name : '')} - triggerClassName="border-slate-100 dark:border-slate-600" + triggerClassName="border-gray-300 dark:border-slate-600" />
-
- - setTaskId(task ? task.id : '')} - itemId={(task) => (task ? task.id : '')} - itemToString={(task) => (task ? task.title : '')} - triggerClassName="border-slate-100 dark:border-slate-600" - /> -
+ { + params === 'AddManuelTime' ? ( + <> -
- -