Skip to content

Commit

Permalink
Merge pull request #2572 from ever-co/stage
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Jun 2, 2024
2 parents e945d04 + 59956c3 commit fae0986
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 19 deletions.
3 changes: 2 additions & 1 deletion apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import { AppsTab } from 'lib/features/activity/apps';
import { VisitedSitesTab } from 'lib/features/activity/visited-sites';
import { activityTypeState } from '@app/stores/activity-type';

type FilterTab = 'Tasks' | 'Screenshots' | 'Apps' | 'Visited Sites';
export type FilterTab = 'Tasks' | 'Screenshots' | 'Apps' | 'Visited Sites';

const Profile = React.memo(function ProfilePage({ params }: { params: { memberId: string } }) {
const profile = useUserProfilePage();

const { user } = useAuthenticateUser();
const { isTrackingEnabled, activeTeam, activeTeamManagers } = useOrganizationTeams();
const members = activeTeam?.members;
Expand Down
8 changes: 5 additions & 3 deletions apps/web/app/hooks/features/useUserProfilePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,21 @@ import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';
import { useRecoilValue } from 'recoil';
import { userDetailAccordion } from '@app/stores';

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

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

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

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

Expand Down
4 changes: 4 additions & 0 deletions apps/web/app/stores/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@ export const userState = atom<IUser | null>({
key: 'userState',
default: null
});
export const userDetailAccordion = atom<string>({
key: 'userDetailAccordion',
default: ''
});
85 changes: 72 additions & 13 deletions apps/web/lib/features/team/user-team-card/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,32 @@ import {
useTaskStatistics,
useOrganizationTeams,
useAuthenticateUser,
useTeamMemberCard
useTeamMemberCard,
useUserProfilePage
} from '@app/hooks';
import { IClassName, IOrganizationTeamList, OT_Member } from '@app/interfaces';
import { timerSecondsState } from '@app/stores';
import { timerSecondsState, userDetailAccordion as userAccordion } from '@app/stores';
import { clsxm } from '@app/utils';
import { Card, InputField, Text, VerticalSeparator } from 'lib/components';
import { TaskTimes, TodayWorkedTime } 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 { useRecoilValue, useSetRecoilState } from 'recoil';
import { useRecoilState, useRecoilValue, useSetRecoilState } from 'recoil';
import { TaskEstimateInfo } from './task-estimate';
import { TaskInfo } from './task-info';
import { UserInfo } from './user-info';
import { UserTeamCardMenu } from './user-team-card-menu';
import React from 'react';
import React, { useCallback, useState } from 'react';
import UserTeamActivity from './user-team-card-activity';
import { CollapseUpIcon, ExpandIcon } from '@components/ui/svgs/expand';
import { activityTypeState } from '@app/stores/activity-type';
import { SixSquareGridIcon } from 'assets/svg';
import { ChevronDoubleDownIcon } from '@heroicons/react/20/solid';
import { useRouter } from 'next/navigation';
import { ScreenshootTab } from 'lib/features/activity/screenshoots';
import { AppsTab } from 'lib/features/activity/apps';
import { VisitedSitesTab } from 'lib/features/activity/visited-sites';
import { FilterTab } from '@app/[locale]/profile/[memberId]/page';
import { Loader } from 'lucide-react';
import { fullWidthState } from '@app/stores/fullWidth';

type IUserTeamCard = {
active?: boolean;
Expand All @@ -53,23 +59,26 @@ export function UserTeamCard({
onDragOver = () => null
}: IUserTeamCard) {
const t = useTranslations();
const profile = useUserProfilePage();
const [userDetailAccordion, setUserDetailAccordion] = useRecoilState(userAccordion);
const hook = useTaskFilter(profile);
const memberInfo = useTeamMemberCard(member);
const taskEdition = useTMCardTaskEdit(memberInfo.memberTask);
const { replace } = useRouter();
const { collaborativeSelect, user_selected, onUserSelect } = useCollaborative(memberInfo.memberUser);
const fullWidth = useRecoilValue(fullWidthState);

const seconds = useRecoilValue(timerSecondsState);
const setActivityFilter = useSetRecoilState(activityTypeState);
const { activeTaskTotalStat, addSeconds } = useTaskStatistics(seconds);
const [showActivity, setShowActivity] = React.useState<boolean>(false);
const [userDetailAccordion, setUserDetailAccordion] = React.useState(false);
const { activeTeamManagers } = useOrganizationTeams();
const { user } = useAuthenticateUser();

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,
Expand Down Expand Up @@ -114,6 +123,21 @@ export function UserTeamCard({
)}
</>
);
const [activityFilter, setActivity] = useState<FilterTab>('Tasks');

const activityScreens = {
Tasks: <UserProfileTask profile={profile} tabFiltered={hook} />,
Screenshots: <ScreenshootTab />,
Apps: <AppsTab />,
'Visited Sites': <VisitedSitesTab />
};
const changeActivityFilter = useCallback(
(filter: FilterTab) => {
setActivity(filter);
},
[setActivity]
);
const canSeeActivity = profile.userProfile?.id === user?.id || isManagerConnectedUser != -1;

return (
<div
Expand Down Expand Up @@ -145,13 +169,19 @@ export function UserTeamCard({
<UserInfo memberInfo={memberInfo} className="2xl:w-[20.625rem] w-1/4" publicTeam={publicTeam} />
<div
onClick={() => {
setUserDetailAccordion(!userDetailAccordion);
replace('/?memberId=' + (memberInfo?.memberUser?.id ?? ''));
setUserDetailAccordion(
userDetailAccordion == memberInfo.memberUser?.id
? ''
: memberInfo.memberUser?.id ?? ''
);
}}
className={clsxm('h-6 w-6 absolute right-4 top-0 cursor-pointer p-[3px]')}
>
<ChevronDoubleDownIcon
className={clsxm('h-4 w-4 transition-all', userDetailAccordion && 'rotate-180')}
className={clsxm(
'h-4 w-4 transition-all',
userDetailAccordion == memberInfo.memberUser?.id && 'rotate-180'
)}
/>
</div>
</div>
Expand Down Expand Up @@ -220,7 +250,36 @@ export function UserTeamCard({
{/* Card menu */}
<div className="absolute right-2">{menu}</div>
</div>
{userDetailAccordion ? <div className="h-96"></div> : null}
{userDetailAccordion == memberInfo.memberUser?.id &&
memberInfo.memberUser.id == profile.userProfile?.id ? (
<div className="h-96 overflow-y-auto">
{canSeeActivity && (
<Container fullWidth={fullWidth} className="py-8">
<div className={clsxm('flex justify-start items-center gap-4 mt-3')}>
{Object.keys(activityScreens).map((filter, i) => (
<div key={i} className="flex cursor-pointer justify-start items-center gap-4">
{i !== 0 && <VerticalSeparator />}
<div
className={clsxm(
'text-gray-500',
activityFilter == filter && 'text-black dark:text-white'
)}
onClick={() => changeActivityFilter(filter as FilterTab)}
>
{filter}
</div>
</div>
))}
</div>
</Container>
)}
{activityScreens[activityFilter] ?? null}
</div>
) : userDetailAccordion == memberInfo.memberUser?.id ? (
<div className="h-20 w-full flex justify-center items-center">
<Loader className="animate-spin" />
</div>
) : null}
<UserTeamActivity showActivity={showActivity} member={member} />
</Card>
<Card
Expand Down
5 changes: 3 additions & 2 deletions apps/web/lib/features/team/user-team-card/user-info.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ export function UserInfo({ className, memberInfo, publicTeam = false }: Props) {
as="h3"
className="overflow-hidden text-ellipsis whitespace-nowrap w-full text-base lg:text-lg flex gap-2"
>
{publicTeam ? <span className="flex capitalize">{fullname.slice(0, 1)} </span> : fullname}

<div className="max-w-[176px] truncate">
{publicTeam ? <span className="flex capitalize">{fullname.slice(0, 1)}</span> : fullname}
</div>
{(member?.role?.name === 'MANAGER' ||
member?.role?.name === 'SUPER_ADMIN' ||
member?.role?.name === 'ADMIN') && (
Expand Down

0 comments on commit fae0986

Please sign in to comment.