diff --git a/apps/web/app/[locale]/page-component.tsx b/apps/web/app/[locale]/page-component.tsx
index 3a2b3b778..00c1ce3fa 100644
--- a/apps/web/app/[locale]/page-component.tsx
+++ b/apps/web/app/[locale]/page-component.tsx
@@ -8,13 +8,7 @@ import { clsxm } from '@app/utils';
import NoTeam from '@components/pages/main/no-team';
import { withAuthentication } from 'lib/app/authenticator';
import { Breadcrumb, Card } from 'lib/components';
-import {
- AuthUserTaskInput,
- TeamInvitations,
- TeamMembers,
- Timer,
- UnverifiedEmail
-} from 'lib/features';
+import { AuthUserTaskInput, TeamInvitations, TeamMembers, Timer, UnverifiedEmail } from 'lib/features';
import { MainLayout } from 'lib/layout';
import { IssuesView } from '@app/constants';
import { useNetworkState } from '@uidotdev/usehooks';
@@ -35,163 +29,144 @@ import { headerTabs } from '@app/stores/header-tabs';
import { usePathname } from 'next/navigation';
import { PeoplesIcon } from 'assets/svg';
import TeamMemberHeader from 'lib/features/team-member-header';
-import {
- ResizableHandle,
- ResizablePanel,
- ResizablePanelGroup
-} from '@components/ui/resizable';
+import { ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@components/ui/resizable';
import { TeamOutstandingNotifications } from 'lib/features/team/team-outstanding-notifications';
function MainPage() {
- const t = useTranslations();
- const [headerSize, setHeaderSize] = useState(10);
- const {
- isTeamMember,
- isTrackingEnabled,
- activeTeam
- } = useOrganizationTeams();
- const [fullWidth, setFullWidth] = useAtom(fullWidthState);
- const [view, setView] = useAtom(headerTabs);
- const path = usePathname();
- const breadcrumb = [
- { title: JSON.parse(t('pages.home.BREADCRUMB')), href: '/' },
- { title: activeTeam?.name || '', href: '/' },
- { title: t(`common.${view}`), href: `/` }
- ];
- const { online } = useNetworkState();
- useEffect(() => {
- if (view == IssuesView.KANBAN && path == '/') {
- setView(IssuesView.CARDS);
- }
- // eslint-disable-next-line react-hooks/exhaustive-deps
- }, [path, setView]);
-
- React.useEffect(() => {
- window && window?.localStorage.getItem('conf-fullWidth-mode');
- setFullWidth(
- JSON.parse(window?.localStorage.getItem('conf-fullWidth-mode') || 'true')
- );
- }, [setFullWidth]);
-
- if (!online) {
- return ;
- }
- return (
- <>
-
- {/*
*/}
-
-
-
-
- {/* */}
- setHeaderSize(size)}
- >
-
-
-
-
-
-
-
-
+ const t = useTranslations();
+ const [headerSize, setHeaderSize] = useState(10);
+ const { isTeamMember, isTrackingEnabled, activeTeam } = useOrganizationTeams();
+ const [fullWidth, setFullWidth] = useAtom(fullWidthState);
+ const [view, setView] = useAtom(headerTabs);
+ const path = usePathname();
+ const breadcrumb = [
+ { title: JSON.parse(t('pages.home.BREADCRUMB')), href: '/' },
+ { title: activeTeam?.name || '', href: '/' },
+ { title: t(`common.${view}`), href: `/` }
+ ];
+ const { online } = useNetworkState();
+ useEffect(() => {
+ if (view == IssuesView.KANBAN && path == '/') {
+ setView(IssuesView.CARDS);
+ }
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [path, setView]);
+
+ React.useEffect(() => {
+ window && window?.localStorage.getItem('conf-fullWidth-mode');
+ setFullWidth(JSON.parse(window?.localStorage.getItem('conf-fullWidth-mode') || 'true'));
+ }, [setFullWidth]);
+
+ if (!online) {
+ return
;
+ }
+ return (
+ <>
+
+ {/*
*/}
+
+
+
+
+
+ {/* */}
+
+ setHeaderSize(size)}
+ >
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {isTeamMember ? (
+
+ ) : null}
+
+
+
+
+
+
+
+
+ {/* */}
+
+ {isTeamMember ? : }
+
+
- {isTeamMember ? (
-
- ) : null}
-
-
-
-
-
-
- {/* */}
-
-
- {isTeamMember ? (
-
- ) : (
-
- )}
-
-
-
-
-
-
-
- >
- );
+
+
+
+ >
+ );
}
-function TaskTimerSection({
- isTrackingEnabled
-}: {
- isTrackingEnabled: boolean;
-}) {
- const [showInput, setShowInput] = React.useState(false);
- return (
-
-
- setShowInput((p) => !p)}
- className="border dark:border-[#26272C] w-full rounded p-2 md:hidden flex justify-center mt-2"
- >
-
- {showInput ? 'hide the issue input' : 'show the issue input'}
-
-
- {isTrackingEnabled ? (
-
-
-
- ) : null}
-
- );
+function TaskTimerSection({ isTrackingEnabled }: { isTrackingEnabled: boolean }) {
+ const [showInput, setShowInput] = React.useState(false);
+ return (
+
+
+ setShowInput((p) => !p)}
+ className="border dark:border-[#26272C] w-full rounded p-2 md:hidden flex justify-center mt-2"
+ >
+
+ {showInput ? 'hide the issue input' : 'show the issue input'}
+
+
+ {isTrackingEnabled ? (
+
+
+
+ ) : null}
+
+ );
}
export default withAuthentication(MainPage, { displayName: 'MainPage' });
diff --git a/apps/web/app/[locale]/team/[teamId]/[profileLink]/page.tsx b/apps/web/app/[locale]/team/[teamId]/[profileLink]/page.tsx
index 62b2ef55c..b6ef5f98e 100644
--- a/apps/web/app/[locale]/team/[teamId]/[profileLink]/page.tsx
+++ b/apps/web/app/[locale]/team/[teamId]/[profileLink]/page.tsx
@@ -5,7 +5,7 @@ import { useRefreshIntervalV2 } from '@app/hooks';
import { usePublicOrganizationTeams } from '@app/hooks/features/usePublicOrganizationTeams';
import { publicState } from '@app/stores/public';
import { Breadcrumb, Container } from 'lib/components';
-import { TeamMembers, UnverifiedEmail, UserTeamCardHeader } from 'lib/features';
+import { TeamMembersView, UnverifiedEmail, UserTeamCardHeader } from 'lib/features';
import { MainHeader, MainLayout } from 'lib/layout';
import { useRouter, useParams, notFound } from 'next/navigation';
import { useCallback, useEffect } from 'react';
@@ -13,84 +13,88 @@ import { useTranslations } from 'next-intl';
import { useAtom, useAtomValue } from 'jotai';
import { fullWidthState } from '@app/stores/fullWidth';
+import { IssuesView } from '@app/constants';
const Team = () => {
- const router = useRouter();
- const params = useParams();
-
- const {
- loadPublicTeamData,
- loadPublicTeamMiscData,
- publicTeam: publicTeamData
- } = usePublicOrganizationTeams();
- const t = useTranslations();
- const [publicTeam, setPublic] = useAtom(publicState);
- const fullWidth = useAtomValue(fullWidthState);
-
- useEffect(() => {
- const userId = getActiveUserIdCookie();
-
- if (
- userId &&
- publicTeamData &&
- publicTeamData.members.find((member) => member.employee.userId === userId)
- ) {
- router.replace('/');
- }
- }, [publicTeamData, router]);
-
- const loadData = useCallback(() => {
- if (params?.teamId && params?.profileLink) {
- loadPublicTeamData(
- params?.profileLink as string,
- params?.teamId as string
- ).then((res: any) => {
- if (res?.data?.data?.status === 404) {
- notFound();
- }
- });
- setPublic(true);
- }
- }, [loadPublicTeamData, setPublic, params?.teamId, params?.profileLink]);
- const loadMicsData = useCallback(() => {
- if (params?.teamId && params?.profileLink) {
- loadPublicTeamMiscData(
- params?.profileLink as string,
- params?.teamId as string
- );
- }
- }, [loadPublicTeamMiscData, params?.teamId, params?.profileLink]);
-
- useEffect(() => {
- loadData();
- }, [loadData]);
- useEffect(() => {
- loadMicsData();
- }, [loadMicsData]);
-
- useRefreshIntervalV2(loadData, 10 * 1000, true);
- useRefreshIntervalV2(loadMicsData, 30 * 1000, true);
-
- const breadcrumb = [...JSON.parse(t('pages.home.BREADCRUMB'))];
- return (
-
-
-
-
-
-
- {/* Header user card list */}
-
-
-
- {/* Divider */}
-
-
-
-
-
-
- );
+ const router = useRouter();
+ const params = useParams();
+
+ const {
+ loadPublicTeamData,
+ loadPublicTeamMiscData,
+ teamsFetching,
+ publicTeam: publicTeamData
+ } = usePublicOrganizationTeams();
+ const t = useTranslations();
+ const [publicTeam, setPublic] = useAtom(publicState);
+ const fullWidth = useAtomValue(fullWidthState);
+
+ useEffect(() => {
+ const userId = getActiveUserIdCookie();
+
+ if (userId && publicTeamData && publicTeamData.members.find((member) => member.employee.userId === userId)) {
+ router.replace('/');
+ }
+ }, [publicTeamData, router]);
+
+ const loadData = useCallback(() => {
+ if (params?.teamId && params?.profileLink) {
+ loadPublicTeamData(params?.profileLink as string, params?.teamId as string).then((res: any) => {
+ if (res?.data?.data?.status === 404) {
+ notFound();
+ }
+ });
+ setPublic(true);
+ }
+ }, [loadPublicTeamData, setPublic, params?.teamId, params?.profileLink]);
+
+ const loadMicsData = useCallback(() => {
+ if (params?.teamId && params?.profileLink) {
+ loadPublicTeamMiscData(params?.profileLink as string, params?.teamId as string);
+ }
+ }, [loadPublicTeamMiscData, params?.teamId, params?.profileLink]);
+
+ useEffect(() => {
+ loadData();
+ }, [loadData]);
+
+ useEffect(() => {
+ loadMicsData();
+ }, [loadMicsData]);
+
+ useRefreshIntervalV2(loadData, 10 * 1000, true);
+ useRefreshIntervalV2(loadMicsData, 30 * 1000, true);
+
+ const breadcrumb = [...JSON.parse(t('pages.home.BREADCRUMB'))];
+
+ return (
+
+
+
+
+
+
+ {/* Header user card list */}
+
+
+
+ {/* Divider */}
+
+
+
+
+
+ {/* */}
+
+
+ );
};
export default Team;
diff --git a/apps/web/app/hooks/features/usePublicOrganizationTeams.ts b/apps/web/app/hooks/features/usePublicOrganizationTeams.ts
index 064e96c64..bb465897d 100644
--- a/apps/web/app/hooks/features/usePublicOrganizationTeams.ts
+++ b/apps/web/app/hooks/features/usePublicOrganizationTeams.ts
@@ -1,7 +1,7 @@
import { ITeamTask } from '@app/interfaces';
import {
- getPublicOrganizationTeamsAPI,
- getPublicOrganizationTeamsMiscDataAPI
+ getPublicOrganizationTeamsAPI,
+ getPublicOrganizationTeamsMiscDataAPI
} from '@app/services/client/api/public-organization-team';
import { publicactiveTeamState } from '@app/stores';
import isEqual from 'lodash/isEqual';
@@ -17,117 +17,107 @@ import { useTaskStatus } from './useTaskStatus';
import { useTeamTasks } from './useTeamTasks';
export function usePublicOrganizationTeams() {
- const { loading, queryCall, loadingRef } = useQuery(
- getPublicOrganizationTeamsAPI
- );
- const { loading: loadingMiscData, queryCall: queryCallMiscData } = useQuery(
- getPublicOrganizationTeamsMiscDataAPI
- );
- const { activeTeam, teams, setTeams } = useOrganizationTeams();
- const { setAllTasks } = useTeamTasks();
- const { setTaskStatus } = useTaskStatus();
- const { setTaskSizes } = useTaskSizes();
- const { setTaskPriorities } = useTaskPriorities();
- const { setTaskLabels } = useTaskLabels();
- const [publicTeam, setPublicTeam] = useAtom(publicactiveTeamState);
+ const { loading, queryCall, loadingRef } = useQuery(getPublicOrganizationTeamsAPI);
+ const { loading: loadingMiscData, queryCall: queryCallMiscData } = useQuery(getPublicOrganizationTeamsMiscDataAPI);
+ const { activeTeam, teams, setTeams, teamsFetching } = useOrganizationTeams();
+ const { setAllTasks } = useTeamTasks();
+ const { setTaskStatus } = useTaskStatus();
+ const { setTaskSizes } = useTaskSizes();
+ const { setTaskPriorities } = useTaskPriorities();
+ const { setTaskLabels } = useTaskLabels();
+ const [publicTeam, setPublicTeam] = useAtom(publicactiveTeamState);
- const loadPublicTeamData = useCallback(
- (profileLink: string, teamId: string) => {
- if (loadingRef.current) {
- return new Promise((response) => {
- response({});
- });
- }
+ const loadPublicTeamData = useCallback(
+ (profileLink: string, teamId: string) => {
+ if (loadingRef.current) {
+ return new Promise((response) => {
+ response({});
+ });
+ }
- return queryCall(profileLink, teamId).then((res) => {
- if (res.data.status === 404) {
- setTeams([]);
- return res;
- }
+ return queryCall(profileLink, teamId).then((res) => {
+ if (res.data.status === 404) {
+ setTeams([]);
+ return res;
+ }
- const updatedTeams = cloneDeep(teams);
- if (updatedTeams.length) {
- const newData = [
- {
- ...updatedTeams[0],
- ...res.data
- }
- ];
+ const updatedTeams = cloneDeep(teams);
+ if (updatedTeams.length) {
+ const newData = [
+ {
+ ...updatedTeams[0],
+ ...res.data
+ }
+ ];
- if (!isEqual(newData, updatedTeams)) {
- setTeams([
- {
- ...updatedTeams[0],
- ...res.data
- }
- ]);
- }
- } else {
- setTeams([res.data]);
- }
+ if (!isEqual(newData, updatedTeams)) {
+ setTeams([
+ {
+ ...updatedTeams[0],
+ ...res.data
+ }
+ ]);
+ }
+ } else {
+ setTeams([res.data]);
+ }
- const newPublicTeamData = {
- ...publicTeam,
- ...res.data
- };
- if (!isEqual(newPublicTeamData, publicTeam)) {
- setPublicTeam(newPublicTeamData);
- }
+ const newPublicTeamData = {
+ ...publicTeam,
+ ...res.data
+ };
+ if (!isEqual(newPublicTeamData, publicTeam)) {
+ setPublicTeam(newPublicTeamData);
+ }
- let responseTasks = (res.data.tasks as ITeamTask[]) || [];
- if (Array.isArray(responseTasks) && responseTasks.length > 0) {
- responseTasks = responseTasks.map((task) => {
- const clone = cloneDeep(task);
- if (task.tags && task.tags?.length) {
- clone.label = task.tags[0].name;
- }
+ let responseTasks = (res.data.tasks as ITeamTask[]) || [];
+ if (Array.isArray(responseTasks) && responseTasks.length > 0) {
+ responseTasks = responseTasks.map((task) => {
+ const clone = cloneDeep(task);
+ if (task.tags && task.tags?.length) {
+ clone.label = task.tags[0].name;
+ }
- return clone;
- });
- }
- setAllTasks(responseTasks);
+ return clone;
+ });
+ }
+ setAllTasks(responseTasks);
- return res;
- });
- },
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [queryCall, setTeams, setAllTasks, setPublicTeam, teams, publicTeam]
- );
+ return res;
+ });
+ },
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ [queryCall, setTeams, setAllTasks, setPublicTeam, teams, publicTeam]
+ );
- const loadPublicTeamMiscData = useCallback(
- (profileLink: string, teamId: string) => {
- return queryCallMiscData(profileLink, teamId).then((res) => {
- if (res.data?.status === 404) {
- setTeams([]);
- return res;
- }
+ const loadPublicTeamMiscData = useCallback(
+ (profileLink: string, teamId: string) => {
+ return queryCallMiscData(profileLink, teamId).then((res) => {
+ if (res.data?.status === 404) {
+ setTeams([]);
+ return res;
+ }
- if (res.data) {
- setTaskStatus(res.data?.statuses || []);
- setTaskSizes(res.data?.sizes || []);
- setTaskPriorities(res.data?.priorities || []);
- setTaskLabels(res.data?.labels || []);
- }
+ if (res.data) {
+ setTaskStatus(res.data?.statuses || []);
+ setTaskSizes(res.data?.sizes || []);
+ setTaskPriorities(res.data?.priorities || []);
+ setTaskLabels(res.data?.labels || []);
+ }
- return res;
- });
- },
- [
- queryCallMiscData,
- setTaskLabels,
- setTaskPriorities,
- setTaskSizes,
- setTaskStatus,
- setTeams
- ]
- );
+ return res;
+ });
+ },
+ [queryCallMiscData, setTaskLabels, setTaskPriorities, setTaskSizes, setTaskStatus, setTeams]
+ );
- return {
- loadPublicTeamData,
- loadPublicTeamMiscData,
- loading,
- loadingMiscData,
- activeTeam,
- publicTeam
- };
+ return {
+ teamsFetching,
+ loadPublicTeamData,
+ loadPublicTeamMiscData,
+ loading,
+ loadingMiscData,
+ activeTeam,
+ publicTeam
+ };
}
diff --git a/apps/web/app/hooks/features/useTaskStatistics.ts b/apps/web/app/hooks/features/useTaskStatistics.ts
index 3f13b82ca..a02e4f016 100644
--- a/apps/web/app/hooks/features/useTaskStatistics.ts
+++ b/apps/web/app/hooks/features/useTaskStatistics.ts
@@ -2,17 +2,17 @@
import { ITeamTask, Nullable } from '@app/interfaces';
import {
- activeTaskTimesheetStatisticsAPI,
- allTaskTimesheetStatisticsAPI,
- tasksTimesheetStatisticsAPI
+ activeTaskTimesheetStatisticsAPI,
+ allTaskTimesheetStatisticsAPI,
+ tasksTimesheetStatisticsAPI
} from '@app/services/client/api';
import {
- activeTaskStatisticsState,
- activeTeamTaskState,
- allTaskStatisticsState,
- tasksFetchingState,
- tasksStatisticsState,
- timerStatusState
+ activeTaskStatisticsState,
+ activeTeamTaskState,
+ allTaskStatisticsState,
+ tasksFetchingState,
+ tasksStatisticsState,
+ timerStatusState
} from '@app/stores';
import { useCallback, useEffect, useMemo, useRef } from 'react';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
@@ -25,220 +25,181 @@ import { useOrganizationTeams } from './useOrganizationTeams';
import { useAuthenticateUser } from './useAuthenticateUser';
export function useTaskStatistics(addSeconds = 0) {
- const { user } = useAuthenticateUser();
- const [statActiveTask, setStatActiveTask] = useAtom(
- activeTaskStatisticsState
- );
- const [statTasks, setStatTasks] = useAtom(tasksStatisticsState);
- const setTasksFetching = useSetAtom(tasksFetchingState);
- const [allTaskStatistics, setAllTaskStatistics] = useAtom(
- allTaskStatisticsState
- );
-
- const {
- firstLoad,
- firstLoadData: firstLoadtasksStatisticsData
- } = useFirstLoad();
-
- const { activeTeam } = useOrganizationTeams();
-
- // Refs
- const initialLoad = useRef(false);
- const statTasksRef = useSyncRef(statTasks);
-
- // Dep status
- const timerStatus = useAtomValue(timerStatusState);
- const activeTeamTask = useAtomValue(activeTeamTaskState);
-
- /**
- * Get employee all tasks statistics (API Call)
- */
- const getTasksStatsData = useCallback(
- (employeeId?: string) => {
- if (!user?.employee.tenantId) {
- return;
- }
- tasksTimesheetStatisticsAPI(
- user?.employee.tenantId,
- '',
- user?.employee.organizationId,
- employeeId
- ).then(({ data }) => {
- setStatTasks({
- all: data.global || [],
- today: data.today || []
- });
- });
- },
- [setStatTasks, user?.employee.organizationId, user?.employee.tenantId]
- );
- const getAllTasksStatsData = useCallback(() => {
- allTaskTimesheetStatisticsAPI().then(({ data }) => {
- setAllTaskStatistics(data);
- });
- }, [setAllTaskStatistics]);
-
- /**
- * Get task timesheet statistics
- */
- const getTaskStat = useCallback(
- (task: Nullable) => {
- const stats = statTasksRef.current;
- return {
- taskTotalStat: stats.all.find((t) => t.id === task?.id),
- taskDailyStat: stats.today.find((t) => t.id === task?.id)
- };
- },
- [statTasksRef]
- );
-
- /**
- * Get statistics of the active tasks fresh (API Call)
- */
- const getActiveTaskStatData = useCallback(() => {
- if (!user?.employee.tenantId || !user?.employee.organizationId) {
- return new Promise((resolve) => {
- resolve(true);
- });
- }
-
- setTasksFetching(true);
-
- const promise = activeTaskTimesheetStatisticsAPI(
- user?.employee.tenantId,
- '',
- user?.employee.organizationId,
- ''
- );
- promise.then(({ data }) => {
- setStatActiveTask({
- total: data.global ? data.global[0] || null : null,
- today: data.today ? data.today[0] || null : null
- });
- });
- promise.finally(() => {
- setTasksFetching(false);
- });
- return promise;
- }, [
- setStatActiveTask,
- setTasksFetching,
- user?.employee.organizationId,
- user?.employee.tenantId
- ]);
-
- // eslint-disable-next-line react-hooks/exhaustive-deps
- const debounceLoadActiveTaskStat = useCallback(
- debounce(getActiveTaskStatData, 100),
- []
- );
-
- /**
- * Get statistics of the active tasks at the component load
- */
- useEffect(() => {
- if (firstLoad) {
- getActiveTaskStatData().then(() => {
- initialLoad.current = true;
- });
- }
- }, [
- firstLoad,
- getActiveTaskStatData,
- user?.employee.organizationId,
- user?.employee.tenantId
- ]);
-
- /**
- * Get fresh statistic of the active task
- */
- useEffect(() => {
- if (firstLoad && initialLoad.current) {
- debounceLoadActiveTaskStat();
- }
- }, [firstLoad, timerStatus, activeTeamTask?.id, debounceLoadActiveTaskStat]);
-
- /**
- * set null to active team stats when active team or active task are changed
- */
- useEffect(() => {
- if (firstLoad && initialLoad.current) {
- setStatActiveTask({
- today: null,
- total: null
- });
- }
- }, [firstLoad, activeTeamTask?.id, setStatActiveTask]);
-
- /**
- * Get task estimation in
- *
- * @param timeSheet
- * @param _task
- * @param addSeconds
- * @returns
- */
- const getEstimation = useCallback(
- (
- timeSheet: Nullable,
- _task: Nullable,
- addSeconds: number,
- estimate = 0
- ) =>
- Math.min(
- Math.floor(
- (((_task?.totalWorkedTime || timeSheet?.duration || 0) + addSeconds) *
- 100) /
- (estimate || _task?.estimate || 0)
- ),
- 100
- ),
- []
- );
-
- const activeTaskEstimation = useMemo(() => {
- let totalWorkedTasksTimer = 0;
- activeTeam?.members?.forEach((member) => {
- const totalWorkedTasks =
- member?.totalWorkedTasks?.find(
- (item) => item.id === activeTeamTask?.id
- ) || null;
- if (totalWorkedTasks) {
- totalWorkedTasksTimer += totalWorkedTasks.duration;
- }
- });
-
- return getEstimation(
- null,
- activeTeamTask,
- totalWorkedTasksTimer,
- activeTeamTask?.estimate || 0
- );
- }, [activeTeam, activeTeamTask, getEstimation]);
-
- const activeTaskDailyEstimation =
- activeTeamTask && activeTeamTask.estimate
- ? getEstimation(statActiveTask.today, activeTeamTask, addSeconds)
- : 0;
-
- return {
- firstLoadtasksStatisticsData,
- getAllTasksStatsData,
- getTasksStatsData,
- getTaskStat,
- activeTaskTotalStat: statActiveTask.total,
- activeTaskDailyStat: statActiveTask.today,
- activeTaskEstimation,
- activeTaskDailyEstimation,
- activeTeamTask,
- addSeconds,
- getEstimation,
- allTaskStatistics
- };
+ const { user } = useAuthenticateUser();
+ const [statActiveTask, setStatActiveTask] = useAtom(activeTaskStatisticsState);
+ const [statTasks, setStatTasks] = useAtom(tasksStatisticsState);
+ const setTasksFetching = useSetAtom(tasksFetchingState);
+ const [allTaskStatistics, setAllTaskStatistics] = useAtom(allTaskStatisticsState);
+
+ const { firstLoad, firstLoadData: firstLoadtasksStatisticsData } = useFirstLoad();
+
+ const { activeTeam } = useOrganizationTeams();
+
+ // Refs
+ const initialLoad = useRef(false);
+ const statTasksRef = useSyncRef(statTasks);
+
+ // Dep status
+ const timerStatus = useAtomValue(timerStatusState);
+ const activeTeamTask = useAtomValue(activeTeamTaskState);
+
+ /**
+ * Get employee all tasks statistics (API Call)
+ */
+ const getTasksStatsData = useCallback(
+ (employeeId?: string) => {
+ if (!user?.employee.tenantId) {
+ return;
+ }
+ tasksTimesheetStatisticsAPI(user?.employee.tenantId, '', user?.employee.organizationId, employeeId).then(
+ ({ data }) => {
+ setStatTasks({
+ all: data.global || [],
+ today: data.today || []
+ });
+ }
+ );
+ },
+ [setStatTasks, user?.employee.organizationId, user?.employee.tenantId]
+ );
+ const getAllTasksStatsData = useCallback(() => {
+ allTaskTimesheetStatisticsAPI().then(({ data }) => {
+ setAllTaskStatistics(data);
+ });
+ }, [setAllTaskStatistics]);
+
+ /**
+ * Get task timesheet statistics
+ */
+ const getTaskStat = useCallback(
+ (task: Nullable) => {
+ const stats = statTasksRef.current;
+ return {
+ taskTotalStat: stats.all.find((t) => t.id === task?.id),
+ taskDailyStat: stats.today.find((t) => t.id === task?.id)
+ };
+ },
+ [statTasksRef]
+ );
+
+ /**
+ * Get statistics of the active tasks fresh (API Call)
+ */
+ const getActiveTaskStatData = useCallback(() => {
+ if (!user?.employee.tenantId || !user?.employee.organizationId) {
+ return new Promise((resolve) => {
+ resolve(true);
+ });
+ }
+
+ setTasksFetching(true);
+
+ const promise = activeTaskTimesheetStatisticsAPI(
+ user?.employee.tenantId,
+ '',
+ user?.employee.organizationId,
+ ''
+ );
+ promise.then(({ data }) => {
+ setStatActiveTask({
+ total: data.global ? data.global[0] || null : null,
+ today: data.today ? data.today[0] || null : null
+ });
+ });
+ promise.finally(() => {
+ setTasksFetching(false);
+ });
+ return promise;
+ }, [setStatActiveTask, setTasksFetching, user?.employee.organizationId, user?.employee.tenantId]);
+
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ const debounceLoadActiveTaskStat = useCallback(debounce(getActiveTaskStatData, 100), []);
+
+ /**
+ * Get statistics of the active tasks at the component load
+ */
+ useEffect(() => {
+ if (firstLoad) {
+ getActiveTaskStatData().then(() => {
+ initialLoad.current = true;
+ });
+ }
+ }, [firstLoad, getActiveTaskStatData, user?.employee.organizationId, user?.employee.tenantId]);
+
+ /**
+ * Get fresh statistic of the active task
+ */
+ useEffect(() => {
+ if (firstLoad && initialLoad.current) {
+ debounceLoadActiveTaskStat();
+ }
+ }, [firstLoad, timerStatus, activeTeamTask?.id, debounceLoadActiveTaskStat]);
+
+ /**
+ * set null to active team stats when active team or active task are changed
+ */
+ useEffect(() => {
+ if (firstLoad && initialLoad.current) {
+ setStatActiveTask({
+ today: null,
+ total: null
+ });
+ }
+ }, [firstLoad, activeTeamTask?.id, setStatActiveTask]);
+
+ /**
+ * Get task estimation in
+ *
+ * @param timeSheet
+ * @param _task
+ * @param addSeconds
+ * @returns
+ */
+ const getEstimation = useCallback(
+ (timeSheet: Nullable, _task: Nullable, addSeconds: number, estimate = 0) =>
+ Math.min(
+ Math.floor(
+ (((_task?.totalWorkedTime || timeSheet?.duration || 0) + addSeconds) * 100) /
+ (estimate || _task?.estimate || 0)
+ ),
+ 100
+ ),
+ []
+ );
+
+ const activeTaskEstimation = useMemo(() => {
+ let totalWorkedTasksTimer = 0;
+ activeTeam?.members?.forEach((member) => {
+ const totalWorkedTasks = member?.totalWorkedTasks?.find((item) => item.id === activeTeamTask?.id) || null;
+ if (totalWorkedTasks) {
+ totalWorkedTasksTimer += totalWorkedTasks.duration;
+ }
+ });
+
+ return getEstimation(null, activeTeamTask, totalWorkedTasksTimer, activeTeamTask?.estimate || 0);
+ }, [activeTeam, activeTeamTask, getEstimation]);
+
+ const activeTaskDailyEstimation =
+ activeTeamTask && activeTeamTask.estimate ? getEstimation(statActiveTask.today, activeTeamTask, addSeconds) : 0;
+
+ return {
+ firstLoadtasksStatisticsData,
+ getAllTasksStatsData,
+ getTasksStatsData,
+ getTaskStat,
+ activeTaskTotalStat: statActiveTask.total,
+ activeTaskDailyStat: statActiveTask.today,
+ activeTaskEstimation,
+ activeTaskDailyEstimation,
+ activeTeamTask,
+ addSeconds,
+ getEstimation,
+ allTaskStatistics
+ };
}
export function useAllTaskStatistics() {
- const { getAllTasksStatsData } = useTaskStatistics();
+ const { getAllTasksStatsData } = useTaskStatistics();
- useRefreshIntervalV2(getAllTasksStatsData, 5000);
+ useRefreshIntervalV2(getAllTasksStatsData, 5000);
}
diff --git a/apps/web/app/services/client/axios.ts b/apps/web/app/services/client/axios.ts
index 38be5aa32..eff23ac40 100644
--- a/apps/web/app/services/client/axios.ts
+++ b/apps/web/app/services/client/axios.ts
@@ -1,5 +1,5 @@
/* eslint-disable no-mixed-spaces-and-tabs */
-import { API_BASE_URL, DEFAULT_APP_PATH, GAUZY_API_BASE_SERVER_URL } from '@app/constants';
+import { API_BASE_URL, APPLICATION_LANGUAGES_CODE, DEFAULT_APP_PATH, GAUZY_API_BASE_SERVER_URL } from '@app/constants';
import {
getAccessTokenCookie,
getActiveTeamIdCookie,
@@ -70,6 +70,14 @@ apiDirect.interceptors.response.use(
const statusCode = error.response?.status;
if (statusCode === 401) {
+ const paths = location.pathname.split('/').filter(Boolean);
+ if (
+ !paths.includes('join') &&
+ (paths[0] === 'team' || (APPLICATION_LANGUAGES_CODE.includes(paths[0]) && paths[1] === 'team'))
+ ) {
+ return error.response;
+ }
+
window.location.assign(DEFAULT_APP_PATH);
}
diff --git a/apps/web/lib/features/team-members-card-view.tsx b/apps/web/lib/features/team-members-card-view.tsx
index 9f246c688..9a0e18090 100644
--- a/apps/web/lib/features/team-members-card-view.tsx
+++ b/apps/web/lib/features/team-members-card-view.tsx
@@ -52,7 +52,6 @@ const TeamMembersCardView: React.FC = ({
return (
<>
-
{/* Current authenticated user members */}
member.employee !== null
- );
- const orderedMembers = [...members].sort((a, b) =>
- sortByWorkStatus(a, b) ? -1 : 1
- );
+export function TeamMembers({ publicTeam = false, kanbanView: view = IssuesView.CARDS }: TeamMembersProps) {
+ const { user } = useAuthenticateUser();
+ const activeFilter = useAtomValue(taskBlockFilterState);
+ const fullWidth = useAtomValue(fullWidthState);
+ const { activeTeam, teamsFetching } = useOrganizationTeams();
- const blockViewMembers = useMemo(() => {
- return activeFilter == 'all'
- ? orderedMembers
- : activeFilter == 'idle'
- ? orderedMembers.filter(
- (m: OT_Member) =>
- m.timerStatus == undefined || m.timerStatus == 'idle'
- )
- : orderedMembers.filter((m) => m.timerStatus === activeFilter);
- }, [activeFilter, orderedMembers]);
+ const [members, orderedMembers] = useMemo(() => {
+ const members = (activeTeam?.members || []).filter((member) => member.employee !== null);
+ const orderedMembers = [...members].sort((a, b) => (sortByWorkStatus(a, b) ? -1 : 1));
- const currentUser = members.find((m) => m.employee.userId === user?.id);
+ return [members, orderedMembers];
+ }, [activeTeam]);
- const $members = useMemo(() => {
- return members
- .filter((member) => member.id !== currentUser?.id)
- .sort((a, b) => {
- if (a.order && b.order) return a.order > b.order ? -1 : 1;
- else return -1;
- });
- }, [members, currentUser]);
+ const blockViewMembers = useMemo(() => {
+ return activeFilter == 'all'
+ ? orderedMembers
+ : activeFilter == 'idle'
+ ? orderedMembers.filter((m: OT_Member) => m.timerStatus == undefined || m.timerStatus == 'idle')
+ : orderedMembers.filter((m) => m.timerStatus === activeFilter);
+ }, [activeFilter, orderedMembers]);
- const $teamsFetching = teamsFetching && members.length === 0;
+ const currentUser = members.find((m) => m.employee.userId === user?.id);
- let teamMembersView;
+ const $members = useMemo(() => {
+ return members
+ .filter((member) => member.id !== currentUser?.id)
+ .sort((a, b) => {
+ if (a.order && b.order) return a.order > b.order ? -1 : 1;
+ else return -1;
+ });
+ }, [members, currentUser]);
- switch (true) {
- case members.length === 0:
- teamMembersView = (
-
-
-
-
-
-
-
-
-
-
-
- );
- break;
- case view === IssuesView.CARDS:
- teamMembersView = (
- <>
- {/* */}
-
-
-
- >
- );
- break;
- case view === IssuesView.TABLE:
- teamMembersView = (
-
-
-
-
-
- );
- break;
+ const $teamsFetching = teamsFetching && members.length === 0;
- case view == IssuesView.BLOCKS:
- teamMembersView = (
-
-
-
- );
- break;
- default:
- teamMembersView = (
-
-
-
- );
- }
- return teamMembersView;
+ return (
+
+ );
+}
+
+type TeamMembersViewProps = {
+ fullWidth?: boolean;
+ members: OT_Member[];
+ currentUser?: OT_Member;
+ teamsFetching: boolean;
+ view: IssuesView;
+ blockViewMembers: OT_Member[];
+ publicTeam: boolean;
+ isMemberActive?: boolean;
+};
+
+export function TeamMembersView({
+ fullWidth,
+ members,
+ currentUser,
+ teamsFetching,
+ view,
+ blockViewMembers,
+ publicTeam,
+ isMemberActive
+}: TeamMembersViewProps) {
+ let teamMembersView;
+
+ switch (true) {
+ case members.length === 0:
+ teamMembersView = (
+
+
+
+
+
+
+
+
+
+
+
+ );
+ break;
+ case view === IssuesView.CARDS:
+ teamMembersView = (
+ <>
+ {/* */}
+
+
+
+ >
+ );
+ break;
+ case view === IssuesView.TABLE:
+ teamMembersView = (
+
+
+
+
+
+ );
+ break;
+
+ case view == IssuesView.BLOCKS:
+ teamMembersView = (
+
+
+
+ );
+ break;
+ default:
+ teamMembersView = (
+
+
+
+ );
+ }
+
+ return teamMembersView;
}
const sortByWorkStatus = (user_a: OT_Member, user_b: OT_Member) => {
- return user_a.timerStatus == 'running' ||
- (user_a.timerStatus == 'online' && user_b.timerStatus != 'running') ||
- (user_a.timerStatus == 'pause' &&
- user_b.timerStatus !== 'running' &&
- user_b.timerStatus !== 'online') ||
- (user_a.timerStatus == 'idle' && user_b.timerStatus == 'suspended') ||
- (user_a.timerStatus === undefined && user_b.timerStatus == 'suspended')
- ? true
- : false;
+ return user_a.timerStatus == 'running' ||
+ (user_a.timerStatus == 'online' && user_b.timerStatus != 'running') ||
+ (user_a.timerStatus == 'pause' && user_b.timerStatus !== 'running' && user_b.timerStatus !== 'online') ||
+ (user_a.timerStatus == 'idle' && user_b.timerStatus == 'suspended') ||
+ (user_a.timerStatus === undefined && user_b.timerStatus == 'suspended')
+ ? true
+ : false;
};
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 b6642b8f8..2f75e630a 100644
--- a/apps/web/lib/features/team/user-team-card/index.tsx
+++ b/apps/web/lib/features/team/user-team-card/index.tsx
@@ -2,33 +2,19 @@
import { secondsToTime } from '@app/helpers';
import {
- useCollaborative,
- useTMCardTaskEdit,
- useTaskStatistics,
- useOrganizationTeams,
- useAuthenticateUser,
- useTeamMemberCard,
- useUserProfilePage
+ useCollaborative,
+ useTMCardTaskEdit,
+ useTaskStatistics,
+ useOrganizationTeams,
+ useAuthenticateUser,
+ useTeamMemberCard,
+ useUserProfilePage
} from '@app/hooks';
import { IClassName, IOrganizationTeamList, OT_Member } from '@app/interfaces';
-import {
- timerSecondsState,
- userDetailAccordion as userAccordion
-} from '@app/stores';
+import { timerSecondsState, userDetailAccordion as userAccordion } from '@app/stores';
import { clsxm } from '@app/utils';
-import {
- Card,
- Container,
- InputField,
- Text,
- VerticalSeparator
-} from 'lib/components';
-import {
- TaskTimes,
- TodayWorkedTime,
- UserProfileTask,
- useTaskFilter
-} from 'lib/features';
+import { Card, Container, InputField, Text, VerticalSeparator } from 'lib/components';
+import { TaskTimes, TodayWorkedTime, UserProfileTask, useTaskFilter } from 'lib/features';
import { useTranslations } from 'next-intl';
import { useAtom, useAtomValue, useSetAtom } from 'jotai';
import { TaskEstimateInfo } from './task-estimate';
@@ -49,352 +35,305 @@ import { Loader } from 'lucide-react';
import { fullWidthState } from '@app/stores/fullWidth';
type IUserTeamCard = {
- active?: boolean;
- member?: IOrganizationTeamList['members'][number];
- publicTeam?: boolean;
- members?: IOrganizationTeamList['members'];
- draggable: boolean;
- onDragStart: () => any;
- onDragEnter: () => any;
- onDragEnd: any;
- onDragOver: (e: React.DragEvent) => any;
- currentExit: boolean;
+ active?: boolean;
+ member?: IOrganizationTeamList['members'][number];
+ publicTeam?: boolean;
+ members?: IOrganizationTeamList['members'];
+ draggable: boolean;
+ onDragStart: () => any;
+ onDragEnter: () => any;
+ onDragEnd: any;
+ onDragOver: (e: React.DragEvent) => any;
+ currentExit: boolean;
} & IClassName;
export function UserTeamCard({
- className,
- active,
- member,
- publicTeam = false,
- draggable = false,
- onDragStart = () => null,
- onDragEnd = () => null,
- onDragEnter = () => null,
- onDragOver = () => null
+ className,
+ active,
+ member,
+ publicTeam = false,
+ draggable = false,
+ onDragStart = () => null,
+ onDragEnd = () => null,
+ onDragEnter = () => null,
+ onDragOver = () => null
}: IUserTeamCard) {
- const t = useTranslations();
- const profile = useUserProfilePage();
- const [userDetailAccordion, setUserDetailAccordion] = useAtom(userAccordion);
- const hook = useTaskFilter(profile);
- const memberInfo = useTeamMemberCard(member);
- const taskEdition = useTMCardTaskEdit(memberInfo.memberTask);
- const { collaborativeSelect, user_selected, onUserSelect } = useCollaborative(
- memberInfo.memberUser
- );
- const fullWidth = useAtomValue(fullWidthState);
+ const t = useTranslations();
+ const profile = useUserProfilePage();
+ const [userDetailAccordion, setUserDetailAccordion] = useAtom(userAccordion);
+ const hook = useTaskFilter(profile);
+ const memberInfo = useTeamMemberCard(member);
+ const taskEdition = useTMCardTaskEdit(memberInfo.memberTask);
+ const { collaborativeSelect, user_selected, onUserSelect } = useCollaborative(memberInfo.memberUser);
+ const fullWidth = useAtomValue(fullWidthState);
- const seconds = useAtomValue(timerSecondsState);
- const setActivityFilter = useSetAtom(activityTypeState);
- const { activeTaskTotalStat, addSeconds } = useTaskStatistics(seconds);
- const [showActivity, setShowActivity] = React.useState(false);
- const { activeTeamManagers } = useOrganizationTeams();
- const { user } = useAuthenticateUser();
+ const seconds = useAtomValue(timerSecondsState);
+ const setActivityFilter = useSetAtom(activityTypeState);
+ const { activeTaskTotalStat, addSeconds } = useTaskStatistics(seconds);
+ const [showActivity, setShowActivity] = React.useState(false);
+ const { activeTeamManagers } = useOrganizationTeams();
+ const { user } = useAuthenticateUser();
- const isManagerConnectedUser = activeTeamManagers.findIndex(
- (member) => member.employee?.user?.id == user?.id
- );
+ const isManagerConnectedUser = activeTeamManagers.findIndex((member) => member.employee?.user?.id == user?.id);
- const showActivityFilter = (
- type: 'DATE' | 'TICKET',
- member: OT_Member | null
- ) => {
- setShowActivity((prev) => !prev);
- setUserDetailAccordion('');
- setActivityFilter((prev) => ({
- ...prev,
- type,
- member
- }));
- };
+ const showActivityFilter = (type: 'DATE' | 'TICKET', member: OT_Member | null) => {
+ setShowActivity((prev) => !prev);
+ setUserDetailAccordion('');
+ setActivityFilter((prev) => ({
+ ...prev,
+ type,
+ member
+ }));
+ };
- let totalWork = <>>;
- if (memberInfo.isAuthUser) {
- const { h, m } = secondsToTime(
- ((member?.totalTodayTasks &&
- member?.totalTodayTasks.reduce(
- (previousValue, currentValue) =>
- previousValue + currentValue.duration,
- 0
- )) ||
- activeTaskTotalStat?.duration ||
- 0) + addSeconds
- );
+ let totalWork = <>>;
+ if (memberInfo.isAuthUser) {
+ const { h, m } = secondsToTime(
+ ((member?.totalTodayTasks &&
+ member?.totalTodayTasks.reduce(
+ (previousValue, currentValue) => previousValue + currentValue.duration,
+ 0
+ )) ||
+ activeTaskTotalStat?.duration ||
+ 0) + addSeconds
+ );
- totalWork = (
-
- {t('common.TOTAL_TIME')}:
-
- {h}h : {m}m
-
-
- );
- }
+ totalWork = (
+
+ {t('common.TOTAL_TIME')}:
+
+ {h}h : {m}m
+
+
+ );
+ }
- const menu = (
- <>
- {(!collaborativeSelect || active) && (
-
- )}
+ const menu = (
+ <>
+ {(!collaborativeSelect || active) && }
- {collaborativeSelect && !active && (
-
- )}
- >
- );
- const [activityFilter, setActivity] = useState('Tasks');
+ {collaborativeSelect && !active && (
+
+ )}
+ >
+ );
+ const [activityFilter, setActivity] = useState('Tasks');
- const activityScreens = {
- Tasks: ,
- Screenshots: ,
- Apps: ,
- 'Visited Sites':
- };
- const changeActivityFilter = useCallback(
- (filter: FilterTab) => {
- setActivity(filter);
- },
- [setActivity]
- );
- const canSeeActivity =
- profile.userProfile?.id === user?.id || isManagerConnectedUser != -1;
+ const activityScreens = {
+ Tasks: ,
+ Screenshots: ,
+ Apps: ,
+ 'Visited Sites':
+ };
+ const changeActivityFilter = useCallback(
+ (filter: FilterTab) => {
+ setActivity(filter);
+ },
+ [setActivity]
+ );
+ const canSeeActivity = profile.userProfile?.id === user?.id || isManagerConnectedUser != -1;
- return (
-
-
+
-
-
-
-
+ className
+ )}
+ >
+
+
+
+
- {/* Show user name, email and image */}
-
-
-
{
- setUserDetailAccordion(
- userDetailAccordion == memberInfo.memberUser?.id
- ? ''
- : memberInfo.memberUser?.id ?? ''
- );
- setShowActivity(false);
- }}
- className={clsxm(
- 'h-6 w-6 absolute right-4 top-0 cursor-pointer p-[3px]'
- )}
- >
-
-
-
-
+ {/* Show user name, email and image */}
+
+
+ {!publicTeam && (
+
{
+ setUserDetailAccordion(
+ userDetailAccordion == memberInfo.memberUser?.id
+ ? ''
+ : memberInfo.memberUser?.id ?? ''
+ );
+ setShowActivity(false);
+ }}
+ className={clsxm('h-6 w-6 absolute right-4 top-0 cursor-pointer p-[3px]')}
+ >
+
+
+ )}
+
+
- {/* Task information */}
-
-
+ {/* Task information */}
+
+
- {isManagerConnectedUser != 1 ? (
-
{
- showActivityFilter('TICKET', memberInfo.member ?? null);
- setUserDetailAccordion('');
- }}
- >
- {!showActivity ? (
-
- ) : (
-
- )}
-
- ) : null}
-
-
+ {isManagerConnectedUser != 1 ? (
+
{
+ showActivityFilter('TICKET', memberInfo.member ?? null);
+ setUserDetailAccordion('');
+ }}
+ >
+ {!showActivity ? (
+
+ ) : (
+
+ )}
+
+ ) : null}
+
+
- {/* TaskTimes */}
-
-
+ {/* TaskTimes */}
+
+
- {/* TaskEstimateInfo */}
-
+ {/* TaskEstimateInfo */}
+
-
+
- {/* TodayWorkedTime */}
-
-
- {isManagerConnectedUser != -1 ? (
-
- showActivityFilter('DATE', memberInfo.member ?? null)
- }
- className="flex items-center justify-center w-8 h-8 text-center border rounded cursor-pointer dark:border-gray-800"
- >
- {!showActivity ? (
-
- ) : (
-
- )}
-
- ) : null}
-
- {/* Card menu */}
-
{menu}
-
- {userDetailAccordion == memberInfo.memberUser?.id &&
- memberInfo.memberUser.id == profile.userProfile?.id &&
- !showActivity ? (
-
- {canSeeActivity && (
-
-
- {Object.keys(activityScreens).map((filter, i) => (
-
- {i !== 0 &&
}
-
- changeActivityFilter(filter as FilterTab)
- }
- >
- {filter}
-
-
- ))}
-
-
- )}
- {activityScreens[activityFilter] ?? null}
-
- ) : userDetailAccordion == memberInfo.memberUser?.id ? (
-
-
-
- ) : null}
-
-
-
-
-
- {/*@ts-ignore*/}
- {totalWork}
-
+ {/* TodayWorkedTime */}
+
+
+ {isManagerConnectedUser != -1 ? (
+
showActivityFilter('DATE', memberInfo.member ?? null)}
+ className="flex items-center justify-center w-8 h-8 text-center border rounded cursor-pointer dark:border-gray-800"
+ >
+ {!showActivity ? (
+
+ ) : (
+
+ )}
+
+ ) : null}
+
+ {/* Card menu */}
+ {menu}
+
+ {userDetailAccordion == memberInfo.memberUser?.id &&
+ memberInfo.memberUser.id == profile.userProfile?.id &&
+ !showActivity ? (
+
+ {canSeeActivity && (
+
+
+ {Object.keys(activityScreens).map((filter, i) => (
+
+ {i !== 0 &&
}
+
changeActivityFilter(filter as FilterTab)}
+ >
+ {filter}
+
+
+ ))}
+
+
+ )}
+ {activityScreens[activityFilter] ?? null}
+
+ ) : userDetailAccordion == memberInfo.memberUser?.id ? (
+
+
+
+ ) : null}
+
+
+
+
+
+ {/*@ts-ignore*/}
+ {totalWork}
+
-
-
-
+
+
+
-
- {/* Card menu */}
- {menu}
-
- {/* {currentExit && (
+ {/* Card menu */}
+ {menu}
+
+ {/* {currentExit && (
)} */}
-
- );
+
+ );
}
diff --git a/apps/web/middleware.ts b/apps/web/middleware.ts
index ec3b297ff..a63df8949 100644
--- a/apps/web/middleware.ts
+++ b/apps/web/middleware.ts
@@ -1,5 +1,6 @@
import {
APPLICATION_DEFAULT_LANGUAGE,
+ APPLICATION_LANGUAGES_CODE,
DEFAULT_APP_PATH,
DEFAULT_MAIN_PATH,
PROTECTED_APP_URL_PATHS,
@@ -34,7 +35,7 @@ export { auth as authMiddleware } from './auth';
export async function middleware(request: NextRequest) {
const nextIntlMiddleware = createMiddleware({
defaultLocale: APPLICATION_DEFAULT_LANGUAGE,
- locales: ['en', 'de', 'ar', 'bg', 'zh', 'nl', 'de', 'he', 'it', 'pl', 'pt', 'ru', 'es', 'fr'],
+ locales: APPLICATION_LANGUAGES_CODE,
// pathnames,
localePrefix: 'as-needed'
});
@@ -43,6 +44,15 @@ export async function middleware(request: NextRequest) {
// let response = NextResponse.next();
let response = nextIntlMiddleware(request);
+ const paths = new URL(request.url).pathname.split('/').filter(Boolean);
+
+ if (
+ !paths.includes('join') &&
+ (paths[0] === 'team' || (APPLICATION_LANGUAGES_CODE.includes(paths[0]) && paths[1] === 'team'))
+ ) {
+ return response;
+ }
+
let access_token = null;
const totalChunksCookie = request.cookies.get(`${TOKEN_COOKIE_NAME}_totalChunks`)?.value.trim();