ptechcore_ui 1.0.12 → 1.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +1914 -428
- package/dist/index.d.cts +74 -1
- package/dist/index.d.ts +74 -1
- package/dist/index.js +1903 -421
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -212,7 +212,7 @@ var FileInput = ({
|
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
// src/components/layout/ModernDoubleSidebarLayout.tsx
|
|
215
|
-
import
|
|
215
|
+
import React4, { useState as useState5, useEffect as useEffect4 } from "react";
|
|
216
216
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
217
217
|
import {
|
|
218
218
|
Settings,
|
|
@@ -223,7 +223,7 @@ import {
|
|
|
223
223
|
User,
|
|
224
224
|
LogOut,
|
|
225
225
|
Menu,
|
|
226
|
-
X,
|
|
226
|
+
X as X2,
|
|
227
227
|
Palette,
|
|
228
228
|
DollarSign,
|
|
229
229
|
HelpCircle,
|
|
@@ -617,21 +617,23 @@ var FetchApi = class {
|
|
|
617
617
|
const headers = {
|
|
618
618
|
"Content-Type": "application/json"
|
|
619
619
|
};
|
|
620
|
-
|
|
621
|
-
|
|
620
|
+
const local_token = localStorage.getItem("token");
|
|
621
|
+
if (local_token) {
|
|
622
|
+
headers["Authorization"] = `Token ${local_token}`;
|
|
622
623
|
}
|
|
623
624
|
const res = await fetch(url, {
|
|
624
625
|
method: "POST",
|
|
625
626
|
headers,
|
|
626
|
-
body: payload ? JSON.stringify(payload) : void 0
|
|
627
|
+
body: payload ? JSON.stringify({ ...payload, business_entity: localStorage.getItem("active_center_id") }) : void 0
|
|
627
628
|
});
|
|
628
629
|
if (!res.ok) throw new Error(await res.text());
|
|
629
630
|
return res.json();
|
|
630
631
|
}
|
|
631
632
|
static async get(url, token) {
|
|
632
633
|
const headers = {};
|
|
633
|
-
|
|
634
|
-
|
|
634
|
+
const local_token = localStorage.getItem("token");
|
|
635
|
+
if (local_token) {
|
|
636
|
+
headers["Authorization"] = `Token ${local_token}`;
|
|
635
637
|
}
|
|
636
638
|
const res = await fetch(url, {
|
|
637
639
|
method: "GET",
|
|
@@ -644,8 +646,9 @@ var FetchApi = class {
|
|
|
644
646
|
const headers = {
|
|
645
647
|
"Content-Type": "application/json"
|
|
646
648
|
};
|
|
647
|
-
|
|
648
|
-
|
|
649
|
+
const local_token = localStorage.getItem("token");
|
|
650
|
+
if (local_token) {
|
|
651
|
+
headers["Authorization"] = `Token ${local_token}`;
|
|
649
652
|
}
|
|
650
653
|
const res = await fetch(url, {
|
|
651
654
|
method: "PUT",
|
|
@@ -657,8 +660,9 @@ var FetchApi = class {
|
|
|
657
660
|
}
|
|
658
661
|
static async delete(url, token) {
|
|
659
662
|
const headers = {};
|
|
660
|
-
|
|
661
|
-
|
|
663
|
+
const local_token = localStorage.getItem("token");
|
|
664
|
+
if (local_token) {
|
|
665
|
+
headers["Authorization"] = `Token ${local_token}`;
|
|
662
666
|
}
|
|
663
667
|
const res = await fetch(url, {
|
|
664
668
|
method: "DELETE",
|
|
@@ -671,46 +675,17 @@ var FetchApi = class {
|
|
|
671
675
|
|
|
672
676
|
// src/services/AuthServices.ts
|
|
673
677
|
var API_BASE_URL = `${API_URL}/core/auth/`;
|
|
674
|
-
var FetchApi2 = class {
|
|
675
|
-
static async post(url, payload, token) {
|
|
676
|
-
const headers = {
|
|
677
|
-
"Content-Type": "application/json"
|
|
678
|
-
};
|
|
679
|
-
if (token) {
|
|
680
|
-
headers["Authorization"] = `Token ${token}`;
|
|
681
|
-
}
|
|
682
|
-
const res = await fetch(url, {
|
|
683
|
-
method: "POST",
|
|
684
|
-
headers,
|
|
685
|
-
body: payload ? JSON.stringify(payload) : void 0
|
|
686
|
-
});
|
|
687
|
-
if (!res.ok) throw new Error(await res.text());
|
|
688
|
-
return res.json();
|
|
689
|
-
}
|
|
690
|
-
static async get(url, token) {
|
|
691
|
-
const headers = {};
|
|
692
|
-
if (token) {
|
|
693
|
-
headers["Authorization"] = `Token ${token}`;
|
|
694
|
-
}
|
|
695
|
-
const res = await fetch(url, {
|
|
696
|
-
method: "GET",
|
|
697
|
-
headers
|
|
698
|
-
});
|
|
699
|
-
if (!res.ok) throw new Error(await res.text());
|
|
700
|
-
return res.json();
|
|
701
|
-
}
|
|
702
|
-
};
|
|
703
678
|
var AuthServices = {
|
|
704
|
-
sendOtp: (payload) =>
|
|
705
|
-
verifyOtp: (payload) =>
|
|
706
|
-
completeRegistration: (payload) =>
|
|
707
|
-
getInvitations: (token) =>
|
|
708
|
-
respondInvitationEmail: (payload) =>
|
|
709
|
-
change_password: (payload) =>
|
|
710
|
-
addUser: (payload) =>
|
|
711
|
-
login: (payload) =>
|
|
712
|
-
getUserInformations: (token) =>
|
|
713
|
-
logout: () =>
|
|
679
|
+
sendOtp: (payload) => FetchApi.post(`${API_BASE_URL}send-otp/`, payload),
|
|
680
|
+
verifyOtp: (payload) => FetchApi.post(`${API_BASE_URL}verify-otp/`, payload),
|
|
681
|
+
completeRegistration: (payload) => FetchApi.post(`${API_BASE_URL}complete-registration/`, payload),
|
|
682
|
+
getInvitations: (token) => FetchApi.get(`${API_BASE_URL}invitations/?token=${token}`),
|
|
683
|
+
respondInvitationEmail: (payload) => FetchApi.post(`${API_BASE_URL}respond-invitation-email/`, payload),
|
|
684
|
+
change_password: (payload) => FetchApi.post(`${API_BASE_URL}change-password/`, payload),
|
|
685
|
+
addUser: (payload) => FetchApi.post(`${API_BASE_URL}add-user/`, payload),
|
|
686
|
+
login: (payload) => FetchApi.post(`${API_BASE_URL}login/`, payload),
|
|
687
|
+
getUserInformations: (token) => FetchApi.get(`${API_BASE_URL}user-informations/`, token),
|
|
688
|
+
logout: () => FetchApi.post(`${API_BASE_URL}logout/`)
|
|
714
689
|
};
|
|
715
690
|
|
|
716
691
|
// src/contexts/SessionContext.tsx
|
|
@@ -773,44 +748,613 @@ var SessionProvider = ({ children }) => {
|
|
|
773
748
|
}, children });
|
|
774
749
|
};
|
|
775
750
|
|
|
751
|
+
// src/services/UserServices.ts
|
|
752
|
+
var API_BASE_URL2 = `${API_URL}/core/auth/`;
|
|
753
|
+
var USERS_API_URL = `${API_URL}/core/users/`;
|
|
754
|
+
var UserServices = {
|
|
755
|
+
// Créer un nouvel utilisateur
|
|
756
|
+
addUser: (data, token) => FetchApi.post(`${API_BASE_URL2}add-user/`, data, token),
|
|
757
|
+
// Obtenir tous les utilisateurs
|
|
758
|
+
getUsers: (token) => FetchApi.get(`${USERS_API_URL}`, token),
|
|
759
|
+
// Obtenir toutes les notifications de l'utilisateur
|
|
760
|
+
getUsersNotifications: () => FetchApi.get(`${USERS_API_URL}notifications/`),
|
|
761
|
+
// Marquer une notification comme lue
|
|
762
|
+
markNotificationAsRead: (notificationId) => FetchApi.post(`${USERS_API_URL}notifications/${notificationId}/mark-read/`, {}),
|
|
763
|
+
// Obtenir un utilisateur par ID
|
|
764
|
+
getUser: (id, token) => FetchApi.get(`${USERS_API_URL}${id}/`, token),
|
|
765
|
+
// Mettre à jour un utilisateur
|
|
766
|
+
updateUser: (id, data, token) => FetchApi.put(`${USERS_API_URL}${id}/`, data, token),
|
|
767
|
+
// Supprimer un utilisateur
|
|
768
|
+
deleteUser: (id, token) => FetchApi.delete(`${USERS_API_URL}${id}/`, token),
|
|
769
|
+
// Obtenir les utilisateurs d'une entité
|
|
770
|
+
getEntityUsers: (entityId, token) => FetchApi.get(`${API_URL}/core/entities/${entityId}/users/`, token),
|
|
771
|
+
// Obtenir les utilisateurs d'une entité
|
|
772
|
+
getuserEntitiesAccess: (id, token) => FetchApi.get(`${API_URL}/core/entities/`, token),
|
|
773
|
+
// !!! ce n'est pas la bonne url
|
|
774
|
+
// Ajouter un utilisateur à une entité
|
|
775
|
+
addUserToEntity: (entityId, userId, token) => FetchApi.post(`${API_URL}/core/entities/${entityId}/users/`, { user_id: userId }, token)
|
|
776
|
+
};
|
|
777
|
+
|
|
778
|
+
// src/contexts/ToastContext.tsx
|
|
779
|
+
import { createContext as createContext3, useContext as useContext3, useState as useState3, useCallback } from "react";
|
|
780
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
781
|
+
var ToastContext = createContext3(void 0);
|
|
782
|
+
var useToast = () => {
|
|
783
|
+
const context = useContext3(ToastContext);
|
|
784
|
+
if (!context) {
|
|
785
|
+
throw new Error("useToast must be used within a ToastProvider");
|
|
786
|
+
}
|
|
787
|
+
return context;
|
|
788
|
+
};
|
|
789
|
+
var ToastProvider = ({ children }) => {
|
|
790
|
+
const [toasts, setToasts] = useState3([]);
|
|
791
|
+
const generateId = () => {
|
|
792
|
+
return Date.now().toString(36) + Math.random().toString(36).substr(2);
|
|
793
|
+
};
|
|
794
|
+
const addToast = useCallback((toast) => {
|
|
795
|
+
const id = generateId();
|
|
796
|
+
const newToast = {
|
|
797
|
+
id,
|
|
798
|
+
duration: 5e3,
|
|
799
|
+
...toast
|
|
800
|
+
};
|
|
801
|
+
setToasts((prev) => [...prev, newToast]);
|
|
802
|
+
if (newToast.duration && newToast.duration > 0) {
|
|
803
|
+
setTimeout(() => {
|
|
804
|
+
removeToast(id);
|
|
805
|
+
}, newToast.duration);
|
|
806
|
+
}
|
|
807
|
+
}, []);
|
|
808
|
+
const removeToast = useCallback((id) => {
|
|
809
|
+
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
|
810
|
+
}, []);
|
|
811
|
+
const success = useCallback((message, duration) => {
|
|
812
|
+
addToast({ message, type: "success", duration });
|
|
813
|
+
}, [addToast]);
|
|
814
|
+
const error = useCallback((message, duration) => {
|
|
815
|
+
addToast({ message, type: "error", duration });
|
|
816
|
+
}, [addToast]);
|
|
817
|
+
const warning = useCallback((message, duration) => {
|
|
818
|
+
addToast({ message, type: "warning", duration });
|
|
819
|
+
}, [addToast]);
|
|
820
|
+
const info = useCallback((message, duration) => {
|
|
821
|
+
addToast({ message, type: "info", duration });
|
|
822
|
+
}, [addToast]);
|
|
823
|
+
const value = {
|
|
824
|
+
toasts,
|
|
825
|
+
addToast,
|
|
826
|
+
removeToast,
|
|
827
|
+
success,
|
|
828
|
+
error,
|
|
829
|
+
warning,
|
|
830
|
+
info
|
|
831
|
+
};
|
|
832
|
+
return /* @__PURE__ */ jsx6(ToastContext.Provider, { value, children });
|
|
833
|
+
};
|
|
834
|
+
|
|
835
|
+
// src/pages/ApprovalPreviewAnswer.tsx
|
|
836
|
+
import { useState as useState4, useEffect as useEffect3 } from "react";
|
|
837
|
+
|
|
838
|
+
// src/components/common/Cards.tsx
|
|
839
|
+
import { jsx as jsx7, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
840
|
+
var RewiseBasicCard = ({ title, children }) => /* @__PURE__ */ jsxs3("div", { className: "bg-white rounded-lg ", children: [
|
|
841
|
+
/* @__PURE__ */ jsx7("div", { className: "px-6 py-2 border-b border-gray-200", children: /* @__PURE__ */ jsx7("div", { className: "flex items-center space-x-4", children: title }) }),
|
|
842
|
+
/* @__PURE__ */ jsx7("div", { className: "p-3", children })
|
|
843
|
+
] });
|
|
844
|
+
|
|
845
|
+
// src/pages/ApprovalPreviewAnswer.tsx
|
|
846
|
+
import { X, Loader, Eye, FileText, Check, XCircle, Edit, CheckCircle, Clock, AlertCircle, User as UserIcon, Send } from "lucide-react";
|
|
847
|
+
import { useParams, useSearchParams } from "react-router-dom";
|
|
848
|
+
|
|
849
|
+
// src/services/ApprovalServices.ts
|
|
850
|
+
var APPROVAL_API_URL = `${API_URL}/approvals/cases/`;
|
|
851
|
+
var ApprovalServices = {
|
|
852
|
+
/**
|
|
853
|
+
* Créer un nouveau cas d'approbation avec vérifications et validations
|
|
854
|
+
*/
|
|
855
|
+
create: (data, token) => FetchApi.post(APPROVAL_API_URL, data, token),
|
|
856
|
+
/**
|
|
857
|
+
* Obtenir tous les cas d'approbation
|
|
858
|
+
*/
|
|
859
|
+
list: (token) => FetchApi.get(APPROVAL_API_URL, token),
|
|
860
|
+
/**
|
|
861
|
+
* Obtenir les détails d'un cas d'approbation par process et object_id
|
|
862
|
+
*/
|
|
863
|
+
getDetails: (process, object_id, token) => FetchApi.get(`${APPROVAL_API_URL}details/?process=${process}&object_id=${object_id}`, token),
|
|
864
|
+
getAnswerDetails: (link_token) => FetchApi.get(`${APPROVAL_API_URL}answers/?link_token=${link_token}`),
|
|
865
|
+
/**
|
|
866
|
+
* Obtenir l'historique des versions d'un cas d'approbation
|
|
867
|
+
*/
|
|
868
|
+
getHistory: (process, object_id, token) => FetchApi.get(`${APPROVAL_API_URL}history/?process=${process}&object_id=${object_id}`, token),
|
|
869
|
+
/**
|
|
870
|
+
* Mettre à jour un cas d'approbation
|
|
871
|
+
*/
|
|
872
|
+
update: (id, data, token) => FetchApi.put(`${APPROVAL_API_URL}${id}/`, data, token),
|
|
873
|
+
/**
|
|
874
|
+
* Démarrer le processus d'approbation d'un cas
|
|
875
|
+
*/
|
|
876
|
+
start: (id, token) => FetchApi.post(`${APPROVAL_API_URL}${id}/start/`, {}, token),
|
|
877
|
+
/**
|
|
878
|
+
* Annuler un cas d'approbation
|
|
879
|
+
*/
|
|
880
|
+
cancel: (id, token) => FetchApi.post(`${APPROVAL_API_URL}${id}/cancel/`, {}, token),
|
|
881
|
+
/**
|
|
882
|
+
* Redémarrer un cas d'approbation (nouvelle version)
|
|
883
|
+
*/
|
|
884
|
+
restart: (id, token) => FetchApi.post(`${APPROVAL_API_URL}${id}/restart/`, {}, token),
|
|
885
|
+
/**
|
|
886
|
+
* Supprimer un cas d'approbation
|
|
887
|
+
*/
|
|
888
|
+
delete: (id, token) => FetchApi.delete(`${APPROVAL_API_URL}${id}/`, token),
|
|
889
|
+
/**
|
|
890
|
+
* Approuver une réponse d'approbation
|
|
891
|
+
*/
|
|
892
|
+
approve: (answerId, note) => FetchApi.post(`${API_URL}/approvals/answers/${answerId}/approve/`, { note: note || "" }),
|
|
893
|
+
/**
|
|
894
|
+
* Rejeter une réponse d'approbation
|
|
895
|
+
*/
|
|
896
|
+
reject: (answerId, note) => FetchApi.post(`${API_URL}/approvals/answers/${answerId}/reject/`, { note: note || "" }),
|
|
897
|
+
/**
|
|
898
|
+
* Suggérer une correction pour une réponse d'approbation
|
|
899
|
+
*/
|
|
900
|
+
suggestChange: (answerId, note) => FetchApi.post(`${API_URL}/approvals/answers/${answerId}/suggest_change/`, { note: note || "" })
|
|
901
|
+
};
|
|
902
|
+
|
|
903
|
+
// src/pages/ApprovalPreviewAnswer.tsx
|
|
904
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
905
|
+
var ApprovalAnswerModal = ({ answer_id, link_token, object_detail }) => {
|
|
906
|
+
const [answerId, setAnswerId] = useState4(answer_id);
|
|
907
|
+
const [caseData, setCaseData] = useState4(object_detail);
|
|
908
|
+
const [loading, setLoading] = useState4(false);
|
|
909
|
+
const { error: showError, success: showSuccess } = useToast();
|
|
910
|
+
const loadData = async () => {
|
|
911
|
+
if (!link_token) {
|
|
912
|
+
showError("Token de lien invalide");
|
|
913
|
+
return;
|
|
914
|
+
}
|
|
915
|
+
setLoading(true);
|
|
916
|
+
try {
|
|
917
|
+
await loadCase();
|
|
918
|
+
} catch (error) {
|
|
919
|
+
console.error("Erreur lors du chargement:", error);
|
|
920
|
+
} finally {
|
|
921
|
+
setLoading(false);
|
|
922
|
+
}
|
|
923
|
+
};
|
|
924
|
+
const loadCase = async () => {
|
|
925
|
+
if (!link_token) return;
|
|
926
|
+
try {
|
|
927
|
+
const response = await ApprovalServices.getAnswerDetails(link_token);
|
|
928
|
+
if (response.success && response.data) {
|
|
929
|
+
setAnswerId(response.data.answer_id);
|
|
930
|
+
setCaseData(response.data.case);
|
|
931
|
+
}
|
|
932
|
+
} catch (error) {
|
|
933
|
+
showError("Erreur lors du chargement du cas d'approbation");
|
|
934
|
+
console.error("Erreur:", error);
|
|
935
|
+
}
|
|
936
|
+
};
|
|
937
|
+
if (loading) {
|
|
938
|
+
return /* @__PURE__ */ jsx8(RewiseBasicCard, { title: "Approbation - Pr\xE9visualisation", children: /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx8(Loader, { className: "w-8 h-8 animate-spin text-[#6A8A82]" }) }) });
|
|
939
|
+
} else {
|
|
940
|
+
return /* @__PURE__ */ jsx8(ApprovalPreviewAnswer, { loadCase: loadData, answerId, caseData });
|
|
941
|
+
}
|
|
942
|
+
};
|
|
943
|
+
var ApprovalAnswerPage = () => {
|
|
944
|
+
const [searchParams] = useSearchParams();
|
|
945
|
+
const { link_token } = useParams();
|
|
946
|
+
const [answerId, setAnswerId] = useState4(null);
|
|
947
|
+
const { error: showError, success: showSuccess } = useToast();
|
|
948
|
+
const [loading, setLoading] = useState4(true);
|
|
949
|
+
const [caseData, setCaseData] = useState4(null);
|
|
950
|
+
useEffect3(() => {
|
|
951
|
+
loadData();
|
|
952
|
+
}, [link_token]);
|
|
953
|
+
const loadData = async () => {
|
|
954
|
+
if (!link_token) {
|
|
955
|
+
showError("Token de lien invalide");
|
|
956
|
+
return;
|
|
957
|
+
}
|
|
958
|
+
setLoading(true);
|
|
959
|
+
try {
|
|
960
|
+
await loadCase();
|
|
961
|
+
} catch (error) {
|
|
962
|
+
console.error("Erreur lors du chargement:", error);
|
|
963
|
+
} finally {
|
|
964
|
+
setLoading(false);
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
const loadCase = async () => {
|
|
968
|
+
if (!link_token) return;
|
|
969
|
+
try {
|
|
970
|
+
const response = await ApprovalServices.getAnswerDetails(link_token);
|
|
971
|
+
if (response.success && response.data) {
|
|
972
|
+
setAnswerId(response.data.answer_id);
|
|
973
|
+
setCaseData(response.data.case);
|
|
974
|
+
}
|
|
975
|
+
} catch (error) {
|
|
976
|
+
showError("Erreur lors du chargement du cas d'approbation");
|
|
977
|
+
console.error("Erreur:", error);
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
const pageTitle = caseData?.title || "Approbation - Pr\xE9visualisation";
|
|
981
|
+
if (loading) {
|
|
982
|
+
return /* @__PURE__ */ jsx8(RewiseBasicCard, { title: "Approbation - Pr\xE9visualisation", children: /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx8(Loader, { className: "w-8 h-8 animate-spin text-[#6A8A82]" }) }) });
|
|
983
|
+
} else {
|
|
984
|
+
return /* @__PURE__ */ jsx8("div", { className: "min-h-screen w-full bg-gray-100 mx-auto p-6", children: /* @__PURE__ */ jsx8("div", { className: "min-h-screen max-w-7xl mx-auto p-6", children: /* @__PURE__ */ jsx8(
|
|
985
|
+
RewiseBasicCard,
|
|
986
|
+
{
|
|
987
|
+
title: /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-between w-full", children: /* @__PURE__ */ jsx8("h2", { className: "text-xl font-semibold text-[#191919]", children: pageTitle }) }),
|
|
988
|
+
children: /* @__PURE__ */ jsx8(ApprovalPreviewAnswer, { loadCase: loadData, answerId, caseData })
|
|
989
|
+
}
|
|
990
|
+
) }) });
|
|
991
|
+
}
|
|
992
|
+
};
|
|
993
|
+
var ApprovalPreviewAnswer = ({ loadCase, answerId, caseData }) => {
|
|
994
|
+
const { error: showError, success: showSuccess } = useToast();
|
|
995
|
+
const [submitting, setSubmitting] = useState4(false);
|
|
996
|
+
const [showNoteModal, setShowNoteModal] = useState4(false);
|
|
997
|
+
const [currentAction, setCurrentAction] = useState4(null);
|
|
998
|
+
const [note, setNote] = useState4("");
|
|
999
|
+
const openNoteModal = (action) => {
|
|
1000
|
+
setCurrentAction(action);
|
|
1001
|
+
setNote("");
|
|
1002
|
+
setShowNoteModal(true);
|
|
1003
|
+
};
|
|
1004
|
+
const closeNoteModal = () => {
|
|
1005
|
+
setShowNoteModal(false);
|
|
1006
|
+
setCurrentAction(null);
|
|
1007
|
+
setNote("");
|
|
1008
|
+
};
|
|
1009
|
+
const executeAction = async () => {
|
|
1010
|
+
if (!answerId) {
|
|
1011
|
+
showError("ID de r\xE9ponse invalide");
|
|
1012
|
+
return;
|
|
1013
|
+
}
|
|
1014
|
+
setSubmitting(true);
|
|
1015
|
+
try {
|
|
1016
|
+
let response;
|
|
1017
|
+
let successMessage = "";
|
|
1018
|
+
switch (currentAction) {
|
|
1019
|
+
case "approve":
|
|
1020
|
+
response = await ApprovalServices.approve(answerId, note);
|
|
1021
|
+
successMessage = "R\xE9ponse approuv\xE9e avec succ\xE8s";
|
|
1022
|
+
break;
|
|
1023
|
+
case "reject":
|
|
1024
|
+
response = await ApprovalServices.reject(answerId, note);
|
|
1025
|
+
successMessage = "R\xE9ponse refus\xE9e avec succ\xE8s";
|
|
1026
|
+
break;
|
|
1027
|
+
case "suggest":
|
|
1028
|
+
response = await ApprovalServices.suggestChange(answerId, note);
|
|
1029
|
+
successMessage = "Correction sugg\xE9r\xE9e avec succ\xE8s";
|
|
1030
|
+
break;
|
|
1031
|
+
default:
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
if (response.success) {
|
|
1035
|
+
showSuccess(successMessage);
|
|
1036
|
+
closeNoteModal();
|
|
1037
|
+
await loadCase();
|
|
1038
|
+
} else {
|
|
1039
|
+
showError(response.message || "Erreur lors de l'op\xE9ration");
|
|
1040
|
+
}
|
|
1041
|
+
} catch (error) {
|
|
1042
|
+
showError("Erreur lors de l'op\xE9ration");
|
|
1043
|
+
console.error("Erreur:", error);
|
|
1044
|
+
} finally {
|
|
1045
|
+
setSubmitting(false);
|
|
1046
|
+
}
|
|
1047
|
+
};
|
|
1048
|
+
const refuse = () => openNoteModal("reject");
|
|
1049
|
+
const suggestCorrection = () => openNoteModal("suggest");
|
|
1050
|
+
const accept = () => openNoteModal("approve");
|
|
1051
|
+
const getAnswerStatusDisplay = (answer) => {
|
|
1052
|
+
switch (answer) {
|
|
1053
|
+
case "approved":
|
|
1054
|
+
return {
|
|
1055
|
+
icon: /* @__PURE__ */ jsx8(CheckCircle, { className: "w-5 h-5 text-green-600" }),
|
|
1056
|
+
label: "Approuv\xE9",
|
|
1057
|
+
bgColor: "bg-green-50",
|
|
1058
|
+
textColor: "text-green-700",
|
|
1059
|
+
borderColor: "border-green-200"
|
|
1060
|
+
};
|
|
1061
|
+
case "refused":
|
|
1062
|
+
return {
|
|
1063
|
+
icon: /* @__PURE__ */ jsx8(XCircle, { className: "w-5 h-5 text-red-600" }),
|
|
1064
|
+
label: "Refus\xE9",
|
|
1065
|
+
bgColor: "bg-red-50",
|
|
1066
|
+
textColor: "text-red-700",
|
|
1067
|
+
borderColor: "border-red-200"
|
|
1068
|
+
};
|
|
1069
|
+
case "suggest-correction":
|
|
1070
|
+
return {
|
|
1071
|
+
icon: /* @__PURE__ */ jsx8(Edit, { className: "w-5 h-5 text-orange-600" }),
|
|
1072
|
+
label: "Correction sugg\xE9r\xE9e",
|
|
1073
|
+
bgColor: "bg-orange-50",
|
|
1074
|
+
textColor: "text-orange-700",
|
|
1075
|
+
borderColor: "border-orange-200"
|
|
1076
|
+
};
|
|
1077
|
+
case "waiting":
|
|
1078
|
+
default:
|
|
1079
|
+
return {
|
|
1080
|
+
icon: /* @__PURE__ */ jsx8(Clock, { className: "w-5 h-5 text-gray-500" }),
|
|
1081
|
+
label: "En attente",
|
|
1082
|
+
bgColor: "bg-gray-50",
|
|
1083
|
+
textColor: "text-gray-700",
|
|
1084
|
+
borderColor: "border-gray-200"
|
|
1085
|
+
};
|
|
1086
|
+
}
|
|
1087
|
+
};
|
|
1088
|
+
const renderApprovalPerson = (approval, index, type, isLast) => {
|
|
1089
|
+
const statusDisplay = getAnswerStatusDisplay(approval.answer);
|
|
1090
|
+
const userName = approval.user_detail ? `${approval.user_detail.first_name} ${approval.user_detail.last_name}`.trim() : approval.full_name || "Utilisateur inconnu";
|
|
1091
|
+
const userEmail = approval.user_detail?.email || approval.email || "";
|
|
1092
|
+
return /* @__PURE__ */ jsxs4("div", { className: "relative flex gap-3", children: [
|
|
1093
|
+
!isLast && /* @__PURE__ */ jsx8("div", { className: "absolute left-[19px] top-[40px] bottom-[-16px] w-0.5 bg-gray-300" }),
|
|
1094
|
+
/* @__PURE__ */ jsx8("div", { className: "relative flex-shrink-0", children: /* @__PURE__ */ jsx8(
|
|
1095
|
+
"div",
|
|
1096
|
+
{
|
|
1097
|
+
className: `w-10 h-10 rounded-full ${statusDisplay.bgColor} border-2 ${statusDisplay.borderColor} flex items-center justify-center`,
|
|
1098
|
+
children: /* @__PURE__ */ jsx8(UserIcon, { className: `w-5 h-5 ${statusDisplay.textColor}` })
|
|
1099
|
+
}
|
|
1100
|
+
) }),
|
|
1101
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 min-w-0 pb-6", children: /* @__PURE__ */ jsxs4("div", { className: `p-3 rounded-lg border ${statusDisplay.borderColor} ${statusDisplay.bgColor}`, children: [
|
|
1102
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-start justify-between gap-2 mb-1", children: [
|
|
1103
|
+
/* @__PURE__ */ jsx8("span", { className: "font-medium text-sm text-[#191919] truncate", children: userName }),
|
|
1104
|
+
/* @__PURE__ */ jsxs4("span", { className: `text-xs font-medium ${statusDisplay.textColor} whitespace-nowrap`, children: [
|
|
1105
|
+
"Rang ",
|
|
1106
|
+
approval.rank
|
|
1107
|
+
] })
|
|
1108
|
+
] }),
|
|
1109
|
+
userEmail && /* @__PURE__ */ jsx8("p", { className: "text-xs text-gray-600 truncate mb-2", children: userEmail }),
|
|
1110
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 mb-1", children: [
|
|
1111
|
+
/* @__PURE__ */ jsx8("div", { className: "", children: /* @__PURE__ */ jsxs4("div", { className: `w-5 h-5 rounded-full bg-white border ${statusDisplay.borderColor} flex items-center justify-center`, children: [
|
|
1112
|
+
approval.answer === "approved" && /* @__PURE__ */ jsx8(CheckCircle, { className: "w-3 h-3 text-green-600" }),
|
|
1113
|
+
approval.answer === "refused" && /* @__PURE__ */ jsx8(XCircle, { className: "w-3 h-3 text-red-600" }),
|
|
1114
|
+
approval.answer === "suggest-correction" && /* @__PURE__ */ jsx8(Edit, { className: "w-3 h-3 text-orange-600" }),
|
|
1115
|
+
approval.answer === "waiting" && /* @__PURE__ */ jsx8(Clock, { className: "w-3 h-3 text-gray-500" })
|
|
1116
|
+
] }) }),
|
|
1117
|
+
/* @__PURE__ */ jsx8("span", { className: `text-xs font-medium ${statusDisplay.textColor}`, children: statusDisplay.label })
|
|
1118
|
+
] }),
|
|
1119
|
+
approval.answered_at && /* @__PURE__ */ jsx8(Fragment, { children: /* @__PURE__ */ jsxs4("p", { className: "text-xs text-gray-500", children: [
|
|
1120
|
+
"R\xE9pondu le ",
|
|
1121
|
+
new Date(approval.answered_at).toLocaleDateString("fr-FR", {
|
|
1122
|
+
day: "2-digit",
|
|
1123
|
+
month: "short",
|
|
1124
|
+
year: "numeric"
|
|
1125
|
+
})
|
|
1126
|
+
] }) }),
|
|
1127
|
+
approval.note && /* @__PURE__ */ jsx8("div", { className: "mt-2 pt-2 border-t border-gray-300", children: /* @__PURE__ */ jsxs4("p", { className: "text-xs text-gray-600 italic", children: [
|
|
1128
|
+
'"',
|
|
1129
|
+
approval.note,
|
|
1130
|
+
'"'
|
|
1131
|
+
] }) })
|
|
1132
|
+
] }) })
|
|
1133
|
+
] }, approval.id);
|
|
1134
|
+
};
|
|
1135
|
+
return /* @__PURE__ */ jsxs4("div", { className: " rounded-lg bg-white shadow-sm", children: [
|
|
1136
|
+
/* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-1 lg:grid-cols-12 gap-6 p-2", children: [
|
|
1137
|
+
/* @__PURE__ */ jsx8("div", { className: "lg:col-span-4 space-y-6 ", children: /* @__PURE__ */ jsxs4("div", { className: "p-4 border bg-gray-50 border-gray-200 rounded-lg", children: [
|
|
1138
|
+
caseData?.requester && /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
|
|
1139
|
+
/* @__PURE__ */ jsxs4("h3", { className: "text-lg font-semibold text-[#191919] flex items-center gap-2", children: [
|
|
1140
|
+
/* @__PURE__ */ jsx8(Send, { className: "w-5 h-5 text-[#6A8A82]" }),
|
|
1141
|
+
"Demandeur"
|
|
1142
|
+
] }),
|
|
1143
|
+
/* @__PURE__ */ jsxs4("div", { className: "relative flex gap-3", children: [
|
|
1144
|
+
(caseData.verifications && caseData.verifications.length > 0 || caseData.validations && caseData.validations.length > 0) && /* @__PURE__ */ jsx8("div", { className: "absolute left-[19px] top-[40px] bottom-[-24px] w-0.5 bg-gray-300" }),
|
|
1145
|
+
/* @__PURE__ */ jsx8("div", { className: "relative flex-shrink-0", children: /* @__PURE__ */ jsx8("div", { className: "w-10 h-10 rounded-full bg-blue-50 border-2 border-blue-200 flex items-center justify-center", children: /* @__PURE__ */ jsx8(UserIcon, { className: "w-5 h-5 text-blue-700" }) }) }),
|
|
1146
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 min-w-0 pb-6", children: /* @__PURE__ */ jsxs4("div", { className: "p-3 rounded-lg border border-blue-200 bg-blue-50", children: [
|
|
1147
|
+
/* @__PURE__ */ jsx8("span", { className: "font-medium text-sm text-[#191919] block mb-1", children: `${caseData.requester.first_name} ${caseData.requester.last_name}`.trim() }),
|
|
1148
|
+
caseData.requester.email && /* @__PURE__ */ jsx8("p", { className: "text-xs text-gray-600 truncate", children: caseData.requester.email }),
|
|
1149
|
+
/* @__PURE__ */ jsxs4("div", { className: "mt-2 mb-1 flex items-center gap-2", children: [
|
|
1150
|
+
/* @__PURE__ */ jsx8("span", { className: "w-5 h-5 rounded-full bg-white border border-blue-200 flex items-center justify-center", children: /* @__PURE__ */ jsx8(Send, { className: "w-3 h-3 text-blue-600" }) }),
|
|
1151
|
+
/* @__PURE__ */ jsxs4("span", { className: "text-xs text-blue-700 font-medium", children: [
|
|
1152
|
+
"Demande cr\xE9\xE9e le ",
|
|
1153
|
+
new Date(caseData.created_at || "").toLocaleDateString("fr-FR", {
|
|
1154
|
+
day: "2-digit",
|
|
1155
|
+
month: "short",
|
|
1156
|
+
year: "numeric"
|
|
1157
|
+
})
|
|
1158
|
+
] })
|
|
1159
|
+
] })
|
|
1160
|
+
] }) })
|
|
1161
|
+
] })
|
|
1162
|
+
] }),
|
|
1163
|
+
caseData?.verifications && caseData.verifications.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
|
|
1164
|
+
/* @__PURE__ */ jsxs4("h3", { className: "text-lg font-semibold text-[#191919] flex items-center gap-2", children: [
|
|
1165
|
+
/* @__PURE__ */ jsx8(FileText, { className: "w-5 h-5 text-[#6A8A82]" }),
|
|
1166
|
+
"V\xE9rifications (",
|
|
1167
|
+
caseData.verifications.length,
|
|
1168
|
+
")"
|
|
1169
|
+
] }),
|
|
1170
|
+
/* @__PURE__ */ jsx8("div", { children: caseData.verifications.sort((a, b) => a.rank - b.rank).map(
|
|
1171
|
+
(verification, index, array) => renderApprovalPerson(
|
|
1172
|
+
verification,
|
|
1173
|
+
index,
|
|
1174
|
+
"verification",
|
|
1175
|
+
index === array.length - 1 && (!caseData.validations || caseData.validations.length === 0)
|
|
1176
|
+
)
|
|
1177
|
+
) })
|
|
1178
|
+
] }),
|
|
1179
|
+
caseData?.validations && caseData.validations.length > 0 && /* @__PURE__ */ jsxs4("div", { className: "space-y-3", children: [
|
|
1180
|
+
/* @__PURE__ */ jsxs4("h3", { className: "text-lg font-semibold text-[#191919] flex items-center gap-2", children: [
|
|
1181
|
+
/* @__PURE__ */ jsx8(CheckCircle, { className: "w-5 h-5 text-[#6A8A82]" }),
|
|
1182
|
+
"Validations (",
|
|
1183
|
+
caseData.validations.length,
|
|
1184
|
+
")"
|
|
1185
|
+
] }),
|
|
1186
|
+
/* @__PURE__ */ jsx8("div", { children: caseData.validations.sort((a, b) => a.rank - b.rank).map(
|
|
1187
|
+
(validation, index, array) => renderApprovalPerson(validation, index, "validation", index === array.length - 1)
|
|
1188
|
+
) })
|
|
1189
|
+
] }),
|
|
1190
|
+
(!caseData?.verifications || caseData.verifications.length === 0) && (!caseData?.validations || caseData.validations.length === 0) && /* @__PURE__ */ jsxs4("div", { className: "text-center py-8 text-gray-500", children: [
|
|
1191
|
+
/* @__PURE__ */ jsx8(AlertCircle, { className: "w-12 h-12 mx-auto mb-3 text-gray-400" }),
|
|
1192
|
+
/* @__PURE__ */ jsx8("p", { className: "text-sm", children: "Aucune approbation requise" })
|
|
1193
|
+
] })
|
|
1194
|
+
] }) }),
|
|
1195
|
+
/* @__PURE__ */ jsxs4("div", { className: "lg:col-span-8 space-y-6", children: [
|
|
1196
|
+
/* @__PURE__ */ jsxs4("div", { className: "bg-gray-50 p-4 rounded-lg border border-gray-200", children: [
|
|
1197
|
+
/* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
|
|
1198
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1199
|
+
/* @__PURE__ */ jsx8("label", { className: "text-xs font-medium text-gray-500 uppercase", children: "Titre" }),
|
|
1200
|
+
/* @__PURE__ */ jsx8("p", { className: "text-sm text-[#191919] font-medium mt-1", children: caseData?.title || "N/A" })
|
|
1201
|
+
] }),
|
|
1202
|
+
/* @__PURE__ */ jsxs4("div", { children: [
|
|
1203
|
+
/* @__PURE__ */ jsx8("label", { className: "text-xs font-medium text-gray-500 uppercase", children: "Statut" }),
|
|
1204
|
+
/* @__PURE__ */ jsx8("p", { className: "text-sm text-[#191919] font-medium mt-1 capitalize", children: caseData?.status || "N/A" })
|
|
1205
|
+
] })
|
|
1206
|
+
] }),
|
|
1207
|
+
caseData?.description && /* @__PURE__ */ jsxs4("div", { className: "mt-3 pt-3 border-t border-gray-300", children: [
|
|
1208
|
+
/* @__PURE__ */ jsx8("label", { className: "text-xs font-medium text-gray-500 uppercase", children: "Description" }),
|
|
1209
|
+
/* @__PURE__ */ jsx8("p", { className: "text-sm text-[#191919] mt-1", children: caseData.description })
|
|
1210
|
+
] })
|
|
1211
|
+
] }),
|
|
1212
|
+
/* @__PURE__ */ jsx8("div", { className: "space-y-3", children: /* @__PURE__ */ jsxs4("div", { className: "prose max-w-none", children: [
|
|
1213
|
+
/* @__PURE__ */ jsx8("h3", { className: "text-lg font-semibold text-[#191919] mb-4", children: "Aper\xE7u du document" }),
|
|
1214
|
+
caseData?.html_content ? /* @__PURE__ */ jsx8(
|
|
1215
|
+
"div",
|
|
1216
|
+
{
|
|
1217
|
+
className: "border border-[#D9D9D9] rounded-lg p-6 bg-white",
|
|
1218
|
+
dangerouslySetInnerHTML: { __html: caseData.html_content }
|
|
1219
|
+
}
|
|
1220
|
+
) : /* @__PURE__ */ jsxs4("div", { className: "text-center py-12 border-2 border-dashed border-[#D9D9D9] rounded-lg bg-[#FAFAFA]", children: [
|
|
1221
|
+
/* @__PURE__ */ jsx8(Eye, { className: "w-12 h-12 text-[#767676] mx-auto mb-4" }),
|
|
1222
|
+
/* @__PURE__ */ jsx8("p", { className: "text-[#767676]", children: "Aucun aper\xE7u disponible" })
|
|
1223
|
+
] })
|
|
1224
|
+
] }) }),
|
|
1225
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex flex-wrap gap-3 justify-end pt-6 border-t border-[#D9D9D9]", children: [
|
|
1226
|
+
/* @__PURE__ */ jsxs4(
|
|
1227
|
+
SecondaryButton,
|
|
1228
|
+
{
|
|
1229
|
+
onClick: refuse,
|
|
1230
|
+
disabled: submitting || caseData?.status !== "waiting",
|
|
1231
|
+
classname: "flex items-center gap-2",
|
|
1232
|
+
children: [
|
|
1233
|
+
submitting ? /* @__PURE__ */ jsx8(Loader, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsx8(XCircle, { className: "w-4 h-4" }),
|
|
1234
|
+
"Refuser"
|
|
1235
|
+
]
|
|
1236
|
+
}
|
|
1237
|
+
),
|
|
1238
|
+
/* @__PURE__ */ jsxs4(
|
|
1239
|
+
SecondaryButton,
|
|
1240
|
+
{
|
|
1241
|
+
onClick: suggestCorrection,
|
|
1242
|
+
disabled: submitting || caseData?.status !== "waiting",
|
|
1243
|
+
classname: "flex items-center gap-2",
|
|
1244
|
+
children: [
|
|
1245
|
+
submitting ? /* @__PURE__ */ jsx8(Loader, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsx8(Edit, { className: "w-4 h-4" }),
|
|
1246
|
+
"Sugg\xE9rer une correction"
|
|
1247
|
+
]
|
|
1248
|
+
}
|
|
1249
|
+
),
|
|
1250
|
+
/* @__PURE__ */ jsxs4(
|
|
1251
|
+
Buttons_default,
|
|
1252
|
+
{
|
|
1253
|
+
onClick: accept,
|
|
1254
|
+
disabled: submitting || caseData?.status !== "waiting",
|
|
1255
|
+
classname: "flex items-center gap-2",
|
|
1256
|
+
children: [
|
|
1257
|
+
submitting ? /* @__PURE__ */ jsx8(Loader, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsx8(Check, { className: "w-4 h-4" }),
|
|
1258
|
+
"Accepter"
|
|
1259
|
+
]
|
|
1260
|
+
}
|
|
1261
|
+
)
|
|
1262
|
+
] })
|
|
1263
|
+
] })
|
|
1264
|
+
] }),
|
|
1265
|
+
showNoteModal && /* @__PURE__ */ jsx8("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4", children: /* @__PURE__ */ jsx8("div", { className: "bg-white rounded-lg shadow-xl max-w-md w-full", children: /* @__PURE__ */ jsxs4("div", { className: "p-6", children: [
|
|
1266
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-between mb-4", children: [
|
|
1267
|
+
/* @__PURE__ */ jsxs4("h3", { className: "text-lg font-semibold text-[#191919]", children: [
|
|
1268
|
+
currentAction === "approve" && "Approuver la demande",
|
|
1269
|
+
currentAction === "reject" && "Refuser la demande",
|
|
1270
|
+
currentAction === "suggest" && "Sugg\xE9rer une correction"
|
|
1271
|
+
] }),
|
|
1272
|
+
/* @__PURE__ */ jsx8(
|
|
1273
|
+
"button",
|
|
1274
|
+
{
|
|
1275
|
+
onClick: closeNoteModal,
|
|
1276
|
+
disabled: submitting,
|
|
1277
|
+
className: "text-gray-500 hover:text-[#6A8A82] transition-colors",
|
|
1278
|
+
children: /* @__PURE__ */ jsx8(X, { className: "w-5 h-5" })
|
|
1279
|
+
}
|
|
1280
|
+
)
|
|
1281
|
+
] }),
|
|
1282
|
+
/* @__PURE__ */ jsxs4("div", { className: "mb-4", children: [
|
|
1283
|
+
/* @__PURE__ */ jsxs4("label", { className: "block text-sm font-medium text-[#191919] mb-2", children: [
|
|
1284
|
+
"Note ",
|
|
1285
|
+
currentAction === "suggest" && "(obligatoire pour suggestion)",
|
|
1286
|
+
":"
|
|
1287
|
+
] }),
|
|
1288
|
+
/* @__PURE__ */ jsx8(
|
|
1289
|
+
"textarea",
|
|
1290
|
+
{
|
|
1291
|
+
value: note,
|
|
1292
|
+
onChange: (e) => setNote(e.target.value),
|
|
1293
|
+
rows: 4,
|
|
1294
|
+
disabled: submitting,
|
|
1295
|
+
className: "w-full px-3 py-2 border border-[#D9D9D9] rounded-lg focus:ring-2 focus:ring-[#6A8A82] focus:border-transparent resize-none disabled:bg-gray-100",
|
|
1296
|
+
placeholder: "Ajoutez un commentaire (optionnel)..."
|
|
1297
|
+
}
|
|
1298
|
+
)
|
|
1299
|
+
] }),
|
|
1300
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex gap-3 justify-end", children: [
|
|
1301
|
+
/* @__PURE__ */ jsx8(
|
|
1302
|
+
SecondaryButton,
|
|
1303
|
+
{
|
|
1304
|
+
onClick: closeNoteModal,
|
|
1305
|
+
disabled: submitting,
|
|
1306
|
+
children: "Annuler"
|
|
1307
|
+
}
|
|
1308
|
+
),
|
|
1309
|
+
/* @__PURE__ */ jsx8(
|
|
1310
|
+
Buttons_default,
|
|
1311
|
+
{
|
|
1312
|
+
onClick: executeAction,
|
|
1313
|
+
disabled: submitting || currentAction === "suggest" && !note.trim(),
|
|
1314
|
+
classname: "flex items-center gap-2",
|
|
1315
|
+
children: submitting ? /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1316
|
+
/* @__PURE__ */ jsx8(Loader, { className: "w-4 h-4 animate-spin" }),
|
|
1317
|
+
"Traitement..."
|
|
1318
|
+
] }) : /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
1319
|
+
currentAction === "approve" && /* @__PURE__ */ jsx8(Check, { className: "w-4 h-4" }),
|
|
1320
|
+
currentAction === "reject" && /* @__PURE__ */ jsx8(XCircle, { className: "w-4 h-4" }),
|
|
1321
|
+
currentAction === "suggest" && /* @__PURE__ */ jsx8(Edit, { className: "w-4 h-4" }),
|
|
1322
|
+
"Confirmer"
|
|
1323
|
+
] })
|
|
1324
|
+
}
|
|
1325
|
+
)
|
|
1326
|
+
] })
|
|
1327
|
+
] }) }) })
|
|
1328
|
+
] });
|
|
1329
|
+
};
|
|
1330
|
+
var ApprovalPreviewAnswer_default = ApprovalPreviewAnswer;
|
|
1331
|
+
|
|
776
1332
|
// src/components/layout/ModernDoubleSidebarLayout.tsx
|
|
777
|
-
import { Fragment, jsx as
|
|
1333
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
778
1334
|
var RewiseLayout = ({ children, module_name = "Rewise", module_description = "Description du module", primaryMenuItems, secondaryMenuItems }) => {
|
|
779
1335
|
const location = useLocation();
|
|
780
1336
|
const navigate = useNavigate();
|
|
781
1337
|
const { theme, themeType, setTheme } = useTheme();
|
|
782
1338
|
const { loggedUser, activeBusinessEntity, setActiveBusinessEntity } = useSession();
|
|
783
|
-
const [primaryCollapsed, setPrimaryCollapsed] =
|
|
784
|
-
const [secondaryCollapsed, setSecondaryCollapsed] =
|
|
785
|
-
const [mobileMenuOpen, setMobileMenuOpen] =
|
|
786
|
-
const [selectedModule, setSelectedModule] =
|
|
787
|
-
const [searchQuery, setSearchQuery] =
|
|
788
|
-
const [showNotifications, setShowNotifications] =
|
|
789
|
-
const [showUserMenu, setShowUserMenu] =
|
|
790
|
-
const [showThemeMenu, setShowThemeMenu] =
|
|
791
|
-
const [showCenterMenu, setShowCenterMenu] =
|
|
792
|
-
const [
|
|
1339
|
+
const [primaryCollapsed, setPrimaryCollapsed] = useState5(false);
|
|
1340
|
+
const [secondaryCollapsed, setSecondaryCollapsed] = useState5(false);
|
|
1341
|
+
const [mobileMenuOpen, setMobileMenuOpen] = useState5(false);
|
|
1342
|
+
const [selectedModule, setSelectedModule] = useState5("dashboard");
|
|
1343
|
+
const [searchQuery, setSearchQuery] = useState5("");
|
|
1344
|
+
const [showNotifications, setShowNotifications] = useState5(false);
|
|
1345
|
+
const [showUserMenu, setShowUserMenu] = useState5(false);
|
|
1346
|
+
const [showThemeMenu, setShowThemeMenu] = useState5(false);
|
|
1347
|
+
const [showCenterMenu, setShowCenterMenu] = useState5(false);
|
|
1348
|
+
const [showApprovalModal, setShowApprovalModal] = useState5(false);
|
|
1349
|
+
const [approvalAnswerDetail, setApprovalAnswerDetail] = useState5(null);
|
|
1350
|
+
const [caseData, setCaseData] = useState5(null);
|
|
1351
|
+
const [selectedCenterId, setSelectedCenterId] = useState5(
|
|
793
1352
|
loggedUser?.centers_access?.[0]?.id || null
|
|
794
1353
|
);
|
|
795
|
-
const
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
message: "3 nouvelles factures en attente de validation",
|
|
800
|
-
type: "info",
|
|
801
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
802
|
-
read: false
|
|
803
|
-
},
|
|
804
|
-
{
|
|
805
|
-
id: "2",
|
|
806
|
-
title: "Cl\xF4ture mensuelle",
|
|
807
|
-
message: "La cl\xF4ture de janvier est pr\xEAte",
|
|
808
|
-
type: "success",
|
|
809
|
-
timestamp: /* @__PURE__ */ new Date(),
|
|
810
|
-
read: false
|
|
811
|
-
}
|
|
812
|
-
]);
|
|
813
|
-
useEffect3(() => {
|
|
1354
|
+
const { success, error: showError } = useToast();
|
|
1355
|
+
const [notifications, setNotifications] = useState5([]);
|
|
1356
|
+
const [loading, setLoading] = useState5(false);
|
|
1357
|
+
useEffect4(() => {
|
|
814
1358
|
const handleKeyDown = (e) => {
|
|
815
1359
|
if (e.altKey && e.key === "m") {
|
|
816
1360
|
e.preventDefault();
|
|
@@ -830,7 +1374,25 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
830
1374
|
document.addEventListener("keydown", handleKeyDown);
|
|
831
1375
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
832
1376
|
}, []);
|
|
833
|
-
|
|
1377
|
+
useEffect4(() => {
|
|
1378
|
+
const loadOrganizations = async () => {
|
|
1379
|
+
try {
|
|
1380
|
+
setLoading(true);
|
|
1381
|
+
const result = await UserServices.getUsersNotifications();
|
|
1382
|
+
setNotifications(result.data);
|
|
1383
|
+
console.log("Notifications:", result.data);
|
|
1384
|
+
} catch (error) {
|
|
1385
|
+
showError("Erreur lors du chargement des organisations");
|
|
1386
|
+
console.error(error);
|
|
1387
|
+
} finally {
|
|
1388
|
+
setLoading(false);
|
|
1389
|
+
}
|
|
1390
|
+
};
|
|
1391
|
+
if (loggedUser) {
|
|
1392
|
+
loadOrganizations();
|
|
1393
|
+
}
|
|
1394
|
+
}, [loggedUser]);
|
|
1395
|
+
useEffect4(() => {
|
|
834
1396
|
const path = location.pathname;
|
|
835
1397
|
const moduleMatch = path.match(/^\/([^/]+)/);
|
|
836
1398
|
if (moduleMatch) {
|
|
@@ -860,13 +1422,25 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
860
1422
|
});
|
|
861
1423
|
return breadcrumbs;
|
|
862
1424
|
};
|
|
863
|
-
const markNotificationAsRead = (id) => {
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1425
|
+
const markNotificationAsRead = async (id) => {
|
|
1426
|
+
const notif = notifications.find((n) => n.id === id);
|
|
1427
|
+
try {
|
|
1428
|
+
if (notif?.object_detail?.link_token) {
|
|
1429
|
+
setApprovalAnswerDetail(notif.object_detail);
|
|
1430
|
+
setShowApprovalModal(true);
|
|
1431
|
+
} else {
|
|
1432
|
+
await UserServices.markNotificationAsRead(Number(id));
|
|
1433
|
+
setNotifications(
|
|
1434
|
+
(prev) => prev.map((n) => n.id === id ? { ...n, read: true, is_read: true } : n)
|
|
1435
|
+
);
|
|
1436
|
+
}
|
|
1437
|
+
} catch (error) {
|
|
1438
|
+
console.error("Erreur lors du marquage de la notification:", error);
|
|
1439
|
+
showError("Erreur lors du marquage de la notification comme lue");
|
|
1440
|
+
}
|
|
867
1441
|
};
|
|
868
|
-
return /* @__PURE__ */
|
|
869
|
-
/* @__PURE__ */
|
|
1442
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex h-screen bg-[var(--color-background)] overflow-hidden", children: [
|
|
1443
|
+
/* @__PURE__ */ jsx9(
|
|
870
1444
|
"a",
|
|
871
1445
|
{
|
|
872
1446
|
href: "#main-content",
|
|
@@ -874,7 +1448,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
874
1448
|
children: "Aller au contenu principal"
|
|
875
1449
|
}
|
|
876
1450
|
),
|
|
877
|
-
/* @__PURE__ */
|
|
1451
|
+
/* @__PURE__ */ jsxs5(
|
|
878
1452
|
"aside",
|
|
879
1453
|
{
|
|
880
1454
|
className: cn(
|
|
@@ -884,38 +1458,38 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
884
1458
|
role: "navigation",
|
|
885
1459
|
"aria-label": "Navigation principale",
|
|
886
1460
|
children: [
|
|
887
|
-
/* @__PURE__ */
|
|
888
|
-
/* @__PURE__ */
|
|
1461
|
+
/* @__PURE__ */ jsxs5("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-sidebar-border)]", children: [
|
|
1462
|
+
/* @__PURE__ */ jsxs5("div", { className: cn(
|
|
889
1463
|
"flex items-center gap-3",
|
|
890
1464
|
primaryCollapsed && "justify-center"
|
|
891
1465
|
), children: [
|
|
892
|
-
/* @__PURE__ */
|
|
893
|
-
!primaryCollapsed && /* @__PURE__ */
|
|
894
|
-
/* @__PURE__ */
|
|
895
|
-
/* @__PURE__ */
|
|
1466
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx9("span", { className: "text-[var(--color-background)] font-bold text-xl", children: "W" }) }),
|
|
1467
|
+
!primaryCollapsed && /* @__PURE__ */ jsxs5("div", { children: [
|
|
1468
|
+
/* @__PURE__ */ jsx9("h1", { className: "text-[var(--color-sidebar-text)] font-bold text-lg", children: module_name }),
|
|
1469
|
+
/* @__PURE__ */ jsx9("p", { className: "text-[var(--color-sidebar-text-secondary)] text-xs", children: module_description })
|
|
896
1470
|
] })
|
|
897
1471
|
] }),
|
|
898
|
-
/* @__PURE__ */
|
|
1472
|
+
/* @__PURE__ */ jsx9(
|
|
899
1473
|
"button",
|
|
900
1474
|
{
|
|
901
1475
|
onClick: () => setPrimaryCollapsed(!primaryCollapsed),
|
|
902
1476
|
className: "text-[var(--color-sidebar-text-secondary)] hover:text-[var(--color-sidebar-text)] transition-colors",
|
|
903
1477
|
"aria-label": primaryCollapsed ? "D\xE9velopper le menu" : "R\xE9duire le menu",
|
|
904
1478
|
"aria-expanded": !primaryCollapsed,
|
|
905
|
-
children: /* @__PURE__ */
|
|
1479
|
+
children: /* @__PURE__ */ jsx9(ChevronLeft, { className: cn(
|
|
906
1480
|
"w-5 h-5 transition-transform",
|
|
907
1481
|
primaryCollapsed && "rotate-180"
|
|
908
1482
|
) })
|
|
909
1483
|
}
|
|
910
1484
|
)
|
|
911
1485
|
] }),
|
|
912
|
-
/* @__PURE__ */
|
|
1486
|
+
/* @__PURE__ */ jsx9(
|
|
913
1487
|
"nav",
|
|
914
1488
|
{
|
|
915
1489
|
className: "flex-1 py-4 overflow-y-auto",
|
|
916
1490
|
role: "menubar",
|
|
917
1491
|
"aria-label": "Modules principaux",
|
|
918
|
-
children: primaryMenuItems.map((item) => /* @__PURE__ */
|
|
1492
|
+
children: primaryMenuItems.map((item) => /* @__PURE__ */ jsxs5(
|
|
919
1493
|
"button",
|
|
920
1494
|
{
|
|
921
1495
|
onClick: () => {
|
|
@@ -936,48 +1510,48 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
936
1510
|
"aria-label": item.ariaLabel || item.label,
|
|
937
1511
|
"aria-current": isModuleActive(item.id) ? "page" : void 0,
|
|
938
1512
|
children: [
|
|
939
|
-
/* @__PURE__ */
|
|
1513
|
+
/* @__PURE__ */ jsx9("div", { className: cn(
|
|
940
1514
|
"transition-colors",
|
|
941
1515
|
isModuleActive(item.id) ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)] group-hover:text-[var(--color-sidebar-text)]"
|
|
942
1516
|
), children: item.icon }),
|
|
943
|
-
!primaryCollapsed && /* @__PURE__ */
|
|
944
|
-
/* @__PURE__ */
|
|
1517
|
+
!primaryCollapsed && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1518
|
+
/* @__PURE__ */ jsx9("span", { className: cn(
|
|
945
1519
|
"flex-1 text-left text-sm font-medium transition-colors",
|
|
946
1520
|
isModuleActive(item.id) ? "text-[var(--color-sidebar-text)]" : "text-[var(--color-sidebar-text-secondary)] group-hover:text-[var(--color-sidebar-text)]"
|
|
947
1521
|
), children: item.label }),
|
|
948
|
-
item.badge && /* @__PURE__ */
|
|
1522
|
+
item.badge && /* @__PURE__ */ jsx9("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-[var(--color-background)] rounded-full", children: item.badge })
|
|
949
1523
|
] }),
|
|
950
|
-
primaryCollapsed && /* @__PURE__ */
|
|
1524
|
+
primaryCollapsed && /* @__PURE__ */ jsx9("div", { className: "absolute left-full ml-2 px-2 py-1 bg-[var(--color-sidebar-active)] text-[var(--color-sidebar-text)] text-xs rounded opacity-0 group-hover:opacity-100 pointer-events-none whitespace-nowrap z-50", children: item.label })
|
|
951
1525
|
]
|
|
952
1526
|
},
|
|
953
1527
|
item.id
|
|
954
1528
|
))
|
|
955
1529
|
}
|
|
956
1530
|
),
|
|
957
|
-
/* @__PURE__ */
|
|
1531
|
+
/* @__PURE__ */ jsx9("div", { className: "p-4 border-t border-[var(--color-sidebar-border)]", children: /* @__PURE__ */ jsxs5("div", { className: cn(
|
|
958
1532
|
"flex items-center gap-3",
|
|
959
1533
|
primaryCollapsed && "justify-center"
|
|
960
1534
|
), children: [
|
|
961
|
-
/* @__PURE__ */
|
|
962
|
-
!primaryCollapsed && /* @__PURE__ */
|
|
963
|
-
/* @__PURE__ */
|
|
964
|
-
/* @__PURE__ */
|
|
1535
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx9(User, { className: "w-5 h-5 text-[var(--color-background)]" }) }),
|
|
1536
|
+
!primaryCollapsed && /* @__PURE__ */ jsxs5("div", { className: "flex-1", children: [
|
|
1537
|
+
/* @__PURE__ */ jsx9("p", { className: "text-sm font-medium text-[var(--color-sidebar-text)]", children: loggedUser?.first_name && loggedUser?.last_name ? `${loggedUser.first_name} ${loggedUser.last_name}` : loggedUser?.username || "Utilisateur" }),
|
|
1538
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-sidebar-text-secondary)]", children: loggedUser?.email || "email@example.com" })
|
|
965
1539
|
] })
|
|
966
1540
|
] }) })
|
|
967
1541
|
]
|
|
968
1542
|
}
|
|
969
1543
|
),
|
|
970
|
-
secondaryMenuItems[selectedModule] && /* @__PURE__ */
|
|
971
|
-
secondaryCollapsed && /* @__PURE__ */
|
|
1544
|
+
secondaryMenuItems[selectedModule] && /* @__PURE__ */ jsxs5(Fragment2, { children: [
|
|
1545
|
+
secondaryCollapsed && /* @__PURE__ */ jsx9(
|
|
972
1546
|
"button",
|
|
973
1547
|
{
|
|
974
1548
|
onClick: () => setSecondaryCollapsed(false),
|
|
975
1549
|
className: "hidden lg:flex items-center justify-center w-12 h-full bg-[var(--color-background)] border-r border-[var(--color-border)] hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
976
1550
|
"aria-label": "Ouvrir le sous-menu",
|
|
977
|
-
children: /* @__PURE__ */
|
|
1551
|
+
children: /* @__PURE__ */ jsx9(ChevronRight, { className: "w-5 h-5 text-[var(--color-text-tertiary)]" })
|
|
978
1552
|
}
|
|
979
1553
|
),
|
|
980
|
-
/* @__PURE__ */
|
|
1554
|
+
/* @__PURE__ */ jsxs5(
|
|
981
1555
|
"aside",
|
|
982
1556
|
{
|
|
983
1557
|
className: cn(
|
|
@@ -987,28 +1561,28 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
987
1561
|
role: "navigation",
|
|
988
1562
|
"aria-label": "Navigation secondaire",
|
|
989
1563
|
children: [
|
|
990
|
-
/* @__PURE__ */
|
|
991
|
-
/* @__PURE__ */
|
|
992
|
-
/* @__PURE__ */
|
|
1564
|
+
/* @__PURE__ */ jsxs5("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-border)]", children: [
|
|
1565
|
+
/* @__PURE__ */ jsx9("h2", { className: "text-sm font-semibold text-[var(--color-text-secondary)] uppercase tracking-wider whitespace-nowrap", children: primaryMenuItems.find((item) => item.id === selectedModule)?.label }),
|
|
1566
|
+
/* @__PURE__ */ jsx9(
|
|
993
1567
|
"button",
|
|
994
1568
|
{
|
|
995
1569
|
onClick: () => setSecondaryCollapsed(!secondaryCollapsed),
|
|
996
1570
|
className: "text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] flex-shrink-0",
|
|
997
1571
|
"aria-label": secondaryCollapsed ? "D\xE9velopper le sous-menu" : "R\xE9duire le sous-menu",
|
|
998
|
-
children: /* @__PURE__ */
|
|
1572
|
+
children: /* @__PURE__ */ jsx9(ChevronLeft, { className: cn(
|
|
999
1573
|
"w-4 h-4 transition-transform",
|
|
1000
1574
|
secondaryCollapsed && "rotate-180"
|
|
1001
1575
|
) })
|
|
1002
1576
|
}
|
|
1003
1577
|
)
|
|
1004
1578
|
] }),
|
|
1005
|
-
/* @__PURE__ */
|
|
1579
|
+
/* @__PURE__ */ jsx9(
|
|
1006
1580
|
"nav",
|
|
1007
1581
|
{
|
|
1008
1582
|
className: "flex-1 py-4 overflow-y-auto",
|
|
1009
1583
|
role: "menu",
|
|
1010
1584
|
"aria-label": "Sous-navigation",
|
|
1011
|
-
children: secondaryMenuItems[selectedModule]?.map((item) => /* @__PURE__ */
|
|
1585
|
+
children: secondaryMenuItems[selectedModule]?.map((item) => /* @__PURE__ */ jsxs5(
|
|
1012
1586
|
"button",
|
|
1013
1587
|
{
|
|
1014
1588
|
onClick: () => item.path && navigate(item.path),
|
|
@@ -1020,15 +1594,15 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1020
1594
|
role: "menuitem",
|
|
1021
1595
|
"aria-current": isActive(item.path || "") ? "page" : void 0,
|
|
1022
1596
|
children: [
|
|
1023
|
-
item.icon && /* @__PURE__ */
|
|
1597
|
+
item.icon && /* @__PURE__ */ jsx9("div", { className: cn(
|
|
1024
1598
|
"transition-colors",
|
|
1025
1599
|
isActive(item.path || "") ? "text-[var(--color-primary)]" : "text-[var(--color-text-tertiary)]"
|
|
1026
1600
|
), children: item.icon }),
|
|
1027
|
-
/* @__PURE__ */
|
|
1601
|
+
/* @__PURE__ */ jsx9("span", { className: cn(
|
|
1028
1602
|
"flex-1 text-left text-sm",
|
|
1029
1603
|
isActive(item.path || "") ? "text-[var(--color-primary)] font-medium" : "text-[var(--color-text-secondary)]"
|
|
1030
1604
|
), children: item.label }),
|
|
1031
|
-
item.badge && /* @__PURE__ */
|
|
1605
|
+
item.badge && /* @__PURE__ */ jsx9("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-white rounded-full", children: item.badge })
|
|
1032
1606
|
]
|
|
1033
1607
|
},
|
|
1034
1608
|
item.id
|
|
@@ -1039,13 +1613,13 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1039
1613
|
}
|
|
1040
1614
|
)
|
|
1041
1615
|
] }),
|
|
1042
|
-
mobileMenuOpen && /* @__PURE__ */
|
|
1616
|
+
mobileMenuOpen && /* @__PURE__ */ jsx9(
|
|
1043
1617
|
"div",
|
|
1044
1618
|
{
|
|
1045
1619
|
className: "fixed inset-0 bg-black bg-opacity-50 z-50 lg:hidden",
|
|
1046
1620
|
onClick: () => setMobileMenuOpen(false),
|
|
1047
1621
|
"aria-hidden": "true",
|
|
1048
|
-
children: /* @__PURE__ */
|
|
1622
|
+
children: /* @__PURE__ */ jsxs5(
|
|
1049
1623
|
"aside",
|
|
1050
1624
|
{
|
|
1051
1625
|
className: "w-80 h-full bg-[var(--color-sidebar-bg)]",
|
|
@@ -1053,26 +1627,26 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1053
1627
|
role: "navigation",
|
|
1054
1628
|
"aria-label": "Navigation mobile",
|
|
1055
1629
|
children: [
|
|
1056
|
-
/* @__PURE__ */
|
|
1057
|
-
/* @__PURE__ */
|
|
1058
|
-
/* @__PURE__ */
|
|
1059
|
-
/* @__PURE__ */
|
|
1060
|
-
/* @__PURE__ */
|
|
1061
|
-
/* @__PURE__ */
|
|
1630
|
+
/* @__PURE__ */ jsxs5("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-sidebar-border)]", children: [
|
|
1631
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
|
|
1632
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx9("span", { className: "text-[var(--color-background)] font-bold text-xl", children: "W" }) }),
|
|
1633
|
+
/* @__PURE__ */ jsxs5("div", { children: [
|
|
1634
|
+
/* @__PURE__ */ jsx9("h1", { className: "text-white font-bold text-lg", children: "WiseBook" }),
|
|
1635
|
+
/* @__PURE__ */ jsx9("p", { className: "text-gray-400 text-xs", children: "ERP Next-Gen" })
|
|
1062
1636
|
] })
|
|
1063
1637
|
] }),
|
|
1064
|
-
/* @__PURE__ */
|
|
1638
|
+
/* @__PURE__ */ jsx9(
|
|
1065
1639
|
"button",
|
|
1066
1640
|
{
|
|
1067
1641
|
onClick: () => setMobileMenuOpen(false),
|
|
1068
1642
|
className: "text-[var(--color-sidebar-text-secondary)]",
|
|
1069
1643
|
"aria-label": "Fermer le menu",
|
|
1070
|
-
children: /* @__PURE__ */
|
|
1644
|
+
children: /* @__PURE__ */ jsx9(X2, { className: "w-6 h-6" })
|
|
1071
1645
|
}
|
|
1072
1646
|
)
|
|
1073
1647
|
] }),
|
|
1074
|
-
/* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1648
|
+
/* @__PURE__ */ jsx9("nav", { className: "py-4", role: "menubar", children: primaryMenuItems.map((item) => /* @__PURE__ */ jsxs5("div", { children: [
|
|
1649
|
+
/* @__PURE__ */ jsxs5(
|
|
1076
1650
|
"button",
|
|
1077
1651
|
{
|
|
1078
1652
|
onClick: () => {
|
|
@@ -1091,19 +1665,19 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1091
1665
|
role: "menuitem",
|
|
1092
1666
|
"aria-current": isModuleActive(item.id) ? "page" : void 0,
|
|
1093
1667
|
children: [
|
|
1094
|
-
/* @__PURE__ */
|
|
1668
|
+
/* @__PURE__ */ jsx9("div", { className: cn(
|
|
1095
1669
|
"transition-colors",
|
|
1096
1670
|
isModuleActive(item.id) ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)]"
|
|
1097
1671
|
), children: item.icon }),
|
|
1098
|
-
/* @__PURE__ */
|
|
1672
|
+
/* @__PURE__ */ jsx9("span", { className: cn(
|
|
1099
1673
|
"flex-1 text-left text-sm font-medium",
|
|
1100
1674
|
isModuleActive(item.id) ? "text-[var(--color-sidebar-text)]" : "text-[var(--color-sidebar-text-secondary)]"
|
|
1101
1675
|
), children: item.label }),
|
|
1102
|
-
item.badge && /* @__PURE__ */
|
|
1676
|
+
item.badge && /* @__PURE__ */ jsx9("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-[var(--color-background)] rounded-full", children: item.badge })
|
|
1103
1677
|
]
|
|
1104
1678
|
}
|
|
1105
1679
|
),
|
|
1106
|
-
isModuleActive(item.id) && secondaryMenuItems[item.id] && /* @__PURE__ */
|
|
1680
|
+
isModuleActive(item.id) && secondaryMenuItems[item.id] && /* @__PURE__ */ jsx9("div", { className: "bg-[var(--color-sidebar-submenu-bg)] py-2", children: secondaryMenuItems[item.id].map((subItem) => /* @__PURE__ */ jsxs5(
|
|
1107
1681
|
"button",
|
|
1108
1682
|
{
|
|
1109
1683
|
onClick: () => {
|
|
@@ -1119,7 +1693,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1119
1693
|
),
|
|
1120
1694
|
children: [
|
|
1121
1695
|
subItem.icon,
|
|
1122
|
-
/* @__PURE__ */
|
|
1696
|
+
/* @__PURE__ */ jsx9("span", { className: cn(
|
|
1123
1697
|
isActive(subItem.path || "") ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)]"
|
|
1124
1698
|
), children: subItem.label })
|
|
1125
1699
|
]
|
|
@@ -1132,31 +1706,31 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1132
1706
|
)
|
|
1133
1707
|
}
|
|
1134
1708
|
),
|
|
1135
|
-
/* @__PURE__ */
|
|
1136
|
-
/* @__PURE__ */
|
|
1709
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex-1 flex flex-col overflow-hidden", children: [
|
|
1710
|
+
/* @__PURE__ */ jsxs5(
|
|
1137
1711
|
"header",
|
|
1138
1712
|
{
|
|
1139
1713
|
className: "h-14 bg-[var(--color-background)] border-b border-[var(--color-border)] flex items-center justify-between px-3 lg:px-4",
|
|
1140
1714
|
role: "banner",
|
|
1141
1715
|
children: [
|
|
1142
|
-
/* @__PURE__ */
|
|
1143
|
-
/* @__PURE__ */
|
|
1716
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-4 flex-1", children: [
|
|
1717
|
+
/* @__PURE__ */ jsx9(
|
|
1144
1718
|
"button",
|
|
1145
1719
|
{
|
|
1146
1720
|
onClick: () => setMobileMenuOpen(true),
|
|
1147
1721
|
className: "lg:hidden text-[var(--color-text-primary)]",
|
|
1148
1722
|
"aria-label": "Ouvrir le menu mobile",
|
|
1149
|
-
children: /* @__PURE__ */
|
|
1723
|
+
children: /* @__PURE__ */ jsx9(Menu, { className: "w-6 h-6" })
|
|
1150
1724
|
}
|
|
1151
1725
|
),
|
|
1152
|
-
/* @__PURE__ */
|
|
1726
|
+
/* @__PURE__ */ jsx9(
|
|
1153
1727
|
"nav",
|
|
1154
1728
|
{
|
|
1155
1729
|
className: "hidden sm:flex items-center gap-2 text-sm",
|
|
1156
1730
|
"aria-label": "Fil d'Ariane",
|
|
1157
|
-
children: getBreadcrumbs().map((crumb, index) => /* @__PURE__ */
|
|
1158
|
-
index > 0 && /* @__PURE__ */
|
|
1159
|
-
/* @__PURE__ */
|
|
1731
|
+
children: getBreadcrumbs().map((crumb, index) => /* @__PURE__ */ jsxs5(React4.Fragment, { children: [
|
|
1732
|
+
index > 0 && /* @__PURE__ */ jsx9(ChevronRight, { className: "w-4 h-4 text-[var(--color-text-tertiary)]" }),
|
|
1733
|
+
/* @__PURE__ */ jsx9(
|
|
1160
1734
|
"button",
|
|
1161
1735
|
{
|
|
1162
1736
|
onClick: () => navigate(crumb.path),
|
|
@@ -1170,9 +1744,9 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1170
1744
|
] }, crumb.path))
|
|
1171
1745
|
}
|
|
1172
1746
|
),
|
|
1173
|
-
/* @__PURE__ */
|
|
1174
|
-
/* @__PURE__ */
|
|
1175
|
-
/* @__PURE__ */
|
|
1747
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative max-w-md flex-1 hidden lg:block", children: [
|
|
1748
|
+
/* @__PURE__ */ jsx9(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-tertiary)] w-5 h-5" }),
|
|
1749
|
+
/* @__PURE__ */ jsx9(
|
|
1176
1750
|
"input",
|
|
1177
1751
|
{
|
|
1178
1752
|
id: "global-search",
|
|
@@ -1186,9 +1760,9 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1186
1760
|
)
|
|
1187
1761
|
] })
|
|
1188
1762
|
] }),
|
|
1189
|
-
/* @__PURE__ */
|
|
1190
|
-
loggedUser?.centers_access && loggedUser.centers_access.length > 0 && /* @__PURE__ */
|
|
1191
|
-
/* @__PURE__ */
|
|
1763
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
|
|
1764
|
+
loggedUser?.centers_access && loggedUser.centers_access.length > 0 && /* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1765
|
+
/* @__PURE__ */ jsxs5(
|
|
1192
1766
|
"button",
|
|
1193
1767
|
{
|
|
1194
1768
|
onClick: () => setShowCenterMenu(!showCenterMenu),
|
|
@@ -1197,24 +1771,24 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1197
1771
|
"aria-label": "S\xE9lecteur de centre",
|
|
1198
1772
|
"aria-expanded": showCenterMenu,
|
|
1199
1773
|
children: [
|
|
1200
|
-
/* @__PURE__ */
|
|
1201
|
-
/* @__PURE__ */
|
|
1202
|
-
/* @__PURE__ */
|
|
1774
|
+
/* @__PURE__ */ jsx9(Building2, { className: "w-4 h-4 text-[var(--color-primary)]" }),
|
|
1775
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-[var(--color-text-primary)] hidden sm:block", children: loggedUser.centers_access.find((c) => c.id === activeBusinessEntity?.id)?.legal_name || "S\xE9lectionner" }),
|
|
1776
|
+
/* @__PURE__ */ jsx9(ChevronRight, { className: cn(
|
|
1203
1777
|
"w-4 h-4 text-[var(--color-text-tertiary)] transition-transform",
|
|
1204
1778
|
showCenterMenu && "rotate-90"
|
|
1205
1779
|
) })
|
|
1206
1780
|
]
|
|
1207
1781
|
}
|
|
1208
1782
|
),
|
|
1209
|
-
showCenterMenu && /* @__PURE__ */
|
|
1783
|
+
showCenterMenu && /* @__PURE__ */ jsx9(
|
|
1210
1784
|
"div",
|
|
1211
1785
|
{
|
|
1212
1786
|
className: "absolute right-0 mt-2 w-64 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50 max-h-80 overflow-y-auto",
|
|
1213
1787
|
role: "menu",
|
|
1214
1788
|
"aria-label": "S\xE9lection du centre",
|
|
1215
|
-
children: /* @__PURE__ */
|
|
1216
|
-
/* @__PURE__ */
|
|
1217
|
-
loggedUser.centers_access.map((center) => /* @__PURE__ */
|
|
1789
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "p-2", children: [
|
|
1790
|
+
/* @__PURE__ */ jsx9("p", { className: "px-3 py-2 text-xs font-semibold text-[var(--color-text-tertiary)] uppercase", children: "Centres disponibles" }),
|
|
1791
|
+
loggedUser.centers_access.map((center) => /* @__PURE__ */ jsxs5(
|
|
1218
1792
|
"button",
|
|
1219
1793
|
{
|
|
1220
1794
|
onClick: () => {
|
|
@@ -1228,16 +1802,16 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1228
1802
|
),
|
|
1229
1803
|
role: "menuitem",
|
|
1230
1804
|
children: [
|
|
1231
|
-
/* @__PURE__ */
|
|
1805
|
+
/* @__PURE__ */ jsx9(Building2, { className: cn(
|
|
1232
1806
|
"w-5 h-5",
|
|
1233
1807
|
selectedCenterId === center.id ? "text-[var(--color-primary)]" : "text-[var(--color-text-tertiary)]"
|
|
1234
1808
|
) }),
|
|
1235
|
-
/* @__PURE__ */
|
|
1236
|
-
/* @__PURE__ */
|
|
1809
|
+
/* @__PURE__ */ jsxs5("div", { className: "text-left flex-1", children: [
|
|
1810
|
+
/* @__PURE__ */ jsx9("p", { className: cn(
|
|
1237
1811
|
"text-sm font-medium",
|
|
1238
1812
|
selectedCenterId === center.id ? "text-[var(--color-primary)]" : "text-[var(--color-text-primary)]"
|
|
1239
1813
|
), children: center.legal_name }),
|
|
1240
|
-
center.trading_name && /* @__PURE__ */
|
|
1814
|
+
center.trading_name && /* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: center.trading_name })
|
|
1241
1815
|
] })
|
|
1242
1816
|
]
|
|
1243
1817
|
},
|
|
@@ -1247,8 +1821,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1247
1821
|
}
|
|
1248
1822
|
)
|
|
1249
1823
|
] }),
|
|
1250
|
-
/* @__PURE__ */
|
|
1251
|
-
/* @__PURE__ */
|
|
1824
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1825
|
+
/* @__PURE__ */ jsx9(
|
|
1252
1826
|
"button",
|
|
1253
1827
|
{
|
|
1254
1828
|
onClick: () => setShowThemeMenu(!showThemeMenu),
|
|
@@ -1256,18 +1830,18 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1256
1830
|
title: "Changer le th\xE8me",
|
|
1257
1831
|
"aria-label": "S\xE9lecteur de th\xE8me",
|
|
1258
1832
|
"aria-expanded": showThemeMenu,
|
|
1259
|
-
children: /* @__PURE__ */
|
|
1833
|
+
children: /* @__PURE__ */ jsx9(Palette, { className: "w-5 h-5 text-[var(--color-text-secondary)]" })
|
|
1260
1834
|
}
|
|
1261
1835
|
),
|
|
1262
|
-
showThemeMenu && /* @__PURE__ */
|
|
1836
|
+
showThemeMenu && /* @__PURE__ */ jsx9(
|
|
1263
1837
|
"div",
|
|
1264
1838
|
{
|
|
1265
1839
|
className: "absolute right-0 mt-2 w-64 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50",
|
|
1266
1840
|
role: "menu",
|
|
1267
1841
|
"aria-label": "S\xE9lection du th\xE8me",
|
|
1268
|
-
children: /* @__PURE__ */
|
|
1269
|
-
/* @__PURE__ */
|
|
1270
|
-
/* @__PURE__ */
|
|
1842
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "p-2", children: [
|
|
1843
|
+
/* @__PURE__ */ jsx9("p", { className: "px-3 py-2 text-xs font-semibold text-[var(--color-text-tertiary)] uppercase", children: "Th\xE8mes disponibles" }),
|
|
1844
|
+
/* @__PURE__ */ jsxs5(
|
|
1271
1845
|
"button",
|
|
1272
1846
|
{
|
|
1273
1847
|
onClick: () => handleThemeChange("elegant"),
|
|
@@ -1277,15 +1851,15 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1277
1851
|
),
|
|
1278
1852
|
role: "menuitem",
|
|
1279
1853
|
children: [
|
|
1280
|
-
/* @__PURE__ */
|
|
1281
|
-
/* @__PURE__ */
|
|
1282
|
-
/* @__PURE__ */
|
|
1283
|
-
/* @__PURE__ */
|
|
1854
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-accent)]" }),
|
|
1855
|
+
/* @__PURE__ */ jsxs5("div", { className: "text-left", children: [
|
|
1856
|
+
/* @__PURE__ */ jsx9("p", { className: "text-sm font-medium", children: "\xC9l\xE9gance Sobre" }),
|
|
1857
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "Finance traditionnelle" })
|
|
1284
1858
|
] })
|
|
1285
1859
|
]
|
|
1286
1860
|
}
|
|
1287
1861
|
),
|
|
1288
|
-
/* @__PURE__ */
|
|
1862
|
+
/* @__PURE__ */ jsxs5(
|
|
1289
1863
|
"button",
|
|
1290
1864
|
{
|
|
1291
1865
|
onClick: () => handleThemeChange("fintech"),
|
|
@@ -1295,15 +1869,15 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1295
1869
|
),
|
|
1296
1870
|
role: "menuitem",
|
|
1297
1871
|
children: [
|
|
1298
|
-
/* @__PURE__ */
|
|
1299
|
-
/* @__PURE__ */
|
|
1300
|
-
/* @__PURE__ */
|
|
1301
|
-
/* @__PURE__ */
|
|
1872
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-success)] to-[var(--color-text-primary)]" }),
|
|
1873
|
+
/* @__PURE__ */ jsxs5("div", { className: "text-left", children: [
|
|
1874
|
+
/* @__PURE__ */ jsx9("p", { className: "text-sm font-medium", children: "Modern Fintech" }),
|
|
1875
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "Tableau de bord moderne" })
|
|
1302
1876
|
] })
|
|
1303
1877
|
]
|
|
1304
1878
|
}
|
|
1305
1879
|
),
|
|
1306
|
-
/* @__PURE__ */
|
|
1880
|
+
/* @__PURE__ */ jsxs5(
|
|
1307
1881
|
"button",
|
|
1308
1882
|
{
|
|
1309
1883
|
onClick: () => handleThemeChange("minimalist"),
|
|
@@ -1313,10 +1887,10 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1313
1887
|
),
|
|
1314
1888
|
role: "menuitem",
|
|
1315
1889
|
children: [
|
|
1316
|
-
/* @__PURE__ */
|
|
1317
|
-
/* @__PURE__ */
|
|
1318
|
-
/* @__PURE__ */
|
|
1319
|
-
/* @__PURE__ */
|
|
1890
|
+
/* @__PURE__ */ jsx9("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-text-secondary)] to-[var(--color-accent)]" }),
|
|
1891
|
+
/* @__PURE__ */ jsxs5("div", { className: "text-left", children: [
|
|
1892
|
+
/* @__PURE__ */ jsx9("p", { className: "text-sm font-medium", children: "Minimaliste Premium" }),
|
|
1893
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "\xC9l\xE9gance minimaliste" })
|
|
1320
1894
|
] })
|
|
1321
1895
|
]
|
|
1322
1896
|
}
|
|
@@ -1325,12 +1899,12 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1325
1899
|
}
|
|
1326
1900
|
)
|
|
1327
1901
|
] }),
|
|
1328
|
-
/* @__PURE__ */
|
|
1329
|
-
/* @__PURE__ */
|
|
1330
|
-
/* @__PURE__ */
|
|
1902
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex items-center px-3 py-1.5 bg-[var(--color-surface)] rounded-lg border border-[var(--color-border)]", children: [
|
|
1903
|
+
/* @__PURE__ */ jsx9(DollarSign, { className: "w-4 h-4 text-[var(--color-primary)] mr-2" }),
|
|
1904
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: "FCFA" })
|
|
1331
1905
|
] }),
|
|
1332
|
-
/* @__PURE__ */
|
|
1333
|
-
/* @__PURE__ */
|
|
1906
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1907
|
+
/* @__PURE__ */ jsxs5(
|
|
1334
1908
|
"button",
|
|
1335
1909
|
{
|
|
1336
1910
|
className: "relative p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
|
|
@@ -1338,20 +1912,20 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1338
1912
|
"aria-label": `Notifications ${notifications.filter((n) => !n.read).length > 0 ? `(${notifications.filter((n) => !n.read).length} non lues)` : ""}`,
|
|
1339
1913
|
"aria-expanded": showNotifications,
|
|
1340
1914
|
children: [
|
|
1341
|
-
/* @__PURE__ */
|
|
1342
|
-
notifications.filter((n) => !n.read).length > 0 && /* @__PURE__ */
|
|
1915
|
+
/* @__PURE__ */ jsx9(Bell, { className: "w-5 h-5 text-[var(--color-text-secondary)]" }),
|
|
1916
|
+
notifications.filter((n) => !n.read).length > 0 && /* @__PURE__ */ jsx9("span", { className: "absolute top-1 right-1 w-2 h-2 bg-[var(--color-error)] rounded-full" })
|
|
1343
1917
|
]
|
|
1344
1918
|
}
|
|
1345
1919
|
),
|
|
1346
|
-
showNotifications && /* @__PURE__ */
|
|
1920
|
+
showNotifications && /* @__PURE__ */ jsxs5(
|
|
1347
1921
|
"div",
|
|
1348
1922
|
{
|
|
1349
1923
|
className: "absolute right-0 mt-2 w-80 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50 max-h-96 overflow-y-auto",
|
|
1350
1924
|
role: "region",
|
|
1351
1925
|
"aria-label": "Centre de notifications",
|
|
1352
1926
|
children: [
|
|
1353
|
-
/* @__PURE__ */
|
|
1354
|
-
/* @__PURE__ */
|
|
1927
|
+
/* @__PURE__ */ jsx9("div", { className: "p-4 border-b border-[var(--color-border)]", children: /* @__PURE__ */ jsx9("h3", { className: "font-semibold text-[var(--color-text-primary)]", children: "Notifications" }) }),
|
|
1928
|
+
/* @__PURE__ */ jsx9("div", { className: "divide-y divide-[var(--color-border)]", children: notifications.map((notif) => /* @__PURE__ */ jsx9(
|
|
1355
1929
|
"div",
|
|
1356
1930
|
{
|
|
1357
1931
|
className: cn(
|
|
@@ -1359,18 +1933,18 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1359
1933
|
!notif.read && "bg-[var(--color-primary-light)] bg-opacity-10"
|
|
1360
1934
|
),
|
|
1361
1935
|
onClick: () => markNotificationAsRead(notif.id),
|
|
1362
|
-
children: /* @__PURE__ */
|
|
1363
|
-
/* @__PURE__ */
|
|
1936
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "flex items-start gap-3", children: [
|
|
1937
|
+
/* @__PURE__ */ jsx9("div", { className: cn(
|
|
1364
1938
|
"w-2 h-2 rounded-full mt-2",
|
|
1365
1939
|
notif.type === "error" && "bg-[var(--color-error)]",
|
|
1366
1940
|
notif.type === "warning" && "bg-[var(--color-warning)]",
|
|
1367
1941
|
notif.type === "success" && "bg-[var(--color-success)]",
|
|
1368
1942
|
notif.type === "info" && "bg-[var(--color-info)]"
|
|
1369
1943
|
) }),
|
|
1370
|
-
/* @__PURE__ */
|
|
1371
|
-
/* @__PURE__ */
|
|
1372
|
-
/* @__PURE__ */
|
|
1373
|
-
/* @__PURE__ */
|
|
1944
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex-1", children: [
|
|
1945
|
+
/* @__PURE__ */ jsx9("p", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: notif.title }),
|
|
1946
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-text-secondary)] mt-1", children: notif.message }),
|
|
1947
|
+
/* @__PURE__ */ jsx9("p", { className: "text-xs text-[var(--color-text-tertiary)] mt-2" })
|
|
1374
1948
|
] })
|
|
1375
1949
|
] })
|
|
1376
1950
|
},
|
|
@@ -1380,36 +1954,36 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1380
1954
|
}
|
|
1381
1955
|
)
|
|
1382
1956
|
] }),
|
|
1383
|
-
/* @__PURE__ */
|
|
1384
|
-
/* @__PURE__ */
|
|
1957
|
+
/* @__PURE__ */ jsxs5("div", { className: "relative", children: [
|
|
1958
|
+
/* @__PURE__ */ jsx9(
|
|
1385
1959
|
"button",
|
|
1386
1960
|
{
|
|
1387
1961
|
onClick: () => setShowUserMenu(!showUserMenu),
|
|
1388
1962
|
className: "flex items-center gap-2 p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
|
|
1389
1963
|
"aria-label": "Menu utilisateur",
|
|
1390
1964
|
"aria-expanded": showUserMenu,
|
|
1391
|
-
children: /* @__PURE__ */
|
|
1965
|
+
children: /* @__PURE__ */ jsx9("div", { className: "w-8 h-8 bg-[var(--color-primary)] rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx9(User, { className: "w-4 h-4 text-[var(--color-background)]" }) })
|
|
1392
1966
|
}
|
|
1393
1967
|
),
|
|
1394
|
-
showUserMenu && /* @__PURE__ */
|
|
1968
|
+
showUserMenu && /* @__PURE__ */ jsx9(
|
|
1395
1969
|
"div",
|
|
1396
1970
|
{
|
|
1397
1971
|
className: "absolute right-0 mt-2 w-56 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50",
|
|
1398
1972
|
role: "menu",
|
|
1399
1973
|
"aria-label": "Menu utilisateur",
|
|
1400
|
-
children: /* @__PURE__ */
|
|
1401
|
-
/* @__PURE__ */
|
|
1974
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "p-2", children: [
|
|
1975
|
+
/* @__PURE__ */ jsxs5(
|
|
1402
1976
|
"button",
|
|
1403
1977
|
{
|
|
1404
1978
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1405
1979
|
role: "menuitem",
|
|
1406
1980
|
children: [
|
|
1407
|
-
/* @__PURE__ */
|
|
1408
|
-
/* @__PURE__ */
|
|
1981
|
+
/* @__PURE__ */ jsx9(User, { className: "w-4 h-4" }),
|
|
1982
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm", children: "Mon profil" })
|
|
1409
1983
|
]
|
|
1410
1984
|
}
|
|
1411
1985
|
),
|
|
1412
|
-
/* @__PURE__ */
|
|
1986
|
+
/* @__PURE__ */ jsxs5(
|
|
1413
1987
|
"button",
|
|
1414
1988
|
{
|
|
1415
1989
|
onClick: () => {
|
|
@@ -1419,31 +1993,31 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1419
1993
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1420
1994
|
role: "menuitem",
|
|
1421
1995
|
children: [
|
|
1422
|
-
/* @__PURE__ */
|
|
1423
|
-
/* @__PURE__ */
|
|
1996
|
+
/* @__PURE__ */ jsx9(Settings, { className: "w-4 h-4" }),
|
|
1997
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm", children: "Param\xE8tres" })
|
|
1424
1998
|
]
|
|
1425
1999
|
}
|
|
1426
2000
|
),
|
|
1427
|
-
/* @__PURE__ */
|
|
2001
|
+
/* @__PURE__ */ jsxs5(
|
|
1428
2002
|
"button",
|
|
1429
2003
|
{
|
|
1430
2004
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1431
2005
|
role: "menuitem",
|
|
1432
2006
|
children: [
|
|
1433
|
-
/* @__PURE__ */
|
|
1434
|
-
/* @__PURE__ */
|
|
2007
|
+
/* @__PURE__ */ jsx9(HelpCircle, { className: "w-4 h-4" }),
|
|
2008
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm", children: "Aide" })
|
|
1435
2009
|
]
|
|
1436
2010
|
}
|
|
1437
2011
|
),
|
|
1438
|
-
/* @__PURE__ */
|
|
1439
|
-
/* @__PURE__ */
|
|
2012
|
+
/* @__PURE__ */ jsx9("hr", { className: "my-2 border-[var(--color-border)]" }),
|
|
2013
|
+
/* @__PURE__ */ jsxs5(
|
|
1440
2014
|
"button",
|
|
1441
2015
|
{
|
|
1442
2016
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] text-[var(--color-error)] transition-colors",
|
|
1443
2017
|
role: "menuitem",
|
|
1444
2018
|
children: [
|
|
1445
|
-
/* @__PURE__ */
|
|
1446
|
-
/* @__PURE__ */
|
|
2019
|
+
/* @__PURE__ */ jsx9(LogOut, { className: "w-4 h-4" }),
|
|
2020
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm", children: "D\xE9connexion" })
|
|
1447
2021
|
]
|
|
1448
2022
|
}
|
|
1449
2023
|
)
|
|
@@ -1455,88 +2029,46 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1455
2029
|
]
|
|
1456
2030
|
}
|
|
1457
2031
|
),
|
|
1458
|
-
/* @__PURE__ */
|
|
2032
|
+
/* @__PURE__ */ jsx9(
|
|
1459
2033
|
"main",
|
|
1460
2034
|
{
|
|
1461
2035
|
id: "main-content",
|
|
1462
2036
|
className: "flex-1 overflow-y-auto bg-[var(--color-background)]",
|
|
1463
2037
|
role: "main",
|
|
1464
|
-
children: /* @__PURE__ */
|
|
2038
|
+
children: /* @__PURE__ */ jsx9("div", { className: "p-3 lg:p-4", children })
|
|
1465
2039
|
}
|
|
1466
2040
|
)
|
|
1467
|
-
] })
|
|
2041
|
+
] }),
|
|
2042
|
+
showApprovalModal && /* @__PURE__ */ jsx9(
|
|
2043
|
+
Modals_default,
|
|
2044
|
+
{
|
|
2045
|
+
title: "NOTIFICATION D'APPROBATION",
|
|
2046
|
+
description: "",
|
|
2047
|
+
open: showApprovalModal,
|
|
2048
|
+
onClose: () => setShowApprovalModal(false),
|
|
2049
|
+
children: /* @__PURE__ */ jsx9(
|
|
2050
|
+
ApprovalAnswerModal,
|
|
2051
|
+
{
|
|
2052
|
+
answer_id: approvalAnswerDetail.answer_id,
|
|
2053
|
+
link_token: approvalAnswerDetail.link_token,
|
|
2054
|
+
object_detail: approvalAnswerDetail.case
|
|
2055
|
+
}
|
|
2056
|
+
)
|
|
2057
|
+
}
|
|
2058
|
+
)
|
|
1468
2059
|
] });
|
|
1469
2060
|
};
|
|
1470
2061
|
var ModernDoubleSidebarLayout_default = RewiseLayout;
|
|
1471
2062
|
|
|
1472
2063
|
// src/components/ui/Toast.tsx
|
|
1473
|
-
import { useEffect as
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
import { createContext as createContext3, useContext as useContext3, useState as useState4, useCallback } from "react";
|
|
1477
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1478
|
-
var ToastContext = createContext3(void 0);
|
|
1479
|
-
var useToast = () => {
|
|
1480
|
-
const context = useContext3(ToastContext);
|
|
1481
|
-
if (!context) {
|
|
1482
|
-
throw new Error("useToast must be used within a ToastProvider");
|
|
1483
|
-
}
|
|
1484
|
-
return context;
|
|
1485
|
-
};
|
|
1486
|
-
var ToastProvider = ({ children }) => {
|
|
1487
|
-
const [toasts, setToasts] = useState4([]);
|
|
1488
|
-
const generateId = () => {
|
|
1489
|
-
return Date.now().toString(36) + Math.random().toString(36).substr(2);
|
|
1490
|
-
};
|
|
1491
|
-
const addToast = useCallback((toast) => {
|
|
1492
|
-
const id = generateId();
|
|
1493
|
-
const newToast = {
|
|
1494
|
-
id,
|
|
1495
|
-
duration: 5e3,
|
|
1496
|
-
...toast
|
|
1497
|
-
};
|
|
1498
|
-
setToasts((prev) => [...prev, newToast]);
|
|
1499
|
-
if (newToast.duration && newToast.duration > 0) {
|
|
1500
|
-
setTimeout(() => {
|
|
1501
|
-
removeToast(id);
|
|
1502
|
-
}, newToast.duration);
|
|
1503
|
-
}
|
|
1504
|
-
}, []);
|
|
1505
|
-
const removeToast = useCallback((id) => {
|
|
1506
|
-
setToasts((prev) => prev.filter((toast) => toast.id !== id));
|
|
1507
|
-
}, []);
|
|
1508
|
-
const success = useCallback((message, duration) => {
|
|
1509
|
-
addToast({ message, type: "success", duration });
|
|
1510
|
-
}, [addToast]);
|
|
1511
|
-
const error = useCallback((message, duration) => {
|
|
1512
|
-
addToast({ message, type: "error", duration });
|
|
1513
|
-
}, [addToast]);
|
|
1514
|
-
const warning = useCallback((message, duration) => {
|
|
1515
|
-
addToast({ message, type: "warning", duration });
|
|
1516
|
-
}, [addToast]);
|
|
1517
|
-
const info = useCallback((message, duration) => {
|
|
1518
|
-
addToast({ message, type: "info", duration });
|
|
1519
|
-
}, [addToast]);
|
|
1520
|
-
const value = {
|
|
1521
|
-
toasts,
|
|
1522
|
-
addToast,
|
|
1523
|
-
removeToast,
|
|
1524
|
-
success,
|
|
1525
|
-
error,
|
|
1526
|
-
warning,
|
|
1527
|
-
info
|
|
1528
|
-
};
|
|
1529
|
-
return /* @__PURE__ */ jsx7(ToastContext.Provider, { value, children });
|
|
1530
|
-
};
|
|
1531
|
-
|
|
1532
|
-
// src/components/ui/Toast.tsx
|
|
1533
|
-
import { CheckCircle, XCircle, AlertTriangle, Info, X as X2 } from "lucide-react";
|
|
1534
|
-
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2064
|
+
import { useEffect as useEffect5, useState as useState6 } from "react";
|
|
2065
|
+
import { CheckCircle as CheckCircle2, XCircle as XCircle2, AlertTriangle, Info, X as X3 } from "lucide-react";
|
|
2066
|
+
import { jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1535
2067
|
var ToastItem = ({ toast }) => {
|
|
1536
2068
|
const { removeToast } = useToast();
|
|
1537
|
-
const [isVisible, setIsVisible] =
|
|
1538
|
-
const [isLeaving, setIsLeaving] =
|
|
1539
|
-
|
|
2069
|
+
const [isVisible, setIsVisible] = useState6(false);
|
|
2070
|
+
const [isLeaving, setIsLeaving] = useState6(false);
|
|
2071
|
+
useEffect5(() => {
|
|
1540
2072
|
const timer = setTimeout(() => setIsVisible(true), 10);
|
|
1541
2073
|
return () => clearTimeout(timer);
|
|
1542
2074
|
}, []);
|
|
@@ -1549,13 +2081,13 @@ var ToastItem = ({ toast }) => {
|
|
|
1549
2081
|
const getIcon = () => {
|
|
1550
2082
|
switch (toast.type) {
|
|
1551
2083
|
case "success":
|
|
1552
|
-
return /* @__PURE__ */
|
|
2084
|
+
return /* @__PURE__ */ jsx10(CheckCircle2, { className: "w-5 h-5 text-green-600" });
|
|
1553
2085
|
case "error":
|
|
1554
|
-
return /* @__PURE__ */
|
|
2086
|
+
return /* @__PURE__ */ jsx10(XCircle2, { className: "w-5 h-5 text-red-600" });
|
|
1555
2087
|
case "warning":
|
|
1556
|
-
return /* @__PURE__ */
|
|
2088
|
+
return /* @__PURE__ */ jsx10(AlertTriangle, { className: "w-5 h-5 text-yellow-600" });
|
|
1557
2089
|
case "info":
|
|
1558
|
-
return /* @__PURE__ */
|
|
2090
|
+
return /* @__PURE__ */ jsx10(Info, { className: "w-5 h-5 text-blue-600" });
|
|
1559
2091
|
}
|
|
1560
2092
|
};
|
|
1561
2093
|
const getBackgroundColor = () => {
|
|
@@ -1570,7 +2102,7 @@ var ToastItem = ({ toast }) => {
|
|
|
1570
2102
|
return "bg-blue-50 border-blue-200";
|
|
1571
2103
|
}
|
|
1572
2104
|
};
|
|
1573
|
-
return /* @__PURE__ */
|
|
2105
|
+
return /* @__PURE__ */ jsxs6(
|
|
1574
2106
|
"div",
|
|
1575
2107
|
{
|
|
1576
2108
|
className: `
|
|
@@ -1581,14 +2113,14 @@ var ToastItem = ({ toast }) => {
|
|
|
1581
2113
|
flex items-start space-x-3
|
|
1582
2114
|
`,
|
|
1583
2115
|
children: [
|
|
1584
|
-
/* @__PURE__ */
|
|
1585
|
-
/* @__PURE__ */
|
|
1586
|
-
/* @__PURE__ */
|
|
2116
|
+
/* @__PURE__ */ jsx10("div", { className: "flex-shrink-0", children: getIcon() }),
|
|
2117
|
+
/* @__PURE__ */ jsx10("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx10("p", { className: "text-sm text-gray-900 font-medium", children: toast.message }) }),
|
|
2118
|
+
/* @__PURE__ */ jsx10(
|
|
1587
2119
|
"button",
|
|
1588
2120
|
{
|
|
1589
2121
|
onClick: handleClose,
|
|
1590
2122
|
className: "flex-shrink-0 ml-4 text-gray-400 hover:text-gray-600 transition-colors",
|
|
1591
|
-
children: /* @__PURE__ */
|
|
2123
|
+
children: /* @__PURE__ */ jsx10(X3, { className: "w-4 h-4" })
|
|
1592
2124
|
}
|
|
1593
2125
|
)
|
|
1594
2126
|
]
|
|
@@ -1597,72 +2129,72 @@ var ToastItem = ({ toast }) => {
|
|
|
1597
2129
|
};
|
|
1598
2130
|
var ToastContainer = () => {
|
|
1599
2131
|
const { toasts } = useToast();
|
|
1600
|
-
return /* @__PURE__ */
|
|
2132
|
+
return /* @__PURE__ */ jsx10("div", { className: "fixed top-4 right-4 z-50 space-y-3", children: toasts.map((toast) => /* @__PURE__ */ jsx10(ToastItem, { toast }, toast.id)) });
|
|
1601
2133
|
};
|
|
1602
2134
|
var Toast_default = ToastContainer;
|
|
1603
2135
|
|
|
1604
2136
|
// src/components/common/Pages.tsx
|
|
1605
2137
|
import { ChevronLeft as ChevronLeft2, Download, Menu as Menu2, Settings as Settings2 } from "lucide-react";
|
|
1606
|
-
import { useState as
|
|
1607
|
-
import { Fragment as
|
|
2138
|
+
import { useState as useState7 } from "react";
|
|
2139
|
+
import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1608
2140
|
var Pages = ({
|
|
1609
2141
|
title = "",
|
|
1610
2142
|
description = "",
|
|
1611
2143
|
sideAction,
|
|
1612
2144
|
sidebar,
|
|
1613
|
-
tabs = /* @__PURE__ */
|
|
2145
|
+
tabs = /* @__PURE__ */ jsx11(Fragment3, {}),
|
|
1614
2146
|
children
|
|
1615
2147
|
}) => {
|
|
1616
|
-
const [sidebarOpen, setSidebarOpen] =
|
|
1617
|
-
return /* @__PURE__ */
|
|
1618
|
-
/* @__PURE__ */
|
|
1619
|
-
/* @__PURE__ */
|
|
1620
|
-
/* @__PURE__ */
|
|
1621
|
-
/* @__PURE__ */
|
|
1622
|
-
/* @__PURE__ */
|
|
1623
|
-
/* @__PURE__ */
|
|
2148
|
+
const [sidebarOpen, setSidebarOpen] = useState7(false);
|
|
2149
|
+
return /* @__PURE__ */ jsxs7("div", { className: "flex h-full bg-gray-100", children: [
|
|
2150
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex-1 flex flex-col", children: [
|
|
2151
|
+
/* @__PURE__ */ jsxs7("div", { className: "bg-white border-b border-gray-200 p-6", children: [
|
|
2152
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
|
|
2153
|
+
/* @__PURE__ */ jsx11("div", { className: "flex items-center space-x-4", children: /* @__PURE__ */ jsxs7("div", { children: [
|
|
2154
|
+
/* @__PURE__ */ jsx11("h1", { className: "text-2xl font-bold text-gray-900", children: title }),
|
|
2155
|
+
/* @__PURE__ */ jsx11("p", { className: "text-sm text-gray-600", children: description })
|
|
1624
2156
|
] }) }),
|
|
1625
|
-
/* @__PURE__ */
|
|
2157
|
+
/* @__PURE__ */ jsx11("div", { className: "flex items-center space-x-3", children: sideAction })
|
|
1626
2158
|
] }),
|
|
1627
2159
|
tabs
|
|
1628
2160
|
] }),
|
|
1629
|
-
/* @__PURE__ */
|
|
2161
|
+
/* @__PURE__ */ jsx11("div", { className: "flex-1 p-6 space-y-6 min-h-[80vh]", children })
|
|
1630
2162
|
] }),
|
|
1631
|
-
sidebar && /* @__PURE__ */
|
|
1632
|
-
/* @__PURE__ */
|
|
1633
|
-
/* @__PURE__ */
|
|
1634
|
-
/* @__PURE__ */
|
|
2163
|
+
sidebar && /* @__PURE__ */ jsxs7("div", { className: `${sidebarOpen ? "w-80" : "w-16"} bg-[var(--color-surface)] border-r border-[var(--color-border)] transition-all duration-300 flex flex-col`, children: [
|
|
2164
|
+
/* @__PURE__ */ jsx11("div", { className: "p-4 ", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
|
|
2165
|
+
/* @__PURE__ */ jsx11("h2", { className: `font-semibold text-[var(--color-text-primary)] ${!sidebarOpen && "hidden"}`, children: "Classes SYSCOHADA" }),
|
|
2166
|
+
/* @__PURE__ */ jsx11(
|
|
1635
2167
|
"button",
|
|
1636
2168
|
{
|
|
1637
2169
|
onClick: () => setSidebarOpen(!sidebarOpen),
|
|
1638
2170
|
className: "p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
|
|
1639
2171
|
"aria-label": sidebarOpen ? "R\xE9duire" : "Ouvrir",
|
|
1640
|
-
children: sidebarOpen ? /* @__PURE__ */
|
|
2172
|
+
children: sidebarOpen ? /* @__PURE__ */ jsx11(ChevronLeft2, { className: "w-5 h-5" }) : /* @__PURE__ */ jsx11(Menu2, { className: "w-5 h-5" })
|
|
1641
2173
|
}
|
|
1642
2174
|
)
|
|
1643
2175
|
] }) }),
|
|
1644
|
-
/* @__PURE__ */
|
|
2176
|
+
/* @__PURE__ */ jsx11("div", { className: "flex-1 overflow-y-auto py-2", children: /* @__PURE__ */ jsx11(
|
|
1645
2177
|
"button",
|
|
1646
2178
|
{
|
|
1647
2179
|
onClick: () => {
|
|
1648
2180
|
},
|
|
1649
2181
|
className: `w-full flex items-center gap-3 px-4 py-3 transition-all relative group hover:bg-[var(--color-surface-hover)]`,
|
|
1650
|
-
children: /* @__PURE__ */
|
|
2182
|
+
children: /* @__PURE__ */ jsx11(
|
|
1651
2183
|
"div",
|
|
1652
2184
|
{
|
|
1653
2185
|
className: `flex-shrink-0 w-10 h-10 rounded-lg flex items-center justify-center transition-colors bg-[var(--color-background)]`,
|
|
1654
|
-
children: /* @__PURE__ */
|
|
2186
|
+
children: /* @__PURE__ */ jsx11("span", { className: "font-bold text-lg", children: 1 })
|
|
1655
2187
|
}
|
|
1656
2188
|
)
|
|
1657
2189
|
}
|
|
1658
2190
|
) }),
|
|
1659
|
-
sidebarOpen && /* @__PURE__ */
|
|
1660
|
-
/* @__PURE__ */
|
|
1661
|
-
/* @__PURE__ */
|
|
2191
|
+
sidebarOpen && /* @__PURE__ */ jsx11("div", { className: "p-4 border-t border-[var(--color-border)]", children: /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
|
|
2192
|
+
/* @__PURE__ */ jsxs7("button", { className: "w-full px-3 py-2 bg-[var(--color-background)] rounded-lg text-sm text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors flex items-center gap-2", children: [
|
|
2193
|
+
/* @__PURE__ */ jsx11(Download, { className: "w-4 h-4" }),
|
|
1662
2194
|
"Exporter le plan"
|
|
1663
2195
|
] }),
|
|
1664
|
-
/* @__PURE__ */
|
|
1665
|
-
/* @__PURE__ */
|
|
2196
|
+
/* @__PURE__ */ jsxs7("button", { className: "w-full px-3 py-2 bg-[var(--color-background)] rounded-lg text-sm text-[var(--color-text-secondary)] hover:bg-[var(--color-surface-hover)] transition-colors flex items-center gap-2", children: [
|
|
2197
|
+
/* @__PURE__ */ jsx11(Settings2, { className: "w-4 h-4" }),
|
|
1666
2198
|
"Configuration"
|
|
1667
2199
|
] })
|
|
1668
2200
|
] }) })
|
|
@@ -1671,34 +2203,11 @@ var Pages = ({
|
|
|
1671
2203
|
};
|
|
1672
2204
|
var Pages_default = Pages;
|
|
1673
2205
|
|
|
1674
|
-
// src/services/UserServices.ts
|
|
1675
|
-
var API_BASE_URL2 = `${API_URL}/core/auth/`;
|
|
1676
|
-
var USERS_API_URL = `${API_URL}/core/users/`;
|
|
1677
|
-
var UserServices = {
|
|
1678
|
-
// Créer un nouvel utilisateur
|
|
1679
|
-
addUser: (data, token) => FetchApi.post(`${API_BASE_URL2}add-user/`, data, token),
|
|
1680
|
-
// Obtenir tous les utilisateurs
|
|
1681
|
-
getUsers: (token) => FetchApi.get(`${USERS_API_URL}`, token),
|
|
1682
|
-
// Obtenir un utilisateur par ID
|
|
1683
|
-
getUser: (id, token) => FetchApi.get(`${USERS_API_URL}${id}/`, token),
|
|
1684
|
-
// Mettre à jour un utilisateur
|
|
1685
|
-
updateUser: (id, data, token) => FetchApi.put(`${USERS_API_URL}${id}/`, data, token),
|
|
1686
|
-
// Supprimer un utilisateur
|
|
1687
|
-
deleteUser: (id, token) => FetchApi.delete(`${USERS_API_URL}${id}/`, token),
|
|
1688
|
-
// Obtenir les utilisateurs d'une entité
|
|
1689
|
-
getEntityUsers: (entityId, token) => FetchApi.get(`${API_URL}/core/entities/${entityId}/users/`, token),
|
|
1690
|
-
// Obtenir les utilisateurs d'une entité
|
|
1691
|
-
getuserEntitiesAccess: (id, token) => FetchApi.get(`${API_URL}/core/entities/`, token),
|
|
1692
|
-
// !!! ce n'est pas la bonne url
|
|
1693
|
-
// Ajouter un utilisateur à une entité
|
|
1694
|
-
addUserToEntity: (entityId, userId, token) => FetchApi.post(`${API_URL}/core/entities/${entityId}/users/`, { user_id: userId }, token)
|
|
1695
|
-
};
|
|
1696
|
-
|
|
1697
2206
|
// src/components/common/FDrawer.tsx
|
|
1698
|
-
import { useEffect as
|
|
1699
|
-
import { useLocation as useLocation2, useNavigate as useNavigate2, useSearchParams, Link as Link2 } from "react-router-dom";
|
|
2207
|
+
import { useEffect as useEffect6, useState as useState8 } from "react";
|
|
2208
|
+
import { useLocation as useLocation2, useNavigate as useNavigate2, useSearchParams as useSearchParams2, Link as Link2 } from "react-router-dom";
|
|
1700
2209
|
import { ArrowDownAZ, ArrowDownUp, ArrowUpAZ, Download as Download2, Filter, MoreVertical, Printer, Search as Search2 } from "lucide-react";
|
|
1701
|
-
import { Fragment as
|
|
2210
|
+
import { Fragment as Fragment4, jsx as jsx12, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1702
2211
|
var FDrawer = ({
|
|
1703
2212
|
children,
|
|
1704
2213
|
apiEndpoint,
|
|
@@ -1708,30 +2217,30 @@ var FDrawer = ({
|
|
|
1708
2217
|
toggle
|
|
1709
2218
|
}) => {
|
|
1710
2219
|
const navigate = useNavigate2();
|
|
1711
|
-
const [searchParams] =
|
|
2220
|
+
const [searchParams] = useSearchParams2();
|
|
1712
2221
|
const location = useLocation2();
|
|
1713
2222
|
const allParams = Object.fromEntries([...searchParams]);
|
|
1714
2223
|
const { activeBusinessEntity, token } = useSession();
|
|
1715
|
-
const [data, setData] =
|
|
1716
|
-
const [order_by, setOrderBy] =
|
|
1717
|
-
const [loading, setLoading] =
|
|
1718
|
-
const [showOrdering, setShowOrdering] =
|
|
1719
|
-
const [showFilters, setShowFilters] =
|
|
1720
|
-
const [dropdownOpen, setDropdownOpen] =
|
|
1721
|
-
const [queryURL, setQueryURL] =
|
|
1722
|
-
const [reponseDetail, setReponseDetail] =
|
|
2224
|
+
const [data, setData] = useState8([]);
|
|
2225
|
+
const [order_by, setOrderBy] = useState8(ordering || "-id");
|
|
2226
|
+
const [loading, setLoading] = useState8(false);
|
|
2227
|
+
const [showOrdering, setShowOrdering] = useState8(null);
|
|
2228
|
+
const [showFilters, setShowFilters] = useState8(null);
|
|
2229
|
+
const [dropdownOpen, setDropdownOpen] = useState8(null);
|
|
2230
|
+
const [queryURL, setQueryURL] = useState8("");
|
|
2231
|
+
const [reponseDetail, setReponseDetail] = useState8({
|
|
1723
2232
|
total_pages: null,
|
|
1724
2233
|
previous: null,
|
|
1725
2234
|
next: null,
|
|
1726
2235
|
current_page: null
|
|
1727
2236
|
});
|
|
1728
|
-
const [searchQuery, setSearchQuery] =
|
|
2237
|
+
const [searchQuery, setSearchQuery] = useState8("");
|
|
1729
2238
|
const makeFilters = () => columns.reduce((acc, item) => {
|
|
1730
2239
|
acc[item.formule ? `${item.search_name}__icontains` : `${item.key}__icontains`] = "";
|
|
1731
2240
|
return acc;
|
|
1732
2241
|
}, {});
|
|
1733
2242
|
const preFilters = columns.length > 0 ? makeFilters() : [];
|
|
1734
|
-
const [filters, setFilters] =
|
|
2243
|
+
const [filters, setFilters] = useState8(
|
|
1735
2244
|
() => Object.keys(allParams).length > 0 ? allParams : { ...preFilters, business_entity_id: activeBusinessEntity?.id ?? null, order_by: order_by ?? "id", page: 1 }
|
|
1736
2245
|
);
|
|
1737
2246
|
const getDataFilter = async () => {
|
|
@@ -1754,12 +2263,12 @@ var FDrawer = ({
|
|
|
1754
2263
|
setLoading(false);
|
|
1755
2264
|
}
|
|
1756
2265
|
};
|
|
1757
|
-
|
|
2266
|
+
useEffect6(() => {
|
|
1758
2267
|
const params = new URLSearchParams(filters).toString();
|
|
1759
2268
|
setQueryURL(`${API_URL}${apiEndpoint}?${params}`);
|
|
1760
2269
|
navigate(`${location.pathname}?${params}`);
|
|
1761
2270
|
}, [filters]);
|
|
1762
|
-
|
|
2271
|
+
useEffect6(() => {
|
|
1763
2272
|
if (!activeBusinessEntity) return;
|
|
1764
2273
|
getDataFilter();
|
|
1765
2274
|
}, [activeBusinessEntity, queryURL, toggle]);
|
|
@@ -1768,7 +2277,7 @@ var FDrawer = ({
|
|
|
1768
2277
|
const handleChange = (key, value) => setFilters({ ...filters, [key]: value, page: 1 });
|
|
1769
2278
|
switch (column.type) {
|
|
1770
2279
|
case "text":
|
|
1771
|
-
return /* @__PURE__ */
|
|
2280
|
+
return /* @__PURE__ */ jsx12(
|
|
1772
2281
|
"input",
|
|
1773
2282
|
{
|
|
1774
2283
|
id: column.key,
|
|
@@ -1780,8 +2289,8 @@ var FDrawer = ({
|
|
|
1780
2289
|
}
|
|
1781
2290
|
);
|
|
1782
2291
|
case "number":
|
|
1783
|
-
return /* @__PURE__ */
|
|
1784
|
-
/* @__PURE__ */
|
|
2292
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex w-full gap-1", children: [
|
|
2293
|
+
/* @__PURE__ */ jsx12(
|
|
1785
2294
|
"input",
|
|
1786
2295
|
{
|
|
1787
2296
|
type: "number",
|
|
@@ -1790,7 +2299,7 @@ var FDrawer = ({
|
|
|
1790
2299
|
onChange: (e) => handleChange(`${column.key}_min`, e.target.value)
|
|
1791
2300
|
}
|
|
1792
2301
|
),
|
|
1793
|
-
/* @__PURE__ */
|
|
2302
|
+
/* @__PURE__ */ jsx12(
|
|
1794
2303
|
"input",
|
|
1795
2304
|
{
|
|
1796
2305
|
type: "number",
|
|
@@ -1801,8 +2310,8 @@ var FDrawer = ({
|
|
|
1801
2310
|
)
|
|
1802
2311
|
] });
|
|
1803
2312
|
case "date":
|
|
1804
|
-
return /* @__PURE__ */
|
|
1805
|
-
/* @__PURE__ */
|
|
2313
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex w-full gap-1", children: [
|
|
2314
|
+
/* @__PURE__ */ jsx12(
|
|
1806
2315
|
"input",
|
|
1807
2316
|
{
|
|
1808
2317
|
type: "date",
|
|
@@ -1811,7 +2320,7 @@ var FDrawer = ({
|
|
|
1811
2320
|
onChange: (e) => handleChange(`${column.key}_from`, e.target.value)
|
|
1812
2321
|
}
|
|
1813
2322
|
),
|
|
1814
|
-
/* @__PURE__ */
|
|
2323
|
+
/* @__PURE__ */ jsx12(
|
|
1815
2324
|
"input",
|
|
1816
2325
|
{
|
|
1817
2326
|
type: "date",
|
|
@@ -1822,7 +2331,7 @@ var FDrawer = ({
|
|
|
1822
2331
|
)
|
|
1823
2332
|
] });
|
|
1824
2333
|
default:
|
|
1825
|
-
return /* @__PURE__ */
|
|
2334
|
+
return /* @__PURE__ */ jsx12(
|
|
1826
2335
|
"input",
|
|
1827
2336
|
{
|
|
1828
2337
|
id: column.key,
|
|
@@ -1837,13 +2346,13 @@ var FDrawer = ({
|
|
|
1837
2346
|
let cellContent = column.formule ? column.formule(item) : item[column.key];
|
|
1838
2347
|
if (column.type === "date" && item[column.key])
|
|
1839
2348
|
cellContent = new Date(item[column.key]).toLocaleDateString();
|
|
1840
|
-
return /* @__PURE__ */
|
|
2349
|
+
return /* @__PURE__ */ jsx12("td", { className: "px-6 py-4 whitespace-nowrap text-sm text-gray-500", children: cellContent }, column.key);
|
|
1841
2350
|
});
|
|
1842
|
-
return /* @__PURE__ */
|
|
1843
|
-
/* @__PURE__ */
|
|
1844
|
-
/* @__PURE__ */
|
|
1845
|
-
/* @__PURE__ */
|
|
1846
|
-
/* @__PURE__ */
|
|
2351
|
+
return /* @__PURE__ */ jsxs8(Fragment4, { children: [
|
|
2352
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-wrap gap-4", children: [
|
|
2353
|
+
/* @__PURE__ */ jsx12("div", { className: "flex-1 min-w-64", children: /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
2354
|
+
/* @__PURE__ */ jsx12(Search2, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 h-4 w-4" }),
|
|
2355
|
+
/* @__PURE__ */ jsx12(
|
|
1847
2356
|
"input",
|
|
1848
2357
|
{
|
|
1849
2358
|
type: "text",
|
|
@@ -1854,49 +2363,49 @@ var FDrawer = ({
|
|
|
1854
2363
|
}
|
|
1855
2364
|
)
|
|
1856
2365
|
] }) }),
|
|
1857
|
-
/* @__PURE__ */
|
|
2366
|
+
/* @__PURE__ */ jsxs8(
|
|
1858
2367
|
Buttons_default,
|
|
1859
2368
|
{
|
|
1860
2369
|
onClick: () => {
|
|
1861
2370
|
},
|
|
1862
2371
|
children: [
|
|
1863
|
-
/* @__PURE__ */
|
|
2372
|
+
/* @__PURE__ */ jsx12(Filter, { className: "h-4 w-4 mr-2" }),
|
|
1864
2373
|
"Filtres"
|
|
1865
2374
|
]
|
|
1866
2375
|
}
|
|
1867
2376
|
),
|
|
1868
|
-
/* @__PURE__ */
|
|
2377
|
+
/* @__PURE__ */ jsxs8(
|
|
1869
2378
|
Buttons_default,
|
|
1870
2379
|
{
|
|
1871
2380
|
onClick: () => {
|
|
1872
2381
|
},
|
|
1873
2382
|
children: [
|
|
1874
|
-
/* @__PURE__ */
|
|
2383
|
+
/* @__PURE__ */ jsx12(Download2, { className: "h-4 w-4 mr-2" }),
|
|
1875
2384
|
"Exporter"
|
|
1876
2385
|
]
|
|
1877
2386
|
}
|
|
1878
2387
|
),
|
|
1879
|
-
/* @__PURE__ */
|
|
2388
|
+
/* @__PURE__ */ jsxs8(
|
|
1880
2389
|
Buttons_default,
|
|
1881
2390
|
{
|
|
1882
2391
|
onClick: () => {
|
|
1883
2392
|
},
|
|
1884
2393
|
children: [
|
|
1885
|
-
/* @__PURE__ */
|
|
2394
|
+
/* @__PURE__ */ jsx12(Printer, { className: "h-4 w-4 mr-2" }),
|
|
1886
2395
|
"Imprimer"
|
|
1887
2396
|
]
|
|
1888
2397
|
}
|
|
1889
2398
|
)
|
|
1890
2399
|
] }),
|
|
1891
|
-
/* @__PURE__ */
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
columns.map((column) => /* @__PURE__ */
|
|
1894
|
-
/* @__PURE__ */
|
|
1895
|
-
/* @__PURE__ */
|
|
1896
|
-
column.sortable && /* @__PURE__ */
|
|
2400
|
+
/* @__PURE__ */ jsxs8("table", { className: "w-full", children: [
|
|
2401
|
+
/* @__PURE__ */ jsx12("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxs8("tr", { children: [
|
|
2402
|
+
columns.map((column) => /* @__PURE__ */ jsxs8("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider relative", scope: "col", children: [
|
|
2403
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex align-center items-center gap-2", children: [
|
|
2404
|
+
/* @__PURE__ */ jsx12("span", { onClick: () => setShowFilters(showFilters === column.key ? "" : column.key), children: column.label }),
|
|
2405
|
+
column.sortable && /* @__PURE__ */ jsx12(ArrowDownUp, { className: "h-4 w-4 cursor-pointer", onClick: () => setShowOrdering(showOrdering === column.key ? "" : column.key) })
|
|
1897
2406
|
] }),
|
|
1898
|
-
showOrdering === column.key && /* @__PURE__ */
|
|
1899
|
-
/* @__PURE__ */
|
|
2407
|
+
showOrdering === column.key && /* @__PURE__ */ jsx12("div", { className: "absolute left-6 mt-2 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50 max-h-80 overflow-y-auto", role: "menu", children: /* @__PURE__ */ jsxs8("div", { className: "p-2", children: [
|
|
2408
|
+
/* @__PURE__ */ jsx12(
|
|
1900
2409
|
"button",
|
|
1901
2410
|
{
|
|
1902
2411
|
type: "button",
|
|
@@ -1907,13 +2416,13 @@ var FDrawer = ({
|
|
|
1907
2416
|
},
|
|
1908
2417
|
className: cn("w-full flex items-center gap-3 px-3 py-1 border-b rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors", order_by === column.key && "bg-[var(--color-primary-light)]"),
|
|
1909
2418
|
role: "menuitem",
|
|
1910
|
-
children: /* @__PURE__ */
|
|
1911
|
-
/* @__PURE__ */
|
|
1912
|
-
/* @__PURE__ */
|
|
2419
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "text-left flex-1 flex items-center gap-2", children: [
|
|
2420
|
+
/* @__PURE__ */ jsx12(ArrowUpAZ, { className: "h-4 w-4" }),
|
|
2421
|
+
/* @__PURE__ */ jsx12("p", { className: cn("text-sm font-medium", order_by === column.key ? "text-[var(--color-primary)]" : "text-[var(--color-text-primary)]"), children: "Croissant" })
|
|
1913
2422
|
] })
|
|
1914
2423
|
}
|
|
1915
2424
|
),
|
|
1916
|
-
/* @__PURE__ */
|
|
2425
|
+
/* @__PURE__ */ jsx12(
|
|
1917
2426
|
"button",
|
|
1918
2427
|
{
|
|
1919
2428
|
type: "button",
|
|
@@ -1924,34 +2433,34 @@ var FDrawer = ({
|
|
|
1924
2433
|
},
|
|
1925
2434
|
className: cn("w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors", order_by === `-${column.key}` && "bg-[var(--color-primary-light)]"),
|
|
1926
2435
|
role: "menuitem",
|
|
1927
|
-
children: /* @__PURE__ */
|
|
1928
|
-
/* @__PURE__ */
|
|
1929
|
-
/* @__PURE__ */
|
|
2436
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "text-left flex-1 flex items-center gap-2", children: [
|
|
2437
|
+
/* @__PURE__ */ jsx12(ArrowDownAZ, { className: "h-4 w-4" }),
|
|
2438
|
+
/* @__PURE__ */ jsx12("p", { className: cn("text-sm font-medium", order_by === `-${column.key}` ? "text-[var(--color-primary)]" : "text-[var(--color-text-primary)]"), children: "D\xE9croissant" })
|
|
1930
2439
|
] })
|
|
1931
2440
|
}
|
|
1932
2441
|
)
|
|
1933
2442
|
] }) }),
|
|
1934
|
-
showFilters === column.key && /* @__PURE__ */
|
|
1935
|
-
/* @__PURE__ */
|
|
1936
|
-
/* @__PURE__ */
|
|
2443
|
+
showFilters === column.key && /* @__PURE__ */ jsxs8("div", { className: "absolute left-6 mt-2 w-[500px] bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50 max-h-80 overflow-y-auto", role: "menu", children: [
|
|
2444
|
+
/* @__PURE__ */ jsx12("div", { className: "py-2 px-4", children: /* @__PURE__ */ jsx12("h3", { className: "font-semibold text-[var(--color-text-primary)]", children: "Filtrer" }) }),
|
|
2445
|
+
/* @__PURE__ */ jsx12("div", { className: "pb-3 px-4", children: renderColumnFilter(column) })
|
|
1937
2446
|
] })
|
|
1938
2447
|
] }, column.key)),
|
|
1939
|
-
/* @__PURE__ */
|
|
2448
|
+
/* @__PURE__ */ jsx12("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" })
|
|
1940
2449
|
] }) }),
|
|
1941
|
-
/* @__PURE__ */
|
|
2450
|
+
/* @__PURE__ */ jsx12("tbody", { className: "bg-white divide-y divide-gray-200", children: data.map((item) => /* @__PURE__ */ jsxs8("tr", { className: "hover:bg-gray-50 cursor-pointer", children: [
|
|
1942
2451
|
renderLine(item),
|
|
1943
|
-
/* @__PURE__ */
|
|
1944
|
-
/* @__PURE__ */
|
|
2452
|
+
/* @__PURE__ */ jsx12("td", { className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium", children: /* @__PURE__ */ jsxs8("div", { className: "relative", children: [
|
|
2453
|
+
/* @__PURE__ */ jsx12(
|
|
1945
2454
|
"button",
|
|
1946
2455
|
{
|
|
1947
2456
|
type: "button",
|
|
1948
2457
|
onClick: () => setDropdownOpen(dropdownOpen === item.id ? null : item.id),
|
|
1949
2458
|
className: "p-1 rounded-full hover:bg-gray-100 transition-colors",
|
|
1950
|
-
children: /* @__PURE__ */
|
|
2459
|
+
children: /* @__PURE__ */ jsx12(MoreVertical, { className: "w-4 h-4 text-gray-400" })
|
|
1951
2460
|
}
|
|
1952
2461
|
),
|
|
1953
|
-
dropdownOpen === item.id && /* @__PURE__ */
|
|
1954
|
-
(action, index) => action.navigate ? /* @__PURE__ */
|
|
2462
|
+
dropdownOpen === item.id && /* @__PURE__ */ jsx12("div", { className: "fixed right-3 mt-2 w-48 bg-white rounded-lg shadow-lg border border-gray-200 py-2 z-10", children: actions.map(
|
|
2463
|
+
(action, index) => action.navigate ? /* @__PURE__ */ jsx12(Link2, { to: action.navigate, className: "w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center space-x-2", children: action.label }, index) : /* @__PURE__ */ jsx12("button", { onClick: () => {
|
|
1955
2464
|
action.onclick(item);
|
|
1956
2465
|
setDropdownOpen(null);
|
|
1957
2466
|
}, className: "w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center space-x-2", children: action.label }, index)
|
|
@@ -1959,7 +2468,7 @@ var FDrawer = ({
|
|
|
1959
2468
|
] }) })
|
|
1960
2469
|
] }, item.id)) })
|
|
1961
2470
|
] }),
|
|
1962
|
-
/* @__PURE__ */
|
|
2471
|
+
/* @__PURE__ */ jsx12(Pagination, { reponseDetail, setQueryURL, filters: [filters, setFilters] })
|
|
1963
2472
|
] });
|
|
1964
2473
|
};
|
|
1965
2474
|
var Pagination = ({
|
|
@@ -1974,27 +2483,27 @@ var Pagination = ({
|
|
|
1974
2483
|
if (total_pages <= 5) {
|
|
1975
2484
|
for (let i = 1; i <= total_pages; i++)
|
|
1976
2485
|
pageItems.push(
|
|
1977
|
-
/* @__PURE__ */
|
|
2486
|
+
/* @__PURE__ */ jsx12("li", { className: `page-item ${current_page === i ? "active" : ""}`, children: /* @__PURE__ */ jsx12(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: i }), children: i }) }, i)
|
|
1978
2487
|
);
|
|
1979
2488
|
} else {
|
|
1980
2489
|
let start = Math.max(1, current_page - range);
|
|
1981
2490
|
let end = Math.min(total_pages, current_page + range);
|
|
1982
2491
|
if (start > 1) {
|
|
1983
2492
|
pageItems.push(
|
|
1984
|
-
/* @__PURE__ */
|
|
2493
|
+
/* @__PURE__ */ jsx12("li", { className: `page-item ${current_page === 1 ? "active" : ""}`, children: /* @__PURE__ */ jsx12(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: 1 }), children: "1" }) }, 1)
|
|
1985
2494
|
);
|
|
1986
2495
|
if (start > 2)
|
|
1987
|
-
pageItems.push(/* @__PURE__ */
|
|
2496
|
+
pageItems.push(/* @__PURE__ */ jsx12("li", { className: "page-item disabled", children: /* @__PURE__ */ jsx12("span", { className: "page-link px-3 py-1 text-sm", children: "..." }) }, "ellipsis-start"));
|
|
1988
2497
|
}
|
|
1989
2498
|
for (let i = start; i <= end; i++)
|
|
1990
2499
|
pageItems.push(
|
|
1991
|
-
/* @__PURE__ */
|
|
2500
|
+
/* @__PURE__ */ jsx12("li", { className: `page-item ${current_page === i ? "active" : ""}`, children: /* @__PURE__ */ jsx12(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: i }), children: i }) }, i)
|
|
1992
2501
|
);
|
|
1993
2502
|
if (end < total_pages) {
|
|
1994
2503
|
if (end < total_pages - 1)
|
|
1995
|
-
pageItems.push(/* @__PURE__ */
|
|
2504
|
+
pageItems.push(/* @__PURE__ */ jsx12("li", { className: "page-item disabled", children: /* @__PURE__ */ jsx12("span", { className: "page-link px-3 py-1 text-sm", children: "..." }) }, "ellipsis-end"));
|
|
1996
2505
|
pageItems.push(
|
|
1997
|
-
/* @__PURE__ */
|
|
2506
|
+
/* @__PURE__ */ jsx12("li", { className: `page-item ${current_page === total_pages ? "active" : ""}`, children: /* @__PURE__ */ jsx12(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: total_pages }), children: total_pages }) }, total_pages)
|
|
1998
2507
|
);
|
|
1999
2508
|
}
|
|
2000
2509
|
}
|
|
@@ -2005,32 +2514,1005 @@ var Pagination = ({
|
|
|
2005
2514
|
if (newPage >= 1 && newPage <= total_pages)
|
|
2006
2515
|
setFilters({ ...filtersValue, page: newPage });
|
|
2007
2516
|
};
|
|
2008
|
-
return /* @__PURE__ */
|
|
2009
|
-
/* @__PURE__ */
|
|
2517
|
+
return /* @__PURE__ */ jsxs8("div", { className: "p-4 border-t border-[#E8E8E8] flex items-center justify-between", children: [
|
|
2518
|
+
/* @__PURE__ */ jsxs8("span", { className: "text-sm text-[#666666]", children: [
|
|
2010
2519
|
"Affichage de 1 \xE0 ",
|
|
2011
2520
|
results?.length ?? 0,
|
|
2012
2521
|
" sur ",
|
|
2013
2522
|
count ?? 0,
|
|
2014
2523
|
" entr\xE9es"
|
|
2015
2524
|
] }),
|
|
2016
|
-
/* @__PURE__ */
|
|
2017
|
-
/* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsx12("nav", { children: /* @__PURE__ */ jsxs8("ul", { className: "flex items-center space-x-2 pagination", children: [
|
|
2526
|
+
/* @__PURE__ */ jsx12("li", { className: `page-item ${previous === null ? "disabled" : ""}`, children: /* @__PURE__ */ jsx12(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm disabled:opacity-50", to: "#", onClick: () => handleChangePage("previous"), tabIndex: -1, "aria-disabled": previous === null, children: "Pr\xE9c\xE9dent" }) }),
|
|
2018
2527
|
pageItems,
|
|
2019
|
-
/* @__PURE__ */
|
|
2020
|
-
/* @__PURE__ */
|
|
2528
|
+
/* @__PURE__ */ jsx12("li", { className: `page-item ${next === null ? "disabled" : ""}`, children: /* @__PURE__ */ jsx12(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm disabled:opacity-50", to: "#", onClick: () => handleChangePage("next"), "aria-disabled": next === null, children: "Suivant" }) }),
|
|
2529
|
+
/* @__PURE__ */ jsx12("li", { className: "page-item", style: { border: "0.02rem solid #f2f2f2" }, children: /* @__PURE__ */ jsx12(
|
|
2021
2530
|
"select",
|
|
2022
2531
|
{
|
|
2023
2532
|
id: "page-select",
|
|
2024
2533
|
value: current_page,
|
|
2025
2534
|
onChange: (e) => setFilters({ ...filtersValue, page: Number(e.target.value) }),
|
|
2026
2535
|
style: { height: "27px", color: "#72939D", border: "0.05rem solid #f2f2f2", background: "#ffffff" },
|
|
2027
|
-
children: Array.from({ length: total_pages }, (_, index) => /* @__PURE__ */
|
|
2536
|
+
children: Array.from({ length: total_pages }, (_, index) => /* @__PURE__ */ jsx12("option", { value: index + 1, children: index + 1 }, index + 1))
|
|
2028
2537
|
}
|
|
2029
2538
|
) })
|
|
2030
2539
|
] }) })
|
|
2031
2540
|
] });
|
|
2032
2541
|
};
|
|
2542
|
+
|
|
2543
|
+
// src/components/common/ApprovalWorkflow.tsx
|
|
2544
|
+
import { useState as useState10, useEffect as useEffect8 } from "react";
|
|
2545
|
+
|
|
2546
|
+
// src/components/common/SearchableSelect.tsx
|
|
2547
|
+
import { useState as useState9, useRef, useEffect as useEffect7 } from "react";
|
|
2548
|
+
import { Search as Search3, ChevronDown, X as X4 } from "lucide-react";
|
|
2549
|
+
import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2550
|
+
var SearchableSelect = ({
|
|
2551
|
+
options,
|
|
2552
|
+
value,
|
|
2553
|
+
placeholder = "S\xE9lectionner une option",
|
|
2554
|
+
searchPlaceholder = "Rechercher...",
|
|
2555
|
+
onSelect,
|
|
2556
|
+
onRemove,
|
|
2557
|
+
disabled = false,
|
|
2558
|
+
allowClear = false,
|
|
2559
|
+
filterFunction
|
|
2560
|
+
}) => {
|
|
2561
|
+
const [isOpen, setIsOpen] = useState9(false);
|
|
2562
|
+
const [searchTerm, setSearchTerm] = useState9("");
|
|
2563
|
+
const dropdownRef = useRef(null);
|
|
2564
|
+
const inputRef = useRef(null);
|
|
2565
|
+
const selectedOption = options.find((option) => option.value === value);
|
|
2566
|
+
const defaultFilter = (option, searchTerm2) => {
|
|
2567
|
+
return option.label.toLowerCase().includes(searchTerm2.toLowerCase());
|
|
2568
|
+
};
|
|
2569
|
+
const filteredOptions = options.filter(
|
|
2570
|
+
(option) => filterFunction ? filterFunction(option, searchTerm) : defaultFilter(option, searchTerm)
|
|
2571
|
+
);
|
|
2572
|
+
useEffect7(() => {
|
|
2573
|
+
const handleClickOutside = (event) => {
|
|
2574
|
+
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
2575
|
+
setIsOpen(false);
|
|
2576
|
+
setSearchTerm("");
|
|
2577
|
+
}
|
|
2578
|
+
};
|
|
2579
|
+
document.addEventListener("mousedown", handleClickOutside);
|
|
2580
|
+
return () => document.removeEventListener("mousedown", handleClickOutside);
|
|
2581
|
+
}, []);
|
|
2582
|
+
const handleSelect = (option) => {
|
|
2583
|
+
onSelect(option);
|
|
2584
|
+
setIsOpen(false);
|
|
2585
|
+
setSearchTerm("");
|
|
2586
|
+
};
|
|
2587
|
+
const handleClear = (e) => {
|
|
2588
|
+
e.stopPropagation();
|
|
2589
|
+
if (onRemove) {
|
|
2590
|
+
onRemove();
|
|
2591
|
+
}
|
|
2592
|
+
};
|
|
2593
|
+
const handleToggle = () => {
|
|
2594
|
+
if (!disabled) {
|
|
2595
|
+
setIsOpen(!isOpen);
|
|
2596
|
+
if (!isOpen) {
|
|
2597
|
+
setTimeout(() => inputRef.current?.focus(), 100);
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
};
|
|
2601
|
+
return /* @__PURE__ */ jsxs9("div", { className: "relative", ref: dropdownRef, children: [
|
|
2602
|
+
/* @__PURE__ */ jsx13(
|
|
2603
|
+
"div",
|
|
2604
|
+
{
|
|
2605
|
+
onClick: handleToggle,
|
|
2606
|
+
className: `
|
|
2607
|
+
w-full px-4 py-3 border border-gray-200 rounded-lg cursor-pointer
|
|
2608
|
+
focus:outline-none focus:ring-2 focus:ring-[#6B7C92] focus:border-transparent
|
|
2609
|
+
${disabled ? "bg-gray-100 cursor-not-allowed" : "bg-white hover:border-gray-300"}
|
|
2610
|
+
${isOpen ? "ring-2 ring-[#6B7C92] border-transparent" : ""}
|
|
2611
|
+
`,
|
|
2612
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
|
|
2613
|
+
/* @__PURE__ */ jsx13("div", { className: "flex items-center space-x-2 flex-1", children: selectedOption ? /* @__PURE__ */ jsxs9(Fragment5, { children: [
|
|
2614
|
+
selectedOption.image && /* @__PURE__ */ jsx13(
|
|
2615
|
+
"img",
|
|
2616
|
+
{
|
|
2617
|
+
src: selectedOption.image,
|
|
2618
|
+
alt: selectedOption.label,
|
|
2619
|
+
className: "w-6 h-6 rounded-full object-cover"
|
|
2620
|
+
}
|
|
2621
|
+
),
|
|
2622
|
+
selectedOption.content || /* @__PURE__ */ jsx13("span", { className: "text-gray-900", children: selectedOption.label })
|
|
2623
|
+
] }) : /* @__PURE__ */ jsx13("span", { className: "text-gray-400", children: placeholder }) }),
|
|
2624
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center space-x-2", children: [
|
|
2625
|
+
allowClear && selectedOption && /* @__PURE__ */ jsx13(
|
|
2626
|
+
"button",
|
|
2627
|
+
{
|
|
2628
|
+
onClick: handleClear,
|
|
2629
|
+
className: "text-gray-400 hover:text-gray-600",
|
|
2630
|
+
type: "button",
|
|
2631
|
+
children: /* @__PURE__ */ jsx13(X4, { size: 16 })
|
|
2632
|
+
}
|
|
2633
|
+
),
|
|
2634
|
+
/* @__PURE__ */ jsx13(
|
|
2635
|
+
ChevronDown,
|
|
2636
|
+
{
|
|
2637
|
+
size: 16,
|
|
2638
|
+
className: `text-gray-400 transition-transform ${isOpen ? "rotate-180" : ""}`
|
|
2639
|
+
}
|
|
2640
|
+
)
|
|
2641
|
+
] })
|
|
2642
|
+
] })
|
|
2643
|
+
}
|
|
2644
|
+
),
|
|
2645
|
+
isOpen && /* @__PURE__ */ jsxs9("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg", children: [
|
|
2646
|
+
/* @__PURE__ */ jsx13("div", { className: "p-3 border-b border-gray-200", children: /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
|
|
2647
|
+
/* @__PURE__ */ jsx13(Search3, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" }),
|
|
2648
|
+
/* @__PURE__ */ jsx13(
|
|
2649
|
+
"input",
|
|
2650
|
+
{
|
|
2651
|
+
ref: inputRef,
|
|
2652
|
+
type: "text",
|
|
2653
|
+
placeholder: searchPlaceholder,
|
|
2654
|
+
value: searchTerm,
|
|
2655
|
+
onChange: (e) => setSearchTerm(e.target.value),
|
|
2656
|
+
className: "w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-[#6B7C92] focus:border-transparent"
|
|
2657
|
+
}
|
|
2658
|
+
)
|
|
2659
|
+
] }) }),
|
|
2660
|
+
/* @__PURE__ */ jsx13("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => /* @__PURE__ */ jsxs9(
|
|
2661
|
+
"div",
|
|
2662
|
+
{
|
|
2663
|
+
onClick: () => handleSelect(option),
|
|
2664
|
+
className: "px-4 py-3 hover:bg-gray-50 cursor-pointer flex items-center space-x-3",
|
|
2665
|
+
children: [
|
|
2666
|
+
option.image && /* @__PURE__ */ jsx13(
|
|
2667
|
+
"img",
|
|
2668
|
+
{
|
|
2669
|
+
src: option.image,
|
|
2670
|
+
alt: option.label,
|
|
2671
|
+
className: "w-8 h-8 rounded-full object-cover"
|
|
2672
|
+
}
|
|
2673
|
+
),
|
|
2674
|
+
option.content || /* @__PURE__ */ jsx13("span", { className: "text-gray-900", children: option.label })
|
|
2675
|
+
]
|
|
2676
|
+
},
|
|
2677
|
+
option.value
|
|
2678
|
+
)) : /* @__PURE__ */ jsx13("div", { className: "px-4 py-3 text-gray-500 text-center", children: "Aucun r\xE9sultat trouv\xE9" }) })
|
|
2679
|
+
] })
|
|
2680
|
+
] });
|
|
2681
|
+
};
|
|
2682
|
+
|
|
2683
|
+
// src/components/common/ApprovalWorkflow.tsx
|
|
2684
|
+
import { X as X5, Plus as Plus2, Trash2 as Trash22, Users as Users2, Loader as Loader2, RotateCcw as RotateCcw2, Ban as Ban2, Eye as Eye2, FileText as FileText2, History as History2 } from "lucide-react";
|
|
2685
|
+
import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2686
|
+
var ApprovalWorkflow = ({
|
|
2687
|
+
process,
|
|
2688
|
+
object_id,
|
|
2689
|
+
title = "Validation t\xE2che",
|
|
2690
|
+
readOnly = false
|
|
2691
|
+
}) => {
|
|
2692
|
+
const { token, loggedUser } = useSession();
|
|
2693
|
+
const { error: showError, success: showSuccess } = useToast();
|
|
2694
|
+
const [activeTab, setActiveTab] = useState10("workflow");
|
|
2695
|
+
const [loading, setLoading] = useState10(true);
|
|
2696
|
+
const [caseData, setCaseData] = useState10(null);
|
|
2697
|
+
const [history, setHistory] = useState10([]);
|
|
2698
|
+
const [loadingHistory, setLoadingHistory] = useState10(false);
|
|
2699
|
+
const [formData, setFormData] = useState10({
|
|
2700
|
+
title: "",
|
|
2701
|
+
file: null,
|
|
2702
|
+
description: "",
|
|
2703
|
+
status: "not-send" /* NOT_SEND */
|
|
2704
|
+
});
|
|
2705
|
+
const [users, setUsers] = useState10([]);
|
|
2706
|
+
const [loadingUsers, setLoadingUsers] = useState10(false);
|
|
2707
|
+
const [saving, setSaving] = useState10(false);
|
|
2708
|
+
const [transmitting, setTransmitting] = useState10(false);
|
|
2709
|
+
const [canceling, setCanceling] = useState10(false);
|
|
2710
|
+
const [restarting, setRestarting] = useState10(false);
|
|
2711
|
+
const [verification, setVerification] = useState10([]);
|
|
2712
|
+
const [validation, setValidation] = useState10([]);
|
|
2713
|
+
useEffect8(() => {
|
|
2714
|
+
loadData();
|
|
2715
|
+
}, [process, object_id]);
|
|
2716
|
+
const loadData = async () => {
|
|
2717
|
+
if (!token) {
|
|
2718
|
+
showError("Vous devez \xEAtre connect\xE9");
|
|
2719
|
+
return;
|
|
2720
|
+
}
|
|
2721
|
+
setLoading(true);
|
|
2722
|
+
try {
|
|
2723
|
+
await Promise.all([loadUsers(), loadCase()]);
|
|
2724
|
+
} catch (error) {
|
|
2725
|
+
console.error("Erreur lors du chargement:", error);
|
|
2726
|
+
} finally {
|
|
2727
|
+
setLoading(false);
|
|
2728
|
+
}
|
|
2729
|
+
};
|
|
2730
|
+
const loadUsers = async () => {
|
|
2731
|
+
if (!token) return;
|
|
2732
|
+
try {
|
|
2733
|
+
setLoadingUsers(true);
|
|
2734
|
+
const result = await UserServices.getUsers(token);
|
|
2735
|
+
setUsers(result.data);
|
|
2736
|
+
} catch (error) {
|
|
2737
|
+
showError("Erreur lors du chargement des utilisateurs");
|
|
2738
|
+
console.error(error);
|
|
2739
|
+
} finally {
|
|
2740
|
+
setLoadingUsers(false);
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2743
|
+
const loadCase = async () => {
|
|
2744
|
+
if (!token) return;
|
|
2745
|
+
try {
|
|
2746
|
+
const response = await ApprovalServices.getDetails(process, object_id, token);
|
|
2747
|
+
if (response.success && response.data) {
|
|
2748
|
+
const caseInfo = response.data;
|
|
2749
|
+
setCaseData(caseInfo);
|
|
2750
|
+
setFormData({
|
|
2751
|
+
title: caseInfo.title || "",
|
|
2752
|
+
file: null,
|
|
2753
|
+
description: caseInfo.description || "",
|
|
2754
|
+
status: caseInfo.status
|
|
2755
|
+
});
|
|
2756
|
+
if (caseInfo.verifications) {
|
|
2757
|
+
setVerification(caseInfo.verifications.map((v, index) => ({
|
|
2758
|
+
id: v.id,
|
|
2759
|
+
stage: index + 1,
|
|
2760
|
+
space_answer: "internal",
|
|
2761
|
+
user: v.user,
|
|
2762
|
+
name: v.user_detail ? `${v.user_detail?.first_name} ${v.user_detail?.last_name}` : "",
|
|
2763
|
+
email: v.user_detail?.email || "",
|
|
2764
|
+
role: v.user_detail?.phonenumber || "-",
|
|
2765
|
+
status: v.answer === "approved" /* APPROVED */ ? "approved" : v.answer === "refused" /* REFUSED */ ? "rejected" : "pending",
|
|
2766
|
+
answer: v.answer === "approved" /* APPROVED */ ? 2 : v.answer === "waiting" /* WAITING */ ? 1 : v.answer === "refused" /* REFUSED */ ? -1 : 0,
|
|
2767
|
+
rank: v.rank,
|
|
2768
|
+
note: v.note
|
|
2769
|
+
})));
|
|
2770
|
+
}
|
|
2771
|
+
if (caseInfo.validations) {
|
|
2772
|
+
setValidation(caseInfo.validations.map((v, index) => ({
|
|
2773
|
+
id: v.id,
|
|
2774
|
+
stage: index + 1,
|
|
2775
|
+
space_answer: "internal",
|
|
2776
|
+
user: v.user,
|
|
2777
|
+
name: v.user_detail ? `${v.user_detail.first_name} ${v.user_detail.last_name}` : "",
|
|
2778
|
+
email: v.user_detail?.email || "",
|
|
2779
|
+
role: v.user_detail?.phonenumber || "-",
|
|
2780
|
+
status: v.answer === "approved" /* APPROVED */ ? "approved" : v.answer === "refused" /* REFUSED */ ? "rejected" : "pending",
|
|
2781
|
+
answer: v.answer === "approved" /* APPROVED */ ? 2 : v.answer === "waiting" /* WAITING */ ? 1 : v.answer === "refused" /* REFUSED */ ? -1 : 0,
|
|
2782
|
+
rank: v.rank,
|
|
2783
|
+
note: v.note
|
|
2784
|
+
})));
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
} catch (error) {
|
|
2788
|
+
console.log("Pas de cas existant, cr\xE9ation d'un nouveau");
|
|
2789
|
+
}
|
|
2790
|
+
};
|
|
2791
|
+
const handleInputChange = (e) => {
|
|
2792
|
+
const { name, value } = e.target;
|
|
2793
|
+
setFormData((prev) => ({ ...prev, [name]: value }));
|
|
2794
|
+
};
|
|
2795
|
+
const handleFileChange = (e) => {
|
|
2796
|
+
if (e.target.files && e.target.files[0]) {
|
|
2797
|
+
setFormData((prev) => ({ ...prev, file: e.target.files[0] }));
|
|
2798
|
+
}
|
|
2799
|
+
};
|
|
2800
|
+
const handleSave = async () => {
|
|
2801
|
+
if (!token || !loggedUser) return;
|
|
2802
|
+
setSaving(true);
|
|
2803
|
+
try {
|
|
2804
|
+
const payload = {
|
|
2805
|
+
title: formData.title,
|
|
2806
|
+
process,
|
|
2807
|
+
object_id,
|
|
2808
|
+
requested_by: loggedUser.id,
|
|
2809
|
+
description: formData.description,
|
|
2810
|
+
verifications: verification.map((v) => ({
|
|
2811
|
+
id: v.id,
|
|
2812
|
+
rank: v.rank,
|
|
2813
|
+
type_answer: "verification" /* VERIFICATION */,
|
|
2814
|
+
answer: "not-send" /* NOT_SEND */,
|
|
2815
|
+
user: v.user,
|
|
2816
|
+
note: v.note,
|
|
2817
|
+
space_answer: v.space_answer
|
|
2818
|
+
})),
|
|
2819
|
+
validations: validation.map((v) => ({
|
|
2820
|
+
id: v.id,
|
|
2821
|
+
rank: v.rank,
|
|
2822
|
+
type_answer: "validation" /* VALIDATION */,
|
|
2823
|
+
answer: "not-send" /* NOT_SEND */,
|
|
2824
|
+
user: v.user,
|
|
2825
|
+
note: v.note,
|
|
2826
|
+
space_answer: v.space_answer
|
|
2827
|
+
}))
|
|
2828
|
+
};
|
|
2829
|
+
let response;
|
|
2830
|
+
if (caseData?.id) {
|
|
2831
|
+
response = await ApprovalServices.update(caseData.id, { id: caseData.id, ...payload }, token);
|
|
2832
|
+
} else {
|
|
2833
|
+
response = await ApprovalServices.create(payload, token);
|
|
2834
|
+
}
|
|
2835
|
+
if (response.success) {
|
|
2836
|
+
showSuccess("Workflow enregistr\xE9 avec succ\xE8s");
|
|
2837
|
+
await loadCase();
|
|
2838
|
+
} else {
|
|
2839
|
+
showError("Erreur lors de l'enregistrement du workflow");
|
|
2840
|
+
}
|
|
2841
|
+
} catch (error) {
|
|
2842
|
+
showError("Erreur lors de l'enregistrement du workflow");
|
|
2843
|
+
console.error(error);
|
|
2844
|
+
} finally {
|
|
2845
|
+
setSaving(false);
|
|
2846
|
+
}
|
|
2847
|
+
};
|
|
2848
|
+
const handleTransmit = async () => {
|
|
2849
|
+
if (!token) return;
|
|
2850
|
+
if (validation.length === 0) {
|
|
2851
|
+
showError("Veuillez ajouter au moins une personne dans le tableau des validations");
|
|
2852
|
+
return;
|
|
2853
|
+
}
|
|
2854
|
+
setTransmitting(true);
|
|
2855
|
+
try {
|
|
2856
|
+
await handleSave();
|
|
2857
|
+
if (caseData?.id) {
|
|
2858
|
+
const response = await ApprovalServices.start(caseData.id, token);
|
|
2859
|
+
if (response.success) {
|
|
2860
|
+
showSuccess("Demande de validation transmise avec succ\xE8s");
|
|
2861
|
+
await loadCase();
|
|
2862
|
+
} else {
|
|
2863
|
+
showError("Erreur lors de la transmission");
|
|
2864
|
+
}
|
|
2865
|
+
}
|
|
2866
|
+
} catch (error) {
|
|
2867
|
+
showError("Erreur lors de la transmission");
|
|
2868
|
+
console.error(error);
|
|
2869
|
+
} finally {
|
|
2870
|
+
setTransmitting(false);
|
|
2871
|
+
}
|
|
2872
|
+
};
|
|
2873
|
+
const handleCancel = async () => {
|
|
2874
|
+
if (!token || !caseData?.id) return;
|
|
2875
|
+
setCanceling(true);
|
|
2876
|
+
try {
|
|
2877
|
+
const response = await ApprovalServices.cancel(caseData.id, token);
|
|
2878
|
+
if (response.success) {
|
|
2879
|
+
showSuccess("Demande d'approbation annul\xE9e avec succ\xE8s");
|
|
2880
|
+
await loadCase();
|
|
2881
|
+
} else {
|
|
2882
|
+
showError("Erreur lors de l'annulation");
|
|
2883
|
+
}
|
|
2884
|
+
} catch (error) {
|
|
2885
|
+
showError("Erreur lors de l'annulation");
|
|
2886
|
+
console.error(error);
|
|
2887
|
+
} finally {
|
|
2888
|
+
setCanceling(false);
|
|
2889
|
+
}
|
|
2890
|
+
};
|
|
2891
|
+
const handleRestart = async () => {
|
|
2892
|
+
if (!token || !caseData?.id) return;
|
|
2893
|
+
setRestarting(true);
|
|
2894
|
+
try {
|
|
2895
|
+
const response = await ApprovalServices.restart(caseData.id, token);
|
|
2896
|
+
if (response.success) {
|
|
2897
|
+
showSuccess("Demande d'approbation red\xE9marr\xE9e avec succ\xE8s");
|
|
2898
|
+
await loadCase();
|
|
2899
|
+
} else {
|
|
2900
|
+
showError("Erreur lors du red\xE9marrage");
|
|
2901
|
+
}
|
|
2902
|
+
} catch (error) {
|
|
2903
|
+
showError("Erreur lors du red\xE9marrage");
|
|
2904
|
+
console.error(error);
|
|
2905
|
+
} finally {
|
|
2906
|
+
setRestarting(false);
|
|
2907
|
+
}
|
|
2908
|
+
};
|
|
2909
|
+
const loadHistory = async () => {
|
|
2910
|
+
if (!token) return;
|
|
2911
|
+
setLoadingHistory(true);
|
|
2912
|
+
try {
|
|
2913
|
+
const response = await ApprovalServices.getHistory(process, object_id, token);
|
|
2914
|
+
if (response.success && response.data) {
|
|
2915
|
+
setHistory(response.data);
|
|
2916
|
+
}
|
|
2917
|
+
} catch (error) {
|
|
2918
|
+
showError("Erreur lors du chargement de l'historique");
|
|
2919
|
+
console.error(error);
|
|
2920
|
+
} finally {
|
|
2921
|
+
setLoadingHistory(false);
|
|
2922
|
+
}
|
|
2923
|
+
};
|
|
2924
|
+
useEffect8(() => {
|
|
2925
|
+
if (activeTab === "history" && history.length === 0) {
|
|
2926
|
+
loadHistory();
|
|
2927
|
+
}
|
|
2928
|
+
}, [activeTab]);
|
|
2929
|
+
const getUserOptions = () => {
|
|
2930
|
+
return users.map((user) => ({
|
|
2931
|
+
value: user.id,
|
|
2932
|
+
label: `${user.first_name} ${user.last_name}`,
|
|
2933
|
+
content: /* @__PURE__ */ jsx14("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ jsxs10("div", { className: "flex-1", children: [
|
|
2934
|
+
/* @__PURE__ */ jsxs10("div", { className: "font-medium text-gray-900", children: [
|
|
2935
|
+
user.first_name,
|
|
2936
|
+
" ",
|
|
2937
|
+
user.last_name
|
|
2938
|
+
] }),
|
|
2939
|
+
/* @__PURE__ */ jsx14("div", { className: "text-sm text-gray-500", children: user.email })
|
|
2940
|
+
] }) })
|
|
2941
|
+
}));
|
|
2942
|
+
};
|
|
2943
|
+
const userFilterFunction = (option, searchTerm) => {
|
|
2944
|
+
const user = users.find((u) => u.id === option.value);
|
|
2945
|
+
if (!user) return false;
|
|
2946
|
+
const searchLower = searchTerm.toLowerCase();
|
|
2947
|
+
return user.first_name?.toLowerCase().includes(searchLower) || user.last_name?.toLowerCase().includes(searchLower) || user.email?.toLowerCase().includes(searchLower);
|
|
2948
|
+
};
|
|
2949
|
+
const renderStageSection = (sectionTitle, stages, setStages, sectionType) => {
|
|
2950
|
+
const addStage = (newStage) => {
|
|
2951
|
+
const duplicate = stages.find((s) => s.email === newStage.email);
|
|
2952
|
+
if (duplicate) {
|
|
2953
|
+
showError("Cet utilisateur a d\xE9j\xE0 \xE9t\xE9 ajout\xE9");
|
|
2954
|
+
return;
|
|
2955
|
+
}
|
|
2956
|
+
setStages((prev) => [...prev, { ...newStage, rank: prev.length + 1 }]);
|
|
2957
|
+
};
|
|
2958
|
+
const updateStage = (index, updatedStage) => {
|
|
2959
|
+
setStages((prev) => prev.map(
|
|
2960
|
+
(stage, i) => i === index ? { ...stage, ...updatedStage } : stage
|
|
2961
|
+
));
|
|
2962
|
+
};
|
|
2963
|
+
const removeStage = (index) => {
|
|
2964
|
+
setStages((prev) => prev.filter((_, i) => i !== index).map((stage, i) => ({
|
|
2965
|
+
...stage,
|
|
2966
|
+
rank: i + 1
|
|
2967
|
+
})));
|
|
2968
|
+
};
|
|
2969
|
+
return /* @__PURE__ */ jsxs10("fieldset", { className: "border border-[#D9D9D9] rounded-lg p-4", children: [
|
|
2970
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between mb-4", children: [
|
|
2971
|
+
/* @__PURE__ */ jsx14("legend", { className: "text-lg font-semibold text-[#191919] px-2", children: sectionTitle }),
|
|
2972
|
+
!readOnly && /* @__PURE__ */ jsx14(
|
|
2973
|
+
AddStageButton,
|
|
2974
|
+
{
|
|
2975
|
+
users,
|
|
2976
|
+
userOptions: getUserOptions(),
|
|
2977
|
+
userFilterFunction,
|
|
2978
|
+
loadingUsers,
|
|
2979
|
+
onAdd: (newStage) => addStage(newStage)
|
|
2980
|
+
}
|
|
2981
|
+
)
|
|
2982
|
+
] }),
|
|
2983
|
+
/* @__PURE__ */ jsx14("div", { className: "overflow-x-auto", children: stages.length === 0 ? /* @__PURE__ */ jsxs10("div", { className: "text-center py-6 border-2 border-dashed border-[#D9D9D9] rounded-lg bg-[#FAFAFA]", children: [
|
|
2984
|
+
/* @__PURE__ */ jsx14(Users2, { className: "w-8 h-8 text-[#767676] mx-auto mb-4" }),
|
|
2985
|
+
/* @__PURE__ */ jsx14("h3", { className: "text-lg font-medium text-[#191919] mb-2", children: "Aucune personne ajout\xE9e" }),
|
|
2986
|
+
/* @__PURE__ */ jsx14("p", { className: "text-[#767676] mb-4", children: 'Cliquez sur le bouton "Ajouter une personne" pour commencer' })
|
|
2987
|
+
] }) : /* @__PURE__ */ jsxs10("table", { className: "w-full border-collapse", children: [
|
|
2988
|
+
/* @__PURE__ */ jsx14("thead", { children: /* @__PURE__ */ jsxs10("tr", { className: "bg-gray-100", children: [
|
|
2989
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-2 py-2 text-left text-sm font-semibold w-10" }),
|
|
2990
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-4 py-2 text-left text-sm font-semibold", children: "Etape" }),
|
|
2991
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-4 py-2 text-left text-sm font-semibold", children: "Type" }),
|
|
2992
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-4 py-2 text-left text-sm font-semibold", children: "Nom et pr\xE9noms" }),
|
|
2993
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-4 py-2 text-left text-sm font-semibold", children: "Email" }),
|
|
2994
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-4 py-2 text-left text-sm font-semibold", children: "Role" }),
|
|
2995
|
+
/* @__PURE__ */ jsx14("th", { className: "border border-gray-300 px-4 py-2 text-left text-sm font-semibold", children: "Status" })
|
|
2996
|
+
] }) }),
|
|
2997
|
+
/* @__PURE__ */ jsx14("tbody", { children: stages.map((stage, index) => /* @__PURE__ */ jsx14(
|
|
2998
|
+
StageRow,
|
|
2999
|
+
{
|
|
3000
|
+
stage,
|
|
3001
|
+
index,
|
|
3002
|
+
users,
|
|
3003
|
+
userOptions: getUserOptions(),
|
|
3004
|
+
userFilterFunction,
|
|
3005
|
+
loadingUsers,
|
|
3006
|
+
readOnly: readOnly || stage.answer !== 0,
|
|
3007
|
+
onUpdate: (updated) => updateStage(index, updated),
|
|
3008
|
+
onRemove: () => removeStage(index)
|
|
3009
|
+
},
|
|
3010
|
+
`${sectionType}-${index}`
|
|
3011
|
+
)) })
|
|
3012
|
+
] }) })
|
|
3013
|
+
] });
|
|
3014
|
+
};
|
|
3015
|
+
if (loading) {
|
|
3016
|
+
return /* @__PURE__ */ jsx14(RewiseBasicCard, { title, children: /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx14(Loader2, { className: "w-8 h-8 animate-spin text-[#6A8A82]" }) }) });
|
|
3017
|
+
}
|
|
3018
|
+
const renderTabContent = () => {
|
|
3019
|
+
switch (activeTab) {
|
|
3020
|
+
case "workflow":
|
|
3021
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-6", children: [
|
|
3022
|
+
renderStageSection("Verification", verification, setVerification, "verification"),
|
|
3023
|
+
renderStageSection("Validation", validation, setValidation, "validation"),
|
|
3024
|
+
!readOnly && /* @__PURE__ */ jsxs10("div", { className: "flex justify-between pt-4 border-t border-[#D9D9D9]", children: [
|
|
3025
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex gap-3", children: [
|
|
3026
|
+
/* @__PURE__ */ jsx14(
|
|
3027
|
+
SecondaryButton,
|
|
3028
|
+
{
|
|
3029
|
+
onClick: () => window.history.back(),
|
|
3030
|
+
type: "button",
|
|
3031
|
+
children: "Retour"
|
|
3032
|
+
}
|
|
3033
|
+
),
|
|
3034
|
+
caseData?.id && formData.status !== "not-send" /* NOT_SEND */ && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3035
|
+
/* @__PURE__ */ jsxs10(
|
|
3036
|
+
SecondaryButton,
|
|
3037
|
+
{
|
|
3038
|
+
onClick: handleCancel,
|
|
3039
|
+
disabled: canceling,
|
|
3040
|
+
type: "button",
|
|
3041
|
+
classname: "flex items-center gap-2",
|
|
3042
|
+
children: [
|
|
3043
|
+
/* @__PURE__ */ jsx14(Ban2, { className: "w-4 h-4" }),
|
|
3044
|
+
canceling ? "Annulation..." : "Annuler la demande"
|
|
3045
|
+
]
|
|
3046
|
+
}
|
|
3047
|
+
),
|
|
3048
|
+
/* @__PURE__ */ jsxs10(
|
|
3049
|
+
SecondaryButton,
|
|
3050
|
+
{
|
|
3051
|
+
onClick: handleRestart,
|
|
3052
|
+
disabled: restarting,
|
|
3053
|
+
type: "button",
|
|
3054
|
+
classname: "flex items-center gap-2",
|
|
3055
|
+
children: [
|
|
3056
|
+
/* @__PURE__ */ jsx14(RotateCcw2, { className: "w-4 h-4" }),
|
|
3057
|
+
restarting ? "Red\xE9marrage..." : "Recommencer"
|
|
3058
|
+
]
|
|
3059
|
+
}
|
|
3060
|
+
)
|
|
3061
|
+
] })
|
|
3062
|
+
] }),
|
|
3063
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex gap-3", children: [
|
|
3064
|
+
/* @__PURE__ */ jsx14(
|
|
3065
|
+
Buttons_default,
|
|
3066
|
+
{
|
|
3067
|
+
onClick: handleSave,
|
|
3068
|
+
disabled: saving,
|
|
3069
|
+
type: "button",
|
|
3070
|
+
children: saving ? "Enregistrement..." : "Enregistrer"
|
|
3071
|
+
}
|
|
3072
|
+
),
|
|
3073
|
+
formData.status === "not-send" /* NOT_SEND */ && /* @__PURE__ */ jsx14(
|
|
3074
|
+
Buttons_default,
|
|
3075
|
+
{
|
|
3076
|
+
onClick: handleTransmit,
|
|
3077
|
+
disabled: transmitting || saving,
|
|
3078
|
+
type: "button",
|
|
3079
|
+
children: transmitting ? "Transmission..." : "Transmettre"
|
|
3080
|
+
}
|
|
3081
|
+
)
|
|
3082
|
+
] })
|
|
3083
|
+
] })
|
|
3084
|
+
] });
|
|
3085
|
+
case "preview":
|
|
3086
|
+
return /* @__PURE__ */ jsx14("div", { className: "space-y-6", children: /* @__PURE__ */ jsxs10("div", { className: "prose max-w-none", children: [
|
|
3087
|
+
/* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold text-[#191919] mb-4", children: "Aper\xE7u du document" }),
|
|
3088
|
+
caseData?.html_content ? /* @__PURE__ */ jsx14(
|
|
3089
|
+
"div",
|
|
3090
|
+
{
|
|
3091
|
+
className: "border border-[#D9D9D9] rounded-lg p-6 bg-white",
|
|
3092
|
+
dangerouslySetInnerHTML: { __html: caseData.html_content }
|
|
3093
|
+
}
|
|
3094
|
+
) : /* @__PURE__ */ jsxs10("div", { className: "text-center py-12 border-2 border-dashed border-[#D9D9D9] rounded-lg bg-[#FAFAFA]", children: [
|
|
3095
|
+
/* @__PURE__ */ jsx14(Eye2, { className: "w-12 h-12 text-[#767676] mx-auto mb-4" }),
|
|
3096
|
+
/* @__PURE__ */ jsx14("p", { className: "text-[#767676]", children: "Aucun aper\xE7u disponible" })
|
|
3097
|
+
] })
|
|
3098
|
+
] }) });
|
|
3099
|
+
case "history":
|
|
3100
|
+
return /* @__PURE__ */ jsxs10("div", { className: "space-y-6", children: [
|
|
3101
|
+
/* @__PURE__ */ jsx14("h3", { className: "text-lg font-semibold text-[#191919]", children: "Historique des versions" }),
|
|
3102
|
+
loadingHistory ? /* @__PURE__ */ jsx14("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx14(Loader2, { className: "w-8 h-8 animate-spin text-[#6A8A82]" }) }) : history.length === 0 ? /* @__PURE__ */ jsxs10("div", { className: "text-center py-12 border-2 border-dashed border-[#D9D9D9] rounded-lg bg-[#FAFAFA]", children: [
|
|
3103
|
+
/* @__PURE__ */ jsx14(History2, { className: "w-12 h-12 text-[#767676] mx-auto mb-4" }),
|
|
3104
|
+
/* @__PURE__ */ jsx14("p", { className: "text-[#767676]", children: "Aucun historique disponible" })
|
|
3105
|
+
] }) : /* @__PURE__ */ jsx14("div", { className: "space-y-4", children: history.map((item, index) => /* @__PURE__ */ jsx14("div", { className: "border border-[#D9D9D9] rounded-lg p-4 bg-white hover:shadow-md transition-shadow", children: /* @__PURE__ */ jsx14("div", { className: "flex items-start justify-between", children: /* @__PURE__ */ jsxs10("div", { className: "flex-1", children: [
|
|
3106
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3 mb-2", children: [
|
|
3107
|
+
/* @__PURE__ */ jsxs10("span", { className: "px-3 py-1 bg-[#6A8A82] text-white text-xs font-medium rounded-full", children: [
|
|
3108
|
+
"Version ",
|
|
3109
|
+
item.version
|
|
3110
|
+
] }),
|
|
3111
|
+
/* @__PURE__ */ jsx14("span", { className: `px-3 py-1 text-xs font-medium rounded-full ${item.status === "approved" /* APPROVED */ ? "bg-green-100 text-green-800" : item.status === "refused" /* REFUSED */ ? "bg-red-100 text-red-800" : item.status === "waiting" /* WAITING */ ? "bg-yellow-100 text-yellow-800" : item.status === "cancel" /* CANCEL */ ? "bg-gray-100 text-gray-800" : "bg-blue-100 text-blue-800"}`, children: item.status })
|
|
3112
|
+
] }),
|
|
3113
|
+
/* @__PURE__ */ jsx14("h4", { className: "font-semibold text-[#191919] mb-1", children: item.title }),
|
|
3114
|
+
/* @__PURE__ */ jsx14("p", { className: "text-sm text-[#767676] mb-2", children: item.description }),
|
|
3115
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-4 text-xs text-[#767676]", children: [
|
|
3116
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
3117
|
+
"Demand\xE9 par: ",
|
|
3118
|
+
item.requested_by?.first_name,
|
|
3119
|
+
" ",
|
|
3120
|
+
item.requested_by?.last_name
|
|
3121
|
+
] }),
|
|
3122
|
+
/* @__PURE__ */ jsx14("span", { children: "\u2022" }),
|
|
3123
|
+
/* @__PURE__ */ jsx14("span", { children: new Date(item.created_at || "").toLocaleDateString("fr-FR") }),
|
|
3124
|
+
item.closed_at && /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3125
|
+
/* @__PURE__ */ jsx14("span", { children: "\u2022" }),
|
|
3126
|
+
/* @__PURE__ */ jsxs10("span", { children: [
|
|
3127
|
+
"Cl\xF4tur\xE9 le: ",
|
|
3128
|
+
new Date(item.closed_at).toLocaleDateString("fr-FR")
|
|
3129
|
+
] })
|
|
3130
|
+
] })
|
|
3131
|
+
] })
|
|
3132
|
+
] }) }) }, item.id || index)) })
|
|
3133
|
+
] });
|
|
3134
|
+
default:
|
|
3135
|
+
return null;
|
|
3136
|
+
}
|
|
3137
|
+
};
|
|
3138
|
+
return /* @__PURE__ */ jsxs10(
|
|
3139
|
+
RewiseBasicCard,
|
|
3140
|
+
{
|
|
3141
|
+
title: /* @__PURE__ */ jsxs10("div", { className: "flex items-center justify-between w-full", children: [
|
|
3142
|
+
/* @__PURE__ */ jsx14("h2", { className: "text-xl font-semibold text-[#191919]", children: title }),
|
|
3143
|
+
/* @__PURE__ */ jsx14(
|
|
3144
|
+
"button",
|
|
3145
|
+
{
|
|
3146
|
+
className: "text-gray-500 hover:text-[#6A8A82] transition-colors",
|
|
3147
|
+
onClick: () => window.history.back(),
|
|
3148
|
+
children: /* @__PURE__ */ jsx14(X5, { className: "w-5 h-5" })
|
|
3149
|
+
}
|
|
3150
|
+
)
|
|
3151
|
+
] }),
|
|
3152
|
+
children: [
|
|
3153
|
+
/* @__PURE__ */ jsxs10("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4", children: [
|
|
3154
|
+
/* @__PURE__ */ jsx14("div", { className: "md:col-span-1", children: /* @__PURE__ */ jsx14(
|
|
3155
|
+
TextInput,
|
|
3156
|
+
{
|
|
3157
|
+
label: "Titre:",
|
|
3158
|
+
name: "title",
|
|
3159
|
+
value: formData.title,
|
|
3160
|
+
onChange: handleInputChange,
|
|
3161
|
+
disabled: readOnly
|
|
3162
|
+
}
|
|
3163
|
+
) }),
|
|
3164
|
+
/* @__PURE__ */ jsx14("div", { className: "md:col-span-1", children: /* @__PURE__ */ jsx14(
|
|
3165
|
+
FileInput,
|
|
3166
|
+
{
|
|
3167
|
+
label: "Joindre un fichier:",
|
|
3168
|
+
name: "file",
|
|
3169
|
+
onChange: handleFileChange,
|
|
3170
|
+
disabled: readOnly
|
|
3171
|
+
}
|
|
3172
|
+
) }),
|
|
3173
|
+
/* @__PURE__ */ jsx14("div", { className: "md:col-span-1", children: /* @__PURE__ */ jsx14(
|
|
3174
|
+
TextInput,
|
|
3175
|
+
{
|
|
3176
|
+
label: "Statut:",
|
|
3177
|
+
name: "status",
|
|
3178
|
+
value: formData.status,
|
|
3179
|
+
onChange: handleInputChange,
|
|
3180
|
+
disabled: true
|
|
3181
|
+
}
|
|
3182
|
+
) })
|
|
3183
|
+
] }),
|
|
3184
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
3185
|
+
/* @__PURE__ */ jsx14("label", { className: "block text-[#191919] text-sm font-medium mb-2", children: "Description:" }),
|
|
3186
|
+
/* @__PURE__ */ jsx14(
|
|
3187
|
+
"textarea",
|
|
3188
|
+
{
|
|
3189
|
+
name: "description",
|
|
3190
|
+
value: formData.description,
|
|
3191
|
+
onChange: handleInputChange,
|
|
3192
|
+
rows: 3,
|
|
3193
|
+
disabled: readOnly,
|
|
3194
|
+
className: "w-full px-3 py-2 border border-[#D9D9D9] rounded-lg focus:ring-2 focus:ring-[#6A8A82] focus:border-transparent resize-none disabled:bg-gray-100",
|
|
3195
|
+
placeholder: "Ajouter une description..."
|
|
3196
|
+
}
|
|
3197
|
+
)
|
|
3198
|
+
] }),
|
|
3199
|
+
/* @__PURE__ */ jsx14("div", { className: "border-b border-[#D9D9D9] mb-6", children: /* @__PURE__ */ jsxs10("nav", { className: "flex gap-1", children: [
|
|
3200
|
+
/* @__PURE__ */ jsxs10(
|
|
3201
|
+
"button",
|
|
3202
|
+
{
|
|
3203
|
+
onClick: () => setActiveTab("workflow"),
|
|
3204
|
+
className: `px-4 py-3 text-sm font-medium transition-colors flex items-center gap-2 ${activeTab === "workflow" ? "border-b-2 border-[#6A8A82] text-[#6A8A82]" : "text-[#767676] hover:text-[#191919]"}`,
|
|
3205
|
+
children: [
|
|
3206
|
+
/* @__PURE__ */ jsx14(FileText2, { className: "w-4 h-4" }),
|
|
3207
|
+
"Workflow"
|
|
3208
|
+
]
|
|
3209
|
+
}
|
|
3210
|
+
),
|
|
3211
|
+
/* @__PURE__ */ jsxs10(
|
|
3212
|
+
"button",
|
|
3213
|
+
{
|
|
3214
|
+
onClick: () => setActiveTab("preview"),
|
|
3215
|
+
className: `px-4 py-3 text-sm font-medium transition-colors flex items-center gap-2 ${activeTab === "preview" ? "border-b-2 border-[#6A8A82] text-[#6A8A82]" : "text-[#767676] hover:text-[#191919]"}`,
|
|
3216
|
+
children: [
|
|
3217
|
+
/* @__PURE__ */ jsx14(Eye2, { className: "w-4 h-4" }),
|
|
3218
|
+
"Aper\xE7u"
|
|
3219
|
+
]
|
|
3220
|
+
}
|
|
3221
|
+
),
|
|
3222
|
+
/* @__PURE__ */ jsxs10(
|
|
3223
|
+
"button",
|
|
3224
|
+
{
|
|
3225
|
+
onClick: () => setActiveTab("history"),
|
|
3226
|
+
className: `px-4 py-3 text-sm font-medium transition-colors flex items-center gap-2 ${activeTab === "history" ? "border-b-2 border-[#6A8A82] text-[#6A8A82]" : "text-[#767676] hover:text-[#191919]"}`,
|
|
3227
|
+
children: [
|
|
3228
|
+
/* @__PURE__ */ jsx14(History2, { className: "w-4 h-4" }),
|
|
3229
|
+
"Historique"
|
|
3230
|
+
]
|
|
3231
|
+
}
|
|
3232
|
+
)
|
|
3233
|
+
] }) }),
|
|
3234
|
+
renderTabContent()
|
|
3235
|
+
]
|
|
3236
|
+
}
|
|
3237
|
+
);
|
|
3238
|
+
};
|
|
3239
|
+
var StageRow = ({
|
|
3240
|
+
stage,
|
|
3241
|
+
index,
|
|
3242
|
+
users,
|
|
3243
|
+
userOptions,
|
|
3244
|
+
userFilterFunction,
|
|
3245
|
+
loadingUsers,
|
|
3246
|
+
readOnly,
|
|
3247
|
+
onUpdate,
|
|
3248
|
+
onRemove
|
|
3249
|
+
}) => {
|
|
3250
|
+
const handleUserSelect = (option) => {
|
|
3251
|
+
const user = users.find((u) => u.id === option.value);
|
|
3252
|
+
if (!user) return;
|
|
3253
|
+
onUpdate({
|
|
3254
|
+
user: user.id,
|
|
3255
|
+
name: `${user.first_name} ${user.last_name}`,
|
|
3256
|
+
email: user.email,
|
|
3257
|
+
role: user.phonenumber || "-"
|
|
3258
|
+
});
|
|
3259
|
+
};
|
|
3260
|
+
const handleSpaceAnswerChange = (e) => {
|
|
3261
|
+
onUpdate({
|
|
3262
|
+
space_answer: e.target.value,
|
|
3263
|
+
name: "",
|
|
3264
|
+
email: "",
|
|
3265
|
+
user: void 0
|
|
3266
|
+
});
|
|
3267
|
+
};
|
|
3268
|
+
const getStatusIcon = (answer) => {
|
|
3269
|
+
if (answer === 2) {
|
|
3270
|
+
return /* @__PURE__ */ jsx14("span", { className: "inline-flex items-center justify-center w-6 h-6 bg-green-500 rounded-full", children: /* @__PURE__ */ jsx14("svg", { className: "w-4 h-4 text-white", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx14("path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }) });
|
|
3271
|
+
} else if (answer === 1) {
|
|
3272
|
+
return /* @__PURE__ */ jsx14("span", { className: "inline-flex items-center justify-center w-6 h-6 bg-gray-300 rounded-full", children: /* @__PURE__ */ jsx14("span", { className: "text-white text-xs", children: "\u23F1" }) });
|
|
3273
|
+
} else if (answer === -1) {
|
|
3274
|
+
return /* @__PURE__ */ jsx14("span", { className: "inline-flex items-center justify-center w-6 h-6 bg-red-500 rounded-full", children: /* @__PURE__ */ jsx14("svg", { className: "w-4 h-4 text-white", fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsx14("path", { fillRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z", clipRule: "evenodd" }) }) });
|
|
3275
|
+
}
|
|
3276
|
+
return /* @__PURE__ */ jsx14("span", { className: "text-gray-400 text-xs", children: "-" });
|
|
3277
|
+
};
|
|
3278
|
+
return /* @__PURE__ */ jsxs10("tr", { className: "hover:bg-gray-50", children: [
|
|
3279
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-2 py-2 text-center", children: !readOnly && /* @__PURE__ */ jsx14(
|
|
3280
|
+
"button",
|
|
3281
|
+
{
|
|
3282
|
+
type: "button",
|
|
3283
|
+
onClick: onRemove,
|
|
3284
|
+
className: "text-[#B85450] hover:text-red-700 transition-colors",
|
|
3285
|
+
title: "Supprimer",
|
|
3286
|
+
children: /* @__PURE__ */ jsx14(Trash22, { className: "w-4 h-4" })
|
|
3287
|
+
}
|
|
3288
|
+
) }),
|
|
3289
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-4 py-2 text-center", children: index + 1 }),
|
|
3290
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-2 py-2", children: /* @__PURE__ */ jsxs10(
|
|
3291
|
+
"select",
|
|
3292
|
+
{
|
|
3293
|
+
value: stage.space_answer,
|
|
3294
|
+
onChange: handleSpaceAnswerChange,
|
|
3295
|
+
disabled: readOnly,
|
|
3296
|
+
className: "w-full px-2 py-1 border border-gray-300 rounded text-sm focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100",
|
|
3297
|
+
children: [
|
|
3298
|
+
/* @__PURE__ */ jsx14("option", { value: "internal", children: "Interne" }),
|
|
3299
|
+
/* @__PURE__ */ jsx14("option", { value: "external", children: "Externe" })
|
|
3300
|
+
]
|
|
3301
|
+
}
|
|
3302
|
+
) }),
|
|
3303
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-2 py-2", children: stage.space_answer === "internal" ? /* @__PURE__ */ jsx14(
|
|
3304
|
+
SearchableSelect,
|
|
3305
|
+
{
|
|
3306
|
+
options: userOptions,
|
|
3307
|
+
value: stage.user,
|
|
3308
|
+
placeholder: "S\xE9lectionner...",
|
|
3309
|
+
searchPlaceholder: "Rechercher...",
|
|
3310
|
+
onSelect: handleUserSelect,
|
|
3311
|
+
disabled: readOnly || loadingUsers,
|
|
3312
|
+
filterFunction: userFilterFunction
|
|
3313
|
+
}
|
|
3314
|
+
) : /* @__PURE__ */ jsx14(
|
|
3315
|
+
"input",
|
|
3316
|
+
{
|
|
3317
|
+
type: "text",
|
|
3318
|
+
value: stage.name,
|
|
3319
|
+
onChange: (e) => onUpdate({ name: e.target.value }),
|
|
3320
|
+
disabled: readOnly,
|
|
3321
|
+
className: "w-full px-2 py-1 border border-gray-300 rounded text-sm focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100"
|
|
3322
|
+
}
|
|
3323
|
+
) }),
|
|
3324
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-2 py-2", children: /* @__PURE__ */ jsx14(
|
|
3325
|
+
"input",
|
|
3326
|
+
{
|
|
3327
|
+
type: "email",
|
|
3328
|
+
value: stage.email,
|
|
3329
|
+
onChange: (e) => onUpdate({ email: e.target.value }),
|
|
3330
|
+
disabled: readOnly || stage.space_answer === "internal",
|
|
3331
|
+
className: "w-full px-2 py-1 border border-gray-300 rounded text-sm focus:ring-2 focus:ring-blue-500 disabled:bg-gray-100"
|
|
3332
|
+
}
|
|
3333
|
+
) }),
|
|
3334
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-2 py-2", children: /* @__PURE__ */ jsx14(
|
|
3335
|
+
"input",
|
|
3336
|
+
{
|
|
3337
|
+
type: "text",
|
|
3338
|
+
value: stage.role,
|
|
3339
|
+
disabled: true,
|
|
3340
|
+
className: "w-full px-2 py-1 border border-gray-300 rounded text-sm bg-gray-100"
|
|
3341
|
+
}
|
|
3342
|
+
) }),
|
|
3343
|
+
/* @__PURE__ */ jsx14("td", { className: "border border-gray-300 px-4 py-2 text-center", children: getStatusIcon(stage.answer) })
|
|
3344
|
+
] });
|
|
3345
|
+
};
|
|
3346
|
+
var AddStageButton = ({
|
|
3347
|
+
users,
|
|
3348
|
+
userOptions,
|
|
3349
|
+
userFilterFunction,
|
|
3350
|
+
loadingUsers,
|
|
3351
|
+
onAdd
|
|
3352
|
+
}) => {
|
|
3353
|
+
const [showModal, setShowModal] = useState10(false);
|
|
3354
|
+
const [newStage, setNewStage] = useState10({
|
|
3355
|
+
space_answer: "internal",
|
|
3356
|
+
name: "",
|
|
3357
|
+
email: "",
|
|
3358
|
+
role: "",
|
|
3359
|
+
answer: 0,
|
|
3360
|
+
rank: 0,
|
|
3361
|
+
stage: 0
|
|
3362
|
+
});
|
|
3363
|
+
const handleAdd = () => {
|
|
3364
|
+
if (!newStage.email) {
|
|
3365
|
+
return;
|
|
3366
|
+
}
|
|
3367
|
+
onAdd({
|
|
3368
|
+
stage: 0,
|
|
3369
|
+
space_answer: newStage.space_answer,
|
|
3370
|
+
user: newStage.user,
|
|
3371
|
+
name: newStage.name || "",
|
|
3372
|
+
email: newStage.email || "",
|
|
3373
|
+
role: newStage.role || "",
|
|
3374
|
+
status: "pending",
|
|
3375
|
+
answer: 0,
|
|
3376
|
+
rank: 0
|
|
3377
|
+
});
|
|
3378
|
+
setNewStage({
|
|
3379
|
+
space_answer: "internal",
|
|
3380
|
+
name: "",
|
|
3381
|
+
email: "",
|
|
3382
|
+
role: "",
|
|
3383
|
+
answer: 0,
|
|
3384
|
+
rank: 0,
|
|
3385
|
+
stage: 0
|
|
3386
|
+
});
|
|
3387
|
+
setShowModal(false);
|
|
3388
|
+
};
|
|
3389
|
+
const handleUserSelect = (option) => {
|
|
3390
|
+
const user = users.find((u) => u.id === option.value);
|
|
3391
|
+
if (!user) return;
|
|
3392
|
+
setNewStage({
|
|
3393
|
+
...newStage,
|
|
3394
|
+
user: user.id,
|
|
3395
|
+
name: `${user.first_name} ${user.last_name}`,
|
|
3396
|
+
email: user.email,
|
|
3397
|
+
role: user.phonenumber || "-"
|
|
3398
|
+
});
|
|
3399
|
+
};
|
|
3400
|
+
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
3401
|
+
/* @__PURE__ */ jsxs10(
|
|
3402
|
+
Buttons_default,
|
|
3403
|
+
{
|
|
3404
|
+
type: "button",
|
|
3405
|
+
onClick: () => setShowModal(true),
|
|
3406
|
+
classname: "gap-2",
|
|
3407
|
+
children: [
|
|
3408
|
+
/* @__PURE__ */ jsx14(Plus2, { className: "w-4 h-4" }),
|
|
3409
|
+
/* @__PURE__ */ jsx14("span", { children: "Ajouter une personne" })
|
|
3410
|
+
]
|
|
3411
|
+
}
|
|
3412
|
+
),
|
|
3413
|
+
/* @__PURE__ */ jsx14(
|
|
3414
|
+
Modals_default,
|
|
3415
|
+
{
|
|
3416
|
+
title: "Ajouter une personne",
|
|
3417
|
+
description: "S\xE9lectionnez un utilisateur interne ou ajoutez un validateur externe",
|
|
3418
|
+
open: showModal,
|
|
3419
|
+
onClose: () => setShowModal(false),
|
|
3420
|
+
children: /* @__PURE__ */ jsxs10("div", { className: "space-y-4 px-6 pb-6", children: [
|
|
3421
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
3422
|
+
/* @__PURE__ */ jsx14("label", { className: "block text-sm font-medium text-[#191919] mb-2", children: "Type" }),
|
|
3423
|
+
/* @__PURE__ */ jsxs10(
|
|
3424
|
+
"select",
|
|
3425
|
+
{
|
|
3426
|
+
value: newStage.space_answer,
|
|
3427
|
+
onChange: (e) => setNewStage({ ...newStage, space_answer: e.target.value, name: "", email: "", user: void 0 }),
|
|
3428
|
+
className: "w-full px-3 py-2 border border-[#D9D9D9] rounded-lg focus:ring-2 focus:ring-[#6A8A82]",
|
|
3429
|
+
children: [
|
|
3430
|
+
/* @__PURE__ */ jsx14("option", { value: "internal", children: "Interne" }),
|
|
3431
|
+
/* @__PURE__ */ jsx14("option", { value: "external", children: "Externe" })
|
|
3432
|
+
]
|
|
3433
|
+
}
|
|
3434
|
+
)
|
|
3435
|
+
] }),
|
|
3436
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
3437
|
+
/* @__PURE__ */ jsx14("label", { className: "block text-sm font-medium text-[#191919] mb-2", children: "Nom et pr\xE9noms" }),
|
|
3438
|
+
newStage.space_answer === "internal" ? /* @__PURE__ */ jsx14(
|
|
3439
|
+
SearchableSelect,
|
|
3440
|
+
{
|
|
3441
|
+
options: userOptions,
|
|
3442
|
+
value: newStage.user,
|
|
3443
|
+
placeholder: "S\xE9lectionner un utilisateur...",
|
|
3444
|
+
searchPlaceholder: "Rechercher...",
|
|
3445
|
+
onSelect: handleUserSelect,
|
|
3446
|
+
disabled: loadingUsers,
|
|
3447
|
+
filterFunction: userFilterFunction
|
|
3448
|
+
}
|
|
3449
|
+
) : /* @__PURE__ */ jsx14(
|
|
3450
|
+
"input",
|
|
3451
|
+
{
|
|
3452
|
+
type: "text",
|
|
3453
|
+
value: newStage.name,
|
|
3454
|
+
onChange: (e) => setNewStage({ ...newStage, name: e.target.value }),
|
|
3455
|
+
className: "w-full px-3 py-2 border border-[#D9D9D9] rounded-lg focus:ring-2 focus:ring-[#6A8A82]",
|
|
3456
|
+
placeholder: "Nom complet"
|
|
3457
|
+
}
|
|
3458
|
+
)
|
|
3459
|
+
] }),
|
|
3460
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
3461
|
+
/* @__PURE__ */ jsx14("label", { className: "block text-sm font-medium text-[#191919] mb-2", children: "Email" }),
|
|
3462
|
+
/* @__PURE__ */ jsx14(
|
|
3463
|
+
"input",
|
|
3464
|
+
{
|
|
3465
|
+
type: "email",
|
|
3466
|
+
value: newStage.email,
|
|
3467
|
+
onChange: (e) => setNewStage({ ...newStage, email: e.target.value }),
|
|
3468
|
+
disabled: newStage.space_answer === "internal",
|
|
3469
|
+
className: "w-full px-3 py-2 border border-[#D9D9D9] rounded-lg focus:ring-2 focus:ring-[#6A8A82] disabled:bg-gray-100",
|
|
3470
|
+
placeholder: "Email"
|
|
3471
|
+
}
|
|
3472
|
+
)
|
|
3473
|
+
] }),
|
|
3474
|
+
newStage.space_answer === "internal" && /* @__PURE__ */ jsxs10("div", { children: [
|
|
3475
|
+
/* @__PURE__ */ jsx14("label", { className: "block text-sm font-medium text-[#191919] mb-2", children: "Role" }),
|
|
3476
|
+
/* @__PURE__ */ jsx14(
|
|
3477
|
+
"input",
|
|
3478
|
+
{
|
|
3479
|
+
type: "text",
|
|
3480
|
+
value: newStage.role,
|
|
3481
|
+
disabled: true,
|
|
3482
|
+
className: "w-full px-3 py-2 border border-[#D9D9D9] rounded-lg bg-gray-100"
|
|
3483
|
+
}
|
|
3484
|
+
)
|
|
3485
|
+
] }),
|
|
3486
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex justify-end gap-3 pt-4 border-t border-[#D9D9D9]", children: [
|
|
3487
|
+
/* @__PURE__ */ jsx14(
|
|
3488
|
+
SecondaryButton,
|
|
3489
|
+
{
|
|
3490
|
+
onClick: () => setShowModal(false),
|
|
3491
|
+
type: "button",
|
|
3492
|
+
children: "Annuler"
|
|
3493
|
+
}
|
|
3494
|
+
),
|
|
3495
|
+
/* @__PURE__ */ jsx14(
|
|
3496
|
+
Buttons_default,
|
|
3497
|
+
{
|
|
3498
|
+
onClick: handleAdd,
|
|
3499
|
+
disabled: !newStage.email,
|
|
3500
|
+
type: "button",
|
|
3501
|
+
children: "Ajouter"
|
|
3502
|
+
}
|
|
3503
|
+
)
|
|
3504
|
+
] })
|
|
3505
|
+
] })
|
|
3506
|
+
}
|
|
3507
|
+
)
|
|
3508
|
+
] });
|
|
3509
|
+
};
|
|
3510
|
+
var ApprovalWorkflow_default = ApprovalWorkflow;
|
|
2033
3511
|
export {
|
|
3512
|
+
ApprovalAnswerModal,
|
|
3513
|
+
ApprovalAnswerPage,
|
|
3514
|
+
ApprovalPreviewAnswer_default as ApprovalPreviewAnswer,
|
|
3515
|
+
ApprovalWorkflow_default as ApprovalWorkflow,
|
|
2034
3516
|
DateInput,
|
|
2035
3517
|
FDrawer,
|
|
2036
3518
|
FileInput,
|