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