Added a badge with the amount of pending tickets assigned to the user

This commit is contained in:
Joao Ramos
2024-02-13 17:29:55 +00:00
parent 64b1d9266e
commit b63ba3f316
4 changed files with 47 additions and 5 deletions

View File

@@ -34,6 +34,7 @@ export default function Layout({user, children, className, navDisabled = false,
onFocusLayerMouseEnter={onFocusLayerMouseEnter}
className="-md:hidden"
userType={user.type}
userId={user.id}
/>
<div
className={clsx(

View File

@@ -24,6 +24,7 @@ import { preventNavigation } from "@/utils/navigation.disabled";
import { useState } from "react";
import usePreferencesStore from "@/stores/preferencesStore";
import { Type } from "@/interfaces/user";
import useTicketsListener from '@/hooks/useTicketsListener';
interface Props {
path: string;
navDisabled?: boolean;
@@ -31,6 +32,7 @@ interface Props {
onFocusLayerMouseEnter?: () => void;
className?: string;
userType?: Type;
userId?: string;
}
interface NavProps {
@@ -40,6 +42,7 @@ interface NavProps {
keyPath: string;
disabled?: boolean;
isMinimized?: boolean;
badge?: number;
}
const Nav = ({
@@ -49,7 +52,10 @@ const Nav = ({
keyPath,
disabled = false,
isMinimized = false,
}: NavProps) => (
badge,
}: NavProps) => {
const displayBadge = badge && badge > 0 ? true : false;
return (
<Link
href={!disabled ? keyPath : ""}
className={clsx(
@@ -64,8 +70,10 @@ const Nav = ({
>
<Icon size={24} />
{!isMinimized && <span className="text-lg font-semibold">{label}</span>}
{displayBadge && <div className="badge badge-primary badge-sm">{badge}</div>}
</Link>
);
}
export default function Sidebar({
path,
@@ -74,6 +82,7 @@ export default function Sidebar({
userType,
onFocusLayerMouseEnter,
className,
userId,
}: Props) {
const router = useRouter();
@@ -82,6 +91,8 @@ export default function Sidebar({
state.toggleSidebarMinimized,
]);
const {totalAssignedTickets } = useTicketsListener(userId);
const logout = async () => {
axios.post("/api/logout").finally(() => {
setTimeout(() => router.reload(), 500);
@@ -177,6 +188,7 @@ export default function Sidebar({
path={path}
keyPath="/tickets"
isMinimized={isMinimized}
badge={totalAssignedTickets}
/>
)}
{userType === "developer" && (

View File

@@ -1,22 +1,22 @@
import { Ticket } from "@/interfaces/ticket";
import { Code, Group, User } from "@/interfaces/user";
import axios from "axios";
import { useEffect, useState } from "react";
import { useEffect, useState, useCallback } from "react";
export default function useTickets() {
const [tickets, setTickets] = useState<Ticket[]>([]);
const [isLoading, setIsLoading] = useState(false);
const [isError, setIsError] = useState(false);
const getData = () => {
const getData = useCallback(() => {
setIsLoading(true);
axios
.get<Ticket[]>(`/api/tickets`)
.then((response) => setTickets(response.data))
.finally(() => setIsLoading(false));
};
}, []);
useEffect(getData, []);
useEffect(getData, [getData]);
return { tickets, isLoading, isError, reload: getData };
}

View File

@@ -0,0 +1,29 @@
import React from "react";
import useTickets from "./useTickets";
const useTicketsListener = (userId?: string) => {
const { tickets, reload } = useTickets();
React.useEffect(() => {
const intervalId = setInterval(() => {
reload();
}, 60 * 1000);
return () => clearInterval(intervalId);
}, [reload]);
if (userId) {
const assignedTickets = tickets.filter(
(ticket) => ticket.assignedTo === userId && ticket.status === "submitted"
);
return {
assignedTickets,
totalAssignedTickets: assignedTickets.length,
};
}
return {};
};
export default useTicketsListener;