ptechcore_ui 1.0.6 → 1.0.8
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 +693 -330
- package/dist/index.d.cts +67 -12
- package/dist/index.d.ts +67 -12
- package/dist/index.js +645 -282
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -212,7 +212,7 @@ var FileInput = ({
|
|
|
212
212
|
};
|
|
213
213
|
|
|
214
214
|
// src/components/layout/ModernDoubleSidebarLayout.tsx
|
|
215
|
-
import React2, { useState as
|
|
215
|
+
import React2, { useState as useState3, useEffect as useEffect3 } from "react";
|
|
216
216
|
import { useLocation, useNavigate } from "react-router-dom";
|
|
217
217
|
import {
|
|
218
218
|
Settings,
|
|
@@ -226,7 +226,8 @@ import {
|
|
|
226
226
|
X,
|
|
227
227
|
Palette,
|
|
228
228
|
DollarSign,
|
|
229
|
-
HelpCircle
|
|
229
|
+
HelpCircle,
|
|
230
|
+
Building2
|
|
230
231
|
} from "lucide-react";
|
|
231
232
|
|
|
232
233
|
// src/utils/utils.ts
|
|
@@ -604,21 +605,194 @@ var ThemeProvider = ({ children }) => {
|
|
|
604
605
|
};
|
|
605
606
|
var ThemeContext_default = ThemeProvider;
|
|
606
607
|
|
|
608
|
+
// src/contexts/SessionContext.tsx
|
|
609
|
+
import { createContext as createContext2, useContext as useContext2, useEffect as useEffect2, useState as useState2 } from "react";
|
|
610
|
+
|
|
611
|
+
// src/services/api.ts
|
|
612
|
+
var ADDRESS_IP = "localhost:8000";
|
|
613
|
+
var ADDRESS_IP_URL = `http://${ADDRESS_IP}/`;
|
|
614
|
+
var API_URL = `${ADDRESS_IP_URL}api`;
|
|
615
|
+
var FetchApi = class {
|
|
616
|
+
static async post(url, payload, token) {
|
|
617
|
+
const headers = {
|
|
618
|
+
"Content-Type": "application/json"
|
|
619
|
+
};
|
|
620
|
+
if (token) {
|
|
621
|
+
headers["Authorization"] = `Token ${token}`;
|
|
622
|
+
}
|
|
623
|
+
const res = await fetch(url, {
|
|
624
|
+
method: "POST",
|
|
625
|
+
headers,
|
|
626
|
+
body: payload ? JSON.stringify(payload) : void 0
|
|
627
|
+
});
|
|
628
|
+
if (!res.ok) throw new Error(await res.text());
|
|
629
|
+
return res.json();
|
|
630
|
+
}
|
|
631
|
+
static async get(url, token) {
|
|
632
|
+
const headers = {};
|
|
633
|
+
if (token) {
|
|
634
|
+
headers["Authorization"] = `Token ${token}`;
|
|
635
|
+
}
|
|
636
|
+
const res = await fetch(url, {
|
|
637
|
+
method: "GET",
|
|
638
|
+
headers
|
|
639
|
+
});
|
|
640
|
+
if (!res.ok) throw new Error(await res.text());
|
|
641
|
+
return res.json();
|
|
642
|
+
}
|
|
643
|
+
static async put(url, payload, token) {
|
|
644
|
+
const headers = {
|
|
645
|
+
"Content-Type": "application/json"
|
|
646
|
+
};
|
|
647
|
+
if (token) {
|
|
648
|
+
headers["Authorization"] = `Token ${token}`;
|
|
649
|
+
}
|
|
650
|
+
const res = await fetch(url, {
|
|
651
|
+
method: "PUT",
|
|
652
|
+
headers,
|
|
653
|
+
body: payload ? JSON.stringify(payload) : void 0
|
|
654
|
+
});
|
|
655
|
+
if (!res.ok) throw new Error(await res.text());
|
|
656
|
+
return res.json();
|
|
657
|
+
}
|
|
658
|
+
static async delete(url, token) {
|
|
659
|
+
const headers = {};
|
|
660
|
+
if (token) {
|
|
661
|
+
headers["Authorization"] = `Token ${token}`;
|
|
662
|
+
}
|
|
663
|
+
const res = await fetch(url, {
|
|
664
|
+
method: "DELETE",
|
|
665
|
+
headers
|
|
666
|
+
});
|
|
667
|
+
if (!res.ok) throw new Error(await res.text());
|
|
668
|
+
return res.json();
|
|
669
|
+
}
|
|
670
|
+
};
|
|
671
|
+
|
|
672
|
+
// src/services/AuthServices.ts
|
|
673
|
+
var API_BASE_URL = `${API_URL}/core/auth/`;
|
|
674
|
+
var FetchApi2 = class {
|
|
675
|
+
static async post(url, payload, token) {
|
|
676
|
+
const headers = {
|
|
677
|
+
"Content-Type": "application/json"
|
|
678
|
+
};
|
|
679
|
+
if (token) {
|
|
680
|
+
headers["Authorization"] = `Token ${token}`;
|
|
681
|
+
}
|
|
682
|
+
const res = await fetch(url, {
|
|
683
|
+
method: "POST",
|
|
684
|
+
headers,
|
|
685
|
+
body: payload ? JSON.stringify(payload) : void 0
|
|
686
|
+
});
|
|
687
|
+
if (!res.ok) throw new Error(await res.text());
|
|
688
|
+
return res.json();
|
|
689
|
+
}
|
|
690
|
+
static async get(url, token) {
|
|
691
|
+
const headers = {};
|
|
692
|
+
if (token) {
|
|
693
|
+
headers["Authorization"] = `Token ${token}`;
|
|
694
|
+
}
|
|
695
|
+
const res = await fetch(url, {
|
|
696
|
+
method: "GET",
|
|
697
|
+
headers
|
|
698
|
+
});
|
|
699
|
+
if (!res.ok) throw new Error(await res.text());
|
|
700
|
+
return res.json();
|
|
701
|
+
}
|
|
702
|
+
};
|
|
703
|
+
var AuthServices = {
|
|
704
|
+
sendOtp: (payload) => FetchApi2.post(`${API_BASE_URL}send-otp/`, payload),
|
|
705
|
+
verifyOtp: (payload) => FetchApi2.post(`${API_BASE_URL}verify-otp/`, payload),
|
|
706
|
+
completeRegistration: (payload) => FetchApi2.post(`${API_BASE_URL}complete-registration/`, payload),
|
|
707
|
+
getInvitations: (token) => FetchApi2.get(`${API_BASE_URL}invitations/?token=${token}`),
|
|
708
|
+
respondInvitationEmail: (payload) => FetchApi2.post(`${API_BASE_URL}respond-invitation-email/`, payload),
|
|
709
|
+
change_password: (payload) => FetchApi2.post(`${API_BASE_URL}change-password/`, payload),
|
|
710
|
+
addUser: (payload) => FetchApi2.post(`${API_BASE_URL}add-user/`, payload),
|
|
711
|
+
login: (payload) => FetchApi2.post(`${API_BASE_URL}login/`, payload),
|
|
712
|
+
getUserInformations: (token) => FetchApi2.get(`${API_BASE_URL}user-informations/`, token),
|
|
713
|
+
logout: () => FetchApi2.post(`${API_BASE_URL}logout/`)
|
|
714
|
+
};
|
|
715
|
+
|
|
716
|
+
// src/contexts/SessionContext.tsx
|
|
717
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
718
|
+
var SessionContext = createContext2(void 0);
|
|
719
|
+
var useSession = () => {
|
|
720
|
+
const context = useContext2(SessionContext);
|
|
721
|
+
if (!context) {
|
|
722
|
+
throw new Error("useSession must be used within a SessionProvider");
|
|
723
|
+
}
|
|
724
|
+
return context;
|
|
725
|
+
};
|
|
726
|
+
var SessionProvider = ({ children }) => {
|
|
727
|
+
const [token, setToken] = useState2(localStorage.getItem("token"));
|
|
728
|
+
const [loggedUser, setLoggedUser] = useState2(null);
|
|
729
|
+
const [activeBusinessEntity, setActiveBusinessEntity] = useState2(null);
|
|
730
|
+
const saved_center_id = localStorage.getItem("active_center_id") || "";
|
|
731
|
+
useEffect2(() => {
|
|
732
|
+
const storedToken = localStorage.getItem("token");
|
|
733
|
+
if (storedToken) {
|
|
734
|
+
setToken(storedToken);
|
|
735
|
+
}
|
|
736
|
+
}, []);
|
|
737
|
+
const login = (newToken) => {
|
|
738
|
+
localStorage.setItem("token", newToken);
|
|
739
|
+
setToken(newToken);
|
|
740
|
+
};
|
|
741
|
+
const logout = () => {
|
|
742
|
+
localStorage.removeItem("token");
|
|
743
|
+
setToken(null);
|
|
744
|
+
};
|
|
745
|
+
useEffect2(() => {
|
|
746
|
+
if (token) {
|
|
747
|
+
AuthServices.getUserInformations(token).then((res) => {
|
|
748
|
+
const result = res;
|
|
749
|
+
if (result.success === true) {
|
|
750
|
+
setLoggedUser(result.data.user);
|
|
751
|
+
setActiveBusinessEntity(result.data.user.centers_access.find((item) => parseInt(item.id) === parseInt(saved_center_id)) || result.data.user.centers_access[0] || null);
|
|
752
|
+
} else {
|
|
753
|
+
setLoggedUser(null);
|
|
754
|
+
}
|
|
755
|
+
}).catch(() => setLoggedUser(null));
|
|
756
|
+
} else {
|
|
757
|
+
setLoggedUser(null);
|
|
758
|
+
}
|
|
759
|
+
}, [token]);
|
|
760
|
+
useEffect2(() => {
|
|
761
|
+
if (activeBusinessEntity) {
|
|
762
|
+
localStorage.setItem("active_center_id", activeBusinessEntity.id.toString());
|
|
763
|
+
}
|
|
764
|
+
}, [activeBusinessEntity]);
|
|
765
|
+
return /* @__PURE__ */ jsx5(SessionContext.Provider, { value: {
|
|
766
|
+
isAuthenticated: !!token,
|
|
767
|
+
loggedUser,
|
|
768
|
+
activeBusinessEntity,
|
|
769
|
+
setActiveBusinessEntity,
|
|
770
|
+
token,
|
|
771
|
+
login,
|
|
772
|
+
logout
|
|
773
|
+
}, children });
|
|
774
|
+
};
|
|
775
|
+
|
|
607
776
|
// src/components/layout/ModernDoubleSidebarLayout.tsx
|
|
608
|
-
import { Fragment, jsx as
|
|
777
|
+
import { Fragment, jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
609
778
|
var RewiseLayout = ({ children, module_name = "Rewise", module_description = "Description du module", primaryMenuItems, secondaryMenuItems }) => {
|
|
610
779
|
const location = useLocation();
|
|
611
780
|
const navigate = useNavigate();
|
|
612
781
|
const { theme, themeType, setTheme } = useTheme();
|
|
613
|
-
const
|
|
614
|
-
const [
|
|
615
|
-
const [
|
|
616
|
-
const [
|
|
617
|
-
const [
|
|
618
|
-
const [
|
|
619
|
-
const [
|
|
620
|
-
const [
|
|
621
|
-
const [
|
|
782
|
+
const { loggedUser, activeBusinessEntity, setActiveBusinessEntity } = useSession();
|
|
783
|
+
const [primaryCollapsed, setPrimaryCollapsed] = useState3(false);
|
|
784
|
+
const [secondaryCollapsed, setSecondaryCollapsed] = useState3(false);
|
|
785
|
+
const [mobileMenuOpen, setMobileMenuOpen] = useState3(false);
|
|
786
|
+
const [selectedModule, setSelectedModule] = useState3("dashboard");
|
|
787
|
+
const [searchQuery, setSearchQuery] = useState3("");
|
|
788
|
+
const [showNotifications, setShowNotifications] = useState3(false);
|
|
789
|
+
const [showUserMenu, setShowUserMenu] = useState3(false);
|
|
790
|
+
const [showThemeMenu, setShowThemeMenu] = useState3(false);
|
|
791
|
+
const [showCenterMenu, setShowCenterMenu] = useState3(false);
|
|
792
|
+
const [selectedCenterId, setSelectedCenterId] = useState3(
|
|
793
|
+
loggedUser?.centers_access?.[0]?.id || null
|
|
794
|
+
);
|
|
795
|
+
const [notifications, setNotifications] = useState3([
|
|
622
796
|
{
|
|
623
797
|
id: "1",
|
|
624
798
|
title: "Nouvelle facture",
|
|
@@ -636,7 +810,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
636
810
|
read: false
|
|
637
811
|
}
|
|
638
812
|
]);
|
|
639
|
-
|
|
813
|
+
useEffect3(() => {
|
|
640
814
|
const handleKeyDown = (e) => {
|
|
641
815
|
if (e.altKey && e.key === "m") {
|
|
642
816
|
e.preventDefault();
|
|
@@ -656,7 +830,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
656
830
|
document.addEventListener("keydown", handleKeyDown);
|
|
657
831
|
return () => document.removeEventListener("keydown", handleKeyDown);
|
|
658
832
|
}, []);
|
|
659
|
-
|
|
833
|
+
useEffect3(() => {
|
|
660
834
|
const path = location.pathname;
|
|
661
835
|
const moduleMatch = path.match(/^\/([^/]+)/);
|
|
662
836
|
if (moduleMatch) {
|
|
@@ -692,7 +866,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
692
866
|
);
|
|
693
867
|
};
|
|
694
868
|
return /* @__PURE__ */ jsxs3("div", { className: "flex h-screen bg-[var(--color-background)] overflow-hidden", children: [
|
|
695
|
-
/* @__PURE__ */
|
|
869
|
+
/* @__PURE__ */ jsx6(
|
|
696
870
|
"a",
|
|
697
871
|
{
|
|
698
872
|
href: "#main-content",
|
|
@@ -715,27 +889,27 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
715
889
|
"flex items-center gap-3",
|
|
716
890
|
primaryCollapsed && "justify-center"
|
|
717
891
|
), children: [
|
|
718
|
-
/* @__PURE__ */
|
|
892
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx6("span", { className: "text-[var(--color-background)] font-bold text-xl", children: "W" }) }),
|
|
719
893
|
!primaryCollapsed && /* @__PURE__ */ jsxs3("div", { children: [
|
|
720
|
-
/* @__PURE__ */
|
|
721
|
-
/* @__PURE__ */
|
|
894
|
+
/* @__PURE__ */ jsx6("h1", { className: "text-[var(--color-sidebar-text)] font-bold text-lg", children: module_name }),
|
|
895
|
+
/* @__PURE__ */ jsx6("p", { className: "text-[var(--color-sidebar-text-secondary)] text-xs", children: module_description })
|
|
722
896
|
] })
|
|
723
897
|
] }),
|
|
724
|
-
/* @__PURE__ */
|
|
898
|
+
/* @__PURE__ */ jsx6(
|
|
725
899
|
"button",
|
|
726
900
|
{
|
|
727
901
|
onClick: () => setPrimaryCollapsed(!primaryCollapsed),
|
|
728
902
|
className: "text-[var(--color-sidebar-text-secondary)] hover:text-[var(--color-sidebar-text)] transition-colors",
|
|
729
903
|
"aria-label": primaryCollapsed ? "D\xE9velopper le menu" : "R\xE9duire le menu",
|
|
730
904
|
"aria-expanded": !primaryCollapsed,
|
|
731
|
-
children: /* @__PURE__ */
|
|
905
|
+
children: /* @__PURE__ */ jsx6(ChevronLeft, { className: cn(
|
|
732
906
|
"w-5 h-5 transition-transform",
|
|
733
907
|
primaryCollapsed && "rotate-180"
|
|
734
908
|
) })
|
|
735
909
|
}
|
|
736
910
|
)
|
|
737
911
|
] }),
|
|
738
|
-
/* @__PURE__ */
|
|
912
|
+
/* @__PURE__ */ jsx6(
|
|
739
913
|
"nav",
|
|
740
914
|
{
|
|
741
915
|
className: "flex-1 py-4 overflow-y-auto",
|
|
@@ -761,45 +935,45 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
761
935
|
"aria-label": item.ariaLabel || item.label,
|
|
762
936
|
"aria-current": isModuleActive(item.id) ? "page" : void 0,
|
|
763
937
|
children: [
|
|
764
|
-
/* @__PURE__ */
|
|
938
|
+
/* @__PURE__ */ jsx6("div", { className: cn(
|
|
765
939
|
"transition-colors",
|
|
766
940
|
isModuleActive(item.id) ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)] group-hover:text-[var(--color-sidebar-text)]"
|
|
767
941
|
), children: item.icon }),
|
|
768
942
|
!primaryCollapsed && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
769
|
-
/* @__PURE__ */
|
|
943
|
+
/* @__PURE__ */ jsx6("span", { className: cn(
|
|
770
944
|
"flex-1 text-left text-sm font-medium transition-colors",
|
|
771
945
|
isModuleActive(item.id) ? "text-[var(--color-sidebar-text)]" : "text-[var(--color-sidebar-text-secondary)] group-hover:text-[var(--color-sidebar-text)]"
|
|
772
946
|
), children: item.label }),
|
|
773
|
-
item.badge && /* @__PURE__ */
|
|
947
|
+
item.badge && /* @__PURE__ */ jsx6("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-[var(--color-background)] rounded-full", children: item.badge })
|
|
774
948
|
] }),
|
|
775
|
-
primaryCollapsed && /* @__PURE__ */
|
|
949
|
+
primaryCollapsed && /* @__PURE__ */ jsx6("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 })
|
|
776
950
|
]
|
|
777
951
|
},
|
|
778
952
|
item.id
|
|
779
953
|
))
|
|
780
954
|
}
|
|
781
955
|
),
|
|
782
|
-
/* @__PURE__ */
|
|
956
|
+
/* @__PURE__ */ jsx6("div", { className: "p-4 border-t border-[var(--color-sidebar-border)]", children: /* @__PURE__ */ jsxs3("div", { className: cn(
|
|
783
957
|
"flex items-center gap-3",
|
|
784
958
|
primaryCollapsed && "justify-center"
|
|
785
959
|
), children: [
|
|
786
|
-
/* @__PURE__ */
|
|
960
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx6(User, { className: "w-5 h-5 text-[var(--color-background)]" }) }),
|
|
787
961
|
!primaryCollapsed && /* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
|
|
788
|
-
/* @__PURE__ */
|
|
789
|
-
/* @__PURE__ */
|
|
962
|
+
/* @__PURE__ */ jsx6("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" }),
|
|
963
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-sidebar-text-secondary)]", children: loggedUser?.email || "email@example.com" })
|
|
790
964
|
] })
|
|
791
965
|
] }) })
|
|
792
966
|
]
|
|
793
967
|
}
|
|
794
968
|
),
|
|
795
969
|
secondaryMenuItems[selectedModule] && /* @__PURE__ */ jsxs3(Fragment, { children: [
|
|
796
|
-
secondaryCollapsed && /* @__PURE__ */
|
|
970
|
+
secondaryCollapsed && /* @__PURE__ */ jsx6(
|
|
797
971
|
"button",
|
|
798
972
|
{
|
|
799
973
|
onClick: () => setSecondaryCollapsed(false),
|
|
800
974
|
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",
|
|
801
975
|
"aria-label": "Ouvrir le sous-menu",
|
|
802
|
-
children: /* @__PURE__ */
|
|
976
|
+
children: /* @__PURE__ */ jsx6(ChevronRight, { className: "w-5 h-5 text-[var(--color-text-tertiary)]" })
|
|
803
977
|
}
|
|
804
978
|
),
|
|
805
979
|
/* @__PURE__ */ jsxs3(
|
|
@@ -813,21 +987,21 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
813
987
|
"aria-label": "Navigation secondaire",
|
|
814
988
|
children: [
|
|
815
989
|
/* @__PURE__ */ jsxs3("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-border)]", children: [
|
|
816
|
-
/* @__PURE__ */
|
|
817
|
-
/* @__PURE__ */
|
|
990
|
+
/* @__PURE__ */ jsx6("h2", { className: "text-sm font-semibold text-[var(--color-text-secondary)] uppercase tracking-wider whitespace-nowrap", children: primaryMenuItems.find((item) => item.id === selectedModule)?.label }),
|
|
991
|
+
/* @__PURE__ */ jsx6(
|
|
818
992
|
"button",
|
|
819
993
|
{
|
|
820
994
|
onClick: () => setSecondaryCollapsed(!secondaryCollapsed),
|
|
821
995
|
className: "text-[var(--color-text-tertiary)] hover:text-[var(--color-text-primary)] flex-shrink-0",
|
|
822
996
|
"aria-label": secondaryCollapsed ? "D\xE9velopper le sous-menu" : "R\xE9duire le sous-menu",
|
|
823
|
-
children: /* @__PURE__ */
|
|
997
|
+
children: /* @__PURE__ */ jsx6(ChevronLeft, { className: cn(
|
|
824
998
|
"w-4 h-4 transition-transform",
|
|
825
999
|
secondaryCollapsed && "rotate-180"
|
|
826
1000
|
) })
|
|
827
1001
|
}
|
|
828
1002
|
)
|
|
829
1003
|
] }),
|
|
830
|
-
/* @__PURE__ */
|
|
1004
|
+
/* @__PURE__ */ jsx6(
|
|
831
1005
|
"nav",
|
|
832
1006
|
{
|
|
833
1007
|
className: "flex-1 py-4 overflow-y-auto",
|
|
@@ -845,15 +1019,15 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
845
1019
|
role: "menuitem",
|
|
846
1020
|
"aria-current": isActive(item.path || "") ? "page" : void 0,
|
|
847
1021
|
children: [
|
|
848
|
-
item.icon && /* @__PURE__ */
|
|
1022
|
+
item.icon && /* @__PURE__ */ jsx6("div", { className: cn(
|
|
849
1023
|
"transition-colors",
|
|
850
1024
|
isActive(item.path || "") ? "text-[var(--color-primary)]" : "text-[var(--color-text-tertiary)]"
|
|
851
1025
|
), children: item.icon }),
|
|
852
|
-
/* @__PURE__ */
|
|
1026
|
+
/* @__PURE__ */ jsx6("span", { className: cn(
|
|
853
1027
|
"flex-1 text-left text-sm",
|
|
854
1028
|
isActive(item.path || "") ? "text-[var(--color-primary)] font-medium" : "text-[var(--color-text-secondary)]"
|
|
855
1029
|
), children: item.label }),
|
|
856
|
-
item.badge && /* @__PURE__ */
|
|
1030
|
+
item.badge && /* @__PURE__ */ jsx6("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-white rounded-full", children: item.badge })
|
|
857
1031
|
]
|
|
858
1032
|
},
|
|
859
1033
|
item.id
|
|
@@ -864,7 +1038,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
864
1038
|
}
|
|
865
1039
|
)
|
|
866
1040
|
] }),
|
|
867
|
-
mobileMenuOpen && /* @__PURE__ */
|
|
1041
|
+
mobileMenuOpen && /* @__PURE__ */ jsx6(
|
|
868
1042
|
"div",
|
|
869
1043
|
{
|
|
870
1044
|
className: "fixed inset-0 bg-black bg-opacity-50 z-50 lg:hidden",
|
|
@@ -880,23 +1054,23 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
880
1054
|
children: [
|
|
881
1055
|
/* @__PURE__ */ jsxs3("div", { className: "h-16 flex items-center justify-between px-4 border-b border-[var(--color-sidebar-border)]", children: [
|
|
882
1056
|
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
|
|
883
|
-
/* @__PURE__ */
|
|
1057
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 bg-[var(--color-primary)] rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsx6("span", { className: "text-[var(--color-background)] font-bold text-xl", children: "W" }) }),
|
|
884
1058
|
/* @__PURE__ */ jsxs3("div", { children: [
|
|
885
|
-
/* @__PURE__ */
|
|
886
|
-
/* @__PURE__ */
|
|
1059
|
+
/* @__PURE__ */ jsx6("h1", { className: "text-white font-bold text-lg", children: "WiseBook" }),
|
|
1060
|
+
/* @__PURE__ */ jsx6("p", { className: "text-gray-400 text-xs", children: "ERP Next-Gen" })
|
|
887
1061
|
] })
|
|
888
1062
|
] }),
|
|
889
|
-
/* @__PURE__ */
|
|
1063
|
+
/* @__PURE__ */ jsx6(
|
|
890
1064
|
"button",
|
|
891
1065
|
{
|
|
892
1066
|
onClick: () => setMobileMenuOpen(false),
|
|
893
1067
|
className: "text-[var(--color-sidebar-text-secondary)]",
|
|
894
1068
|
"aria-label": "Fermer le menu",
|
|
895
|
-
children: /* @__PURE__ */
|
|
1069
|
+
children: /* @__PURE__ */ jsx6(X, { className: "w-6 h-6" })
|
|
896
1070
|
}
|
|
897
1071
|
)
|
|
898
1072
|
] }),
|
|
899
|
-
/* @__PURE__ */
|
|
1073
|
+
/* @__PURE__ */ jsx6("nav", { className: "py-4", role: "menubar", children: primaryMenuItems.map((item) => /* @__PURE__ */ jsxs3("div", { children: [
|
|
900
1074
|
/* @__PURE__ */ jsxs3(
|
|
901
1075
|
"button",
|
|
902
1076
|
{
|
|
@@ -916,19 +1090,19 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
916
1090
|
role: "menuitem",
|
|
917
1091
|
"aria-current": isModuleActive(item.id) ? "page" : void 0,
|
|
918
1092
|
children: [
|
|
919
|
-
/* @__PURE__ */
|
|
1093
|
+
/* @__PURE__ */ jsx6("div", { className: cn(
|
|
920
1094
|
"transition-colors",
|
|
921
1095
|
isModuleActive(item.id) ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)]"
|
|
922
1096
|
), children: item.icon }),
|
|
923
|
-
/* @__PURE__ */
|
|
1097
|
+
/* @__PURE__ */ jsx6("span", { className: cn(
|
|
924
1098
|
"flex-1 text-left text-sm font-medium",
|
|
925
1099
|
isModuleActive(item.id) ? "text-[var(--color-sidebar-text)]" : "text-[var(--color-sidebar-text-secondary)]"
|
|
926
1100
|
), children: item.label }),
|
|
927
|
-
item.badge && /* @__PURE__ */
|
|
1101
|
+
item.badge && /* @__PURE__ */ jsx6("span", { className: "px-2 py-0.5 text-xs bg-[var(--color-primary)] text-[var(--color-background)] rounded-full", children: item.badge })
|
|
928
1102
|
]
|
|
929
1103
|
}
|
|
930
1104
|
),
|
|
931
|
-
isModuleActive(item.id) && secondaryMenuItems[item.id] && /* @__PURE__ */
|
|
1105
|
+
isModuleActive(item.id) && secondaryMenuItems[item.id] && /* @__PURE__ */ jsx6("div", { className: "bg-[var(--color-sidebar-submenu-bg)] py-2", children: secondaryMenuItems[item.id].map((subItem) => /* @__PURE__ */ jsxs3(
|
|
932
1106
|
"button",
|
|
933
1107
|
{
|
|
934
1108
|
onClick: () => {
|
|
@@ -944,7 +1118,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
944
1118
|
),
|
|
945
1119
|
children: [
|
|
946
1120
|
subItem.icon,
|
|
947
|
-
/* @__PURE__ */
|
|
1121
|
+
/* @__PURE__ */ jsx6("span", { className: cn(
|
|
948
1122
|
isActive(subItem.path || "") ? "text-[var(--color-primary)]" : "text-[var(--color-sidebar-text-secondary)]"
|
|
949
1123
|
), children: subItem.label })
|
|
950
1124
|
]
|
|
@@ -965,23 +1139,23 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
965
1139
|
role: "banner",
|
|
966
1140
|
children: [
|
|
967
1141
|
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-4 flex-1", children: [
|
|
968
|
-
/* @__PURE__ */
|
|
1142
|
+
/* @__PURE__ */ jsx6(
|
|
969
1143
|
"button",
|
|
970
1144
|
{
|
|
971
1145
|
onClick: () => setMobileMenuOpen(true),
|
|
972
1146
|
className: "lg:hidden text-[var(--color-text-primary)]",
|
|
973
1147
|
"aria-label": "Ouvrir le menu mobile",
|
|
974
|
-
children: /* @__PURE__ */
|
|
1148
|
+
children: /* @__PURE__ */ jsx6(Menu, { className: "w-6 h-6" })
|
|
975
1149
|
}
|
|
976
1150
|
),
|
|
977
|
-
/* @__PURE__ */
|
|
1151
|
+
/* @__PURE__ */ jsx6(
|
|
978
1152
|
"nav",
|
|
979
1153
|
{
|
|
980
1154
|
className: "hidden sm:flex items-center gap-2 text-sm",
|
|
981
1155
|
"aria-label": "Fil d'Ariane",
|
|
982
1156
|
children: getBreadcrumbs().map((crumb, index) => /* @__PURE__ */ jsxs3(React2.Fragment, { children: [
|
|
983
|
-
index > 0 && /* @__PURE__ */
|
|
984
|
-
/* @__PURE__ */
|
|
1157
|
+
index > 0 && /* @__PURE__ */ jsx6(ChevronRight, { className: "w-4 h-4 text-[var(--color-text-tertiary)]" }),
|
|
1158
|
+
/* @__PURE__ */ jsx6(
|
|
985
1159
|
"button",
|
|
986
1160
|
{
|
|
987
1161
|
onClick: () => navigate(crumb.path),
|
|
@@ -996,8 +1170,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
996
1170
|
}
|
|
997
1171
|
),
|
|
998
1172
|
/* @__PURE__ */ jsxs3("div", { className: "relative max-w-md flex-1 hidden lg:block", children: [
|
|
999
|
-
/* @__PURE__ */
|
|
1000
|
-
/* @__PURE__ */
|
|
1173
|
+
/* @__PURE__ */ jsx6(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-[var(--color-text-tertiary)] w-5 h-5" }),
|
|
1174
|
+
/* @__PURE__ */ jsx6(
|
|
1001
1175
|
"input",
|
|
1002
1176
|
{
|
|
1003
1177
|
id: "global-search",
|
|
@@ -1012,8 +1186,68 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1012
1186
|
] })
|
|
1013
1187
|
] }),
|
|
1014
1188
|
/* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-3", children: [
|
|
1189
|
+
loggedUser?.centers_access && loggedUser.centers_access.length > 0 && /* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
1190
|
+
/* @__PURE__ */ jsxs3(
|
|
1191
|
+
"button",
|
|
1192
|
+
{
|
|
1193
|
+
onClick: () => setShowCenterMenu(!showCenterMenu),
|
|
1194
|
+
className: "flex items-center gap-2 px-3 py-1.5 bg-[var(--color-surface)] rounded-lg border border-[var(--color-border)] hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1195
|
+
title: "S\xE9lectionner un centre",
|
|
1196
|
+
"aria-label": "S\xE9lecteur de centre",
|
|
1197
|
+
"aria-expanded": showCenterMenu,
|
|
1198
|
+
children: [
|
|
1199
|
+
/* @__PURE__ */ jsx6(Building2, { className: "w-4 h-4 text-[var(--color-primary)]" }),
|
|
1200
|
+
/* @__PURE__ */ jsx6("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" }),
|
|
1201
|
+
/* @__PURE__ */ jsx6(ChevronRight, { className: cn(
|
|
1202
|
+
"w-4 h-4 text-[var(--color-text-tertiary)] transition-transform",
|
|
1203
|
+
showCenterMenu && "rotate-90"
|
|
1204
|
+
) })
|
|
1205
|
+
]
|
|
1206
|
+
}
|
|
1207
|
+
),
|
|
1208
|
+
showCenterMenu && /* @__PURE__ */ jsx6(
|
|
1209
|
+
"div",
|
|
1210
|
+
{
|
|
1211
|
+
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",
|
|
1212
|
+
role: "menu",
|
|
1213
|
+
"aria-label": "S\xE9lection du centre",
|
|
1214
|
+
children: /* @__PURE__ */ jsxs3("div", { className: "p-2", children: [
|
|
1215
|
+
/* @__PURE__ */ jsx6("p", { className: "px-3 py-2 text-xs font-semibold text-[var(--color-text-tertiary)] uppercase", children: "Centres disponibles" }),
|
|
1216
|
+
loggedUser.centers_access.map((center) => /* @__PURE__ */ jsxs3(
|
|
1217
|
+
"button",
|
|
1218
|
+
{
|
|
1219
|
+
onClick: () => {
|
|
1220
|
+
setActiveBusinessEntity(center);
|
|
1221
|
+
setSelectedCenterId(center.id);
|
|
1222
|
+
setShowCenterMenu(false);
|
|
1223
|
+
},
|
|
1224
|
+
className: cn(
|
|
1225
|
+
"w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1226
|
+
selectedCenterId === center.id && "bg-[var(--color-primary-light)] border-l-2 border-[var(--color-primary)]"
|
|
1227
|
+
),
|
|
1228
|
+
role: "menuitem",
|
|
1229
|
+
children: [
|
|
1230
|
+
/* @__PURE__ */ jsx6(Building2, { className: cn(
|
|
1231
|
+
"w-5 h-5",
|
|
1232
|
+
selectedCenterId === center.id ? "text-[var(--color-primary)]" : "text-[var(--color-text-tertiary)]"
|
|
1233
|
+
) }),
|
|
1234
|
+
/* @__PURE__ */ jsxs3("div", { className: "text-left flex-1", children: [
|
|
1235
|
+
/* @__PURE__ */ jsx6("p", { className: cn(
|
|
1236
|
+
"text-sm font-medium",
|
|
1237
|
+
selectedCenterId === center.id ? "text-[var(--color-primary)]" : "text-[var(--color-text-primary)]"
|
|
1238
|
+
), children: center.legal_name }),
|
|
1239
|
+
center.trading_name && /* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: center.trading_name })
|
|
1240
|
+
] })
|
|
1241
|
+
]
|
|
1242
|
+
},
|
|
1243
|
+
center.id
|
|
1244
|
+
))
|
|
1245
|
+
] })
|
|
1246
|
+
}
|
|
1247
|
+
)
|
|
1248
|
+
] }),
|
|
1015
1249
|
/* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
1016
|
-
/* @__PURE__ */
|
|
1250
|
+
/* @__PURE__ */ jsx6(
|
|
1017
1251
|
"button",
|
|
1018
1252
|
{
|
|
1019
1253
|
onClick: () => setShowThemeMenu(!showThemeMenu),
|
|
@@ -1021,17 +1255,17 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1021
1255
|
title: "Changer le th\xE8me",
|
|
1022
1256
|
"aria-label": "S\xE9lecteur de th\xE8me",
|
|
1023
1257
|
"aria-expanded": showThemeMenu,
|
|
1024
|
-
children: /* @__PURE__ */
|
|
1258
|
+
children: /* @__PURE__ */ jsx6(Palette, { className: "w-5 h-5 text-[var(--color-text-secondary)]" })
|
|
1025
1259
|
}
|
|
1026
1260
|
),
|
|
1027
|
-
showThemeMenu && /* @__PURE__ */
|
|
1261
|
+
showThemeMenu && /* @__PURE__ */ jsx6(
|
|
1028
1262
|
"div",
|
|
1029
1263
|
{
|
|
1030
1264
|
className: "absolute right-0 mt-2 w-64 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50",
|
|
1031
1265
|
role: "menu",
|
|
1032
1266
|
"aria-label": "S\xE9lection du th\xE8me",
|
|
1033
1267
|
children: /* @__PURE__ */ jsxs3("div", { className: "p-2", children: [
|
|
1034
|
-
/* @__PURE__ */
|
|
1268
|
+
/* @__PURE__ */ jsx6("p", { className: "px-3 py-2 text-xs font-semibold text-[var(--color-text-tertiary)] uppercase", children: "Th\xE8mes disponibles" }),
|
|
1035
1269
|
/* @__PURE__ */ jsxs3(
|
|
1036
1270
|
"button",
|
|
1037
1271
|
{
|
|
@@ -1042,10 +1276,10 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1042
1276
|
),
|
|
1043
1277
|
role: "menuitem",
|
|
1044
1278
|
children: [
|
|
1045
|
-
/* @__PURE__ */
|
|
1279
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-primary)] to-[var(--color-accent)]" }),
|
|
1046
1280
|
/* @__PURE__ */ jsxs3("div", { className: "text-left", children: [
|
|
1047
|
-
/* @__PURE__ */
|
|
1048
|
-
/* @__PURE__ */
|
|
1281
|
+
/* @__PURE__ */ jsx6("p", { className: "text-sm font-medium", children: "\xC9l\xE9gance Sobre" }),
|
|
1282
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "Finance traditionnelle" })
|
|
1049
1283
|
] })
|
|
1050
1284
|
]
|
|
1051
1285
|
}
|
|
@@ -1060,10 +1294,10 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1060
1294
|
),
|
|
1061
1295
|
role: "menuitem",
|
|
1062
1296
|
children: [
|
|
1063
|
-
/* @__PURE__ */
|
|
1297
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-success)] to-[var(--color-text-primary)]" }),
|
|
1064
1298
|
/* @__PURE__ */ jsxs3("div", { className: "text-left", children: [
|
|
1065
|
-
/* @__PURE__ */
|
|
1066
|
-
/* @__PURE__ */
|
|
1299
|
+
/* @__PURE__ */ jsx6("p", { className: "text-sm font-medium", children: "Modern Fintech" }),
|
|
1300
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "Tableau de bord moderne" })
|
|
1067
1301
|
] })
|
|
1068
1302
|
]
|
|
1069
1303
|
}
|
|
@@ -1078,10 +1312,10 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1078
1312
|
),
|
|
1079
1313
|
role: "menuitem",
|
|
1080
1314
|
children: [
|
|
1081
|
-
/* @__PURE__ */
|
|
1315
|
+
/* @__PURE__ */ jsx6("div", { className: "w-10 h-10 rounded-lg bg-gradient-to-br from-[var(--color-text-secondary)] to-[var(--color-accent)]" }),
|
|
1082
1316
|
/* @__PURE__ */ jsxs3("div", { className: "text-left", children: [
|
|
1083
|
-
/* @__PURE__ */
|
|
1084
|
-
/* @__PURE__ */
|
|
1317
|
+
/* @__PURE__ */ jsx6("p", { className: "text-sm font-medium", children: "Minimaliste Premium" }),
|
|
1318
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-text-tertiary)]", children: "\xC9l\xE9gance minimaliste" })
|
|
1085
1319
|
] })
|
|
1086
1320
|
]
|
|
1087
1321
|
}
|
|
@@ -1091,8 +1325,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1091
1325
|
)
|
|
1092
1326
|
] }),
|
|
1093
1327
|
/* @__PURE__ */ jsxs3("div", { className: "flex items-center px-3 py-1.5 bg-[var(--color-surface)] rounded-lg border border-[var(--color-border)]", children: [
|
|
1094
|
-
/* @__PURE__ */
|
|
1095
|
-
/* @__PURE__ */
|
|
1328
|
+
/* @__PURE__ */ jsx6(DollarSign, { className: "w-4 h-4 text-[var(--color-primary)] mr-2" }),
|
|
1329
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: "FCFA" })
|
|
1096
1330
|
] }),
|
|
1097
1331
|
/* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
1098
1332
|
/* @__PURE__ */ jsxs3(
|
|
@@ -1103,8 +1337,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1103
1337
|
"aria-label": `Notifications ${notifications.filter((n) => !n.read).length > 0 ? `(${notifications.filter((n) => !n.read).length} non lues)` : ""}`,
|
|
1104
1338
|
"aria-expanded": showNotifications,
|
|
1105
1339
|
children: [
|
|
1106
|
-
/* @__PURE__ */
|
|
1107
|
-
notifications.filter((n) => !n.read).length > 0 && /* @__PURE__ */
|
|
1340
|
+
/* @__PURE__ */ jsx6(Bell, { className: "w-5 h-5 text-[var(--color-text-secondary)]" }),
|
|
1341
|
+
notifications.filter((n) => !n.read).length > 0 && /* @__PURE__ */ jsx6("span", { className: "absolute top-1 right-1 w-2 h-2 bg-[var(--color-error)] rounded-full" })
|
|
1108
1342
|
]
|
|
1109
1343
|
}
|
|
1110
1344
|
),
|
|
@@ -1115,8 +1349,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1115
1349
|
role: "region",
|
|
1116
1350
|
"aria-label": "Centre de notifications",
|
|
1117
1351
|
children: [
|
|
1118
|
-
/* @__PURE__ */
|
|
1119
|
-
/* @__PURE__ */
|
|
1352
|
+
/* @__PURE__ */ jsx6("div", { className: "p-4 border-b border-[var(--color-border)]", children: /* @__PURE__ */ jsx6("h3", { className: "font-semibold text-[var(--color-text-primary)]", children: "Notifications" }) }),
|
|
1353
|
+
/* @__PURE__ */ jsx6("div", { className: "divide-y divide-[var(--color-border)]", children: notifications.map((notif) => /* @__PURE__ */ jsx6(
|
|
1120
1354
|
"div",
|
|
1121
1355
|
{
|
|
1122
1356
|
className: cn(
|
|
@@ -1125,7 +1359,7 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1125
1359
|
),
|
|
1126
1360
|
onClick: () => markNotificationAsRead(notif.id),
|
|
1127
1361
|
children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start gap-3", children: [
|
|
1128
|
-
/* @__PURE__ */
|
|
1362
|
+
/* @__PURE__ */ jsx6("div", { className: cn(
|
|
1129
1363
|
"w-2 h-2 rounded-full mt-2",
|
|
1130
1364
|
notif.type === "error" && "bg-[var(--color-error)]",
|
|
1131
1365
|
notif.type === "warning" && "bg-[var(--color-warning)]",
|
|
@@ -1133,9 +1367,9 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1133
1367
|
notif.type === "info" && "bg-[var(--color-info)]"
|
|
1134
1368
|
) }),
|
|
1135
1369
|
/* @__PURE__ */ jsxs3("div", { className: "flex-1", children: [
|
|
1136
|
-
/* @__PURE__ */
|
|
1137
|
-
/* @__PURE__ */
|
|
1138
|
-
/* @__PURE__ */
|
|
1370
|
+
/* @__PURE__ */ jsx6("p", { className: "text-sm font-medium text-[var(--color-text-primary)]", children: notif.title }),
|
|
1371
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-text-secondary)] mt-1", children: notif.message }),
|
|
1372
|
+
/* @__PURE__ */ jsx6("p", { className: "text-xs text-[var(--color-text-tertiary)] mt-2", children: notif.timestamp.toLocaleTimeString() })
|
|
1139
1373
|
] })
|
|
1140
1374
|
] })
|
|
1141
1375
|
},
|
|
@@ -1146,17 +1380,17 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1146
1380
|
)
|
|
1147
1381
|
] }),
|
|
1148
1382
|
/* @__PURE__ */ jsxs3("div", { className: "relative", children: [
|
|
1149
|
-
/* @__PURE__ */
|
|
1383
|
+
/* @__PURE__ */ jsx6(
|
|
1150
1384
|
"button",
|
|
1151
1385
|
{
|
|
1152
1386
|
onClick: () => setShowUserMenu(!showUserMenu),
|
|
1153
1387
|
className: "flex items-center gap-2 p-2 hover:bg-[var(--color-surface-hover)] rounded-lg transition-colors",
|
|
1154
1388
|
"aria-label": "Menu utilisateur",
|
|
1155
1389
|
"aria-expanded": showUserMenu,
|
|
1156
|
-
children: /* @__PURE__ */
|
|
1390
|
+
children: /* @__PURE__ */ jsx6("div", { className: "w-8 h-8 bg-[var(--color-primary)] rounded-full flex items-center justify-center", children: /* @__PURE__ */ jsx6(User, { className: "w-4 h-4 text-[var(--color-background)]" }) })
|
|
1157
1391
|
}
|
|
1158
1392
|
),
|
|
1159
|
-
showUserMenu && /* @__PURE__ */
|
|
1393
|
+
showUserMenu && /* @__PURE__ */ jsx6(
|
|
1160
1394
|
"div",
|
|
1161
1395
|
{
|
|
1162
1396
|
className: "absolute right-0 mt-2 w-56 bg-[var(--color-background)] rounded-lg shadow-xl border border-[var(--color-border)] z-50",
|
|
@@ -1169,8 +1403,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1169
1403
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1170
1404
|
role: "menuitem",
|
|
1171
1405
|
children: [
|
|
1172
|
-
/* @__PURE__ */
|
|
1173
|
-
/* @__PURE__ */
|
|
1406
|
+
/* @__PURE__ */ jsx6(User, { className: "w-4 h-4" }),
|
|
1407
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm", children: "Mon profil" })
|
|
1174
1408
|
]
|
|
1175
1409
|
}
|
|
1176
1410
|
),
|
|
@@ -1184,8 +1418,8 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1184
1418
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1185
1419
|
role: "menuitem",
|
|
1186
1420
|
children: [
|
|
1187
|
-
/* @__PURE__ */
|
|
1188
|
-
/* @__PURE__ */
|
|
1421
|
+
/* @__PURE__ */ jsx6(Settings, { className: "w-4 h-4" }),
|
|
1422
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm", children: "Param\xE8tres" })
|
|
1189
1423
|
]
|
|
1190
1424
|
}
|
|
1191
1425
|
),
|
|
@@ -1195,20 +1429,20 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1195
1429
|
className: "w-full flex items-center gap-3 px-3 py-2 rounded-lg hover:bg-[var(--color-surface-hover)] transition-colors",
|
|
1196
1430
|
role: "menuitem",
|
|
1197
1431
|
children: [
|
|
1198
|
-
/* @__PURE__ */
|
|
1199
|
-
/* @__PURE__ */
|
|
1432
|
+
/* @__PURE__ */ jsx6(HelpCircle, { className: "w-4 h-4" }),
|
|
1433
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm", children: "Aide" })
|
|
1200
1434
|
]
|
|
1201
1435
|
}
|
|
1202
1436
|
),
|
|
1203
|
-
/* @__PURE__ */
|
|
1437
|
+
/* @__PURE__ */ jsx6("hr", { className: "my-2 border-[var(--color-border)]" }),
|
|
1204
1438
|
/* @__PURE__ */ jsxs3(
|
|
1205
1439
|
"button",
|
|
1206
1440
|
{
|
|
1207
1441
|
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",
|
|
1208
1442
|
role: "menuitem",
|
|
1209
1443
|
children: [
|
|
1210
|
-
/* @__PURE__ */
|
|
1211
|
-
/* @__PURE__ */
|
|
1444
|
+
/* @__PURE__ */ jsx6(LogOut, { className: "w-4 h-4" }),
|
|
1445
|
+
/* @__PURE__ */ jsx6("span", { className: "text-sm", children: "D\xE9connexion" })
|
|
1212
1446
|
]
|
|
1213
1447
|
}
|
|
1214
1448
|
)
|
|
@@ -1220,13 +1454,13 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1220
1454
|
]
|
|
1221
1455
|
}
|
|
1222
1456
|
),
|
|
1223
|
-
/* @__PURE__ */
|
|
1457
|
+
/* @__PURE__ */ jsx6(
|
|
1224
1458
|
"main",
|
|
1225
1459
|
{
|
|
1226
1460
|
id: "main-content",
|
|
1227
1461
|
className: "flex-1 overflow-y-auto bg-[var(--color-background)]",
|
|
1228
1462
|
role: "main",
|
|
1229
|
-
children: /* @__PURE__ */
|
|
1463
|
+
children: /* @__PURE__ */ jsx6("div", { className: "p-3 lg:p-4", children })
|
|
1230
1464
|
}
|
|
1231
1465
|
)
|
|
1232
1466
|
] })
|
|
@@ -1235,21 +1469,21 @@ var RewiseLayout = ({ children, module_name = "Rewise", module_description = "De
|
|
|
1235
1469
|
var ModernDoubleSidebarLayout_default = RewiseLayout;
|
|
1236
1470
|
|
|
1237
1471
|
// src/components/ui/Toast.tsx
|
|
1238
|
-
import { useEffect as
|
|
1472
|
+
import { useEffect as useEffect4, useState as useState5 } from "react";
|
|
1239
1473
|
|
|
1240
1474
|
// src/contexts/ToastContext.tsx
|
|
1241
|
-
import { createContext as
|
|
1242
|
-
import { jsx as
|
|
1243
|
-
var ToastContext =
|
|
1475
|
+
import { createContext as createContext3, useContext as useContext3, useState as useState4, useCallback } from "react";
|
|
1476
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1477
|
+
var ToastContext = createContext3(void 0);
|
|
1244
1478
|
var useToast = () => {
|
|
1245
|
-
const context =
|
|
1479
|
+
const context = useContext3(ToastContext);
|
|
1246
1480
|
if (!context) {
|
|
1247
1481
|
throw new Error("useToast must be used within a ToastProvider");
|
|
1248
1482
|
}
|
|
1249
1483
|
return context;
|
|
1250
1484
|
};
|
|
1251
1485
|
var ToastProvider = ({ children }) => {
|
|
1252
|
-
const [toasts, setToasts] =
|
|
1486
|
+
const [toasts, setToasts] = useState4([]);
|
|
1253
1487
|
const generateId = () => {
|
|
1254
1488
|
return Date.now().toString(36) + Math.random().toString(36).substr(2);
|
|
1255
1489
|
};
|
|
@@ -1291,17 +1525,17 @@ var ToastProvider = ({ children }) => {
|
|
|
1291
1525
|
warning,
|
|
1292
1526
|
info
|
|
1293
1527
|
};
|
|
1294
|
-
return /* @__PURE__ */
|
|
1528
|
+
return /* @__PURE__ */ jsx7(ToastContext.Provider, { value, children });
|
|
1295
1529
|
};
|
|
1296
1530
|
|
|
1297
1531
|
// src/components/ui/Toast.tsx
|
|
1298
1532
|
import { CheckCircle, XCircle, AlertTriangle, Info, X as X2 } from "lucide-react";
|
|
1299
|
-
import { jsx as
|
|
1533
|
+
import { jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1300
1534
|
var ToastItem = ({ toast }) => {
|
|
1301
1535
|
const { removeToast } = useToast();
|
|
1302
|
-
const [isVisible, setIsVisible] =
|
|
1303
|
-
const [isLeaving, setIsLeaving] =
|
|
1304
|
-
|
|
1536
|
+
const [isVisible, setIsVisible] = useState5(false);
|
|
1537
|
+
const [isLeaving, setIsLeaving] = useState5(false);
|
|
1538
|
+
useEffect4(() => {
|
|
1305
1539
|
const timer = setTimeout(() => setIsVisible(true), 10);
|
|
1306
1540
|
return () => clearTimeout(timer);
|
|
1307
1541
|
}, []);
|
|
@@ -1314,13 +1548,13 @@ var ToastItem = ({ toast }) => {
|
|
|
1314
1548
|
const getIcon = () => {
|
|
1315
1549
|
switch (toast.type) {
|
|
1316
1550
|
case "success":
|
|
1317
|
-
return /* @__PURE__ */
|
|
1551
|
+
return /* @__PURE__ */ jsx8(CheckCircle, { className: "w-5 h-5 text-green-600" });
|
|
1318
1552
|
case "error":
|
|
1319
|
-
return /* @__PURE__ */
|
|
1553
|
+
return /* @__PURE__ */ jsx8(XCircle, { className: "w-5 h-5 text-red-600" });
|
|
1320
1554
|
case "warning":
|
|
1321
|
-
return /* @__PURE__ */
|
|
1555
|
+
return /* @__PURE__ */ jsx8(AlertTriangle, { className: "w-5 h-5 text-yellow-600" });
|
|
1322
1556
|
case "info":
|
|
1323
|
-
return /* @__PURE__ */
|
|
1557
|
+
return /* @__PURE__ */ jsx8(Info, { className: "w-5 h-5 text-blue-600" });
|
|
1324
1558
|
}
|
|
1325
1559
|
};
|
|
1326
1560
|
const getBackgroundColor = () => {
|
|
@@ -1346,14 +1580,14 @@ var ToastItem = ({ toast }) => {
|
|
|
1346
1580
|
flex items-start space-x-3
|
|
1347
1581
|
`,
|
|
1348
1582
|
children: [
|
|
1349
|
-
/* @__PURE__ */
|
|
1350
|
-
/* @__PURE__ */
|
|
1351
|
-
/* @__PURE__ */
|
|
1583
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-shrink-0", children: getIcon() }),
|
|
1584
|
+
/* @__PURE__ */ jsx8("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx8("p", { className: "text-sm text-gray-900 font-medium", children: toast.message }) }),
|
|
1585
|
+
/* @__PURE__ */ jsx8(
|
|
1352
1586
|
"button",
|
|
1353
1587
|
{
|
|
1354
1588
|
onClick: handleClose,
|
|
1355
1589
|
className: "flex-shrink-0 ml-4 text-gray-400 hover:text-gray-600 transition-colors",
|
|
1356
|
-
children: /* @__PURE__ */
|
|
1590
|
+
children: /* @__PURE__ */ jsx8(X2, { className: "w-4 h-4" })
|
|
1357
1591
|
}
|
|
1358
1592
|
)
|
|
1359
1593
|
]
|
|
@@ -1362,179 +1596,24 @@ var ToastItem = ({ toast }) => {
|
|
|
1362
1596
|
};
|
|
1363
1597
|
var ToastContainer = () => {
|
|
1364
1598
|
const { toasts } = useToast();
|
|
1365
|
-
return /* @__PURE__ */
|
|
1599
|
+
return /* @__PURE__ */ jsx8("div", { className: "fixed top-4 right-4 z-50 space-y-3", children: toasts.map((toast) => /* @__PURE__ */ jsx8(ToastItem, { toast }, toast.id)) });
|
|
1366
1600
|
};
|
|
1367
1601
|
var Toast_default = ToastContainer;
|
|
1368
1602
|
|
|
1369
|
-
// src/contexts/SessionContext.tsx
|
|
1370
|
-
import { createContext as createContext3, useContext as useContext3, useEffect as useEffect4, useState as useState5 } from "react";
|
|
1371
|
-
|
|
1372
|
-
// src/services/api.ts
|
|
1373
|
-
var ADDRESS_IP = "localhost:8000";
|
|
1374
|
-
var ADDRESS_IP_URL = `http://${ADDRESS_IP}/`;
|
|
1375
|
-
var API_URL = `${ADDRESS_IP_URL}api`;
|
|
1376
|
-
var FetchApi = class {
|
|
1377
|
-
static async post(url, payload, token) {
|
|
1378
|
-
const headers = {
|
|
1379
|
-
"Content-Type": "application/json"
|
|
1380
|
-
};
|
|
1381
|
-
if (token) {
|
|
1382
|
-
headers["Authorization"] = `Token ${token}`;
|
|
1383
|
-
}
|
|
1384
|
-
const res = await fetch(url, {
|
|
1385
|
-
method: "POST",
|
|
1386
|
-
headers,
|
|
1387
|
-
body: payload ? JSON.stringify(payload) : void 0
|
|
1388
|
-
});
|
|
1389
|
-
if (!res.ok) throw new Error(await res.text());
|
|
1390
|
-
return res.json();
|
|
1391
|
-
}
|
|
1392
|
-
static async get(url, token) {
|
|
1393
|
-
const headers = {};
|
|
1394
|
-
if (token) {
|
|
1395
|
-
headers["Authorization"] = `Token ${token}`;
|
|
1396
|
-
}
|
|
1397
|
-
const res = await fetch(url, {
|
|
1398
|
-
method: "GET",
|
|
1399
|
-
headers
|
|
1400
|
-
});
|
|
1401
|
-
if (!res.ok) throw new Error(await res.text());
|
|
1402
|
-
return res.json();
|
|
1403
|
-
}
|
|
1404
|
-
static async put(url, payload, token) {
|
|
1405
|
-
const headers = {
|
|
1406
|
-
"Content-Type": "application/json"
|
|
1407
|
-
};
|
|
1408
|
-
if (token) {
|
|
1409
|
-
headers["Authorization"] = `Token ${token}`;
|
|
1410
|
-
}
|
|
1411
|
-
const res = await fetch(url, {
|
|
1412
|
-
method: "PUT",
|
|
1413
|
-
headers,
|
|
1414
|
-
body: payload ? JSON.stringify(payload) : void 0
|
|
1415
|
-
});
|
|
1416
|
-
if (!res.ok) throw new Error(await res.text());
|
|
1417
|
-
return res.json();
|
|
1418
|
-
}
|
|
1419
|
-
static async delete(url, token) {
|
|
1420
|
-
const headers = {};
|
|
1421
|
-
if (token) {
|
|
1422
|
-
headers["Authorization"] = `Token ${token}`;
|
|
1423
|
-
}
|
|
1424
|
-
const res = await fetch(url, {
|
|
1425
|
-
method: "DELETE",
|
|
1426
|
-
headers
|
|
1427
|
-
});
|
|
1428
|
-
if (!res.ok) throw new Error(await res.text());
|
|
1429
|
-
return res.json();
|
|
1430
|
-
}
|
|
1431
|
-
};
|
|
1432
|
-
|
|
1433
|
-
// src/services/AuthServices.ts
|
|
1434
|
-
var API_BASE_URL = `${API_URL}/core/auth/`;
|
|
1435
|
-
var FetchApi2 = class {
|
|
1436
|
-
static async post(url, payload, token) {
|
|
1437
|
-
const headers = {
|
|
1438
|
-
"Content-Type": "application/json"
|
|
1439
|
-
};
|
|
1440
|
-
if (token) {
|
|
1441
|
-
headers["Authorization"] = `Token ${token}`;
|
|
1442
|
-
}
|
|
1443
|
-
const res = await fetch(url, {
|
|
1444
|
-
method: "POST",
|
|
1445
|
-
headers,
|
|
1446
|
-
body: payload ? JSON.stringify(payload) : void 0
|
|
1447
|
-
});
|
|
1448
|
-
if (!res.ok) throw new Error(await res.text());
|
|
1449
|
-
return res.json();
|
|
1450
|
-
}
|
|
1451
|
-
static async get(url, token) {
|
|
1452
|
-
const headers = {};
|
|
1453
|
-
if (token) {
|
|
1454
|
-
headers["Authorization"] = `Token ${token}`;
|
|
1455
|
-
}
|
|
1456
|
-
const res = await fetch(url, {
|
|
1457
|
-
method: "GET",
|
|
1458
|
-
headers
|
|
1459
|
-
});
|
|
1460
|
-
if (!res.ok) throw new Error(await res.text());
|
|
1461
|
-
return res.json();
|
|
1462
|
-
}
|
|
1463
|
-
};
|
|
1464
|
-
var AuthServices = {
|
|
1465
|
-
sendOtp: (payload) => FetchApi2.post(`${API_BASE_URL}send-otp/`, payload),
|
|
1466
|
-
verifyOtp: (payload) => FetchApi2.post(`${API_BASE_URL}verify-otp/`, payload),
|
|
1467
|
-
completeRegistration: (payload) => FetchApi2.post(`${API_BASE_URL}complete-registration/`, payload),
|
|
1468
|
-
addUser: (payload) => FetchApi2.post(`${API_BASE_URL}add-user/`, payload),
|
|
1469
|
-
login: (payload) => FetchApi2.post(`${API_BASE_URL}login/`, payload),
|
|
1470
|
-
getUserInformations: (token) => FetchApi2.get(`${API_BASE_URL}user-informations/`, token),
|
|
1471
|
-
logout: () => FetchApi2.post(`${API_BASE_URL}logout/`)
|
|
1472
|
-
};
|
|
1473
|
-
|
|
1474
|
-
// src/contexts/SessionContext.tsx
|
|
1475
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1476
|
-
var SessionContext = createContext3(void 0);
|
|
1477
|
-
var useSession = () => {
|
|
1478
|
-
const context = useContext3(SessionContext);
|
|
1479
|
-
if (!context) {
|
|
1480
|
-
throw new Error("useSession must be used within a SessionProvider");
|
|
1481
|
-
}
|
|
1482
|
-
return context;
|
|
1483
|
-
};
|
|
1484
|
-
var SessionProvider = ({ children }) => {
|
|
1485
|
-
const [token, setToken] = useState5(localStorage.getItem("token"));
|
|
1486
|
-
const [loggedUser, setLoggedUser] = useState5(null);
|
|
1487
|
-
useEffect4(() => {
|
|
1488
|
-
const storedToken = localStorage.getItem("token");
|
|
1489
|
-
if (storedToken) {
|
|
1490
|
-
setToken(storedToken);
|
|
1491
|
-
}
|
|
1492
|
-
}, []);
|
|
1493
|
-
const login = (newToken) => {
|
|
1494
|
-
localStorage.setItem("token", newToken);
|
|
1495
|
-
setToken(newToken);
|
|
1496
|
-
};
|
|
1497
|
-
const logout = () => {
|
|
1498
|
-
localStorage.removeItem("token");
|
|
1499
|
-
setToken(null);
|
|
1500
|
-
};
|
|
1501
|
-
useEffect4(() => {
|
|
1502
|
-
if (token) {
|
|
1503
|
-
AuthServices.getUserInformations(token).then((res) => {
|
|
1504
|
-
const result = res;
|
|
1505
|
-
if (result.success === true) {
|
|
1506
|
-
setLoggedUser(result.data.user);
|
|
1507
|
-
} else {
|
|
1508
|
-
setLoggedUser(null);
|
|
1509
|
-
}
|
|
1510
|
-
}).catch(() => setLoggedUser(null));
|
|
1511
|
-
} else {
|
|
1512
|
-
setLoggedUser(null);
|
|
1513
|
-
}
|
|
1514
|
-
}, [token]);
|
|
1515
|
-
return /* @__PURE__ */ jsx8(SessionContext.Provider, { value: {
|
|
1516
|
-
isAuthenticated: !!token,
|
|
1517
|
-
loggedUser,
|
|
1518
|
-
token,
|
|
1519
|
-
login,
|
|
1520
|
-
logout
|
|
1521
|
-
}, children });
|
|
1522
|
-
};
|
|
1523
|
-
|
|
1524
1603
|
// src/components/common/Pages.tsx
|
|
1525
1604
|
import { ChevronLeft as ChevronLeft2, Download, Menu as Menu2, Settings as Settings2 } from "lucide-react";
|
|
1526
1605
|
import { useState as useState6 } from "react";
|
|
1527
|
-
import { jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1606
|
+
import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1528
1607
|
var Pages = ({
|
|
1529
1608
|
title = "",
|
|
1530
1609
|
description = "",
|
|
1531
1610
|
sideAction,
|
|
1532
1611
|
sidebar,
|
|
1533
|
-
tabs =
|
|
1612
|
+
tabs = /* @__PURE__ */ jsx9(Fragment2, {}),
|
|
1534
1613
|
children
|
|
1535
1614
|
}) => {
|
|
1536
1615
|
const [sidebarOpen, setSidebarOpen] = useState6(false);
|
|
1537
|
-
return /* @__PURE__ */ jsxs5("div", { className: "flex h-full bg-gray-
|
|
1616
|
+
return /* @__PURE__ */ jsxs5("div", { className: "flex h-full bg-gray-100", children: [
|
|
1538
1617
|
/* @__PURE__ */ jsxs5("div", { className: "flex-1 flex flex-col", children: [
|
|
1539
1618
|
/* @__PURE__ */ jsxs5("div", { className: "bg-white border-b border-gray-200 p-6", children: [
|
|
1540
1619
|
/* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
|
|
@@ -1544,16 +1623,9 @@ var Pages = ({
|
|
|
1544
1623
|
] }) }),
|
|
1545
1624
|
/* @__PURE__ */ jsx9("div", { className: "flex items-center space-x-3", children: sideAction })
|
|
1546
1625
|
] }),
|
|
1547
|
-
tabs
|
|
1548
|
-
"button",
|
|
1549
|
-
{
|
|
1550
|
-
className: `px-4 py-2 text-sm rounded-lg transition-all whitespace-nowrap ${tab.id === "manual" ? "bg-[#6A8A82] text-white shadow-md" : "text-gray-600 hover:bg-gray-100"}`,
|
|
1551
|
-
children: tab.label
|
|
1552
|
-
},
|
|
1553
|
-
tab.id
|
|
1554
|
-
)) })
|
|
1626
|
+
tabs
|
|
1555
1627
|
] }),
|
|
1556
|
-
/* @__PURE__ */ jsx9("div", { className: "flex-1 p-6 space-y-6", children })
|
|
1628
|
+
/* @__PURE__ */ jsx9("div", { className: "flex-1 p-6 space-y-6 min-h-[80vh]", children })
|
|
1557
1629
|
] }),
|
|
1558
1630
|
sidebar && /* @__PURE__ */ jsxs5("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: [
|
|
1559
1631
|
/* @__PURE__ */ jsx9("div", { className: "p-4 ", children: /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
|
|
@@ -1603,7 +1675,7 @@ var API_BASE_URL2 = `${API_URL}/core/auth/`;
|
|
|
1603
1675
|
var USERS_API_URL = `${API_URL}/core/users/`;
|
|
1604
1676
|
var UserServices = {
|
|
1605
1677
|
// Créer un nouvel utilisateur
|
|
1606
|
-
addUser: (data, token) => FetchApi.post(`${
|
|
1678
|
+
addUser: (data, token) => FetchApi.post(`${API_BASE_URL2}add-user/`, data, token),
|
|
1607
1679
|
// Obtenir tous les utilisateurs
|
|
1608
1680
|
getUsers: (token) => FetchApi.get(`${USERS_API_URL}`, token),
|
|
1609
1681
|
// Obtenir un utilisateur par ID
|
|
@@ -1614,11 +1686,302 @@ var UserServices = {
|
|
|
1614
1686
|
deleteUser: (id, token) => FetchApi.delete(`${USERS_API_URL}${id}/`, token),
|
|
1615
1687
|
// Obtenir les utilisateurs d'une entité
|
|
1616
1688
|
getEntityUsers: (entityId, token) => FetchApi.get(`${API_URL}/core/entities/${entityId}/users/`, token),
|
|
1689
|
+
// Obtenir les utilisateurs d'une entité
|
|
1690
|
+
getuserEntitiesAccess: (id, token) => FetchApi.get(`${API_URL}/core/entities/`, token),
|
|
1691
|
+
// !!! ce n'est pas la bonne url
|
|
1617
1692
|
// Ajouter un utilisateur à une entité
|
|
1618
1693
|
addUserToEntity: (entityId, userId, token) => FetchApi.post(`${API_URL}/core/entities/${entityId}/users/`, { user_id: userId }, token)
|
|
1619
1694
|
};
|
|
1695
|
+
|
|
1696
|
+
// src/components/common/FDrawer.tsx
|
|
1697
|
+
import { useEffect as useEffect5, useState as useState7 } from "react";
|
|
1698
|
+
import { useLocation as useLocation2, useNavigate as useNavigate2, useSearchParams, Link as Link2 } from "react-router-dom";
|
|
1699
|
+
import { ArrowDownAZ, ArrowDownUp, ArrowUpAZ, MoreVertical } from "lucide-react";
|
|
1700
|
+
import { Fragment as Fragment3, jsx as jsx10, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1701
|
+
var FDrawer = ({
|
|
1702
|
+
children,
|
|
1703
|
+
apiEndpoint,
|
|
1704
|
+
columns,
|
|
1705
|
+
actions,
|
|
1706
|
+
ordering,
|
|
1707
|
+
toggle
|
|
1708
|
+
}) => {
|
|
1709
|
+
const navigate = useNavigate2();
|
|
1710
|
+
const [searchParams] = useSearchParams();
|
|
1711
|
+
const location = useLocation2();
|
|
1712
|
+
const allParams = Object.fromEntries([...searchParams]);
|
|
1713
|
+
const { activeBusinessEntity, token } = useSession();
|
|
1714
|
+
const [data, setData] = useState7([]);
|
|
1715
|
+
const [order_by, setOrderBy] = useState7(ordering || "-id");
|
|
1716
|
+
const [loading, setLoading] = useState7(false);
|
|
1717
|
+
const [showOrdering, setShowOrdering] = useState7(null);
|
|
1718
|
+
const [showFilters, setShowFilters] = useState7(null);
|
|
1719
|
+
const [dropdownOpen, setDropdownOpen] = useState7(null);
|
|
1720
|
+
const [queryURL, setQueryURL] = useState7("");
|
|
1721
|
+
const [reponseDetail, setReponseDetail] = useState7({
|
|
1722
|
+
total_pages: null,
|
|
1723
|
+
previous: null,
|
|
1724
|
+
next: null,
|
|
1725
|
+
current_page: null
|
|
1726
|
+
});
|
|
1727
|
+
const makeFilters = () => columns.reduce((acc, item) => {
|
|
1728
|
+
acc[item.formule ? `${item.search_name}__icontains` : `${item.key}__icontains`] = "";
|
|
1729
|
+
return acc;
|
|
1730
|
+
}, {});
|
|
1731
|
+
const preFilters = columns.length > 0 ? makeFilters() : [];
|
|
1732
|
+
const [filters, setFilters] = useState7(
|
|
1733
|
+
() => Object.keys(allParams).length > 0 ? allParams : { ...preFilters, center_id: activeBusinessEntity?.id ?? null, order_by: order_by ?? "id", page: 1 }
|
|
1734
|
+
);
|
|
1735
|
+
const getDataFilter = async () => {
|
|
1736
|
+
setLoading(true);
|
|
1737
|
+
try {
|
|
1738
|
+
const response = await fetch(queryURL, {
|
|
1739
|
+
method: "GET",
|
|
1740
|
+
headers: {
|
|
1741
|
+
"Content-Type": "application/json",
|
|
1742
|
+
"Authorization": `token ${token}`
|
|
1743
|
+
}
|
|
1744
|
+
});
|
|
1745
|
+
if (!response.ok) throw new Error(`HTTP ERROR! STATUS: ${response.status}`);
|
|
1746
|
+
const data2 = await response.json();
|
|
1747
|
+
setReponseDetail(data2.paginate);
|
|
1748
|
+
setData(data2.data);
|
|
1749
|
+
} catch (error) {
|
|
1750
|
+
console.error("ERROR FETCHING DATA", error);
|
|
1751
|
+
} finally {
|
|
1752
|
+
setLoading(false);
|
|
1753
|
+
}
|
|
1754
|
+
};
|
|
1755
|
+
useEffect5(() => {
|
|
1756
|
+
const params = new URLSearchParams(filters).toString();
|
|
1757
|
+
setQueryURL(`${API_URL}${apiEndpoint}?${params}`);
|
|
1758
|
+
navigate(`${location.pathname}?${params}`);
|
|
1759
|
+
}, [filters]);
|
|
1760
|
+
useEffect5(() => {
|
|
1761
|
+
getDataFilter();
|
|
1762
|
+
}, [activeBusinessEntity, queryURL, toggle]);
|
|
1763
|
+
const renderColumnFilter = (column) => {
|
|
1764
|
+
if (!column.filterable) return null;
|
|
1765
|
+
const handleChange = (key, value) => setFilters({ ...filters, [key]: value, page: 1 });
|
|
1766
|
+
switch (column.type) {
|
|
1767
|
+
case "text":
|
|
1768
|
+
return /* @__PURE__ */ jsx10(
|
|
1769
|
+
"input",
|
|
1770
|
+
{
|
|
1771
|
+
id: column.key,
|
|
1772
|
+
type: "text",
|
|
1773
|
+
value: filters[`${column.key}__icontains`] || "",
|
|
1774
|
+
placeholder: "Rechercher...",
|
|
1775
|
+
className: "border border-gray-300 rounded-lg p-3 w-full",
|
|
1776
|
+
onChange: (e) => handleChange(`${column.key}__icontains`, e.target.value)
|
|
1777
|
+
}
|
|
1778
|
+
);
|
|
1779
|
+
case "number":
|
|
1780
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex w-full gap-1", children: [
|
|
1781
|
+
/* @__PURE__ */ jsx10(
|
|
1782
|
+
"input",
|
|
1783
|
+
{
|
|
1784
|
+
type: "number",
|
|
1785
|
+
placeholder: "Min",
|
|
1786
|
+
className: "border border-gray-300 rounded-lg p-3 w-1/2",
|
|
1787
|
+
onChange: (e) => handleChange(`${column.key}_min`, e.target.value)
|
|
1788
|
+
}
|
|
1789
|
+
),
|
|
1790
|
+
/* @__PURE__ */ jsx10(
|
|
1791
|
+
"input",
|
|
1792
|
+
{
|
|
1793
|
+
type: "number",
|
|
1794
|
+
placeholder: "Max",
|
|
1795
|
+
className: "border border-gray-300 rounded-lg p-3 w-1/2",
|
|
1796
|
+
onChange: (e) => handleChange(`${column.key}_max`, e.target.value)
|
|
1797
|
+
}
|
|
1798
|
+
)
|
|
1799
|
+
] });
|
|
1800
|
+
case "date":
|
|
1801
|
+
return /* @__PURE__ */ jsxs6("div", { className: "flex w-full gap-1", children: [
|
|
1802
|
+
/* @__PURE__ */ jsx10(
|
|
1803
|
+
"input",
|
|
1804
|
+
{
|
|
1805
|
+
type: "date",
|
|
1806
|
+
placeholder: "Du",
|
|
1807
|
+
className: "border border-gray-300 rounded-lg p-3 w-1/2",
|
|
1808
|
+
onChange: (e) => handleChange(`${column.key}_from`, e.target.value)
|
|
1809
|
+
}
|
|
1810
|
+
),
|
|
1811
|
+
/* @__PURE__ */ jsx10(
|
|
1812
|
+
"input",
|
|
1813
|
+
{
|
|
1814
|
+
type: "date",
|
|
1815
|
+
placeholder: "Au",
|
|
1816
|
+
className: "border border-gray-300 rounded-lg p-3 w-1/2",
|
|
1817
|
+
onChange: (e) => handleChange(`${column.key}_to`, e.target.value)
|
|
1818
|
+
}
|
|
1819
|
+
)
|
|
1820
|
+
] });
|
|
1821
|
+
default:
|
|
1822
|
+
return /* @__PURE__ */ jsx10(
|
|
1823
|
+
"input",
|
|
1824
|
+
{
|
|
1825
|
+
id: column.key,
|
|
1826
|
+
type: column.type,
|
|
1827
|
+
className: "border border-gray-300 rounded-md p-1",
|
|
1828
|
+
onChange: (e) => handleChange(column.key, e.target.value)
|
|
1829
|
+
}
|
|
1830
|
+
);
|
|
1831
|
+
}
|
|
1832
|
+
};
|
|
1833
|
+
const renderLine = (item) => columns.map((column) => {
|
|
1834
|
+
let cellContent = column.formule ? column.formule(item) : item[column.key];
|
|
1835
|
+
if (column.type === "date" && item[column.key])
|
|
1836
|
+
cellContent = new Date(item[column.key]).toLocaleDateString();
|
|
1837
|
+
return /* @__PURE__ */ jsx10("td", { className: "px-6 py-4 whitespace-nowrap text-sm text-gray-500", children: cellContent }, column.key);
|
|
1838
|
+
});
|
|
1839
|
+
return /* @__PURE__ */ jsxs6(Fragment3, { children: [
|
|
1840
|
+
/* @__PURE__ */ jsxs6("table", { className: "w-full", children: [
|
|
1841
|
+
/* @__PURE__ */ jsx10("thead", { className: "bg-gray-50", children: /* @__PURE__ */ jsxs6("tr", { children: [
|
|
1842
|
+
columns.map((column) => /* @__PURE__ */ jsxs6("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider relative", scope: "col", children: [
|
|
1843
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex align-center items-center gap-2", children: [
|
|
1844
|
+
/* @__PURE__ */ jsx10("span", { onClick: () => setShowFilters(showFilters === column.key ? "" : column.key), children: column.label }),
|
|
1845
|
+
/* @__PURE__ */ jsx10(ArrowDownUp, { className: "h-4 w-4 cursor-pointer", onClick: () => setShowOrdering(showOrdering === column.key ? "" : column.key) })
|
|
1846
|
+
] }),
|
|
1847
|
+
showOrdering === column.key && /* @__PURE__ */ jsx10("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__ */ jsxs6("div", { className: "p-2", children: [
|
|
1848
|
+
/* @__PURE__ */ jsx10(
|
|
1849
|
+
"button",
|
|
1850
|
+
{
|
|
1851
|
+
type: "button",
|
|
1852
|
+
onClick: () => {
|
|
1853
|
+
setOrderBy(column.key);
|
|
1854
|
+
setFilters({ ...filters, order_by: column.key });
|
|
1855
|
+
setShowOrdering(null);
|
|
1856
|
+
},
|
|
1857
|
+
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)]"),
|
|
1858
|
+
role: "menuitem",
|
|
1859
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "text-left flex-1 flex items-center gap-2", children: [
|
|
1860
|
+
/* @__PURE__ */ jsx10(ArrowUpAZ, { className: "h-4 w-4" }),
|
|
1861
|
+
/* @__PURE__ */ jsx10("p", { className: cn("text-sm font-medium", order_by === column.key ? "text-[var(--color-primary)]" : "text-[var(--color-text-primary)]"), children: "Croissant" })
|
|
1862
|
+
] })
|
|
1863
|
+
}
|
|
1864
|
+
),
|
|
1865
|
+
/* @__PURE__ */ jsx10(
|
|
1866
|
+
"button",
|
|
1867
|
+
{
|
|
1868
|
+
type: "button",
|
|
1869
|
+
onClick: () => {
|
|
1870
|
+
setOrderBy(`-${column.key}`);
|
|
1871
|
+
setFilters({ ...filters, order_by: `-${column.key}` });
|
|
1872
|
+
setShowOrdering(null);
|
|
1873
|
+
},
|
|
1874
|
+
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)]"),
|
|
1875
|
+
role: "menuitem",
|
|
1876
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "text-left flex-1 flex items-center gap-2", children: [
|
|
1877
|
+
/* @__PURE__ */ jsx10(ArrowDownAZ, { className: "h-4 w-4" }),
|
|
1878
|
+
/* @__PURE__ */ jsx10("p", { className: cn("text-sm font-medium", order_by === `-${column.key}` ? "text-[var(--color-primary)]" : "text-[var(--color-text-primary)]"), children: "D\xE9croissant" })
|
|
1879
|
+
] })
|
|
1880
|
+
}
|
|
1881
|
+
)
|
|
1882
|
+
] }) }),
|
|
1883
|
+
showFilters === column.key && /* @__PURE__ */ jsxs6("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: [
|
|
1884
|
+
/* @__PURE__ */ jsx10("div", { className: "py-2 px-4", children: /* @__PURE__ */ jsx10("h3", { className: "font-semibold text-[var(--color-text-primary)]", children: "Filtrer" }) }),
|
|
1885
|
+
/* @__PURE__ */ jsx10("div", { className: "pb-3 px-4", children: renderColumnFilter(column) })
|
|
1886
|
+
] })
|
|
1887
|
+
] }, column.key)),
|
|
1888
|
+
/* @__PURE__ */ jsx10("th", { className: "px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider" })
|
|
1889
|
+
] }) }),
|
|
1890
|
+
/* @__PURE__ */ jsx10("tbody", { className: "bg-white divide-y divide-gray-200", children: data.map((item) => /* @__PURE__ */ jsxs6("tr", { className: "hover:bg-gray-50 cursor-pointer", children: [
|
|
1891
|
+
renderLine(item),
|
|
1892
|
+
/* @__PURE__ */ jsx10("td", { className: "px-6 py-4 whitespace-nowrap text-right text-sm font-medium", children: /* @__PURE__ */ jsxs6("div", { className: "relative", children: [
|
|
1893
|
+
/* @__PURE__ */ jsx10(
|
|
1894
|
+
"button",
|
|
1895
|
+
{
|
|
1896
|
+
type: "button",
|
|
1897
|
+
onClick: () => setDropdownOpen(dropdownOpen === item.id ? null : item.id),
|
|
1898
|
+
className: "p-1 rounded-full hover:bg-gray-100 transition-colors",
|
|
1899
|
+
children: /* @__PURE__ */ jsx10(MoreVertical, { className: "w-4 h-4 text-gray-400" })
|
|
1900
|
+
}
|
|
1901
|
+
),
|
|
1902
|
+
dropdownOpen === item.id && /* @__PURE__ */ jsx10("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(
|
|
1903
|
+
(action, index) => action.navigate ? /* @__PURE__ */ jsx10(Link2, { to: action.navigate, className: "w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center space-x-2", children: action.label }, index) : /* @__PURE__ */ jsx10("button", { onClick: () => {
|
|
1904
|
+
action.onclick(item);
|
|
1905
|
+
setDropdownOpen(null);
|
|
1906
|
+
}, 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)
|
|
1907
|
+
) })
|
|
1908
|
+
] }) })
|
|
1909
|
+
] }, item.id)) })
|
|
1910
|
+
] }),
|
|
1911
|
+
/* @__PURE__ */ jsx10(Pagination, { reponseDetail, setQueryURL, filters: [filters, setFilters] })
|
|
1912
|
+
] });
|
|
1913
|
+
};
|
|
1914
|
+
var Pagination = ({
|
|
1915
|
+
reponseDetail,
|
|
1916
|
+
filters
|
|
1917
|
+
}) => {
|
|
1918
|
+
const [filtersValue, setFilters] = filters;
|
|
1919
|
+
const { current_page, total_pages, previous, next, results, count } = reponseDetail;
|
|
1920
|
+
const range = 1;
|
|
1921
|
+
const pageItems = [];
|
|
1922
|
+
const generatePages = () => {
|
|
1923
|
+
if (total_pages <= 5) {
|
|
1924
|
+
for (let i = 1; i <= total_pages; i++)
|
|
1925
|
+
pageItems.push(
|
|
1926
|
+
/* @__PURE__ */ jsx10("li", { className: `page-item ${current_page === i ? "active" : ""}`, children: /* @__PURE__ */ jsx10(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: i }), children: i }) }, i)
|
|
1927
|
+
);
|
|
1928
|
+
} else {
|
|
1929
|
+
let start = Math.max(1, current_page - range);
|
|
1930
|
+
let end = Math.min(total_pages, current_page + range);
|
|
1931
|
+
if (start > 1) {
|
|
1932
|
+
pageItems.push(
|
|
1933
|
+
/* @__PURE__ */ jsx10("li", { className: `page-item ${current_page === 1 ? "active" : ""}`, children: /* @__PURE__ */ jsx10(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: 1 }), children: "1" }) }, 1)
|
|
1934
|
+
);
|
|
1935
|
+
if (start > 2)
|
|
1936
|
+
pageItems.push(/* @__PURE__ */ jsx10("li", { className: "page-item disabled", children: /* @__PURE__ */ jsx10("span", { className: "page-link px-3 py-1 text-sm", children: "..." }) }, "ellipsis-start"));
|
|
1937
|
+
}
|
|
1938
|
+
for (let i = start; i <= end; i++)
|
|
1939
|
+
pageItems.push(
|
|
1940
|
+
/* @__PURE__ */ jsx10("li", { className: `page-item ${current_page === i ? "active" : ""}`, children: /* @__PURE__ */ jsx10(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: i }), children: i }) }, i)
|
|
1941
|
+
);
|
|
1942
|
+
if (end < total_pages) {
|
|
1943
|
+
if (end < total_pages - 1)
|
|
1944
|
+
pageItems.push(/* @__PURE__ */ jsx10("li", { className: "page-item disabled", children: /* @__PURE__ */ jsx10("span", { className: "page-link px-3 py-1 text-sm", children: "..." }) }, "ellipsis-end"));
|
|
1945
|
+
pageItems.push(
|
|
1946
|
+
/* @__PURE__ */ jsx10("li", { className: `page-item ${current_page === total_pages ? "active" : ""}`, children: /* @__PURE__ */ jsx10(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm", to: "#", onClick: () => setFilters({ ...filtersValue, page: total_pages }), children: total_pages }) }, total_pages)
|
|
1947
|
+
);
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
};
|
|
1951
|
+
generatePages();
|
|
1952
|
+
const handleChangePage = (direction) => {
|
|
1953
|
+
let newPage = current_page + (direction === "next" ? 1 : -1);
|
|
1954
|
+
if (newPage >= 1 && newPage <= total_pages)
|
|
1955
|
+
setFilters({ ...filtersValue, page: newPage });
|
|
1956
|
+
};
|
|
1957
|
+
return /* @__PURE__ */ jsxs6("div", { className: "p-4 border-t border-[#E8E8E8] flex items-center justify-between", children: [
|
|
1958
|
+
/* @__PURE__ */ jsxs6("span", { className: "text-sm text-[#666666]", children: [
|
|
1959
|
+
"Affichage de 1 \xE0 ",
|
|
1960
|
+
results?.length ?? 0,
|
|
1961
|
+
" sur ",
|
|
1962
|
+
count ?? 0,
|
|
1963
|
+
" entr\xE9es"
|
|
1964
|
+
] }),
|
|
1965
|
+
/* @__PURE__ */ jsx10("nav", { children: /* @__PURE__ */ jsxs6("ul", { className: "flex items-center space-x-2 pagination", children: [
|
|
1966
|
+
/* @__PURE__ */ jsx10("li", { className: `page-item ${previous === null ? "disabled" : ""}`, children: /* @__PURE__ */ jsx10(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm disabled:opacity-50", to: "#", onClick: () => handleChangePage("previous"), tabIndex: -1, "aria-disabled": previous === null, children: "Pr\xE9c\xE9dent" }) }),
|
|
1967
|
+
pageItems,
|
|
1968
|
+
/* @__PURE__ */ jsx10("li", { className: `page-item ${next === null ? "disabled" : ""}`, children: /* @__PURE__ */ jsx10(Link2, { className: "page-link px-3 py-1 border border-[#E8E8E8] rounded text-sm disabled:opacity-50", to: "#", onClick: () => handleChangePage("next"), "aria-disabled": next === null, children: "Suivant" }) }),
|
|
1969
|
+
/* @__PURE__ */ jsx10("li", { className: "page-item", style: { border: "0.02rem solid #f2f2f2" }, children: /* @__PURE__ */ jsx10(
|
|
1970
|
+
"select",
|
|
1971
|
+
{
|
|
1972
|
+
id: "page-select",
|
|
1973
|
+
value: current_page,
|
|
1974
|
+
onChange: (e) => setFilters({ ...filtersValue, page: Number(e.target.value) }),
|
|
1975
|
+
style: { height: "27px", color: "#72939D", border: "0.05rem solid #f2f2f2", background: "#ffffff" },
|
|
1976
|
+
children: Array.from({ length: total_pages }, (_, index) => /* @__PURE__ */ jsx10("option", { value: index + 1, children: index + 1 }, index + 1))
|
|
1977
|
+
}
|
|
1978
|
+
) })
|
|
1979
|
+
] }) })
|
|
1980
|
+
] });
|
|
1981
|
+
};
|
|
1620
1982
|
export {
|
|
1621
1983
|
DateInput,
|
|
1984
|
+
FDrawer,
|
|
1622
1985
|
FileInput,
|
|
1623
1986
|
InputField,
|
|
1624
1987
|
Modals_default as Modal,
|