Added a badge with the amount of pending tickets assigned to the user
This commit is contained in:
@@ -34,6 +34,7 @@ export default function Layout({user, children, className, navDisabled = false,
|
|||||||
onFocusLayerMouseEnter={onFocusLayerMouseEnter}
|
onFocusLayerMouseEnter={onFocusLayerMouseEnter}
|
||||||
className="-md:hidden"
|
className="-md:hidden"
|
||||||
userType={user.type}
|
userType={user.type}
|
||||||
|
userId={user.id}
|
||||||
/>
|
/>
|
||||||
<div
|
<div
|
||||||
className={clsx(
|
className={clsx(
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import { preventNavigation } from "@/utils/navigation.disabled";
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import usePreferencesStore from "@/stores/preferencesStore";
|
import usePreferencesStore from "@/stores/preferencesStore";
|
||||||
import { Type } from "@/interfaces/user";
|
import { Type } from "@/interfaces/user";
|
||||||
|
import useTicketsListener from '@/hooks/useTicketsListener';
|
||||||
interface Props {
|
interface Props {
|
||||||
path: string;
|
path: string;
|
||||||
navDisabled?: boolean;
|
navDisabled?: boolean;
|
||||||
@@ -31,6 +32,7 @@ interface Props {
|
|||||||
onFocusLayerMouseEnter?: () => void;
|
onFocusLayerMouseEnter?: () => void;
|
||||||
className?: string;
|
className?: string;
|
||||||
userType?: Type;
|
userType?: Type;
|
||||||
|
userId?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface NavProps {
|
interface NavProps {
|
||||||
@@ -40,6 +42,7 @@ interface NavProps {
|
|||||||
keyPath: string;
|
keyPath: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
isMinimized?: boolean;
|
isMinimized?: boolean;
|
||||||
|
badge?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Nav = ({
|
const Nav = ({
|
||||||
@@ -49,7 +52,10 @@ const Nav = ({
|
|||||||
keyPath,
|
keyPath,
|
||||||
disabled = false,
|
disabled = false,
|
||||||
isMinimized = false,
|
isMinimized = false,
|
||||||
}: NavProps) => (
|
badge,
|
||||||
|
}: NavProps) => {
|
||||||
|
const displayBadge = badge && badge > 0 ? true : false;
|
||||||
|
return (
|
||||||
<Link
|
<Link
|
||||||
href={!disabled ? keyPath : ""}
|
href={!disabled ? keyPath : ""}
|
||||||
className={clsx(
|
className={clsx(
|
||||||
@@ -64,8 +70,10 @@ const Nav = ({
|
|||||||
>
|
>
|
||||||
<Icon size={24} />
|
<Icon size={24} />
|
||||||
{!isMinimized && <span className="text-lg font-semibold">{label}</span>}
|
{!isMinimized && <span className="text-lg font-semibold">{label}</span>}
|
||||||
|
{displayBadge && <div className="badge badge-primary badge-sm">{badge}</div>}
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export default function Sidebar({
|
export default function Sidebar({
|
||||||
path,
|
path,
|
||||||
@@ -74,6 +82,7 @@ export default function Sidebar({
|
|||||||
userType,
|
userType,
|
||||||
onFocusLayerMouseEnter,
|
onFocusLayerMouseEnter,
|
||||||
className,
|
className,
|
||||||
|
userId,
|
||||||
}: Props) {
|
}: Props) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -82,6 +91,8 @@ export default function Sidebar({
|
|||||||
state.toggleSidebarMinimized,
|
state.toggleSidebarMinimized,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
const {totalAssignedTickets } = useTicketsListener(userId);
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
axios.post("/api/logout").finally(() => {
|
axios.post("/api/logout").finally(() => {
|
||||||
setTimeout(() => router.reload(), 500);
|
setTimeout(() => router.reload(), 500);
|
||||||
@@ -177,6 +188,7 @@ export default function Sidebar({
|
|||||||
path={path}
|
path={path}
|
||||||
keyPath="/tickets"
|
keyPath="/tickets"
|
||||||
isMinimized={isMinimized}
|
isMinimized={isMinimized}
|
||||||
|
badge={totalAssignedTickets}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{userType === "developer" && (
|
{userType === "developer" && (
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import { Ticket } from "@/interfaces/ticket";
|
import { Ticket } from "@/interfaces/ticket";
|
||||||
import { Code, Group, User } from "@/interfaces/user";
|
import { Code, Group, User } from "@/interfaces/user";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState, useCallback } from "react";
|
||||||
|
|
||||||
export default function useTickets() {
|
export default function useTickets() {
|
||||||
const [tickets, setTickets] = useState<Ticket[]>([]);
|
const [tickets, setTickets] = useState<Ticket[]>([]);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
const [isError, setIsError] = useState(false);
|
const [isError, setIsError] = useState(false);
|
||||||
|
|
||||||
const getData = () => {
|
const getData = useCallback(() => {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
axios
|
axios
|
||||||
.get<Ticket[]>(`/api/tickets`)
|
.get<Ticket[]>(`/api/tickets`)
|
||||||
.then((response) => setTickets(response.data))
|
.then((response) => setTickets(response.data))
|
||||||
.finally(() => setIsLoading(false));
|
.finally(() => setIsLoading(false));
|
||||||
};
|
}, []);
|
||||||
|
|
||||||
useEffect(getData, []);
|
useEffect(getData, [getData]);
|
||||||
|
|
||||||
return { tickets, isLoading, isError, reload: getData };
|
return { tickets, isLoading, isError, reload: getData };
|
||||||
}
|
}
|
||||||
|
|||||||
29
src/hooks/useTicketsListener.tsx
Normal file
29
src/hooks/useTicketsListener.tsx
Normal 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;
|
||||||
Reference in New Issue
Block a user