diff --git a/apps/web/lib/features/task/daily-plan/future-tasks.tsx b/apps/web/lib/features/task/daily-plan/future-tasks.tsx index 48a6e748b..18c37ed84 100644 --- a/apps/web/lib/features/task/daily-plan/future-tasks.tsx +++ b/apps/web/lib/features/task/daily-plan/future-tasks.tsx @@ -12,12 +12,12 @@ import { clsxm } from '@app/utils'; import { HorizontalSeparator, AlertPopup } from 'lib/components'; import { useEffect, useState } from 'react'; import { filterDailyPlan } from '@app/hooks/useFilterDateRange'; -import { IDailyPlan } from '@app/interfaces'; +import { IDailyPlan, IUser } from '@app/interfaces'; import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; import { useDateRange } from '@app/hooks/useDateRange'; import DailyPlanTasksTableView from './table-view'; -export function FutureTasks({ profile }: { profile: any }) { +export function FutureTasks({ profile, user }: { profile: any; user?: IUser }) { const { deleteDailyPlan, deleteDailyPlanLoading, futurePlans } = useDailyPlan(); const canSeeActivity = useCanSeeActivityScreen(); const [popupOpen, setPopupOpen] = useState(false); @@ -30,6 +30,22 @@ export function FutureTasks({ profile }: { profile: any }) { }, [date, setDate, futurePlans]); const view = useAtomValue(dailyPlanViewHeaderTabs); + useEffect(() => { + let filteredData = futurePlans; + + // Filter tasks for specific user if provided + if (user) { + filteredData = filteredData + .map((plan) => ({ + ...plan, + tasks: plan.tasks?.filter((task) => task.members?.some((member) => member.userId === user.id)) + })) + .filter((plan) => plan.tasks && plan.tasks.length > 0); + + setFutureDailyPlanTasks(filterDailyPlan(date as any, filteredData)); + } + }, [date, futurePlans, user]); + return (
{futureDailyPlanTasks?.length > 0 ? ( diff --git a/apps/web/lib/features/task/daily-plan/outstanding-all.tsx b/apps/web/lib/features/task/daily-plan/outstanding-all.tsx index 406d1eca7..b0ba77c32 100644 --- a/apps/web/lib/features/task/daily-plan/outstanding-all.tsx +++ b/apps/web/lib/features/task/daily-plan/outstanding-all.tsx @@ -8,25 +8,32 @@ import TaskBlockCard from '../task-block-card'; import { clsxm } from '@app/utils'; import { DragDropContext, Draggable, Droppable, DroppableProvided } from 'react-beautiful-dnd'; import { useState } from 'react'; -import { ITeamTask } from '@app/interfaces'; +import { ITeamTask, IUser } from '@app/interfaces'; import { handleDragAndDropDailyOutstandingAll } from '@app/helpers'; interface OutstandingAll { profile: any; + user?: IUser; } -export function OutstandingAll({ profile }: OutstandingAll) { +export function OutstandingAll({ profile, user }: OutstandingAll) { const { outstandingPlans } = useDailyPlan(); const view = useAtomValue(dailyPlanViewHeaderTabs); const displayedTaskId = new Set(); - const tasks = outstandingPlans.map((plan) => plan.tasks).reduce((red, curr) => red?.concat(curr || []), []); - const [task, setTask] = useState(() => tasks ?? []); + const tasks = outstandingPlans.flatMap( + (plan) => + (user + ? plan.tasks?.filter((task) => task.members?.some((member) => member.userId === user.id)) + : plan.tasks) ?? [] + ); + + const [task, setTask] = useState(() => tasks); return (
- {tasks && tasks?.length > 0 ? ( + {tasks.length > 0 ? ( <> handleDragAndDropDailyOutstandingAll(result, task, setTask)} diff --git a/apps/web/lib/features/task/daily-plan/outstanding-date.tsx b/apps/web/lib/features/task/daily-plan/outstanding-date.tsx index b0b6097bf..92524578f 100644 --- a/apps/web/lib/features/task/daily-plan/outstanding-date.tsx +++ b/apps/web/lib/features/task/daily-plan/outstanding-date.tsx @@ -9,28 +9,45 @@ import { clsxm } from '@app/utils'; import { useAtomValue } from 'jotai'; import { dailyPlanViewHeaderTabs } from '@app/stores/header-tabs'; import { DragDropContext, Draggable, Droppable } from 'react-beautiful-dnd'; -import { useState } from 'react'; -import { IDailyPlan } from '@app/interfaces'; +import { useEffect, useState } from 'react'; +import { IDailyPlan, IUser } from '@app/interfaces'; interface IOutstandingFilterDate { profile: any; + user?: IUser; } -export function OutstandingFilterDate({ profile }: IOutstandingFilterDate) { +export function OutstandingFilterDate({ profile, user }: IOutstandingFilterDate) { const { outstandingPlans } = useDailyPlan(); const view = useAtomValue(dailyPlanViewHeaderTabs); - const [outstandingTasks, setOutstandingTasks] = useState(outstandingPlans); + const [plans, setPlans] = useState(outstandingPlans); + + useEffect(() => { + let data = [...outstandingPlans]; + + // Filter plans for specific user if provided + if (user) { + data = data + .map((plan) => ({ + ...plan, + tasks: plan.tasks?.filter((task) => task.members?.some((member) => member.userId === user.id)) + })) + .filter((plan) => plan.tasks && plan.tasks.length > 0); + + setPlans(data); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [user]); + return (
- {outstandingTasks?.length > 0 ? ( - handleDragAndDrop(result, outstandingTasks, setOutstandingTasks)} - > + {plans?.length > 0 ? ( + handleDragAndDrop(result, plans, setPlans)}> new Date(plan.date).toISOString().split('T')[0])} + defaultValue={plans?.map((plan) => new Date(plan.date).toISOString().split('T')[0])} > - {outstandingTasks?.map((plan) => ( + {plans?.map((plan) => ( (pastPlans); + const [pastPlans, setPastPlans] = useState(_pastPlans); const { date } = useDateRange(window.localStorage.getItem('daily-plan-tab')); useEffect(() => { - setPastTasks(filterDailyPlan(date as any, pastPlans)); + setPastPlans(filterDailyPlan(date as any, pastPlans)); }, [date, pastPlans]); + useEffect(() => { + let filteredData = pastPlans; + + // Filter tasks for specific user if provided + if (user) { + filteredData = filteredData + .map((plan) => ({ + ...plan, + tasks: plan.tasks?.filter((task) => task.members?.some((member) => member.userId === user.id)) + })) + .filter((plan) => plan.tasks && plan.tasks.length > 0); + } + + setPastPlans(filteredData); + }, [date, pastPlans, user]); + return (
- {pastTasks?.length > 0 ? ( - handleDragAndDrop(result, pastPlans, setPastTasks)}> + {pastPlans?.length > 0 ? ( + handleDragAndDrop(result, pastPlans, setPastPlans)}> - {pastTasks?.map((plan) => ( + {pastPlans?.map((plan) => ( { - if (!plan) { +export const getTotalTasks = (plans: IDailyPlan[], user?: IUser): number => { + if (!plans || plans.length === 0) { return 0; } - const tasksPerPlan = plan.map((plan) => plan.tasks?.length); - if (tasksPerPlan.length <= 0) { - return 0; - } + const tasksPerPlan = plans.map((plan) => { + const filteredTasks = user + ? plan.tasks?.filter((task) => task.members?.some((member) => member.userId === user.id)) + : plan.tasks; + + return filteredTasks?.length || 0; + }); - return tasksPerPlan.reduce((a, b) => (a ?? 0) + (b ?? 0)) ?? 0; + return tasksPerPlan.reduce((total, taskCount) => total + taskCount, 0); }; diff --git a/apps/web/lib/features/team/user-team-card/index.tsx b/apps/web/lib/features/team/user-team-card/index.tsx index bf5ab103d..787d6ee9d 100644 --- a/apps/web/lib/features/team/user-team-card/index.tsx +++ b/apps/web/lib/features/team/user-team-card/index.tsx @@ -126,7 +126,7 @@ export function UserTeamCard({ const [activityFilter, setActivity] = useState('Tasks'); const activityScreens = { - Tasks: , + Tasks: , Screenshots: , Apps: , 'Visited Sites': diff --git a/apps/web/lib/features/user-profile-plans.tsx b/apps/web/lib/features/user-profile-plans.tsx index 87c427328..b0471f39a 100644 --- a/apps/web/lib/features/user-profile-plans.tsx +++ b/apps/web/lib/features/user-profile-plans.tsx @@ -26,7 +26,7 @@ import { HAS_SEEN_DAILY_PLAN_SUGGESTION_MODAL, HAS_VISITED_OUTSTANDING_TASKS } from '@app/constants'; -import { IDailyPlan, ITeamTask } from '@app/interfaces'; +import { IDailyPlan, ITeamTask, IUser } from '@app/interfaces'; import { dataDailyPlanState } from '@app/stores'; import { fullWidthState } from '@app/stores/fullWidth'; import { dailyPlanViewHeaderTabs } from '@app/stores/header-tabs'; @@ -55,9 +55,15 @@ import DailyPlanTasksTableView from './task/daily-plan/table-view'; export type FilterTabs = 'Today Tasks' | 'Future Tasks' | 'Past Tasks' | 'All Tasks' | 'Outstanding'; type FilterOutstanding = 'ALL' | 'DATE'; -export function UserProfilePlans() { +interface IUserProfilePlansProps { + user?: IUser; +} + +export function UserProfilePlans(props: IUserProfilePlansProps) { const t = useTranslations(); + const { user } = props; + const profile = useUserProfilePage(); const { todayPlan, @@ -76,14 +82,14 @@ export function UserProfilePlans() { const { setDate, date } = useDateRange(currentTab); const screenOutstanding = { - ALL: , - DATE: + ALL: , + DATE: }; const tabsScreens = { - 'Today Tasks': , - 'Future Tasks': , - 'Past Tasks': , - 'All Tasks': , + 'Today Tasks': , + 'Future Tasks': , + 'Past Tasks': , + 'All Tasks': , Outstanding: }; const [filterFuturePlanData, setFilterFuturePlanData] = useState(futurePlans); @@ -169,15 +175,24 @@ export function UserProfilePlans() { currentTab == filter && 'dark:bg-gray-600' )} > - {filter === 'Today Tasks' && getTotalTasks(todayPlan)} - {filter === 'Future Tasks' && getTotalTasks(filterFuturePlanData)} - {filter === 'Past Tasks' && getTotalTasks(filterPastPlanData)} - {filter === 'All Tasks' && getTotalTasks(filterAllPlanData)} + {filter === 'Today Tasks' && getTotalTasks(todayPlan, user)} + {filter === 'Future Tasks' && + getTotalTasks(filterFuturePlanData, user)} + {filter === 'Past Tasks' && getTotalTasks(filterPastPlanData, user)} + {filter === 'All Tasks' && getTotalTasks(filterAllPlanData, user)} {filter === 'Outstanding' && estimatedTotalTime( - outstandingPlans.map((plan) => - plan.tasks?.map((task) => task) - ) + outstandingPlans.map((plan) => { + const tasks = plan.tasks ?? []; + if (user) { + return tasks.filter((task) => + task.members?.some( + (member) => member.userId === user.id + ) + ); + } + return tasks; + }) ).totalTasks}
@@ -285,7 +300,15 @@ export function UserProfilePlans() { * @param {{ profile: any; currentTab?: FilterTabs }} { profile, currentTab = 'All Tasks' } * @return {*} */ -function AllPlans({ profile, currentTab = 'All Tasks' }: { profile: any; currentTab?: FilterTabs }) { +function AllPlans({ + profile, + currentTab = 'All Tasks', + user +}: { + profile: any; + currentTab?: FilterTabs; + user?: IUser; +}) { // Filter plans const filteredPlans = useRef([]); const { sortedPlans, todayPlan } = useDailyPlan(); @@ -305,6 +328,22 @@ function AllPlans({ profile, currentTab = 'All Tasks' }: { profile: any; current setPlans(filterDailyPlan(date as any, filteredPlans.current)); }, [date, todayPlan]); + useEffect(() => { + let filteredData = filterDailyPlan(date as any, filteredPlans.current); + + // Filter tasks for specific user if provided + if (user) { + filteredData = filteredData + .map((plan) => ({ + ...plan, + tasks: plan.tasks?.filter((task) => task.members?.some((member) => member.userId === user.id)) + })) + .filter((plan) => plan.tasks && plan.tasks.length > 0); + } + + setPlans(filteredData); + }, [date, todayPlan, user]); + return (
{Array.isArray(plans) && plans?.length > 0 ? ( diff --git a/apps/web/lib/features/user-profile-tasks.tsx b/apps/web/lib/features/user-profile-tasks.tsx index 46b02dfa4..663d49138 100644 --- a/apps/web/lib/features/user-profile-tasks.tsx +++ b/apps/web/lib/features/user-profile-tasks.tsx @@ -8,11 +8,13 @@ import { useEffect, useMemo, useState } from 'react'; import { ScreenCalendar } from './activity/screen-calendar'; import { cn } from 'lib/utils'; import { useScrollPagination } from '@app/hooks/features/usePagination'; +import { IUser } from '@/app/interfaces'; type Props = { tabFiltered: I_TaskFilter; profile: I_UserProfilePage; paginateTasks?: boolean; + user?: IUser; }; /** @@ -20,7 +22,7 @@ type Props = { * @param - `profile` - The user profile page data. * @returns A component that displays a user's profile page. */ -export function UserProfileTask({ profile, paginateTasks, tabFiltered }: Props) { +export function UserProfileTask({ profile, paginateTasks, tabFiltered, user }: Props) { const [scrollableContainer, setScrollableContainer] = useState(null); const t = useTranslations(); @@ -93,7 +95,7 @@ export function UserProfileTask({ profile, paginateTasks, tabFiltered }: Props) /> )} {tabFiltered.tab === 'stats' && } - {tabFiltered.tab === 'dailyplan' && } + {tabFiltered.tab === 'dailyplan' && } {tabFiltered.tab === 'worked' && otherTasks.length > 0 && (