Skip to content

Commit

Permalink
Merge pull request #2109 from ever-co/feat/activityTask
Browse files Browse the repository at this point in the history
Feat: activity for Task
  • Loading branch information
evereq authored Jan 23, 2024
2 parents 3c07ace + b82f949 commit 25bedac
Show file tree
Hide file tree
Showing 39 changed files with 438 additions and 42 deletions.
6 changes: 3 additions & 3 deletions apps/web/app/[locale]/error.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use client';

import Maintenance from '@components/pages/maintenance';
import ErrorPage from '@components/pages/error';

const Error = () => {
const Error = ({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) => {
return (
<>
<Maintenance />
<ErrorPage error={error} reset={reset} />
</>
);
};
Expand Down
28 changes: 25 additions & 3 deletions apps/web/app/api/tasks/employee/[employeeId]/route.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,37 @@
import { authenticatedGuard } from '@app/services/server/guards/authenticated-guard-app';
import { deleteEmployeeFromTasksRequest } from '@app/services/server/requests';
import { deleteEmployeeFromTasksRequest, getEmployeeTasksRequest } from '@app/services/server/requests';
import { NextResponse } from 'next/server';

export async function DELETE(req: Request, { params }: { params: { employeeId: string } }) {
export async function GET(req: Request, { params }: { params: { employeeId: string } }) {
const res = new NextResponse();
const { $res, user, tenantId, access_token: bearer_token } = await authenticatedGuard(req, res);
if (!user) return $res('Unauthorized');

const { searchParams } = new URL(req.url);

const { employeeId} = params
const { employeeId } = params;
const { organizationTeamId } = searchParams as unknown as {
organizationTeamId: string;
};

return $res(
await getEmployeeTasksRequest({
tenantId,
employeeId,
organizationTeamId,
bearer_token
})
);
}

export async function DELETE(req: Request, { params }: { params: { employeeId: string } }) {
const res = new NextResponse();
const { $res, user, tenantId, access_token: bearer_token } = await authenticatedGuard(req, res);
if (!user) return $res('Unauthorized');

const { searchParams } = new URL(req.url);

const { employeeId } = params;
const { organizationTeamId } = searchParams as unknown as {
organizationTeamId: string;
};
Expand Down
27 changes: 25 additions & 2 deletions apps/web/app/hooks/features/useTeamTasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,16 @@ import {
getTeamTasksAPI,
updateTaskAPI,
deleteEmployeeFromTasksAPI,
getTasksByIdAPI
getTasksByIdAPI,
getTasksByEmployeeIdAPI
} from '@app/services/client/api';
import { activeTeamState, detailedTaskState, memberActiveTaskIdState, userState } from '@app/stores';
import {
activeTeamState,
detailedTaskState,
// employeeTasksState,
memberActiveTaskIdState,
userState
} from '@app/stores';
import { activeTeamTaskState, tasksByTeamState, tasksFetchingState, teamTasksState } from '@app/stores';
import isEqual from 'lodash/isEqual';
import { useCallback, useEffect } from 'react';
Expand All @@ -40,6 +47,7 @@ export function useTeamTasks() {
const [tasksFetching, setTasksFetching] = useRecoilState(tasksFetchingState);
const authUser = useSyncRef(useRecoilValue(userState));
const memberActiveTaskId = useRecoilValue(memberActiveTaskIdState);
// const [employeeState, setEmployeeState] = useRecoilState(employeeTasksState);

const activeTeam = useRecoilValue(activeTeamState);
const activeTeamRef = useSyncRef(activeTeam);
Expand All @@ -51,6 +59,8 @@ export function useTeamTasks() {
// Queries hooks
const { queryCall, loading, loadingRef } = useQuery(getTeamTasksAPI);
const { queryCall: getTasksByIdQueryCall, loading: getTasksByIdLoading } = useQuery(getTasksByIdAPI);
const { queryCall: getTasksByEmployeeIdQueryCall, loading: getTasksByEmployeeIdLoading } =
useQuery(getTasksByEmployeeIdAPI);

const { queryCall: deleteQueryCall, loading: deleteLoading } = useQuery(deleteTaskAPI);

Expand All @@ -71,6 +81,16 @@ export function useTeamTasks() {
[getTasksByIdQueryCall, setDetailedTask]
);

const getTasksByEmployeeId = useCallback(
(employeeId: string, organizationTeamId: string) => {
return getTasksByEmployeeIdQueryCall(employeeId, organizationTeamId).then((res) => {
// setEmployeeState(res?.data || []);
return res.data;
});
},
[getTasksByEmployeeIdQueryCall]
);

const deepCheckAndUpdateTasks = useCallback(
(responseTasks: ITeamTask[], deepCheck?: boolean) => {
if (responseTasks && responseTasks.length) {
Expand Down Expand Up @@ -398,6 +418,9 @@ export function useTeamTasks() {
updateDescription,
updatePublicity,
handleStatusUpdate,
// employeeState,
getTasksByEmployeeId,
getTasksByEmployeeIdLoading,
activeTeam,
activeTeamId: activeTeam?.id,
setAllTasks,
Expand Down
6 changes: 1 addition & 5 deletions apps/web/app/hooks/features/useUserProfilePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,20 @@ import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';
import { useRecoilValue } from 'recoil';
import { activityTypeState } from '@app/stores/activity-type';

export function useUserProfilePage() {
const { activeTeam } = useOrganizationTeams();
const { activeTeamTask, updateTask } = useTeamTasks();
const activityFilter = useRecoilValue(activityTypeState);

const { user: auth } = useAuthenticateUser();
const { getTasksStatsData } = useTaskStatistics();

const params = useParams();
const memberId: string = useMemo(() => {
return (params?.memberId ?? activityFilter.member?.id ?? '') as string;
return (params?.memberId ?? '') as string;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [params]);

console.log({memberId})
const members = activeTeam?.members || [];

const matchUser = members.find((m) => {
Expand Down
68 changes: 68 additions & 0 deletions apps/web/app/hooks/features/useUserSelectedPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
'use client';

import { ITeamTask } from '@app/interfaces';
import { useCallback, useEffect } from 'react';
import { useAuthenticateUser } from './useAuthenticateUser';
import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';

export function useUserSelectedPage(id?: string) {
const { activeTeam } = useOrganizationTeams();
const { activeTeamTask, updateTask } = useTeamTasks();

const { user: auth } = useAuthenticateUser();
const { getTasksStatsData } = useTaskStatistics();

const memberId: string = id || '';

const members = activeTeam?.members || [];

const matchUser = members.find((m) => {
return m.employee.userId === memberId;
});

const isAuthUser = auth?.employee?.userId === memberId;

const activeUserTeamTask = isAuthUser ? activeTeamTask : matchUser?.lastWorkedTask;

const userProfile = isAuthUser ? auth : matchUser?.employee.user;

const employeeId = isAuthUser ? auth?.employee?.id : matchUser?.employeeId;

/* Filtering the tasks */
const tasksGrouped = useAuthTeamTasks(userProfile);

useEffect(() => {
if (employeeId) {
getTasksStatsData(employeeId);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [employeeId]);

const assignTask = useCallback(
(task: ITeamTask) => {
if (!matchUser?.employeeId) {
return Promise.resolve();
}

return updateTask({
...task,
members: [...task.members, (matchUser?.employeeId ? { id: matchUser?.employeeId } : {}) as any]
});
},
[updateTask, matchUser]
);

return {
isAuthUser,
activeUserTeamTask,
userProfile,
tasksGrouped,
member: matchUser,
assignTask
};
}

export type I_UserProfilePage = ReturnType<typeof useUserSelectedPage>;
4 changes: 4 additions & 0 deletions apps/web/app/services/client/api/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,3 +157,7 @@ export function allTaskTimesheetStatisticsAPI() {
export function deleteEmployeeFromTasksAPI(employeeId: string, organizationTeamId: string) {
return api.delete<DeleteResponse>(`/tasks/employee/${employeeId}?organizationTeamId=${organizationTeamId}`);
}

export function getTasksByEmployeeIdAPI(employeeId: string, organizationTeamId: string) {
return api.get<ITeamTask[]>(`/tasks/employee/${employeeId}?organizationTeamId=${organizationTeamId}`);
}
19 changes: 19 additions & 0 deletions apps/web/app/services/server/requests/tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,22 @@ export function deleteEmployeeFromTasksRequest({
tenantId
});
}

export function getEmployeeTasksRequest({
tenantId,
employeeId,
organizationTeamId,
bearer_token
}: {
tenantId: string;
employeeId: string;
organizationTeamId: string;
bearer_token: string;
}) {
return serverFetch<ITeamTask[]>({
path: `/tasks/employee/${employeeId}?organizationTeamId=${organizationTeamId}`,
method: 'GET',
bearer_token,
tenantId
});
}
7 changes: 6 additions & 1 deletion apps/web/app/stores/team-tasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,19 @@ export const detailedTaskState = atom<ITeamTask | null>({
default: null
});

// export const employeeTasksState = atom<ITeamTask[] | null>({
// key: 'employeeTasksState',
// default: null
// });

export const tasksByTeamState = selector<ITeamTask[]>({
key: 'tasksByTeamState',
get: ({ get }) => {
const tasks = get(teamTasksState);

return tasks
.filter(() => {
return true
return true;
})
.sort((a, b) => moment(b.createdAt).diff(a.createdAt));
}
Expand Down
41 changes: 41 additions & 0 deletions apps/web/components/pages/error/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';

import SadCry from '@components/ui/svgs/sad-cry';
import { Text } from 'lib/components';
import { useTranslations } from 'next-intl';
import React from 'react';

function ErrorPage({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
const t = useTranslations();

React.useEffect(() => {
console.error(error);
}, [error]);

return (
<div className="mt-28 flex flex-col gap-7 items-center">
<div className="m-auto relative flex justify-center items-center gap-4 text-center ">
<SadCry width={97} height={97} />
<Text className="text-[78px] font-semibold text-chetwodeBlue">{t('pages.error.TITLE')}</Text>
</div>

<Text className="text-[40px] font-bold text-center text-[#282048] dark:text-light--theme">
{t('pages.error.HEADING_TITLE')}
</Text>
<div className="flex flex-col gap-4">
<Text className="text-[20px] font-normal text-center text-gray-400">
{t('pages.error.HEADING_DESCRIPTION')}
</Text>
<button onClick={() => reset()}>Try again</button>
</div>

<div className="p-2 flex flex-col gap-y-3 container max-w-5xl border border-red-500 rounded mt-5">
<h4 className="text-2xl text-red-400 font-medium">{JSON.stringify(error.cause)}</h4>
<p className="text-lg text-red-400 font-semibold">{error.message}</p>
<p className="text-sm text-red-400">{error.stack}</p>
</div>
</div>
);
}

export default ErrorPage;
12 changes: 7 additions & 5 deletions apps/web/components/pages/maintenance/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@ import { useTranslations } from 'next-intl';
function Maintenance() {
const t = useTranslations();
return (
<div className="h-screen flex flex-col gap-4 justify-center items-center ">
<div className="mt-28 flex flex-col gap-7 items-center">
<RocketIcon width={200} height={200} className="text-xl text-chetwodeBlue" />
<div className="m-auto relative my-6 pt-12 flex justify-center items-center gap-4 text-center ">
<Text className="text-[78px] text-center font-semibold text-chetwodeBlue">
{t('pages.maintenance.HEADING_TITLE')}
</Text>
<Text className="text-[78px] text-center font-semibold text-chetwodeBlue">Maintenance</Text>
</div>

<Text className="text-[40px] my-4 font-bold text-center text-[#282048] dark:text-light--theme">
<Text className="text-[40px] font-bold text-center text-[#282048] dark:text-light--theme">
{t('pages.maintenance.HEADING_TITLE')}
</Text>

<Text className="text-[20px] font-normal text-center text-gray-400">
{t('pages.maintenance.HEADING_DESCRIPTION')}
</Text>
</div>
Expand Down
Loading

0 comments on commit 25bedac

Please sign in to comment.