{title}
{description}
@@ -34,53 +34,60 @@ export function AreaChartAgency({
config={chartConfig}
className="aspect-auto h-[250px] w-full"
>
-
-
-
-
-
-
-
-
- {
- const date = new Date(value);
- return date.toLocaleDateString("fr-FR", {
- year: "numeric",
- month: "short",
- });
- }}
- />
-
- {
- return new Date(value).toLocaleDateString("fr-FR", {
- month: "long",
- });
- }}
- indicator="dot"
- />
- }
- />
-
-
+ {data.length === 0 ? (
+
+ ) : (
+
+
+
+
+
+
+
+
+ {
+ const date = new Date(value);
+ return date.toLocaleDateString("fr-FR", {
+ year: "numeric",
+ month: "short",
+ });
+ }}
+ />
+
+ {
+ return new Date(value).toLocaleDateString("fr-FR", {
+ month: "long",
+ });
+ }}
+ indicator="dot"
+ />
+ }
+ />
+
+
+
+ )}
diff --git a/react-app/src/modules/organisation/components/chart/barChart.tsx b/react-app/src/modules/organisation/components/chart/barChart.tsx
index 84cc31e..07cc4c2 100644
--- a/react-app/src/modules/organisation/components/chart/barChart.tsx
+++ b/react-app/src/modules/organisation/components/chart/barChart.tsx
@@ -1,6 +1,5 @@
"use client";
-import { TrendingUp } from "lucide-react";
import {
Bar,
BarChart,
@@ -14,7 +13,6 @@ import {
Card,
CardContent,
CardDescription,
- CardFooter,
CardHeader,
CardTitle,
} from "@/components/ui/card.js";
@@ -26,12 +24,11 @@ import {
} from "@/components/ui/chart.js";
const chartData = [
- { month: "January", desktop: 186, mobile: 80 },
- { month: "February", desktop: 305, mobile: 200 },
- { month: "March", desktop: 237, mobile: 120 },
- { month: "April", desktop: 73, mobile: 190 },
- { month: "May", desktop: 209, mobile: 130 },
- { month: "June", desktop: 214, mobile: 140 },
+ { day: "Lundi", absence: 5 },
+ { day: "Mardi", absence: 2 },
+ { day: "Mercredi", absence: 1 },
+ { day: "Jeudi", absence: 2 },
+ { day: "Vendredi", absence: 3 },
];
const chartConfig = {
@@ -48,12 +45,15 @@ const chartConfig = {
},
} satisfies ChartConfig;
-export function BarChartAgency() {
+export function BarChartAgency({
+ title = "Area Chart - Interactive",
+ description = "Showing total visitors for the last 3 months",
+}) {
return (
- Bar Chart - Custom Label
- January - June 2024
+ {title}
+ {description}
@@ -75,26 +75,26 @@ export function BarChartAgency() {
tickFormatter={(value) => value.slice(0, 3)}
hide
/>
-
+
}
/>
-
-
- Trending up by 5.2% this month
-
-
- Showing total visitors for the last 6 months
-
-
);
}
diff --git a/react-app/src/modules/organisation/components/chart/radialChart.tsx b/react-app/src/modules/organisation/components/chart/radialChart.tsx
index d39604a..c4ec4d0 100644
--- a/react-app/src/modules/organisation/components/chart/radialChart.tsx
+++ b/react-app/src/modules/organisation/components/chart/radialChart.tsx
@@ -1,8 +1,6 @@
"use client";
-import { TrendingUp } from "lucide-react";
import { Label, PolarRadiusAxis, RadialBar, RadialBarChart } from "recharts";
-
import {
Card,
CardContent,
@@ -17,27 +15,31 @@ import {
ChartTooltip,
ChartTooltipContent,
} from "@/components/ui/chart.js";
-const chartData = [{ month: "january", desktop: 1260, mobile: 570 }];
+
+const chartData = [{ month: "january", present: 6, absent: 4 }];
const chartConfig = {
desktop: {
- label: "Desktop",
+ label: "Present",
color: "hsl(var(--chart-1))",
},
mobile: {
- label: "Mobile",
+ label: "Absent",
color: "hsl(var(--chart-2))",
},
} satisfies ChartConfig;
-export function RadialChartAgency() {
- const totalVisitors = chartData[0].desktop + chartData[0].mobile;
+export function RadialChartAgency({
+ title = "Area Chart - Interactive",
+ description = "Showing total visitors for the last 3 months",
+}) {
+ const totalVisitors = chartData[0].present + chartData[0].absent;
return (
- Radial Chart - Stacked
- January - June 2024
+ {title}
+ {description}
{totalVisitors.toLocaleString()}
- Visitors
+ Total employé
);
@@ -81,14 +83,14 @@ export function RadialChartAgency() {
/>
-
-
- Trending up by 5.2% this month
-
-
- Showing total visitors for the last 6 months
-
-
+
);
}
diff --git a/react-app/src/modules/organisation/components/agencyDepartment.tsx b/react-app/src/modules/organisation/components/service/agencyDepartment.tsx
similarity index 62%
rename from react-app/src/modules/organisation/components/agencyDepartment.tsx
rename to react-app/src/modules/organisation/components/service/agencyDepartment.tsx
index c76c0ec..577ce63 100644
--- a/react-app/src/modules/organisation/components/agencyDepartment.tsx
+++ b/react-app/src/modules/organisation/components/service/agencyDepartment.tsx
@@ -12,7 +12,7 @@ import { CaretLeftIcon, CaretRightIcon, PlusIcon } from "@radix-ui/react-icons";
import { Button } from "@/components/ui/button.js";
import { useNavigate } from "react-router-dom";
import { customFetcher } from "@/common/helper/fetchInstance.js";
-import { DepartmentList } from "@/models/organisation/DepartmentList.model.js";
+import { DepartmentList } from "@/models/organisation/department/DepartmentList.model.ts";
import { Label } from "@/components/ui/label.js";
import {
Select,
@@ -22,6 +22,8 @@ import {
SelectTrigger,
SelectValue,
} from "@/components/ui/select.js";
+import { Card } from "@/components/ui/card";
+import { GrGroup } from "react-icons/gr";
interface AgencyDetailsProps {
agency: AgencyModel;
@@ -69,54 +71,64 @@ export const AgencyDepartment: React.FC
= (agency) => {
navigate("service/create");
};
+ const handleClick = (id_service: number) => {
+ navigate(`service/details/${id_service}`);
+ };
return (
-
+
-
-
-
- Service
- Collaborateur
- Status
-
-
-
- {departmentList.length === 0 ? (
+
+
+
-
- Aucun département trouvé
-
+ Service
+ Chef de service
- ) : (
- departmentList.map((department: DepartmentList) => (
- handleClick(department.id)}
- >
-
- {department.label}
-
-
- {department.id_user_lead_service}
-
-
- {/* {getClassForStatus(department.status)} */}
- {department.minimum_users}
+
+
+ {departmentList.length === 0 ? (
+
+
+
+ Aucun service trouvé
+ Céez en un
+
- ))
- )}
-
-
+ ) : (
+ departmentList.map((department: DepartmentList) => (
+ handleClick(department.id)}
+ >
+
+
+
+
{department.label}
+
+ nombre totale d'équipe {department.team_count}
+
+
+
+
+ {department.lead_service_firstname}{" "}
+ {department.lead_service_lastname}
+
+
+ ))
+ )}
+
+
+
-
+
- {`${1 + pageSize * (pageNumber - 1)} - ${departmentList.length + pageSize * (pageNumber - 1)} sur ${totalData}`}
+ {`${departmentList.length === 0 ? 0 : 1 + pageSize * (pageNumber - 1)} - ${departmentList.length + pageSize * (pageNumber - 1)} sur ${totalData}`}
@@ -99,10 +107,64 @@ export const Agency = () => {
- Agence
+ Organisation
{agencyLoaded && agencyMainPage}
{agencyNotFound && noAgency}
);
};
+
+interface ConfirmDeleteItemProps {
+ agency: AgencyModel;
+ navigate: ReturnType
;
+}
+
+export function ConfirmDeleteItem({
+ agency,
+ navigate,
+}: ConfirmDeleteItemProps) {
+ const { refreshCurrentUser } = useCurrentUser();
+
+ const fetchAgency = async () => {
+ const response = await customFetcher(
+ `http://localhost:5000/api/agency/${agency.id}`,
+ {
+ method: "DELETE",
+ },
+ );
+
+ if (response.response.status === 200) {
+ navigate("/organisation", { replace: true });
+ }
+
+ refreshCurrentUser();
+ };
+
+ return (
+
+
+
+
+ Supprimer
+
+
+
+
+ Êtes vous vraiment sur?
+
+ Vous êtes sur le point de supprimer de manière definitive l'agence
+ sélectionnée, cette action est irréversible.
+
+
+
+ Annuler
+
+
+ Supprimer
+
+
+
+
+ );
+}
diff --git a/react-app/src/modules/organisation/pages/AgencyCreate.tsx b/react-app/src/modules/organisation/pages/AgencyCreate.tsx
index 9488abd..506d564 100644
--- a/react-app/src/modules/organisation/pages/AgencyCreate.tsx
+++ b/react-app/src/modules/organisation/pages/AgencyCreate.tsx
@@ -9,7 +9,7 @@ import { Button } from "@/components/ui/button.js";
import { useNavigate } from "react-router-dom";
import { Label } from "@/components/ui/label.js";
import React, { useState } from "react";
-import { CreateOrganisationFormDataModel } from "@/models/organisation/CreateOrganisationFormData.model.js";
+import { CreateOrganisationFormDataModel } from "@/models/organisation/CreateOrganisationFormData.model.ts";
import { customFetcher } from "@/common/helper/fetchInstance.js";
// Définir une interface pour les erreurs
diff --git a/react-app/src/modules/organisation/pages/AgencyDetails.tsx b/react-app/src/modules/organisation/pages/AgencyDetails.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/react-app/src/modules/organisation/pages/AgencyEdit.tsx b/react-app/src/modules/organisation/pages/AgencyEdit.tsx
deleted file mode 100644
index e69de29..0000000
diff --git a/react-app/src/modules/profile/Notifications.tsx b/react-app/src/modules/profile/Notifications.tsx
index 1917b25..d2fcf11 100644
--- a/react-app/src/modules/profile/Notifications.tsx
+++ b/react-app/src/modules/profile/Notifications.tsx
@@ -1,10 +1,10 @@
import { MainRoot } from "@/components/navigation/MainRoot.tsx";
-import { InProgress } from "@/components/navigation/InProgress.tsx";
+import { NotificationsCard } from "@/modules/profile/components/notificationsCard.tsx";
export const Notifications = () => {
return (
-
+
);
};
diff --git a/react-app/src/modules/profile/Profile.tsx b/react-app/src/modules/profile/Profile.tsx
index 882e3cd..2f4fcf4 100644
--- a/react-app/src/modules/profile/Profile.tsx
+++ b/react-app/src/modules/profile/Profile.tsx
@@ -25,7 +25,9 @@ export const Profile = () => {
{currentUser?.firstname} {currentUser?.lastname}
- {currentUser?.email}
+
+ {currentUser?.email}
+
diff --git a/react-app/src/modules/profile/components/notificationsCard.tsx b/react-app/src/modules/profile/components/notificationsCard.tsx
new file mode 100644
index 0000000..769b404
--- /dev/null
+++ b/react-app/src/modules/profile/components/notificationsCard.tsx
@@ -0,0 +1,188 @@
+import { useEffect, useState } from "react";
+import { customFetcher } from "@/common/helper/fetchInstance.ts";
+import { Card } from "@/components/ui/card.tsx";
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table.tsx";
+import { dateOptions } from "@/common/helper/DateHelper.ts";
+import { Label } from "@/components/ui/label.tsx";
+import {
+ Select,
+ SelectContent,
+ SelectGroup,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select.tsx";
+import { Button } from "@/components/ui/button.tsx";
+import { CaretLeftIcon, CaretRightIcon } from "@radix-ui/react-icons";
+import { GoDotFill } from "react-icons/go";
+
+export const NotificationsCard = () => {
+ const [pageSize, setPageSize] = useState(5);
+ const [pageNumber, setPageNumber] = useState(1);
+ const [totalData, setTotalData] = useState(0);
+ const [notifications, setNotifications] = useState([]);
+
+ const fetchNotifications = async (pageSize: number, pageNumber: number) => {
+ await customFetcher(
+ "http://localhost:5000/api/notification?" +
+ new URLSearchParams({
+ pageSize: pageSize.toString() || "10",
+ pageNumber: pageNumber.toString() || "1",
+ }),
+ ).then((response) => {
+ if (response.response.status !== 200) {
+ return;
+ }
+ setTotalData(response.data.data.totalData);
+ setNotifications(response.data.data.list);
+ });
+ };
+
+ useEffect(() => {
+ fetchNotifications(pageSize, pageNumber).then();
+ }, [pageSize, pageNumber]);
+
+ const handlePageSize = (pageSize: string) => {
+ setPageNumber(1);
+ setPageSize(+pageSize);
+ };
+
+ const handlePreviousPageNumber = () => {
+ setPageNumber(pageNumber - 1);
+ };
+
+ const handleNextPageNumber = () => {
+ setPageNumber(pageNumber + 1);
+ };
+
+ const handleTouchNotification = async (notificationId: number) => {
+ const notification: any = notifications.find(
+ (notify: any) => notify.id === notificationId,
+ );
+
+ if (notification?.touched) {
+ return;
+ }
+
+ await customFetcher(
+ `http://localhost:5000/api/notification/touch/${notificationId}`,
+ ).then(async (response) => {
+ if (response.response.status !== 200) {
+ return;
+ }
+ await fetchNotifications(pageSize, pageNumber);
+ });
+ };
+
+ return (
+ <>
+
+
+
+
+ Libellé
+ Date de création
+
+
+
+ {notifications?.length ? (
+ notifications?.map((notification: any) =>
+ notification?.touched ? (
+ handleTouchNotification(notification?.id)}
+ >
+
+ {notification?.description}
+
+
+ {new Date(notification?.created_at).toLocaleDateString(
+ "fr-FR",
+ dateOptions,
+ )}
+
+
+ ) : (
+ handleTouchNotification(notification?.id)}
+ >
+
+
+ {notification?.description}
+
+
+ {new Date(notification?.created_at).toLocaleDateString(
+ "fr-FR",
+ dateOptions,
+ )}
+
+
+ ),
+ )
+ ) : (
+
+
+ Aucune Notification
+
+
+ )}
+
+
+
+
+
+
+
+
+
+
+ {`${notifications.length === 0 ? 0 : 1 + pageSize * (pageNumber - 1)} - ${notifications.length + pageSize * (pageNumber - 1)} sur ${totalData}`}
+
+
+
+
+ = totalData}
+ aria-label="next notifications page"
+ >
+
+
+
+
+ >
+ );
+};
diff --git a/react-app/src/modules/user/components/demand/userDemands.tsx b/react-app/src/modules/user/components/demand/userDemands.tsx
index c46ab74..a0edbed 100644
--- a/react-app/src/modules/user/components/demand/userDemands.tsx
+++ b/react-app/src/modules/user/components/demand/userDemands.tsx
@@ -27,6 +27,7 @@ import { UserConfirmDemand } from "@/modules/user/components/demand/userConfirmD
import { DemandStatus } from "@/common/enum/DemandStatus.enum.js";
import { getDemandBadge } from "@/modules/demand/components/demandBadge.js";
import { DemandListLabel } from "@/modules/demand/components/demandListLabel.js";
+import { Card } from "@/components/ui/card";
interface UserDemandProps {
user: UserModel;
@@ -84,7 +85,7 @@ export const UserDemands: React.FC
= ({ user }) => {
return (
<>
-
+
@@ -169,7 +170,7 @@ export const UserDemands: React.FC = ({ user }) => {
)}
-
+
@@ -191,7 +192,7 @@ export const UserDemands: React.FC = ({ user }) => {
- {`${1 + pageSize * (pageNumber - 1)} - ${
+ {`${demandList.length === 0 ? 0 : 1 + pageSize * (pageNumber - 1)} - ${
demandList.length + pageSize * (pageNumber - 1)
} sur ${totalData}`}
diff --git a/react-app/src/modules/user/components/expense/userExpenseDetails.tsx b/react-app/src/modules/user/components/expense/userExpenseDetails.tsx
index 4e26b53..4b363fb 100644
--- a/react-app/src/modules/user/components/expense/userExpenseDetails.tsx
+++ b/react-app/src/modules/user/components/expense/userExpenseDetails.tsx
@@ -94,7 +94,7 @@ export const UserExpenseDetails = () => {
};
const handlePreviewFile = () => {
- window.open(expense.fileUrl, "_blank");
+ window.open(`${expense.fileUrl}`, "_blank");
};
return (
diff --git a/react-app/src/modules/user/components/expense/userExpenses.tsx b/react-app/src/modules/user/components/expense/userExpenses.tsx
index 5b27d35..ea34796 100644
--- a/react-app/src/modules/user/components/expense/userExpenses.tsx
+++ b/react-app/src/modules/user/components/expense/userExpenses.tsx
@@ -36,6 +36,7 @@ import { UserModel } from "@/models/user/User.model.js";
import { UserRejectExpense } from "@/modules/user/components/expense/userRejectExpense.js";
import { UserConfirmExpense } from "@/modules/user/components/expense/userConfirmExpense.js";
import { useNavigate } from "react-router-dom";
+import { Card } from "@/components/ui/card.js";
interface UserExpenseProps {
user: UserModel;
@@ -143,7 +144,7 @@ export const UserExpenses: React.FC
= ({ user }) => {
return (
<>
-
+
@@ -231,46 +232,46 @@ export const UserExpenses: React.FC = ({ user }) => {
)}
-
-
-
-
-
-
-
- {`${1 + pageSize * (pageNumber - 1)} - ${
- expenseList.length + pageSize * (pageNumber - 1)
- } sur ${totalData}`}
-
-
-
-
- = totalData}
- >
-
-
-
+
+
+
+
+
+
+
+
+ {`${expenseList.length === 0 ? 0 : 1 + pageSize * (pageNumber - 1)} - ${
+ expenseList.length + pageSize * (pageNumber - 1)
+ } sur ${totalData}`}
+
+
+
+
+ = totalData}
+ >
+
+
>
diff --git a/react-app/src/modules/user/components/userAddress.tsx b/react-app/src/modules/user/components/userAddress.tsx
index 059b8f9..d0d261b 100644
--- a/react-app/src/modules/user/components/userAddress.tsx
+++ b/react-app/src/modules/user/components/userAddress.tsx
@@ -154,7 +154,9 @@ export const UserAddress: React.FC
= ({
) : (
- Modifier
+
+ Modifier
+
)}
diff --git a/react-app/src/modules/user/components/userAvatar.tsx b/react-app/src/modules/user/components/userAvatar.tsx
index 93837d0..f09c405 100644
--- a/react-app/src/modules/user/components/userAvatar.tsx
+++ b/react-app/src/modules/user/components/userAvatar.tsx
@@ -75,7 +75,10 @@ export const UserAvatar: React.FC = ({
-
+
{user?.firstname?.charAt(0)}
{user?.lastname?.charAt(0)}
diff --git a/react-app/src/modules/user/components/userBankInfos.tsx b/react-app/src/modules/user/components/userBankInfos.tsx
index 60789ed..8e5ac52 100644
--- a/react-app/src/modules/user/components/userBankInfos.tsx
+++ b/react-app/src/modules/user/components/userBankInfos.tsx
@@ -111,7 +111,9 @@ export const UserBankInfos: React.FC = ({
) : (
- Modifier
+
+ Modifier
+
)}
diff --git a/react-app/src/modules/user/components/userInfos.tsx b/react-app/src/modules/user/components/userInfos.tsx
index 5f02bde..2f42a27 100644
--- a/react-app/src/modules/user/components/userInfos.tsx
+++ b/react-app/src/modules/user/components/userInfos.tsx
@@ -169,7 +169,9 @@ export const UserInfos: React.FC = ({
) : (
- Modifier
+
+ Modifier
+
)}
diff --git a/react-app/src/modules/user/pages/User.tsx b/react-app/src/modules/user/pages/User.tsx
index 9df0d66..ade84dd 100644
--- a/react-app/src/modules/user/pages/User.tsx
+++ b/react-app/src/modules/user/pages/User.tsx
@@ -76,7 +76,9 @@ export function User() {
)}
- {foundUser.email}
+
+ {foundUser.email}
+
@@ -109,7 +111,7 @@ export function User() {
- Utilisateurs
+ Collaborateurs
{userLoaded && userMainPage}
{userNotFound && noUser}
diff --git a/react-app/src/modules/user/pages/Users.tsx b/react-app/src/modules/user/pages/Users.tsx
index 1826518..8c9bccb 100644
--- a/react-app/src/modules/user/pages/Users.tsx
+++ b/react-app/src/modules/user/pages/Users.tsx
@@ -30,14 +30,15 @@ import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar.js";
import { Badge } from "@/components/ui/badge.tsx";
import { UserList } from "@/common/type/user/user-list.type.ts";
import { customFetcher } from "@/common/helper/fetchInstance.js";
+import { Card } from "@/components/ui/card";
export function Users() {
const [users, setUsers] = useState
([]);
const [usersLoaded, setUsersLoaded] = useState(false);
- const navigate = useNavigate();
const [pageSize, setPageSize] = useState(5);
const [pageNumber, setPageNumber] = useState(1);
const [totalData, setTotalData] = useState(0);
+ const navigate = useNavigate();
function handleClick(userId: number) {
navigate(`/user/${userId}`);
@@ -89,8 +90,8 @@ export function Users() {
};
const usersTable = (
-
-
+
+
@@ -110,7 +111,10 @@ export function Users() {
>
-
+
{user.firstname?.charAt(0)}
{user.lastname?.charAt(0)}
@@ -151,15 +155,15 @@ export function Users() {
)}
-
+
-
+
- {`${1 + pageSize * (pageNumber - 1)} - ${users.length + pageSize * (pageNumber - 1)} sur ${totalData}`}
+ {`${users.length === 0 ? 0 : 1 + pageSize * (pageNumber - 1)} - ${users.length + pageSize * (pageNumber - 1)} sur ${totalData}`}
@@ -186,6 +191,7 @@ export function Users() {
variant="ghost"
onClick={handleNextPageNumber}
disabled={pageSize * pageNumber >= totalData}
+ aria-label="next page"
>