-
Notifications
You must be signed in to change notification settings - Fork 50
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2078 from ever-co/feat/activity
feat: get daily apps visited
- Loading branch information
Showing
24 changed files
with
349 additions
and
15 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { authenticatedGuard } from '@app/services/server/guards/authenticated-guard-app'; | ||
import { getEmployeeDailyRequest } from '@app/services/server/requests/timer/daily'; | ||
import { NextResponse } from 'next/server'; | ||
|
||
export async function GET(req: Request) { | ||
const res = new NextResponse(); | ||
const { $res, user, tenantId, organizationId, access_token } = await authenticatedGuard(req, res); | ||
if (!user) return $res('Unauthorized'); | ||
|
||
const { searchParams } = new URL(req.url); | ||
|
||
const { endDate, startDate, type } = searchParams as unknown as { | ||
startDate: Date; | ||
endDate: Date; | ||
type: string; | ||
}; | ||
|
||
const { data } = await getEmployeeDailyRequest({ | ||
tenantId, | ||
organizationId, | ||
employeeId: user.employee.id, | ||
todayEnd: endDate, | ||
todayStart: startDate, | ||
type, | ||
bearer_token: access_token | ||
}); | ||
|
||
return $res(data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
'use client'; | ||
|
||
import { useCallback, useEffect } from 'react'; | ||
import { useQuery } from '../useQuery'; | ||
import { useRecoilState } from 'recoil'; | ||
import { timeAppsState } from '@app/stores/time-slot'; | ||
import moment from 'moment'; | ||
import { useAuthenticateUser } from './useAuthenticateUser'; | ||
import { getTimerDailyRequestAPI } from '@app/services/client/api'; | ||
|
||
export function useTimeDailyActivity(type: string) { | ||
const { user } = useAuthenticateUser(); | ||
const [visitedApps, setVisitedApps] = useRecoilState(timeAppsState); | ||
|
||
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, | ||
type, | ||
todayStart | ||
}) | ||
.then((response) => { | ||
if (response.data) { | ||
console.log(response.data); | ||
setVisitedApps(response.data?.data); | ||
} | ||
}) | ||
.catch((err) => console.log(err)); | ||
}, [queryCall, setVisitedApps, user, type]); | ||
|
||
useEffect(() => { | ||
getVisitedApps(); | ||
}, [user, getVisitedApps]); | ||
|
||
return { | ||
visitedApps, | ||
getVisitedApps, | ||
loading | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export interface ITimerApps { | ||
sessions: string; | ||
duration: string; | ||
employeeId: string; | ||
date: Date | string; | ||
time: string; | ||
title: string; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { get } from '@app/services/client/axios'; | ||
import { GAUZY_API_BASE_SERVER_URL } from '@app/constants'; | ||
|
||
export async function getTimerDailyRequestAPI({ | ||
tenantId, | ||
organizationId, | ||
employeeId, | ||
todayEnd, | ||
todayStart, | ||
type | ||
}: { | ||
tenantId: string; | ||
organizationId: string; | ||
employeeId: string; | ||
todayEnd: Date; | ||
todayStart: Date; | ||
type: string; | ||
}) { | ||
const params = { | ||
tenantId: tenantId, | ||
organizationId: organizationId, | ||
'employeeIds[0]': employeeId, | ||
startDate: todayStart.toISOString(), | ||
endDate: todayEnd.toISOString(), | ||
'types[0]': type | ||
}; | ||
const query = new URLSearchParams(params); | ||
const endpoint = GAUZY_API_BASE_SERVER_URL.value | ||
? `/timesheet/activity/daily?${query.toString()}` | ||
: `/timer/daily?${query.toString()}`; | ||
|
||
const data = await get(endpoint, true); | ||
|
||
return data; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { serverFetch } from '../../fetch'; | ||
import { ITimerSlotDataRequest } from '@app/interfaces/timer/ITimerSlot'; | ||
|
||
export function getEmployeeDailyRequest({ | ||
bearer_token, | ||
tenantId, | ||
organizationId, | ||
todayEnd, | ||
todayStart, | ||
employeeId, | ||
type | ||
}: { | ||
bearer_token: string; | ||
tenantId: string; | ||
organizationId: string; | ||
todayEnd: Date; | ||
todayStart: Date; | ||
employeeId: string; | ||
type: string; | ||
}) { | ||
const params = { | ||
tenantId: tenantId, | ||
organizationId: organizationId, | ||
'employeeIds[0]': employeeId, | ||
startDate: todayStart.toISOString(), | ||
endDate: todayEnd.toISOString(), | ||
'types[0]': type | ||
}; | ||
const query = new URLSearchParams(params); | ||
return serverFetch<ITimerSlotDataRequest>({ | ||
path: `/timesheet/activity/daily?${query.toString()}`, | ||
method: 'GET', | ||
bearer_token, | ||
tenantId | ||
}); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,13 @@ | ||
import { ITimerApps } from '@app/interfaces/timer/ITimerApp'; | ||
import { ITimerSlot } from '@app/interfaces/timer/ITimerSlot'; | ||
import { atom } from 'recoil'; | ||
|
||
export const timeSlotsState = atom<ITimerSlot[]>({ | ||
key: 'timeSlotsState', | ||
default: [] | ||
}); | ||
|
||
export const timeAppsState = atom<ITimerApps[]>({ | ||
key: 'timeAppsState', | ||
default: [] | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,50 @@ | ||
import { useTimeDailyActivity } from '@app/hooks/features/useTimeDailyActivity'; | ||
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'; | ||
|
||
export function AppsTab() { | ||
return <div>Apps Tab</div>; | ||
const { visitedApps, loading } = useTimeDailyActivity('APP'); | ||
const t = useTranslations(); | ||
const apps = groupAppsByHour(visitedApps); | ||
return ( | ||
<div> | ||
<div className="flex justify-end w-full">{/* TODO: Filters components */}</div> | ||
<header className="bg-gray-200 dark:bg-[#26272C] rounded-md p-4 flex items-center justify-between"> | ||
<h3 className="text-lg font-semibold w-1/4">{t('timer.APPS')}</h3> | ||
<h3 className="text-lg text-center font-semibold w-1/4">{t('timer.VISITED_DATES')}</h3> | ||
<h3 className="text-lg text-center font-semibold w-1/4">{t('timer.PERCENT_USED')}</h3> | ||
<h3 className="text-lg font-semibold w-1/4 text-end">{t('timer.TIME_SPENT_IN_HOURS')}</h3> | ||
</header> | ||
<section> | ||
{apps.map((app, i) => ( | ||
<div | ||
key={i} | ||
className="border shadow-lg shadow-gray-200 rounded-md my-4 p-4 dark:border-[#FFFFFF0D] bg-white dark:bg-[#1B1D22]" | ||
> | ||
<h3>{app.hour}</h3> | ||
<div> | ||
{app.apps?.map((item, i) => ( | ||
<div key={i} className="w-full"> | ||
<AppVisitedItem app={item} totalMilliseconds={app.totalMilliseconds} /> | ||
</div> | ||
))} | ||
</div> | ||
</div> | ||
))} | ||
</section> | ||
{visitedApps.length < 1 && !loading && ( | ||
<div className="hover:dark:bg-[#26272C] border dark:border-[#26272C] dark:bg-[#191a20] p-4 py-16 rounded-md flex justify-center items-center my-2"> | ||
<p className="text-lg text-center">{t('timer.THERE_IS_NO_APPS_VISITED')}</p> | ||
</div> | ||
)} | ||
{loading && visitedApps.length < 1 && ( | ||
<> | ||
<AppVisitedSkeleton /> | ||
<AppVisitedSkeleton /> | ||
</> | ||
)} | ||
</div> | ||
); | ||
} |
24 changes: 24 additions & 0 deletions
24
apps/web/lib/features/activity/components/app-visited-Item.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { formatDateString, secondsToTime } from '@app/helpers'; | ||
import { ITimerApps } from '@app/interfaces/timer/ITimerApp'; | ||
import { ProgressBar } from 'lib/components'; | ||
import React from 'react'; | ||
|
||
const AppVisitedItem = ({ app, totalMilliseconds }: { app: ITimerApps; totalMilliseconds: number }) => { | ||
const { h, m, s } = secondsToTime(+app.duration); | ||
const percent = ((+app.duration * 100) / totalMilliseconds).toFixed(2); | ||
return ( | ||
<div className="hover:dark:bg-[#26272C] border dark:border-[#26272C] bg-gray-200 dark:bg-[#191a20] p-4 rounded-md flex justify-between apps-center my-2"> | ||
<p className="text-lg w-1/4">{app.title}</p> | ||
<p className="text-lg text-center w-1/4"> | ||
{formatDateString(new Date(app.date).toISOString())} - {app.time} | ||
</p> | ||
<div className="text-lg w-1/4 flex justify-center gap-2 px-4"> | ||
<p className="w-1/4">{percent}%</p> | ||
<ProgressBar progress={percent + '%'} width={`75%`} /> | ||
</div> | ||
<p className="text-lg w-1/4 text-end">{`${h}:${m}:${s}`}</p> | ||
</div> | ||
); | ||
}; | ||
|
||
export default AppVisitedItem; |
18 changes: 18 additions & 0 deletions
18
apps/web/lib/features/activity/components/app-visited-skeleton.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
export function AppVisitedSkeleton() { | ||
return ( | ||
<div className=" dark:bg-[#26272C] p-4 py-6 animate-pulse rounded-md flex justify-between items-center my-2"> | ||
<div className="w-1/4 p-2"> | ||
<p className="animate-pulse w-28 py-2 rounded bg-gray-200 dark:bg-[#191a20]"></p> | ||
</div> | ||
<div className="w-1/4 p-2"> | ||
<p className="animate-pulse w-28 py-2 rounded bg-gray-200 dark:bg-[#191a20]"></p> | ||
</div> | ||
<div className="w-1/4 p-2"> | ||
<p className="animate-pulse w-28 py-2 rounded bg-gray-200 dark:bg-[#191a20]"></p> | ||
</div> | ||
<div className="w-1/4 p-2"> | ||
<p className="animate-pulse w-28 py-2 rounded bg-gray-200 dark:bg-[#191a20]"></p> | ||
</div> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.