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