Skip to content

Commit

Permalink
Merge pull request #2655 from ever-co/feat/user-notification-outstanding
Browse files Browse the repository at this point in the history
User notification outstanding
  • Loading branch information
evereq authored Jun 29, 2024
2 parents 6e80735 + c825483 commit 2679f69
Show file tree
Hide file tree
Showing 19 changed files with 220 additions and 21 deletions.
8 changes: 5 additions & 3 deletions apps/web/app/[locale]/auth/passcode/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ function PasscodeScreen({ form, className }: { form: TAuthenticationPasscode } &
if (formRef.current) {
formRef.current.dispatchEvent(new Event('submit', { cancelable: true, bubbles: true }));
}
}
};

return (
<form className={className} ref={formRef} onSubmit={form.handleCodeSubmit} autoComplete="off">
Expand Down Expand Up @@ -306,6 +306,7 @@ function WorkSpaceScreen({ form, className }: { form: TAuthenticationPasscode }
(e: any) => {
if (typeof selectedWorkspace !== 'undefined') {
form.handleWorkspaceSubmit(e, form.workspaces[selectedWorkspace].token, selectedTeam);
window && window?.localStorage.removeItem('user-saw-notif');
}
},
[selectedWorkspace, selectedTeam, form]
Expand Down Expand Up @@ -387,8 +388,9 @@ export function WorkSpaceComponent(props: IWorkSpace) {
{props.workspaces?.map((worksace, index) => (
<div
key={index}
className={`w-full flex flex-col border border-[#0000001A] dark:border-[#34353D] ${props.selectedWorkspace === index ? 'bg-[#FCFCFC] dark:bg-[#1F2024]' : ''
} hover:bg-[#FCFCFC] dark:hover:bg-[#1F2024] rounded-xl`}
className={`w-full flex flex-col border border-[#0000001A] dark:border-[#34353D] ${
props.selectedWorkspace === index ? 'bg-[#FCFCFC] dark:bg-[#1F2024]' : ''
} hover:bg-[#FCFCFC] dark:hover:bg-[#1F2024] rounded-xl`}
>
<div className="text-base font-medium py-[1.25rem] px-4 flex flex-col gap-[1.0625rem]">
<div className="flex justify-between">
Expand Down
1 change: 1 addition & 0 deletions apps/web/app/[locale]/auth/password/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ function WorkSpaceScreen({ form, className }: { form: TAuthenticationPassword }
(e: any) => {
if (typeof selectedWorkspace !== 'undefined') {
form.handleWorkspaceSubmit(e, form.workspaces[selectedWorkspace].token, selectedTeam);
window && window?.localStorage.removeItem('user-saw-notif');
}
},
[selectedWorkspace, selectedTeam, form]
Expand Down
1 change: 1 addition & 0 deletions apps/web/app/[locale]/auth/workspace/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ function WorkSpaceScreen() {
new Array(3).fill('').forEach((_, i) => {
Cookies.remove(`authjs.session-token.${i}`);
});
window && window?.localStorage.removeItem('user-saw-notif');
};

const updateOAuthSession = useCallback(() => {
Expand Down
19 changes: 16 additions & 3 deletions apps/web/app/[locale]/page-component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

'use client';

import React, { useEffect } from 'react';
import React, { useEffect, useState } from 'react';
import { useOrganizationTeams } from '@app/hooks';
import { clsxm } from '@app/utils';
import NoTeam from '@components/pages/main/no-team';
Expand Down Expand Up @@ -30,9 +30,13 @@ 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 { 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] = useRecoilState(fullWidthState);
const [view, setView] = useRecoilState(headerTabs);
Expand Down Expand Up @@ -67,8 +71,16 @@ function MainPage() {
<div className="pt-3 h-[80vh]">
<ResizablePanelGroup direction="vertical">
{/* <Container className="mx-0 " fullWidth={fullWidth}> */}
<ResizablePanel defaultSize={45} maxSize={44}>
<div className="bg-white sticky z-50 border-b-[0.125rem] dark:border-[#26272C] dark:bg-dark-high">
<ResizablePanel
defaultSize={50}
maxSize={48}
className={clsxm(
headerSize < 20 ? '!overflow-hidden' : '!overflow-visible',
'dark:bg-dark-high border-b-[0.125rem] dark:border-[#26272C]'
)}
onResize={(size) => setHeaderSize(size)}
>
<div className="bg-white sticky z-50 dark:bg-dark-high">
<div
className={clsxm(
'bg-white dark:bg-dark-high ',
Expand All @@ -87,6 +99,7 @@ function MainPage() {
<div className="mx-8-container mb-1">
<UnverifiedEmail />
<TeamInvitations />
<TeamOutstandingNotifications />
{isTeamMember ? (
<TaskTimerSection isTrackingEnabled={isTrackingEnabled} />
) : null}
Expand Down
95 changes: 95 additions & 0 deletions apps/web/lib/features/team/team-outstanding-notifications.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
'use client';
import { useAuthenticateUser, useDailyPlan } from '@app/hooks';
import { IDailyPlan, IUser } from '@app/interfaces';
import { Cross2Icon, EyeOpenIcon } from '@radix-ui/react-icons';
import { Tooltip } from 'lib/components';
import { useTranslations } from 'next-intl';
import Link from 'next/link';
import { useEffect, useState } from 'react';

export function TeamOutstandingNotifications() {
const { getEmployeeDayPlans, outstandingPlans } = useDailyPlan();

const { user } = useAuthenticateUser();

useEffect(() => {
getEmployeeDayPlans(user?.employee.id || '');
}, [getEmployeeDayPlans, user?.employee.id]);

return (
<>
{outstandingPlans && outstandingPlans.length > 0 && (
<UserOutstandingNotification outstandingTasks={outstandingPlans} user={user} />
)}
</>
);
}

function UserOutstandingNotification({ outstandingTasks, user }: { outstandingTasks: IDailyPlan[]; user?: IUser }) {
const t = useTranslations();

// Notification will be displayed 6 hours after the user closed it
const REAPPEAR_INTERVAL = 6 * 60 * 60 * 1000; // 6 hours in milliseconds;
const DISMISSAL_TIMESTAMP_KEY = 'user-saw-notif';

const name = user?.name || user?.firstName || user?.lastName || user?.username;

const [visible, setVisible] = useState(false);
const tasks = outstandingTasks.flatMap((plan) => plan.tasks);

useEffect(() => {
const checkNotification = () => {
const alreadySeen = window && parseInt(window?.localStorage.getItem(DISMISSAL_TIMESTAMP_KEY) || '0', 10);
const currentTime = new Date().getTime();

if (!alreadySeen || currentTime - alreadySeen > REAPPEAR_INTERVAL) {
setVisible(true);
}
};

checkNotification();
const intervalId = setInterval(checkNotification, REAPPEAR_INTERVAL);
return () => clearInterval(intervalId);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

const onClose = () => {
window && window?.localStorage.setItem(DISMISSAL_TIMESTAMP_KEY, new Date().getTime().toString());
setVisible(false);
};

return (
<>
{visible && (
<div className="rounded-2xl dark:border-dark--theme-light border py-2 px-6 flex justify-between items-center text-xs mb-2">
<div>
{t('pages.home.OUTSTANDING_NOTIFICATIONS.SUBJECT')} {tasks?.length}{' '}
{t('pages.home.OUTSTANDING_NOTIFICATIONS.USER_LABEL')}{' '}
<span className="font-medium">
{t('pages.home.OUTSTANDING_NOTIFICATIONS.OUTSTANDING_VIEW')}
</span>
</div>
<div className="flex items-center gap-5">
<div>
<Link
href={`/profile/${user?.id}?name=${name || ''}`}
className="bg-primary text-white py-2 px-4 flex gap-2 items-center rounded-xl"
onClick={() => {
onClose();
window && window.localStorage.setItem('task-tab', 'dailyplan');
window && window.localStorage.setItem('daily-plan-tab', 'Outstanding');
}}
>
<EyeOpenIcon />
<span>{t('pages.home.OUTSTANDING_NOTIFICATIONS.VIEW_BUTTON')}</span>
</Link>
</div>
<Tooltip label={t('common.CLOSE')}>
<Cross2Icon className="text-xl cursor-pointer" onClick={onClose} />
</Tooltip>
</div>
</div>
)}
</>
);
}
13 changes: 11 additions & 2 deletions apps/web/lib/features/user-profile-plans.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useState } from 'react';
import { useEffect, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { useCanSeeActivityScreen, useDailyPlan, useUserProfilePage } from '@app/hooks';
import { TaskCard } from './task/task-card';
Expand All @@ -19,11 +19,16 @@ import { Button } from '@components/ui/button';
type FilterTabs = 'Today Tasks' | 'Future Tasks' | 'Past Tasks' | 'All Tasks' | 'Outstanding';

export function UserProfilePlans() {
const defaultTab =
typeof window !== 'undefined'
? (window.localStorage.getItem('daily-plan-tab') as FilterTabs) || null
: 'Today Tasks';

const profile = useUserProfilePage();
const { todayPlan, futurePlans, pastPlans, outstandingPlans, sortedPlans, profileDailyPlans } = useDailyPlan();
const fullWidth = useRecoilValue(fullWidthState);

const [currentTab, setCurrentTab] = useState<FilterTabs>('Today Tasks');
const [currentTab, setCurrentTab] = useState<FilterTabs>(defaultTab || 'Today Tasks');

const tabsScreens = {
'Today Tasks': <AllPlans profile={profile} currentTab={currentTab} />,
Expand All @@ -33,6 +38,10 @@ export function UserProfilePlans() {
Outstanding: <Outstanding profile={profile} />
};

useEffect(() => {
window.localStorage.setItem('daily-plan-tab', currentTab);
}, [currentTab]);

return (
<div className="">
<Container fullWidth={fullWidth} className="pb-8 mb-5">
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": "لإعادة إرسال الرمز إذا لم تتلقاه.",
"INVITATIONS": "لقد تمت دعوتك للانضمام إلى",
"CONFIRM_ACCEPT_INVITATION": "هل أنت متأكد من رغبتك في قبول الدعوة؟",
"CONFIRM_REJECT_INVITATION": "هل أنت متأكد من رغبتك في رفض الدعوة؟"
"CONFIRM_REJECT_INVITATION": "هل أنت متأكد من رغبتك في رفض الدعوة؟",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "لديك",
"USER_LABEL": "مهام غير مكتملة، يرجى التحقق منها",
"OUTSTANDING_VIEW": "عرض المهام المعلقة",
"VIEW_BUTTON": "عرض"
}
},
"kanban": {
"KANBAN_BOARD": "لوحة كانبان"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/bg.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": "за да изпратите кода отново, ако не сте го получили.",
"INVITATIONS": "Поканени сте да се присъедините към",
"CONFIRM_ACCEPT_INVITATION": "Сигурни ли сте, че искате да приемете поканата?",
"CONFIRM_REJECT_INVITATION": "Сигурни ли сте, че искате да отхвърлите поканата?"
"CONFIRM_REJECT_INVITATION": "Сигурни ли сте, че искате да отхвърлите поканата?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Имате",
"USER_LABEL": "незавършени задачи, моля, проверете",
"OUTSTANDING_VIEW": "Преглед на изчакващите задачи",
"VIEW_BUTTON": "Преглед"
}
},
"kanban": {
"KANBAN_BOARD": "Канбан дъска"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " um den Code erneut zu senden, falls Sie ihn nicht erhalten haben.",
"INVITATIONS": "Sie wurden eingeladen, beizutreten",
"CONFIRM_ACCEPT_INVITATION": "Möchten Sie die Einladung wirklich annehmen?",
"CONFIRM_REJECT_INVITATION": "Möchten Sie die Einladung wirklich ablehnen?"
"CONFIRM_REJECT_INVITATION": "Möchten Sie die Einladung wirklich ablehnen?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Sie haben",
"USER_LABEL": "unvollständige Aufgaben, bitte überprüfen",
"OUTSTANDING_VIEW": "Ausstehende Ansicht",
"VIEW_BUTTON": "Ansehen"
}
},
"kanban": {
"KANBAN_BOARD": "Kanban-Board"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " to resend the code, if you did not received it.",
"INVITATIONS": "You've been invited to join",
"CONFIRM_ACCEPT_INVITATION": "Are you sure you want to accept the invitation?",
"CONFIRM_REJECT_INVITATION": "Are you sure you want to reject the invitation?"
"CONFIRM_REJECT_INVITATION": "Are you sure you want to reject the invitation?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "You've",
"USER_LABEL": "uncompleted tasks, please check in",
"OUTSTANDING_VIEW": "Outstanding View",
"VIEW_BUTTON": "View"
}
},
"profile": {
"BREADCRUMB": "[\"Member Tasks\"]",
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " para reenviar el código, si no lo recibiste.",
"INVITATIONS": "Has sido invitado a unirte a",
"CONFIRM_ACCEPT_INVITATION": "¿Estás seguro de que deseas aceptar la invitación?",
"CONFIRM_REJECT_INVITATION": "¿Estás seguro de que deseas rechazar la invitación?"
"CONFIRM_REJECT_INVITATION": "¿Estás seguro de que deseas rechazar la invitación?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Tienes",
"USER_LABEL": "tareas incompletas, por favor revisa",
"OUTSTANDING_VIEW": "Vista pendiente",
"VIEW_BUTTON": "Ver"
}
},
"kanban": {
"KANBAN_BOARD": "tablero kanban"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " pour renvoyer le code si vous ne l'avez pas reçu.",
"INVITATIONS": "Vous avez été invité à rejoindre",
"CONFIRM_ACCEPT_INVITATION": "Êtes-vous sûr de vouloir accepter l'invitation ?",
"CONFIRM_REJECT_INVITATION": "Êtes-vous sûr de vouloir refuser l'invitation ?"
"CONFIRM_REJECT_INVITATION": "Êtes-vous sûr de vouloir refuser l'invitation ?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Vous avez",
"USER_LABEL": "des tâches incomplètes, veuillez vérifier",
"OUTSTANDING_VIEW": "Vue des tâches en attente",
"VIEW_BUTTON": "Voir"
}
},
"kanban": {
"KANBAN_BOARD": "Tableau Kanban"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/he.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " כדי לשלוח מחדש את הקוד, אם לא קיבלת אותו.",
"INVITATIONS": "הוזמנת להצטרף ל-",
"CONFIRM_ACCEPT_INVITATION": "האם אתה בטוח שברצונך לקבל את ההזמנה?",
"CONFIRM_REJECT_INVITATION": "האם אתה בטוח שברצונך לדחות את ההזמנה?"
"CONFIRM_REJECT_INVITATION": "האם אתה בטוח שברצונך לדחות את ההזמנה?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "יש לך",
"USER_LABEL": "משימות שלא הושלמו, נא לבדוק",
"OUTSTANDING_VIEW": "תצוגה ממתינה",
"VIEW_BUTTON": "הצג"
}
},
"kanban": {
"KANBAN_BOARD": "לוח Kanban"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/it.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " per inviare nuovamente il codice, se non l'hai ricevuto.",
"INVITATIONS": "Sei stato invitato a unirti a",
"CONFIRM_ACCEPT_INVITATION": "Sei sicuro di voler accettare l'invito?",
"CONFIRM_REJECT_INVITATION": "Sei sicuro di voler rifiutare l'invito?"
"CONFIRM_REJECT_INVITATION": "Sei sicuro di voler rifiutare l'invito?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Hai",
"USER_LABEL": "compiti incompleti, controlla per favore",
"OUTSTANDING_VIEW": "Vista delle attività in sospeso",
"VIEW_BUTTON": "Vedi"
}
},
"kanban": {
"KANBAN_BOARD": "Tabellone Kanban"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/nl.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": "om de code opnieuw te verzenden, voor het geval u deze niet heeft ontvangen.",
"INVITATIONS": "U bent uitgenodigd om lid te worden van",
"CONFIRM_ACCEPT_INVITATION": "Weet u zeker dat u de uitnodiging wilt accepteren?",
"CONFIRM_REJECT_INVITATION": "Weet u zeker dat u de uitnodiging wilt afwijzen?"
"CONFIRM_REJECT_INVITATION": "Weet u zeker dat u de uitnodiging wilt afwijzen?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Je hebt",
"USER_LABEL": "onvoltooide taken, controleer alsjeblieft",
"OUTSTANDING_VIEW": "Uitzicht op uitstaande taken",
"VIEW_BUTTON": "Bekijk"
}
},
"kanban": {
"KANBAN_BOARD": "Kanban-bord"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/pl.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " aby ponownie wysłać kod, jeśli go nie otrzymałeś.",
"INVITATIONS": "Zostałeś zaproszony do dołączenia do",
"CONFIRM_ACCEPT_INVITATION": "Czy na pewno chcesz zaakceptować zaproszenie?",
"CONFIRM_REJECT_INVITATION": "Czy na pewno chcesz odrzucić zaproszenie?"
"CONFIRM_REJECT_INVITATION": "Czy na pewno chcesz odrzucić zaproszenie?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Masz",
"USER_LABEL": "niezakończone zadania, proszę sprawdź",
"OUTSTANDING_VIEW": "Widok zadań do wykonania",
"VIEW_BUTTON": "Zobacz"
}
},
"kanban": {
"KANBAN_BOARD": "Tablica Kanbana"
Expand Down
8 changes: 7 additions & 1 deletion apps/web/locales/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@
"SENT_EMAIL_VERIFICATION_RESEND": " para reenviar o código, caso não o tenha recebido.",
"INVITATIONS": "Você foi convidado a participar de",
"CONFIRM_ACCEPT_INVITATION": "Você tem certeza de que deseja aceitar o convite?",
"CONFIRM_REJECT_INVITATION": "Você tem certeza de que deseja rejeitar o convite?"
"CONFIRM_REJECT_INVITATION": "Você tem certeza de que deseja rejeitar o convite?",
"OUTSTANDING_NOTIFICATIONS": {
"SUBJECT": "Você tem",
"USER_LABEL": "tarefas não concluídas, por favor verifique",
"OUTSTANDING_VIEW": "Visualização de pendências",
"VIEW_BUTTON": "Ver"
}
},
"kanban": {
"KANBAN_BOARD": "Quadro Kanban"
Expand Down
Loading

0 comments on commit 2679f69

Please sign in to comment.