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