Skip to content

Commit

Permalink
Merge pull request #2088 from ever-co/develop
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Jan 15, 2024
2 parents 46e0355 + a38555d commit c05b27a
Show file tree
Hide file tree
Showing 11 changed files with 209 additions and 53 deletions.
14 changes: 9 additions & 5 deletions apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

/* eslint-disable no-mixed-spaces-and-tabs */
import { imgTitle } from '@app/helpers';
import { useOrganizationTeams, useTimer, useUserProfilePage } from '@app/hooks';
import { useAuthenticateUser, useOrganizationTeams, useTimer, useUserProfilePage } from '@app/hooks';
import { ITimerStatusEnum, OT_Member } from '@app/interfaces';
import { clsxm, isValidUrl } from '@app/utils';
import clsx from 'clsx';
Expand All @@ -25,18 +25,22 @@ import { VisitedSitesTab } from 'lib/features/activity/visited-sites';

const Profile = ({ params }: { params: { memberId: string } }) => {
const profile = useUserProfilePage();
const { user } = useAuthenticateUser();
const { isTrackingEnabled, activeTeam } = useOrganizationTeams();
const fullWidth = useRecoilValue(fullWidthState);
const [activityFilter, setActivityFilter] = useState<ActivityFilters>(ActivityFilters.TASKS);

const hook = useTaskFilter(profile);
const canSeeActivity = profile.userProfile?.id === user?.id || user?.role?.name?.toUpperCase() == 'MANAGER';

const t = useTranslations();
const breadcrumb = [
{ title: activeTeam?.name || '', href: '/' },
{ title: JSON.parse(t('pages.profile.BREADCRUMB')) || '', href: `/profile/${params.memberId}` }
];

console.log({ activityFilter });

const profileIsAuthUser = useMemo(() => profile.isAuthUser, [profile.isAuthUser]);
const hookFilterType = useMemo(() => hook.filterType, [hook.filterType]);

Expand Down Expand Up @@ -73,7 +77,7 @@ const Profile = ({ params }: { params: { memberId: string } }) => {
</MainHeader>
{/* Divider */}
<div className="h-0.5 bg-[#FFFFFF14]"></div>
{hook.tab == 'worked' && (
{hook.tab == 'worked' && canSeeActivity && (
<Container fullWidth={fullWidth} className="py-8">
<div className={clsxm('flex justify-start items-center gap-4')}>
{Object.values(ActivityFilters).map((filter: ActivityFilters, i) => (
Expand All @@ -97,11 +101,11 @@ const Profile = ({ params }: { params: { memberId: string } }) => {
<Container fullWidth={fullWidth} className="mb-10">
{hook.tab == 'worked' && activityFilter == ActivityFilters.TASKS ? (
<UserProfileTask profile={profile} tabFiltered={hook} />
) : hook.tab == 'worked' && activityFilter == ActivityFilters.SCREENSHOOTS ? (
) : hook.tab == 'worked' && canSeeActivity && activityFilter == ActivityFilters.SCREENSHOOTS ? (
<ScreenshootTab />
) : hook.tab == 'worked' && activityFilter == ActivityFilters.APPS ? (
) : hook.tab == 'worked' && canSeeActivity && activityFilter == ActivityFilters.APPS ? (
<AppsTab />
) : hook.tab == 'worked' && activityFilter == ActivityFilters.VISITED_SITES ? (
) : hook.tab == 'worked' && canSeeActivity && activityFilter == ActivityFilters.VISITED_SITES ? (
<VisitedSitesTab />
) : (
<UserProfileTask profile={profile} tabFiltered={hook} />
Expand Down
66 changes: 45 additions & 21 deletions apps/web/app/hooks/features/useTimeDailyActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,70 @@
import { useCallback, useEffect } from 'react';
import { useQuery } from '../useQuery';
import { useRecoilState } from 'recoil';
import { timeAppsState, timeVisitedSitesState } from '@app/stores/time-slot';
import { timeAppVisitedDetail, timeAppsState, timeVisitedSitesState } from '@app/stores/time-slot';
import moment from 'moment';
import { useAuthenticateUser } from './useAuthenticateUser';
import { getTimerDailyRequestAPI } from '@app/services/client/api';
import { useUserProfilePage } from './useUserProfilePage';

export function useTimeDailyActivity(type: string) {
const profile = useUserProfilePage();
const { user } = useAuthenticateUser();
const [visitedApps, setVisitedApps] = useRecoilState(timeAppsState);
const [visitedAppDetail, setVisitedAppDetail] = useRecoilState(timeAppVisitedDetail);
const [visitedSites, setVisitedSites] = useRecoilState(timeVisitedSitesState);

const { loading, queryCall } = useQuery(getTimerDailyRequestAPI);

const getVisitedApps = useCallback(() => {
const todayStart = moment().startOf('day').toDate();
const todayEnd = moment().endOf('day').toDate();

queryCall({
tenantId: user?.tenantId ?? '',
organizationId: user?.employee.organizationId ?? '',
employeeId: user?.employee.id ?? '',
todayEnd,
const getVisitedApps = useCallback(
({ title }: { title?: string }) => {
const todayStart = moment().startOf('day').toDate();
const todayEnd = moment().endOf('day').toDate();
const employeeId = profile.member?.employeeId ?? '';
if (profile.userProfile?.id === user?.id || user?.role?.name?.toUpperCase() == 'MANAGER') {
queryCall({
tenantId: user?.tenantId ?? '',
organizationId: user?.employee.organizationId ?? '',
employeeId: employeeId,
todayEnd,
type,
todayStart,
title
})
.then((response) => {
if (response.data) {
// @ts-ignore
if (title) setVisitedAppDetail(response.data[0]);
else if (type == 'APP') setVisitedApps(response.data);
else setVisitedSites(response.data);
}
})
.catch((err) => console.log(err));
}
},
[
profile.member?.employeeId,
profile.userProfile?.id,
user?.id,
user?.role?.name,
user?.tenantId,
user?.employee.organizationId,
queryCall,
type,
todayStart
})
.then((response) => {
if (response.data) {
if (type == 'APP') setVisitedApps(response.data);
else setVisitedSites(response.data);
}
})
.catch((err) => console.log(err));
}, [queryCall, setVisitedApps, setVisitedSites, user, type]);
setVisitedAppDetail,
setVisitedApps,
setVisitedSites
]
);

useEffect(() => {
getVisitedApps();
getVisitedApps({});
}, [user, getVisitedApps]);

return {
visitedApps,
visitedSites,
visitedAppDetail,
getVisitedApps,
loading
};
Expand Down
40 changes: 27 additions & 13 deletions apps/web/app/hooks/features/useTimeSlot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,44 @@ import { timeSlotsState } from '@app/stores/time-slot';
import moment from 'moment';
import { useAuthenticateUser } from './useAuthenticateUser';
import { deleteTimerLogsRequestAPI, getTimerLogsRequestAPI } from '@app/services/client/api';
import { useUserProfilePage } from './useUserProfilePage';

export function useTimeSlots() {
const { user } = useAuthenticateUser();
const [timeSlots, setTimeSlots] = useRecoilState(timeSlotsState);
const profile = useUserProfilePage();

const { loading, queryCall } = useQuery(getTimerLogsRequestAPI);
const { loading: loadingDelete, queryCall: queryDeleteCall } = useQuery(deleteTimerLogsRequestAPI);

const getTimeSlots = useCallback(() => {
const todayStart = moment().startOf('day').toDate();
const todayEnd = moment().endOf('day').toDate();
queryCall({
tenantId: user?.tenantId ?? '',
organizationId: user?.employee.organizationId ?? '',
employeeId: user?.employee.id ?? '',
todayEnd,
todayStart
}).then((response) => {
if (response.data) {
// @ts-expect-error
setTimeSlots(response.data[0].timeSlots);
}
});
}, [queryCall, setTimeSlots, user]);
const employeeId = profile.member?.employeeId ?? '';
if (profile.userProfile?.id === user?.id || user?.role?.name?.toUpperCase() == 'MANAGER') {
queryCall({
tenantId: user?.tenantId ?? '',
organizationId: user?.employee.organizationId ?? '',
employeeId: employeeId,
todayEnd,
todayStart
}).then((response) => {
if (response.data) {
// @ts-expect-error
setTimeSlots(response.data[0].timeSlots);
}
});
}
}, [
profile.member?.employeeId,
profile.userProfile?.id,
user?.id,
user?.role?.name,
user?.tenantId,
user?.employee.organizationId,
queryCall,
setTimeSlots
]);

const deleteTimeSlots = useCallback(
(ids: string[]) => {
Expand Down
15 changes: 13 additions & 2 deletions apps/web/app/services/client/api/activity/activity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,34 @@ export async function getTimerDailyRequestAPI({
employeeId,
todayEnd,
todayStart,
type
type,
title
}: {
tenantId: string;
organizationId: string;
employeeId: string;
todayEnd: Date;
todayStart: Date;
type: string;
title?: string;
}) {
const params = {
const params: {
tenantId: string;
organizationId: string;
'employeeIds[0]': string;
startDate: string;
endDate: string;
'types[0]': string;
'title[0]'?: string;
} = {
tenantId: tenantId,
organizationId: organizationId,
'employeeIds[0]': employeeId,
startDate: todayStart.toISOString(),
endDate: todayEnd.toISOString(),
'types[0]': type
};
if (title) params['title[0]'] = title;
const query = new URLSearchParams(params);
const endpoint = GAUZY_API_BASE_SERVER_URL.value
? `/timesheet/activity/daily?${query.toString()}`
Expand Down
18 changes: 17 additions & 1 deletion apps/web/app/services/client/api/timer/timer-status.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,29 @@
import { ITimerStatus } from '@app/interfaces';
import { get } from '../../axios';
import { GAUZY_API_BASE_SERVER_URL } from '@app/constants';

export async function getTaskStatusList(
tenantId: string,
organizationId: string,
employeeId: string,
organizationTeamId: string | null
) {
const endpoint = `/timer/status?tenantId=${tenantId}&organizationId=${organizationId}&organizationTeamId=${organizationTeamId}&employeeId=${employeeId}`;
const params: {
tenantId: string;
organizationId: string;
employeeId: string;
organizationTeamId?: string;
} = {
tenantId: tenantId,
organizationId: organizationId,
employeeId: employeeId
};
if (organizationTeamId) params.organizationTeamId = organizationTeamId;
const query = new URLSearchParams(params);

const endpoint = GAUZY_API_BASE_SERVER_URL.value
? `/timesheet/timer/status?${query.toString()}`
: `/timer/status?tenantId=${tenantId}&organizationId=${organizationId}&organizationTeamId=${organizationTeamId}&employeeId=${employeeId}`;

return get<ITimerStatus>(endpoint, { tenantId });
}
Expand Down
34 changes: 34 additions & 0 deletions apps/web/app/services/server/requests/timer/status.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { ITimerSlotDataRequest } from '@app/interfaces/timer/ITimerSlot';
import { serverFetch } from '../../fetch';

export function getTimerStatusRequest({
bearer_token,
tenantId,
organizationId,
todayEnd,
todayStart,
employeeId
}: {
bearer_token: string;
tenantId: string;
organizationId: string;
todayEnd: Date;
todayStart: Date;
employeeId: string;
}) {
const params = {
tenantId: tenantId,
organizationId: organizationId,
employeeId,
todayStart: todayStart.toISOString(),
todayEnd: todayEnd.toISOString(),
'relations[0]': 'employee'
};
const query = new URLSearchParams(params);
return serverFetch<ITimerSlotDataRequest>({
path: `/timesheet/timer/status?${query.toString()}`,
method: 'GET',
bearer_token,
tenantId
});
}
6 changes: 5 additions & 1 deletion apps/web/app/stores/time-slot.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ITimerApps } from '@app/interfaces/timer/ITimerApp';
import { IDetailTimerSite, ITimerApps } from '@app/interfaces/timer/ITimerApp';
import { ITimerSlot } from '@app/interfaces/timer/ITimerSlot';
import { atom } from 'recoil';

Expand All @@ -16,3 +16,7 @@ export const timeVisitedSitesState = atom<ITimerApps[]>({
key: 'timeVisitedSiteState',
default: []
});

export const timeAppVisitedDetail = atom<IDetailTimerSite>({
key: 'timeAppVisitedDetail'
});
9 changes: 8 additions & 1 deletion apps/web/lib/features/activity/apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { AppVisitedSkeleton } from './components/app-visited-skeleton';
import { groupAppsByHour } from '@app/helpers/array-data';
import { useTranslations } from 'next-intl';
import AppVisitedItem from './components/app-visited-Item';
import { AppVisitedModal } from './components/app-visited-details';

export function AppsTab() {
const { visitedApps, loading } = useTimeDailyActivity('APP');
Expand All @@ -27,7 +28,13 @@ export function AppsTab() {
<div>
{app.apps?.map((item, i) => (
<div key={i} className="w-full">
<AppVisitedItem app={item} totalMilliseconds={app.totalMilliseconds} type="APP"/>
<AppVisitedModal>
<AppVisitedItem
app={item}
totalMilliseconds={app.totalMilliseconds}
type="APP"
/>
</AppVisitedModal>
</div>
))}
</div>
Expand Down
32 changes: 32 additions & 0 deletions apps/web/lib/features/activity/components/app-visited-details.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { useModal } from '@app/hooks';
// import { useTimeDailyActivity } from '@app/hooks/features/useTimeDailyActivity';
import { Modal } from 'lib/components';
import React, { PropsWithChildren } from 'react';

export function AppVisitedModal({ children }: PropsWithChildren) {
const { closeModal, isOpen, openModal } = useModal();
// const { visitedAppDetail, loading } = useTimeDailyActivity('APP');
return (
<div>
<div onClick={openModal}>{children}</div>
<Modal
isOpen={isOpen}
closeModal={closeModal}
title="Screenshots detail"
className="bg-white dark:bg-[#343434d4] p-4 rounded-lg lg:w-[60vw] xl:w-[50vw] 2xl:w-[40vw] m-8"
>
{/* {loading ? (
<div>Loading ...</div>
) : (
<div>
<h3>{visitedAppDetail.title}</h3>
<p>{visitedAppDetail.description}</p>
<div>
<span>{visitedAppDetail.isActive && 'Active'}</span>
</div>
</div>
)} */}
</Modal>
</div>
);
}
Loading

0 comments on commit c05b27a

Please sign in to comment.