diff --git a/apps/web/app/[locale]/profile/[memberId]/page.tsx b/apps/web/app/[locale]/profile/[memberId]/page.tsx index 3e3dd3ebf..c44a3d619 100644 --- a/apps/web/app/[locale]/profile/[memberId]/page.tsx +++ b/apps/web/app/[locale]/profile/[memberId]/page.tsx @@ -13,7 +13,7 @@ import { TaskFilter, Timer, TimerStatus, UserProfileTask, getTimerStatusValue, u import { MainHeader, MainLayout } from 'lib/layout'; import Link from 'next/link'; import React, { useCallback, useMemo, useState } from 'react'; -import { useTranslations } from 'next-intl'; +import { useTranslations } from 'next-intl' import stc from 'string-to-color'; import { useRecoilValue, useSetRecoilState } from 'recoil'; @@ -126,7 +126,6 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId {/* User Profile Detail */}
- {profileIsAuthUser && isTrackingEnabled && ( - - {/* Divider */} - {/*
*/} {hook.tab == 'worked' && canSeeActivity && ( diff --git a/apps/web/lib/features/task/task-filters.tsx b/apps/web/lib/features/task/task-filters.tsx index e2e1a8659..f098f23fc 100644 --- a/apps/web/lib/features/task/task-filters.tsx +++ b/apps/web/lib/features/task/task-filters.tsx @@ -6,7 +6,9 @@ import { useAuthenticateUser, useDailyPlan, useOrganizationTeams, - useOutsideClick + useOutsideClick, + useModal, + useTeamTasks } from '@app/hooks'; import { IClassName, ITeamTask } from '@app/interfaces'; import { clsxm } from '@app/utils'; @@ -14,16 +16,25 @@ import { Transition } from '@headlessui/react'; import { Button, InputField, Tooltip, VerticalSeparator } from 'lib/components'; import { SearchNormalIcon } from 'assets/svg'; import intersection from 'lodash/intersection'; -import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useCallback, useEffect, useMemo, useState, FormEvent } from 'react'; import { TaskUnOrAssignPopover } from './task-assign-popover'; import { TaskLabelsDropdown, TaskPropertiesDropdown, TaskSizesDropdown, TaskStatusDropdown } from './task-status'; import { useTranslations } from 'next-intl'; import { SettingFilterIcon } from 'assets/svg'; import { DailyPlanFilter } from './daily-plan/daily-plan-filter'; +import { Modal, Divider } from 'lib/components'; +import api from '@app/services/client/axios'; +import { MdOutlineMoreTime } from "react-icons/md"; +import { IoIosTimer } from "react-icons/io"; +import { FiLoader } from "react-icons/fi"; +import { DatePicker } from '@components/ui/DatePicker'; +import { PencilSquareIcon } from '@heroicons/react/20/solid'; +import { FaRegCalendarAlt } from "react-icons/fa"; import { useDateRange } from '@app/hooks/useDateRange'; import { TaskDatePickerWithRange } from './task-date-range'; export type ITab = 'worked' | 'assigned' | 'unassigned' | 'dailyplan'; + type ITabs = { tab: ITab; name: string; @@ -263,6 +274,105 @@ export function TaskFilter({ className, hook, profile }: IClassName & Props) { function InputFilters({ hook, profile }: Props) { const t = useTranslations(); const [loading, setLoading] = useState(false); + const { tasks } = useTeamTasks(); + const { activeTeam } = useOrganizationTeams(); + const members = activeTeam?.members; + + const [date, setDate] = useState(''); + const [isBillable, setIsBillable] = useState(false); + const [startTime, setStartTime] = useState(''); + const [endTime, setEndTime] = useState(''); + const [team, setTeam] = useState(''); + const [task, setTask] = useState(''); + const [description, setDescription] = useState(''); + const [reason, setReason] = useState(''); + const [timeDifference, setTimeDifference] = useState(''); + const [errorMsg, setError] = useState(''); + const [loading1, setLoading1] = useState(false); + + const { isOpen, openModal, closeModal } = useModal(); + + useEffect(() => { + const now = new Date(); + const currentDate = now.toISOString().slice(0, 10); + const currentTime = now.toTimeString().slice(0, 5); + + setDate(currentDate); + setStartTime(currentTime); + setEndTime(currentTime); + }, []); + + + const handleSubmit = (e: FormEvent) => { + e.preventDefault(); + + const timeObject = { + date, + isBillable, + startTime, + endTime, + team, + task, + description, + reason, + timeDifference + }; + + if (date && startTime && endTime && team && task) { + setLoading1(true); + setError(''); + const postData = async () => { + try { + const response = await api.post('/add_time', timeObject); + if (response.data.message) { + setLoading1(false); + closeModal(); + } + + } catch (err) { + setError('Failed to post data'); + setLoading1(false); + } + }; + + postData(); + } else { + setError(`Please complete all required fields with a ${"*"}`) + } + }; + + const calculateTimeDifference = () => { + + const [startHours, startMinutes] = startTime.split(':').map(Number); + const [endHours, endMinutes] = endTime.split(':').map(Number); + + const startTotalMinutes = startHours * 60 + startMinutes; + const endTotalMinutes = endHours * 60 + endMinutes; + + const diffMinutes = endTotalMinutes - startTotalMinutes; + if (diffMinutes < 0) { + return; + } + + const hours = Math.floor(diffMinutes / 60); + const minutes = diffMinutes % 60; + setTimeDifference(`${hours} Hours ${minutes} Minutes`); + }; + + useEffect(() => { + calculateTimeDifference(); + }, [endTime, startTime]); + + useEffect(() => { + if (task == '') { + setTask(tasks[0]?.id); + } + if (team == '') { + members && setTeam(members[0].id); + } + + }, [tasks, members]); + const osSpecificAssignTaskTooltipLabel = 'A'; return ( @@ -294,6 +404,12 @@ function InputFilters({ hook, profile }: Props) { {t('common.FILTER')} + {/* Assign task combobox */} {t('common.ASSIGN_TASK')} -
+
+ + +
+
+ +
+ + { + date ? +
+ + {date} +
+ : ( + + )} +
+ } + selected={new Date()} + onSelect={(dateI) => { + dateI && setDate(dateI.toDateString()); + }} + mode={'single'} + /> +
+
+ +
+ +
setIsBillable(!isBillable)} + style={isBillable ? { background: 'linear-gradient(to right, #3726a662, transparent)' } : { background: '#3726a662' }} + > +
+
+
+
+
+ + setStartTime(e.target.value)} + className="w-full p-2 border text-[13px] font-bold border-gray-300 rounded-[10px]" + required + /> +
+ +
+ + setEndTime(e.target.value)} + className="w-full p-2 border text-[13px] font-bold border-gray-300 rounded-[10px]" + required + /> +
+
+ +
+ +
+ + {timeDifference} +
+
+ +
+ + +
+ +
+ + +
+ +
+ +