@ramses1er/cbk-toolkit 1.7.0 → 1.9.0

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.d.ts CHANGED
@@ -107,6 +107,21 @@ interface ConfirmationProps {
107
107
  }
108
108
  declare function Confirmation({ question, messageYes, messageNo, requestClose, onAction, isProcessing, error, resetRequest, }: ConfirmationProps): React$1.JSX.Element | null;
109
109
 
110
+ type HeaderContentProps = {
111
+ title: string;
112
+ description: string;
113
+ actionLabel?: string;
114
+ onAction?: () => void;
115
+ icon?: React__default.ReactNode;
116
+ };
117
+ declare function HeaderContent({ title, description, actionLabel, onAction, icon, }: HeaderContentProps): React__default.JSX.Element;
118
+
119
+ interface FormProps extends React__default.FormHTMLAttributes<HTMLFormElement> {
120
+ erreurs?: ApiError | null;
121
+ onErrorClose?: () => void;
122
+ }
123
+ declare const Form: React__default.FC<FormProps>;
124
+
110
125
  declare class HttpError extends Error {
111
126
  status: number;
112
127
  code?: string;
@@ -122,4 +137,4 @@ declare class HttpError extends Error {
122
137
  */
123
138
  declare function handleServerError(error: unknown, defaultStatus?: number, showDetails?: boolean): Response;
124
139
 
125
- export { ActionsMenu, ApiError, type Column, Confirmation, type FetcherOptions, HttpError, Modal, type NavItem, SideNav, type SideNavProps, type SideNavStaticConfig, Table, type TableAction, createSideNav, fetcher, handleServerError };
140
+ export { ActionsMenu, ApiError, type Column, Confirmation, type FetcherOptions, Form, HeaderContent, HttpError, Modal, type NavItem, SideNav, type SideNavProps, type SideNavStaticConfig, Table, type TableAction, createSideNav, fetcher, handleServerError };
package/dist/index.js CHANGED
@@ -810,6 +810,119 @@ function Confirmation({
810
810
  ] });
811
811
  }
812
812
 
813
+ // packages/ui/src/headers/header-content.tsx
814
+ import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
815
+ function HeaderContent({
816
+ title,
817
+ description,
818
+ actionLabel,
819
+ onAction,
820
+ icon
821
+ }) {
822
+ return /* @__PURE__ */ jsxs7("div", { className: "flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-6", children: [
823
+ /* @__PURE__ */ jsxs7("div", { children: [
824
+ /* @__PURE__ */ jsx8("h1", { className: "text-xl text-blue-600 flex items-center gap-2", children: title }),
825
+ description && /* @__PURE__ */ jsx8("p", { className: "text-sm text-gray-500 mt-1", children: description })
826
+ ] }),
827
+ actionLabel && onAction && /* @__PURE__ */ jsxs7(
828
+ "button",
829
+ {
830
+ onClick: onAction,
831
+ className: "font-semibold md:inline-flex items-center gap-2 bg-blue-500 text-white px-4 py-2 rounded-md text-sm hover:bg-blue-700 transition hover:cursor-pointer",
832
+ children: [
833
+ icon && /* @__PURE__ */ jsx8("span", { className: "w-4 h-4", children: icon }),
834
+ actionLabel
835
+ ]
836
+ }
837
+ )
838
+ ] });
839
+ }
840
+
841
+ // packages/ui/src/forms/form.tsx
842
+ import { useState as useState6, useEffect as useEffect5, useRef as useRef3, useCallback as useCallback3 } from "react";
843
+ import { X as X3 } from "lucide-react";
844
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
845
+ var Form = ({
846
+ erreurs,
847
+ onErrorClose,
848
+ children,
849
+ className,
850
+ ...props
851
+ }) => {
852
+ const formClassName = ["flex flex-col gap-3", className].filter(Boolean).join(" ");
853
+ const errorMessage = erreurs?.message || null;
854
+ const [showError, setShowError] = useState6(!!erreurs);
855
+ const [countdown, setCountdown] = useState6(erreurs ? 10 : 0);
856
+ const [animating, setAnimating] = useState6(!!erreurs);
857
+ const intervalRef = useRef3(null);
858
+ const hasClosedRef = useRef3(false);
859
+ const closeError = useCallback3(
860
+ (triggerCallback = true) => {
861
+ if (intervalRef.current !== null) {
862
+ window.clearInterval(intervalRef.current);
863
+ intervalRef.current = null;
864
+ }
865
+ setShowError(false);
866
+ setAnimating(false);
867
+ setCountdown(0);
868
+ if (triggerCallback && onErrorClose && !hasClosedRef.current) {
869
+ hasClosedRef.current = true;
870
+ onErrorClose();
871
+ }
872
+ },
873
+ [onErrorClose]
874
+ );
875
+ useEffect5(() => {
876
+ hasClosedRef.current = false;
877
+ if (!erreurs) {
878
+ const closeTimeout = window.setTimeout(() => closeError(false), 0);
879
+ return () => {
880
+ window.clearTimeout(closeTimeout);
881
+ };
882
+ }
883
+ const initTimeout = window.setTimeout(() => {
884
+ setShowError(true);
885
+ setAnimating(true);
886
+ setCountdown(10);
887
+ }, 0);
888
+ intervalRef.current = window.setInterval(() => {
889
+ setCountdown((prev) => {
890
+ if (prev <= 1) {
891
+ closeError(true);
892
+ return 0;
893
+ }
894
+ return prev - 1;
895
+ });
896
+ }, 1e3);
897
+ return () => {
898
+ window.clearTimeout(initTimeout);
899
+ if (intervalRef.current !== null) {
900
+ window.clearInterval(intervalRef.current);
901
+ intervalRef.current = null;
902
+ }
903
+ };
904
+ }, [erreurs, closeError]);
905
+ return /* @__PURE__ */ jsxs8(Fragment2, { children: [
906
+ /* @__PURE__ */ jsx9("form", { className: formClassName, ...props, children }),
907
+ showError && errorMessage && /* @__PURE__ */ jsxs8(
908
+ "div",
909
+ {
910
+ className: `fixed top-0 left-0 right-0 z-[9999] bg-red-500 text-white p-4 rounded-b-md shadow-lg flex justify-between items-center transition-transform duration-300 ${animating ? "transform translate-y-0" : "transform -translate-y-full"}`,
911
+ children: [
912
+ /* @__PURE__ */ jsx9("span", { children: errorMessage }),
913
+ /* @__PURE__ */ jsxs8("div", { className: "flex items-center", children: [
914
+ /* @__PURE__ */ jsxs8("span", { className: "mr-2", children: [
915
+ countdown,
916
+ "s"
917
+ ] }),
918
+ /* @__PURE__ */ jsx9("button", { onClick: () => closeError(true), children: /* @__PURE__ */ jsx9(X3, { size: 20 }) })
919
+ ] })
920
+ ]
921
+ }
922
+ )
923
+ ] });
924
+ };
925
+
813
926
  // packages/utils/src/fetcher.ts
814
927
  var ApiError = class extends Error {
815
928
  status;
@@ -918,6 +1031,8 @@ export {
918
1031
  ActionsMenu,
919
1032
  ApiError,
920
1033
  Confirmation,
1034
+ Form,
1035
+ HeaderContent,
921
1036
  HttpError,
922
1037
  Modal,
923
1038
  SideNav,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../packages/ui/src/layouts/side-nav.tsx","../packages/ui/src/config/create-side-nav.tsx","../packages/ui/src/table/table.tsx","../packages/ui/src/feedback/error-display.tsx","../packages/ui/src/table/actions-menu.tsx","../packages/ui/src/modals/modal.tsx","../packages/ui/src/feedback/confirmation.tsx","../packages/utils/src/fetcher.ts","../packages/lib/src/http-error.ts","../packages/lib/src/handle-server-error.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport {\r\n ReactNode,\r\n useState,\r\n useEffect,\r\n createElement,\r\n isValidElement,\r\n type ComponentType,\r\n} from \"react\";\r\n\r\ntype IconType = ReactNode | ComponentType<{ size?: number }>;\r\n\r\nexport interface NavItem {\r\n id: string;\r\n label: string;\r\n title?: string;\r\n icon?: IconType;\r\n href: string;\r\n subItems?: NavItem[];\r\n}\r\n\r\nexport interface SideNavStaticConfig {\r\n brand?: {\r\n logo?: ReactNode;\r\n name?: string;\r\n tagline?: string;\r\n };\r\n mainItems: NavItem[];\r\n title?: string;\r\n footer?: { icon?: IconType; label: string; href: string }[];\r\n toggleIcon?: ReactNode;\r\n}\r\n\r\nexport interface SideNavProps extends SideNavStaticConfig {\r\n children: ReactNode;\r\n currentPath: string;\r\n}\r\n\r\nfunction isActive(href: string, currentPath: string) {\r\n return currentPath === href || currentPath.startsWith(href + \"/\");\r\n}\r\n\r\nfunction isExactActive(href: string, currentPath: string) {\r\n return currentPath === href;\r\n}\r\n\r\nexport function SideNav({\r\n children,\r\n title,\r\n mainItems,\r\n currentPath,\r\n brand,\r\n footer,\r\n toggleIcon,\r\n}: SideNavProps) {\r\n const activeMain = mainItems.find((item) => isActive(item.href, currentPath));\r\n const headerTitle = title ?? activeMain?.title ?? activeMain?.label;\r\n const [expandedSection, setExpandedSection] = useState<string | null>(\r\n activeMain?.id ?? null,\r\n );\r\n\r\n const toggleSection = (id: string) => {\r\n setExpandedSection((prev) => (prev === id ? null : id));\r\n };\r\n\r\n const [isMobileOpen, setIsMobileOpen] = useState(false);\r\n\r\n useEffect(() => {\r\n const handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === \"Escape\") setIsMobileOpen(false);\r\n };\r\n document.addEventListener(\"keydown\", handleEscape);\r\n return () => document.removeEventListener(\"keydown\", handleEscape);\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (isMobileOpen) {\r\n document.body.style.overflow = \"hidden\";\r\n } else {\r\n document.body.style.overflow = \"\";\r\n }\r\n return () => {\r\n document.body.style.overflow = \"\";\r\n };\r\n }, [isMobileOpen]);\r\n\r\n const closeMobileNav = () => setIsMobileOpen(false);\r\n\r\n return (\r\n <div className=\"flex min-h-screen\">\r\n <aside\r\n className={`w-64 bg-white border-r border-gray-200 flex flex-col fixed h-full z-50 transition-transform duration-300 ease-in-out md:translate-x-0 ${\r\n isMobileOpen ? \"translate-x-0\" : \"-translate-x-full\"\r\n }`}\r\n >\r\n {brand && (\r\n <div className=\"p-[6.5px] border-b border-gray-100\">\r\n <div className=\"flex flex-row gap-2 items-center\">\r\n {brand.logo &&\r\n (typeof brand.logo === \"string\" ? (\r\n <img\r\n src={brand.logo}\r\n alt={brand.name ?? \"\"}\r\n className=\"w-12.5 h-12.5\"\r\n />\r\n ) : (\r\n brand.logo\r\n ))}\r\n {brand.name && (\r\n <p className=\"text-gray-500 text-base font-semibold\">\r\n {brand.name}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <nav className=\"flex-1 p-4 overflow-y-auto\">\r\n <ul className=\"space-y-1\">\r\n {mainItems.map((item) => {\r\n const active = isActive(item.href, currentPath);\r\n const isExpanded = expandedSection === item.id;\r\n const hasSubItems = item.subItems && item.subItems.length > 0;\r\n\r\n return (\r\n <li key={item.id}>\r\n <div className=\"flex items-center gap-1\">\r\n <a\r\n href={item.href}\r\n onClick={closeMobileNav}\r\n className={`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors flex-1 ${\r\n active\r\n ? \"bg-gray-200 text-black\"\r\n : \"text-gray-500 hover:bg-gray-100\"\r\n }`}\r\n >\r\n {item.icon &&\r\n (typeof item.icon === \"string\" ? (\r\n <span className=\"text-lg\">{item.icon}</span>\r\n ) : isValidElement(item.icon) ? (\r\n item.icon\r\n ) : (\r\n createElement(\r\n item.icon as ComponentType<{ size?: number }>,\r\n { size: 20 },\r\n )\r\n ))}\r\n {item.label}\r\n </a>\r\n {active && hasSubItems && (\r\n <button\r\n onClick={() => toggleSection(item.id)}\r\n className={`p-1.5 rounded-lg transition-colors ${\r\n active\r\n ? \"text-black hover:bg-gray-100\"\r\n : \"text-gray-500 hover:bg-gray-100\"\r\n }`}\r\n title={isExpanded ? \"Réduire\" : \"Développer\"}\r\n >\r\n {toggleIcon ? (\r\n <span\r\n className={`inline-block transition-transform duration-200 ${\r\n isExpanded ? \"rotate-0\" : \"-rotate-90\"\r\n }`}\r\n >\r\n {toggleIcon}\r\n </span>\r\n ) : (\r\n <span className=\"text-xs\">\r\n {isExpanded ? \"▼\" : \"▶\"}\r\n </span>\r\n )}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {active && hasSubItems && (\r\n <div\r\n className={`grid transition-all duration-300 ease-in-out ${\r\n isExpanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\"\r\n }`}\r\n >\r\n <div className=\"overflow-hidden\">\r\n <ul className=\"ml-4 mt-1 space-y-1 pl-2\">\r\n {item.subItems!.map((sub) => (\r\n <li key={sub.id}>\r\n <a\r\n href={sub.href}\r\n onClick={closeMobileNav}\r\n className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors ${\r\n isExactActive(sub.href, currentPath)\r\n ? \"bg-gray-200 text-black\"\r\n : \"text-gray-500 hover:bg-gray-100\"\r\n }`}\r\n >\r\n {sub.label}\r\n </a>\r\n </li>\r\n ))}\r\n </ul>\r\n </div>\r\n </div>\r\n )}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n </nav>\r\n\r\n {footer && footer.length > 0 && (\r\n <div className=\"p-4 border-t border-gray-100 space-y-1\">\r\n {footer.map((item) => (\r\n <a\r\n key={item.label}\r\n href={item.href}\r\n onClick={closeMobileNav}\r\n className=\"flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors\"\r\n >\r\n {typeof item.icon === \"string\" ? (\r\n <span className=\"text-lg\">{item.icon}</span>\r\n ) : isValidElement(item.icon) ? (\r\n item.icon\r\n ) : (\r\n createElement(item.icon as ComponentType<{ size?: number }>, {\r\n size: 20,\r\n })\r\n )}\r\n {item.label}\r\n </a>\r\n ))}\r\n </div>\r\n )}\r\n </aside>\r\n\r\n {isMobileOpen && (\r\n <div\r\n className=\"fixed inset-0 z-40 bg-black/50 md:hidden\"\r\n onClick={closeMobileNav}\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n\r\n <div className=\"flex-1 ml-64 max-md:ml-0 min-w-0\">\r\n {headerTitle && (\r\n <header className=\"h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6 fixed top-0 right-0 left-64 max-md:left-0 z-20\">\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n className=\"md:hidden p-2 -ml-2 rounded-lg hover:bg-gray-100 transition-colors\"\r\n onClick={() => setIsMobileOpen(!isMobileOpen)}\r\n aria-label={isMobileOpen ? \"Fermer le menu\" : \"Menu\"}\r\n aria-expanded={isMobileOpen}\r\n >\r\n {isMobileOpen ? (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M6 18L18 6M6 6l12 12\"\r\n />\r\n </svg>\r\n ) : (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M4 6h16M4 12h16M4 18h16\"\r\n />\r\n </svg>\r\n )}\r\n </button>\r\n <h1 className=\"text-base font-semibold text-gray-500\">\r\n {headerTitle}\r\n </h1>\r\n </div>\r\n {brand?.tagline && (\r\n <span className=\"text-sm text-gray-500 max-md:hidden\">\r\n {brand.tagline}\r\n </span>\r\n )}\r\n </header>\r\n )}\r\n {!headerTitle && (\r\n <button\r\n className=\"md:hidden fixed top-4 left-4 z-10 p-2 rounded-lg bg-white border border-gray-200 shadow-sm hover:bg-gray-100 transition-colors\"\r\n onClick={() => setIsMobileOpen(!isMobileOpen)}\r\n aria-label={isMobileOpen ? \"Fermer le menu\" : \"Menu\"}\r\n aria-expanded={isMobileOpen}\r\n >\r\n {isMobileOpen ? (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M6 18L18 6M6 6l12 12\"\r\n />\r\n </svg>\r\n ) : (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M4 6h16M4 12h16M4 18h16\"\r\n />\r\n </svg>\r\n )}\r\n </button>\r\n )}\r\n <main\r\n className={(headerTitle ? \"p-6 pt-20\" : \"p-6\") + \" overflow-x-auto\"}\r\n >\r\n {children}\r\n </main>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { SideNav, type SideNavStaticConfig } from \"../layouts/side-nav\";\n\nexport function createSideNav(config: SideNavStaticConfig) {\n return function ConfiguredSideNav({\n children,\n currentPath,\n }: {\n children: React.ReactNode;\n currentPath: string;\n }) {\n return (\n <SideNav {...config} currentPath={currentPath}>\n {children}\n </SideNav>\n );\n };\n}\n","\"use client\";\r\n\r\nimport { Printer, ChevronLeft, ChevronRight } from \"lucide-react\";\r\nimport clsx from \"clsx\";\r\nimport { useState, useMemo, useCallback } from \"react\";\r\nimport { ErrorDisplay } from \"../feedback/error-display\";\r\nimport { ApiError } from \"../../../utils/src/fetcher\";\r\n\r\nexport type Column<T> = {\r\n header: string;\r\n accessor?: keyof T;\r\n render?: (row: T) => React.ReactNode;\r\n excludeFromPrint?: boolean;\r\n};\r\n\r\ntype TableProps<T> = {\r\n data: T[];\r\n columns: Column<T>[];\r\n loading?: boolean;\r\n error?: ApiError | null;\r\n label?: string;\r\n printable?: boolean;\r\n pageSize?: number;\r\n pageSizeOptions?: number[];\r\n showPagination?: boolean;\r\n};\r\n\r\nconst VISIBLE_PAGES = 5;\r\n\r\nexport function Table<T>({\r\n data,\r\n columns,\r\n loading,\r\n error,\r\n label,\r\n printable,\r\n pageSize = 5,\r\n pageSizeOptions = [5, 10, 20],\r\n showPagination = true,\r\n}: TableProps<T>) {\r\n const [tooltip, setTooltip] = useState<{\r\n content: string;\r\n x: number;\r\n y: number;\r\n } | null>(null);\r\n const [page, setPage] = useState(1);\r\n const [perPage, setPerPage] = useState(pageSize);\r\n\r\n const totalPages = useMemo(\r\n () => Math.max(1, Math.ceil(data.length / perPage)),\r\n [data.length, perPage],\r\n );\r\n\r\n const safePage = Math.min(page, totalPages);\r\n\r\n const displayData = useMemo(\r\n () => data.slice((safePage - 1) * perPage, safePage * perPage),\r\n [data, safePage, perPage],\r\n );\r\n\r\n const paginationRange = useMemo(() => {\r\n const half = Math.floor(VISIBLE_PAGES / 2);\r\n let start = Math.max(1, safePage - half);\r\n let end = Math.min(totalPages, start + VISIBLE_PAGES - 1);\r\n if (end - start + 1 < VISIBLE_PAGES) {\r\n start = Math.max(1, end - VISIBLE_PAGES + 1);\r\n }\r\n const range: (number | \"...\")[] = [];\r\n if (start > 1) {\r\n range.push(1);\r\n if (start > 2) range.push(\"...\");\r\n }\r\n for (let i = start; i <= end; i++) range.push(i);\r\n if (end < totalPages) {\r\n if (end < totalPages - 1) range.push(\"...\");\r\n range.push(totalPages);\r\n }\r\n return range;\r\n }, [safePage, totalPages]);\r\n\r\n const handlePageSizeChange = useCallback((value: number) => {\r\n setPerPage(value);\r\n setPage(1);\r\n }, []);\r\n\r\n const colCount = columns.length;\r\n const colWidth = colCount > 0 ? `${Math.round(100 / colCount)}%` : \"auto\";\r\n\r\n const handleMouseEnter = (\r\n e: React.MouseEvent<HTMLDivElement>,\r\n content: string,\r\n ) => {\r\n const rect = e.currentTarget.getBoundingClientRect();\r\n setTooltip({\r\n content,\r\n x: rect.left + rect.width / 2,\r\n y: rect.top,\r\n });\r\n };\r\n\r\n const handleMouseLeave = () => {\r\n setTooltip(null);\r\n };\r\n\r\n const banner = error ? (\r\n <div className=\"mb-4\">\r\n <ErrorDisplay key={error.message} error={error} />\r\n </div>\r\n ) : null;\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n {banner}\r\n <div className=\"rounded-lg shadow-md border border-gray-200\">\r\n <div className=\"flex items-center justify-center py-20 text-gray-500\">\r\n Chargement...\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!data || data.length === 0) {\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n {banner}\r\n <div className=\"rounded-lg shadow-md border border-gray-200\">\r\n <div className=\"flex items-center justify-center py-20 text-gray-500\">\r\n Aucun élément\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n {banner}\r\n <div className=\"flex items-center justify-between mb-2\">\r\n {label && (\r\n <div className=\"text-sm font-semibold text-gray-700\">\r\n {label}: {data.length}\r\n </div>\r\n )}\r\n {printable && (\r\n <button\r\n onClick={() => window.print()}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-blue-500 rounded-lg hover:bg-blue-600 transition-colors print:hidden\"\r\n >\r\n <Printer className=\"w-4 h-4\" />\r\n Imprimer\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"rounded-lg shadow-md border border-gray-200\">\r\n <table className=\"w-full table-fixed divide-y divide-gray-200 print:table-fixed\">\r\n <thead className=\"bg-blue-500 rounded-t-lg\">\r\n <tr>\r\n {columns.map((col, index) => (\r\n <th\r\n key={index}\r\n style={{ width: colWidth }}\r\n className={clsx(\r\n \"px-6 py-3 text-left text-xs font-bold text-white uppercase tracking-wider truncate\",\r\n col.excludeFromPrint && \"print:hidden\",\r\n )}\r\n >\r\n {col.header}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody\r\n className={clsx(\r\n \"bg-white divide-y divide-gray-200\",\r\n printable && \"print:hidden\",\r\n )}\r\n >\r\n {displayData.map((row, rowIndex) => (\r\n <tr\r\n key={rowIndex}\r\n className=\"hover:bg-gray-100 transition-colors duration-200\"\r\n >\r\n {columns.map((col, colIndex) => {\r\n const cellContent = col.render\r\n ? col.render(row)\r\n : String(row[col.accessor!]);\r\n const textContent =\r\n typeof cellContent === \"string\" ? cellContent : \"\";\r\n\r\n return (\r\n <td\r\n key={colIndex}\r\n style={{ width: colWidth }}\r\n className={clsx(\r\n \"px-6 py-4 text-sm text-gray-700\",\r\n col.excludeFromPrint && \"print:hidden\",\r\n )}\r\n >\r\n {typeof cellContent === \"string\" ? (\r\n <div\r\n className=\"truncate\"\r\n onMouseEnter={(e) => handleMouseEnter(e, textContent)}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n {cellContent}\r\n </div>\r\n ) : (\r\n cellContent\r\n )}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n ))}\r\n </tbody>\r\n {printable && (\r\n <tbody className=\"hidden print:table-row-group\">\r\n {data.map((row, rowIndex) => (\r\n <tr key={rowIndex}>\r\n {columns.map((col, colIndex) => {\r\n const cellContent = col.render\r\n ? col.render(row)\r\n : String(row[col.accessor!]);\r\n\r\n return (\r\n <td\r\n key={colIndex}\r\n style={{ width: colWidth }}\r\n className={clsx(\r\n \"px-6 py-4 text-sm text-gray-700\",\r\n col.excludeFromPrint && \"print:hidden\",\r\n )}\r\n >\r\n {cellContent}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n ))}\r\n </tbody>\r\n )}\r\n </table>\r\n </div>\r\n\r\n {showPagination && totalPages > 1 && (\r\n <div className=\"flex items-center justify-between mt-4 text-sm print:hidden\">\r\n <div className=\"flex items-center gap-2 text-gray-600\">\r\n <span>Lignes par page :</span>\r\n <select\r\n value={perPage}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n className=\"border border-gray-300 rounded px-2 py-1 text-sm bg-white focus:outline-none focus:ring-2 focus:ring-blue-400\"\r\n >\r\n {pageSizeOptions.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"flex items-center gap-1\">\r\n <button\r\n onClick={() => setPage((p) => Math.max(1, p - 1))}\r\n disabled={safePage <= 1}\r\n className={clsx(\r\n \"p-1.5 rounded transition-colors\",\r\n safePage <= 1\r\n ? \"text-gray-300 cursor-not-allowed\"\r\n : \"text-gray-600 hover:bg-gray-100\",\r\n )}\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n\r\n {paginationRange.map((item, i) =>\r\n item === \"...\" ? (\r\n <span key={`ellipsis-${i}`} className=\"px-2 text-gray-400\">\r\n ...\r\n </span>\r\n ) : (\r\n <button\r\n key={item}\r\n onClick={() => setPage(item)}\r\n className={clsx(\r\n \"min-w-8 px-2 py-1 rounded text-sm font-medium transition-colors\",\r\n item === safePage\r\n ? \"bg-blue-500 text-white\"\r\n : \"text-gray-600 hover:bg-gray-100\",\r\n )}\r\n >\r\n {item}\r\n </button>\r\n ),\r\n )}\r\n\r\n <button\r\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\r\n disabled={safePage >= totalPages}\r\n className={clsx(\r\n \"p-1.5 rounded transition-colors\",\r\n safePage >= totalPages\r\n ? \"text-gray-300 cursor-not-allowed\"\r\n : \"text-gray-600 hover:bg-gray-100\",\r\n )}\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"text-gray-500\">\r\n Page {safePage} sur {totalPages}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {tooltip && (\r\n <div\r\n className=\"fixed z-20 px-3 py-2 text-sm text-white bg-gray-800 rounded-lg shadow-lg pointer-events-none whitespace-nowrap\"\r\n style={{\r\n left: tooltip.x,\r\n top: tooltip.y - 8,\r\n transform: \"translate(-50%, -100%)\",\r\n }}\r\n >\r\n {tooltip.content}\r\n </div>\r\n )}\r\n <style>{`\r\n @media print {\r\n body * { visibility: hidden; }\r\n .w-full.overflow-x-auto { visibility: visible; }\r\n .w-full.overflow-x-auto * { visibility: visible; }\r\n .w-full.overflow-x-auto { position: absolute; left: 0; top: 0; width: 100%; }\r\n }\r\n `}</style>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { X } from \"lucide-react\";\r\nimport { ApiError } from \"../../../utils/src\";\r\nimport { useState } from \"react\";\r\n\r\ninterface ErrorDisplayProps {\r\n error: ApiError | null;\r\n}\r\n\r\nexport function ErrorDisplay({ error }: ErrorDisplayProps) {\r\n const [dismissed, setDismissed] = useState(false);\r\n\r\n if (!error || dismissed) return null;\r\n\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n <div className=\"rounded-lg shadow-md border border-red-200 bg-red-50\">\r\n <div className=\"flex items-start justify-between gap-4 px-4 py-4\">\r\n <div className=\"flex flex-col gap-1\">\r\n <p className=\"text-red-700 font-medium\">Erreur</p>\r\n <p className=\"text-red-600 text-sm\">{error.message}</p>\r\n </div>\r\n <button\r\n onClick={() => setDismissed(true)}\r\n className=\"text-red-400 hover:text-red-600 shrink-0 cursor-pointer\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from \"react\";\r\nimport { Ellipsis } from \"lucide-react\";\r\n\r\nexport type TableAction<T> = {\r\n label: string;\r\n icon: React.ReactNode;\r\n callback: (row: T) => void;\r\n color?: string;\r\n};\r\n\r\ntype ActionsMenuProps<T> = {\r\n row: T;\r\n actions: TableAction<T>[];\r\n};\r\n\r\nexport function ActionsMenu<T>({ row, actions }: ActionsMenuProps<T>) {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [coords, setCoords] = useState({ top: 0, left: 0 });\r\n const buttonRef = useRef<HTMLButtonElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n\r\n // Fermer le menu si clic en dehors\r\n useEffect(() => {\r\n function handleClickOutside(event: MouseEvent) {\r\n if (\r\n menuRef.current &&\r\n buttonRef.current &&\r\n !menuRef.current.contains(event.target as Node) &&\r\n !buttonRef.current.contains(event.target as Node)\r\n ) {\r\n setIsOpen(false);\r\n }\r\n }\r\n\r\n document.addEventListener(\"mousedown\", handleClickOutside);\r\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\r\n }, []);\r\n\r\n const toggleMenu = () => {\r\n if (buttonRef.current) {\r\n const rect = buttonRef.current.getBoundingClientRect();\r\n const menuWidth = 180;\r\n const menuHeight = actions.length * 40;\r\n\r\n const spaceBelow = window.innerHeight - rect.bottom;\r\n const spaceRight = window.innerWidth - rect.left;\r\n\r\n let top = rect.bottom;\r\n let left = rect.left;\r\n\r\n // If not enough space below, show above\r\n if (spaceBelow < menuHeight + 20) {\r\n top = rect.top - menuHeight;\r\n }\r\n\r\n // If not enough space on the right, align to the left\r\n if (spaceRight < menuWidth + 20) {\r\n left = rect.left - menuWidth + 30;\r\n }\r\n\r\n setCoords({ top, left });\r\n }\r\n setIsOpen(!isOpen);\r\n };\r\n\r\n return (\r\n <>\r\n <button\r\n ref={buttonRef}\r\n onClick={toggleMenu}\r\n className=\"p-1 hover:bg-gray-100 rounded-full\"\r\n >\r\n <Ellipsis className=\"w-5 h-5\" />\r\n </button>\r\n\r\n {isOpen && (\r\n <div\r\n ref={menuRef}\r\n className=\"fixed bg-white border border-gray-200 rounded shadow-lg z-20\"\r\n style={{\r\n top: coords.top,\r\n left: coords.left,\r\n minWidth: 180,\r\n }}\r\n >\r\n {actions.map((action, idx) => (\r\n <button\r\n key={idx}\r\n className={`flex items-center gap-2 px-4 py-2 w-full text-sm hover:bg-gray-100 ${\r\n action.color || \"text-gray-700\"\r\n }`}\r\n onClick={() => {\r\n action.callback(row);\r\n setIsOpen(false);\r\n }}\r\n >\r\n {action.icon}\r\n {action.label}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { X } from \"lucide-react\";\r\nimport React, { useEffect } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\n\r\ntype ModalProps = {\r\n title: string;\r\n isOpen: boolean;\r\n onClose: () => void;\r\n children: React.ReactNode | ((requestClose: () => void) => React.ReactNode);\r\n};\r\n\r\nexport function Modal({ title, isOpen, onClose, children }: ModalProps) {\r\n const requestClose = () => {\r\n onClose();\r\n };\r\n\r\n useEffect(() => {\r\n if (isOpen) {\r\n document.body.style.overflow = \"hidden\";\r\n }\r\n\r\n return () => {\r\n document.body.style.overflow = \"\";\r\n };\r\n }, [isOpen]);\r\n\r\n useEffect(() => {\r\n function handleEsc(e: KeyboardEvent) {\r\n if (e.key === \"Escape\") {\r\n onClose();\r\n }\r\n }\r\n\r\n if (isOpen) {\r\n document.addEventListener(\"keydown\", handleEsc);\r\n }\r\n\r\n return () => {\r\n document.removeEventListener(\"keydown\", handleEsc);\r\n };\r\n }, [isOpen, onClose]);\r\n\r\n if (!isOpen) return null;\r\n\r\n const content =\r\n typeof children === \"function\" ? children(requestClose) : children;\r\n\r\n return createPortal(\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\r\n <div\r\n className=\"absolute inset-0 bg-black/20 backdrop-blur-sm\"\r\n onClick={onClose}\r\n />\r\n\r\n <div className=\"relative bg-white rounded-lg shadow-lg w-full max-w-2xl mx-4 p-6 flex flex-col max-h-[85vh]\">\r\n <div className=\"flex items-center justify-between mb-4 border-b-2 border-gray-400 pb-3 sticky top-0 bg-white z-10\">\r\n <h2 className=\"text-lg font-semibold text-gray-900\">{title}</h2>\r\n\r\n <button\r\n onClick={onClose}\r\n className=\"text-gray-500 hover:text-gray-700 text-xl cursor-pointer\"\r\n >\r\n <X />\r\n </button>\r\n </div>\r\n\r\n <div className=\"overflow-y-auto flex-1 min-h-0\">{content}</div>\r\n </div>\r\n </div>,\r\n document.body,\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport { ApiError } from \"../../../utils/src/fetcher\";\r\nimport { CircleQuestionMark } from \"lucide-react\";\r\n\r\nconst ERROR_COUNTDOWN = 10;\r\n\r\ninterface ConfirmationProps {\r\n question: string;\r\n messageYes: string;\r\n messageNo: string;\r\n requestClose: () => void;\r\n onAction: () =>\r\n | void\r\n | Promise<void>\r\n | Promise<boolean>\r\n | Promise<{ success: true }>;\r\n isProcessing: boolean;\r\n error: ApiError | null;\r\n resetRequest: () => void;\r\n}\r\n\r\nexport function Confirmation({\r\n question,\r\n messageYes,\r\n messageNo,\r\n requestClose,\r\n onAction,\r\n isProcessing,\r\n error,\r\n resetRequest,\r\n}: ConfirmationProps) {\r\n const [countdown, setCountdown] = useState(0);\r\n const countdownRef = useRef<number | null>(null);\r\n const resetRequestRef = useRef(resetRequest);\r\n\r\n useEffect(() => {\r\n resetRequestRef.current = resetRequest;\r\n }, [resetRequest]);\r\n\r\n const clearCountdown = useCallback(() => {\r\n if (countdownRef.current !== null) {\r\n window.clearInterval(countdownRef.current);\r\n countdownRef.current = null;\r\n }\r\n }, []);\r\n\r\n const resetConfirmationState = useCallback(() => {\r\n clearCountdown();\r\n setCountdown(0);\r\n }, [clearCountdown]);\r\n\r\n const handleResetRequest = useCallback(() => {\r\n resetConfirmationState();\r\n resetRequest();\r\n }, [resetConfirmationState, resetRequest]);\r\n\r\n const handleRequestClose = useCallback(() => {\r\n resetConfirmationState();\r\n resetRequest();\r\n requestClose();\r\n }, [requestClose, resetConfirmationState, resetRequest]);\r\n\r\n const handleAction = useCallback(async () => {\r\n try {\r\n await onAction();\r\n handleRequestClose();\r\n } catch {\r\n // L'erreur est propagée par le parent via la prop `error`.\r\n }\r\n }, [handleRequestClose, onAction]);\r\n\r\n useEffect(() => {\r\n clearCountdown();\r\n\r\n if (!error) {\r\n const resetTimeoutId = window.setTimeout(() => {\r\n setCountdown(0);\r\n }, 0);\r\n\r\n return () => {\r\n window.clearTimeout(resetTimeoutId);\r\n };\r\n }\r\n\r\n const startCountdownTimeoutId = window.setTimeout(() => {\r\n setCountdown(ERROR_COUNTDOWN);\r\n\r\n countdownRef.current = window.setInterval(() => {\r\n setCountdown((previousCountdown) => {\r\n if (previousCountdown <= 1) {\r\n clearCountdown();\r\n window.setTimeout(() => {\r\n resetRequestRef.current();\r\n }, 0);\r\n\r\n return 0;\r\n }\r\n\r\n return previousCountdown - 1;\r\n });\r\n }, 1000);\r\n }, 0);\r\n\r\n return () => {\r\n window.clearTimeout(startCountdownTimeoutId);\r\n clearCountdown();\r\n };\r\n }, [clearCountdown, error]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n clearCountdown();\r\n resetRequestRef.current();\r\n };\r\n }, [clearCountdown]);\r\n\r\n const isErrorVisible = Boolean(error) && countdown > 0;\r\n\r\n if (!question) return null;\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-3 z-40\">\r\n <CircleQuestionMark className=\"text-red-500 text-5xl\" />\r\n <h2 className=\"text-xl font-bold text-red-500\">Confirmation requise</h2>\r\n\r\n <p className=\"mt-4 text-md leading-relaxed text-gray-700\">{question}</p>\r\n\r\n <div className=\"mt-6 flex w-full gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={handleRequestClose}\r\n disabled={isProcessing}\r\n className=\"w-full rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-semibold text-gray-700 transition hover:cursor-pointer hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-white\"\r\n >\r\n {messageNo}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={handleAction}\r\n disabled={isProcessing}\r\n className=\"w-full rounded-lg bg-red-400 px-4 py-2 text-sm font-semibold text-white transition hover:cursor-pointer hover:bg-red-500 active:scale-95 disabled:opacity-50 disabled:hover:bg-red-500\"\r\n >\r\n {isProcessing ? \"operation en cours\" : messageYes}\r\n </button>\r\n </div>\r\n\r\n {error && isErrorVisible && (\r\n <div className=\"mt-4 w-full rounded-lg border border-red-200 bg-red-50 p-4 text-left text-sm text-red-700\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div>\r\n <p className=\"font-semibold\">Erreur</p>\r\n <p className=\"mt-1 text-sm\">{error.message}</p>\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={handleResetRequest}\r\n className=\"rounded-full bg-red-100 px-2 py-1 text-xs font-semibold text-red-700 hover:bg-red-200\"\r\n >\r\n Fermer\r\n </button>\r\n </div>\r\n\r\n <p className=\"mt-3 text-xs text-red-600\">\r\n Ce message disparait dans {countdown}s...\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","export class ApiError extends Error {\r\n public status: number;\r\n public code?: string;\r\n public data?: unknown;\r\n\r\n constructor(params: {\r\n message: string;\r\n status: number;\r\n code?: string;\r\n data?: unknown;\r\n }) {\r\n super(params.message);\r\n this.status = params.status;\r\n this.code = params.code;\r\n this.data = params.data;\r\n }\r\n}\r\n\r\ntype BackendErrorShape = {\r\n code?: string;\r\n status?: number;\r\n message?: string;\r\n};\r\n\r\nexport type FetcherOptions = RequestInit & {\r\n skipJsonParsing?: boolean;\r\n};\r\n\r\nexport async function fetcher<T = unknown>(\r\n url: string,\r\n options: FetcherOptions = {},\r\n): Promise<T> {\r\n const { headers, skipJsonParsing = false, ...rest } = options;\r\n\r\n const response = await fetch(url, {\r\n credentials: \"include\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n },\r\n ...rest,\r\n });\r\n\r\n let responseData: unknown = null;\r\n const contentType = response.headers.get(\"content-type\");\r\n\r\n if (!skipJsonParsing && contentType?.includes(\"application/json\")) {\r\n responseData = await response.json();\r\n }\r\n\r\n if (!response.ok) {\r\n const backendError = responseData as BackendErrorShape;\r\n\r\n throw new ApiError({\r\n message: backendError?.message || \"Une erreur est survenue\",\r\n status: backendError?.status || response.status,\r\n code: backendError?.code,\r\n data: responseData,\r\n });\r\n }\r\n\r\n return responseData as T;\r\n}\r\n","export class HttpError extends Error {\r\n status: number;\r\n code?: string;\r\n\r\n constructor(message: string, status = 400, code?: string) {\r\n super(message);\r\n\r\n this.name = \"HttpError\";\r\n this.status = status;\r\n this.code = code;\r\n\r\n Object.setPrototypeOf(this, HttpError.prototype);\r\n }\r\n}\r\n","import { HttpError } from \"./http-error\";\r\n\r\nconst GENERIC_MESSAGE = \"Erreur serveur\";\r\n\r\nfunction shouldShowDetails(showDetails?: boolean): boolean {\r\n return showDetails ?? process.env.NODE_ENV !== \"production\";\r\n}\r\n\r\nfunction sanitizedResponse(\r\n message: string,\r\n code: string,\r\n status: number,\r\n showDetails?: boolean,\r\n) {\r\n return Response.json(\r\n {\r\n message: showDetails ? message : GENERIC_MESSAGE,\r\n code: showDetails ? code : \"INTERNAL_ERROR\",\r\n status,\r\n },\r\n { status },\r\n );\r\n}\r\n\r\n/**\r\n * Transforme n'importe quelle erreur en réponse JSON standardisée\r\n * @param error L'erreur levée\r\n * @param defaultStatus Statut HTTP par défaut si non défini\r\n * @param showDetails Force l'affichage des détails (true) ou le mode sécurisé (false). Par défaut : automatique selon NODE_ENV\r\n * @returns Response JSON\r\n */\r\nexport function handleServerError(\r\n error: unknown,\r\n defaultStatus = 500,\r\n showDetails?: boolean,\r\n) {\r\n const details = shouldShowDetails(showDetails);\r\n\r\n console.error(\"Erreur capturée :\", error);\r\n\r\n // Cas HttpError personnalisé — toujours visible (erreur intentionnelle)\r\n if (error instanceof HttpError) {\r\n const status = error.status ?? defaultStatus;\r\n return Response.json(\r\n {\r\n message: error.message,\r\n code: error.code ?? \"INTERNAL_ERROR\",\r\n status,\r\n },\r\n { status },\r\n );\r\n }\r\n\r\n // Cas classique : objet Error\r\n if (error instanceof Error) {\r\n return sanitizedResponse(\r\n error.message,\r\n \"INTERNAL_ERROR\",\r\n defaultStatus,\r\n details,\r\n );\r\n }\r\n\r\n // Cas objet brut ou autre type\r\n if (typeof error === \"object\" && error !== null) {\r\n return sanitizedResponse(\r\n JSON.stringify(error),\r\n \"INTERNAL_ERROR\",\r\n defaultStatus,\r\n details,\r\n );\r\n }\r\n\r\n // Cas fallback : string ou autre\r\n return sanitizedResponse(\r\n String(error),\r\n \"INTERNAL_ERROR\",\r\n defaultStatus,\r\n details,\r\n );\r\n}\r\n"],"mappings":"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","names":["jsx","useState","useState","jsx","jsxs","jsx","jsxs","useState","useState","useEffect","jsx","jsxs","X","useEffect","jsx","jsxs","useCallback","useEffect","useRef","useState","jsx","jsxs"]}
1
+ {"version":3,"sources":["../packages/ui/src/layouts/side-nav.tsx","../packages/ui/src/config/create-side-nav.tsx","../packages/ui/src/table/table.tsx","../packages/ui/src/feedback/error-display.tsx","../packages/ui/src/table/actions-menu.tsx","../packages/ui/src/modals/modal.tsx","../packages/ui/src/feedback/confirmation.tsx","../packages/ui/src/headers/header-content.tsx","../packages/ui/src/forms/form.tsx","../packages/utils/src/fetcher.ts","../packages/lib/src/http-error.ts","../packages/lib/src/handle-server-error.ts"],"sourcesContent":["\"use client\";\r\n\r\nimport {\r\n ReactNode,\r\n useState,\r\n useEffect,\r\n createElement,\r\n isValidElement,\r\n type ComponentType,\r\n} from \"react\";\r\n\r\ntype IconType = ReactNode | ComponentType<{ size?: number }>;\r\n\r\nexport interface NavItem {\r\n id: string;\r\n label: string;\r\n title?: string;\r\n icon?: IconType;\r\n href: string;\r\n subItems?: NavItem[];\r\n}\r\n\r\nexport interface SideNavStaticConfig {\r\n brand?: {\r\n logo?: ReactNode;\r\n name?: string;\r\n tagline?: string;\r\n };\r\n mainItems: NavItem[];\r\n title?: string;\r\n footer?: { icon?: IconType; label: string; href: string }[];\r\n toggleIcon?: ReactNode;\r\n}\r\n\r\nexport interface SideNavProps extends SideNavStaticConfig {\r\n children: ReactNode;\r\n currentPath: string;\r\n}\r\n\r\nfunction isActive(href: string, currentPath: string) {\r\n return currentPath === href || currentPath.startsWith(href + \"/\");\r\n}\r\n\r\nfunction isExactActive(href: string, currentPath: string) {\r\n return currentPath === href;\r\n}\r\n\r\nexport function SideNav({\r\n children,\r\n title,\r\n mainItems,\r\n currentPath,\r\n brand,\r\n footer,\r\n toggleIcon,\r\n}: SideNavProps) {\r\n const activeMain = mainItems.find((item) => isActive(item.href, currentPath));\r\n const headerTitle = title ?? activeMain?.title ?? activeMain?.label;\r\n const [expandedSection, setExpandedSection] = useState<string | null>(\r\n activeMain?.id ?? null,\r\n );\r\n\r\n const toggleSection = (id: string) => {\r\n setExpandedSection((prev) => (prev === id ? null : id));\r\n };\r\n\r\n const [isMobileOpen, setIsMobileOpen] = useState(false);\r\n\r\n useEffect(() => {\r\n const handleEscape = (e: KeyboardEvent) => {\r\n if (e.key === \"Escape\") setIsMobileOpen(false);\r\n };\r\n document.addEventListener(\"keydown\", handleEscape);\r\n return () => document.removeEventListener(\"keydown\", handleEscape);\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (isMobileOpen) {\r\n document.body.style.overflow = \"hidden\";\r\n } else {\r\n document.body.style.overflow = \"\";\r\n }\r\n return () => {\r\n document.body.style.overflow = \"\";\r\n };\r\n }, [isMobileOpen]);\r\n\r\n const closeMobileNav = () => setIsMobileOpen(false);\r\n\r\n return (\r\n <div className=\"flex min-h-screen\">\r\n <aside\r\n className={`w-64 bg-white border-r border-gray-200 flex flex-col fixed h-full z-50 transition-transform duration-300 ease-in-out md:translate-x-0 ${\r\n isMobileOpen ? \"translate-x-0\" : \"-translate-x-full\"\r\n }`}\r\n >\r\n {brand && (\r\n <div className=\"p-[6.5px] border-b border-gray-100\">\r\n <div className=\"flex flex-row gap-2 items-center\">\r\n {brand.logo &&\r\n (typeof brand.logo === \"string\" ? (\r\n <img\r\n src={brand.logo}\r\n alt={brand.name ?? \"\"}\r\n className=\"w-12.5 h-12.5\"\r\n />\r\n ) : (\r\n brand.logo\r\n ))}\r\n {brand.name && (\r\n <p className=\"text-gray-500 text-base font-semibold\">\r\n {brand.name}\r\n </p>\r\n )}\r\n </div>\r\n </div>\r\n )}\r\n\r\n <nav className=\"flex-1 p-4 overflow-y-auto\">\r\n <ul className=\"space-y-1\">\r\n {mainItems.map((item) => {\r\n const active = isActive(item.href, currentPath);\r\n const isExpanded = expandedSection === item.id;\r\n const hasSubItems = item.subItems && item.subItems.length > 0;\r\n\r\n return (\r\n <li key={item.id}>\r\n <div className=\"flex items-center gap-1\">\r\n <a\r\n href={item.href}\r\n onClick={closeMobileNav}\r\n className={`flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium transition-colors flex-1 ${\r\n active\r\n ? \"bg-gray-200 text-black\"\r\n : \"text-gray-500 hover:bg-gray-100\"\r\n }`}\r\n >\r\n {item.icon &&\r\n (typeof item.icon === \"string\" ? (\r\n <span className=\"text-lg\">{item.icon}</span>\r\n ) : isValidElement(item.icon) ? (\r\n item.icon\r\n ) : (\r\n createElement(\r\n item.icon as ComponentType<{ size?: number }>,\r\n { size: 20 },\r\n )\r\n ))}\r\n {item.label}\r\n </a>\r\n {active && hasSubItems && (\r\n <button\r\n onClick={() => toggleSection(item.id)}\r\n className={`p-1.5 rounded-lg transition-colors ${\r\n active\r\n ? \"text-black hover:bg-gray-100\"\r\n : \"text-gray-500 hover:bg-gray-100\"\r\n }`}\r\n title={isExpanded ? \"Réduire\" : \"Développer\"}\r\n >\r\n {toggleIcon ? (\r\n <span\r\n className={`inline-block transition-transform duration-200 ${\r\n isExpanded ? \"rotate-0\" : \"-rotate-90\"\r\n }`}\r\n >\r\n {toggleIcon}\r\n </span>\r\n ) : (\r\n <span className=\"text-xs\">\r\n {isExpanded ? \"▼\" : \"▶\"}\r\n </span>\r\n )}\r\n </button>\r\n )}\r\n </div>\r\n\r\n {active && hasSubItems && (\r\n <div\r\n className={`grid transition-all duration-300 ease-in-out ${\r\n isExpanded ? \"grid-rows-[1fr]\" : \"grid-rows-[0fr]\"\r\n }`}\r\n >\r\n <div className=\"overflow-hidden\">\r\n <ul className=\"ml-4 mt-1 space-y-1 pl-2\">\r\n {item.subItems!.map((sub) => (\r\n <li key={sub.id}>\r\n <a\r\n href={sub.href}\r\n onClick={closeMobileNav}\r\n className={`flex items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium transition-colors ${\r\n isExactActive(sub.href, currentPath)\r\n ? \"bg-gray-200 text-black\"\r\n : \"text-gray-500 hover:bg-gray-100\"\r\n }`}\r\n >\r\n {sub.label}\r\n </a>\r\n </li>\r\n ))}\r\n </ul>\r\n </div>\r\n </div>\r\n )}\r\n </li>\r\n );\r\n })}\r\n </ul>\r\n </nav>\r\n\r\n {footer && footer.length > 0 && (\r\n <div className=\"p-4 border-t border-gray-100 space-y-1\">\r\n {footer.map((item) => (\r\n <a\r\n key={item.label}\r\n href={item.href}\r\n onClick={closeMobileNav}\r\n className=\"flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-medium text-gray-700 hover:bg-gray-100 transition-colors\"\r\n >\r\n {typeof item.icon === \"string\" ? (\r\n <span className=\"text-lg\">{item.icon}</span>\r\n ) : isValidElement(item.icon) ? (\r\n item.icon\r\n ) : (\r\n createElement(item.icon as ComponentType<{ size?: number }>, {\r\n size: 20,\r\n })\r\n )}\r\n {item.label}\r\n </a>\r\n ))}\r\n </div>\r\n )}\r\n </aside>\r\n\r\n {isMobileOpen && (\r\n <div\r\n className=\"fixed inset-0 z-40 bg-black/50 md:hidden\"\r\n onClick={closeMobileNav}\r\n aria-hidden=\"true\"\r\n />\r\n )}\r\n\r\n <div className=\"flex-1 ml-64 max-md:ml-0 min-w-0\">\r\n {headerTitle && (\r\n <header className=\"h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6 fixed top-0 right-0 left-64 max-md:left-0 z-20\">\r\n <div className=\"flex items-center gap-2\">\r\n <button\r\n className=\"md:hidden p-2 -ml-2 rounded-lg hover:bg-gray-100 transition-colors\"\r\n onClick={() => setIsMobileOpen(!isMobileOpen)}\r\n aria-label={isMobileOpen ? \"Fermer le menu\" : \"Menu\"}\r\n aria-expanded={isMobileOpen}\r\n >\r\n {isMobileOpen ? (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M6 18L18 6M6 6l12 12\"\r\n />\r\n </svg>\r\n ) : (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M4 6h16M4 12h16M4 18h16\"\r\n />\r\n </svg>\r\n )}\r\n </button>\r\n <h1 className=\"text-base font-semibold text-gray-500\">\r\n {headerTitle}\r\n </h1>\r\n </div>\r\n {brand?.tagline && (\r\n <span className=\"text-sm text-gray-500 max-md:hidden\">\r\n {brand.tagline}\r\n </span>\r\n )}\r\n </header>\r\n )}\r\n {!headerTitle && (\r\n <button\r\n className=\"md:hidden fixed top-4 left-4 z-10 p-2 rounded-lg bg-white border border-gray-200 shadow-sm hover:bg-gray-100 transition-colors\"\r\n onClick={() => setIsMobileOpen(!isMobileOpen)}\r\n aria-label={isMobileOpen ? \"Fermer le menu\" : \"Menu\"}\r\n aria-expanded={isMobileOpen}\r\n >\r\n {isMobileOpen ? (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M6 18L18 6M6 6l12 12\"\r\n />\r\n </svg>\r\n ) : (\r\n <svg\r\n className=\"w-5 h-5\"\r\n fill=\"none\"\r\n viewBox=\"0 0 24 24\"\r\n stroke=\"currentColor\"\r\n strokeWidth={2}\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n d=\"M4 6h16M4 12h16M4 18h16\"\r\n />\r\n </svg>\r\n )}\r\n </button>\r\n )}\r\n <main\r\n className={(headerTitle ? \"p-6 pt-20\" : \"p-6\") + \" overflow-x-auto\"}\r\n >\r\n {children}\r\n </main>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","import { SideNav, type SideNavStaticConfig } from \"../layouts/side-nav\";\n\nexport function createSideNav(config: SideNavStaticConfig) {\n return function ConfiguredSideNav({\n children,\n currentPath,\n }: {\n children: React.ReactNode;\n currentPath: string;\n }) {\n return (\n <SideNav {...config} currentPath={currentPath}>\n {children}\n </SideNav>\n );\n };\n}\n","\"use client\";\r\n\r\nimport { Printer, ChevronLeft, ChevronRight } from \"lucide-react\";\r\nimport clsx from \"clsx\";\r\nimport { useState, useMemo, useCallback } from \"react\";\r\nimport { ErrorDisplay } from \"../feedback/error-display\";\r\nimport { ApiError } from \"../../../utils/src/fetcher\";\r\n\r\nexport type Column<T> = {\r\n header: string;\r\n accessor?: keyof T;\r\n render?: (row: T) => React.ReactNode;\r\n excludeFromPrint?: boolean;\r\n};\r\n\r\ntype TableProps<T> = {\r\n data: T[];\r\n columns: Column<T>[];\r\n loading?: boolean;\r\n error?: ApiError | null;\r\n label?: string;\r\n printable?: boolean;\r\n pageSize?: number;\r\n pageSizeOptions?: number[];\r\n showPagination?: boolean;\r\n};\r\n\r\nconst VISIBLE_PAGES = 5;\r\n\r\nexport function Table<T>({\r\n data,\r\n columns,\r\n loading,\r\n error,\r\n label,\r\n printable,\r\n pageSize = 5,\r\n pageSizeOptions = [5, 10, 20],\r\n showPagination = true,\r\n}: TableProps<T>) {\r\n const [tooltip, setTooltip] = useState<{\r\n content: string;\r\n x: number;\r\n y: number;\r\n } | null>(null);\r\n const [page, setPage] = useState(1);\r\n const [perPage, setPerPage] = useState(pageSize);\r\n\r\n const totalPages = useMemo(\r\n () => Math.max(1, Math.ceil(data.length / perPage)),\r\n [data.length, perPage],\r\n );\r\n\r\n const safePage = Math.min(page, totalPages);\r\n\r\n const displayData = useMemo(\r\n () => data.slice((safePage - 1) * perPage, safePage * perPage),\r\n [data, safePage, perPage],\r\n );\r\n\r\n const paginationRange = useMemo(() => {\r\n const half = Math.floor(VISIBLE_PAGES / 2);\r\n let start = Math.max(1, safePage - half);\r\n let end = Math.min(totalPages, start + VISIBLE_PAGES - 1);\r\n if (end - start + 1 < VISIBLE_PAGES) {\r\n start = Math.max(1, end - VISIBLE_PAGES + 1);\r\n }\r\n const range: (number | \"...\")[] = [];\r\n if (start > 1) {\r\n range.push(1);\r\n if (start > 2) range.push(\"...\");\r\n }\r\n for (let i = start; i <= end; i++) range.push(i);\r\n if (end < totalPages) {\r\n if (end < totalPages - 1) range.push(\"...\");\r\n range.push(totalPages);\r\n }\r\n return range;\r\n }, [safePage, totalPages]);\r\n\r\n const handlePageSizeChange = useCallback((value: number) => {\r\n setPerPage(value);\r\n setPage(1);\r\n }, []);\r\n\r\n const colCount = columns.length;\r\n const colWidth = colCount > 0 ? `${Math.round(100 / colCount)}%` : \"auto\";\r\n\r\n const handleMouseEnter = (\r\n e: React.MouseEvent<HTMLDivElement>,\r\n content: string,\r\n ) => {\r\n const rect = e.currentTarget.getBoundingClientRect();\r\n setTooltip({\r\n content,\r\n x: rect.left + rect.width / 2,\r\n y: rect.top,\r\n });\r\n };\r\n\r\n const handleMouseLeave = () => {\r\n setTooltip(null);\r\n };\r\n\r\n const banner = error ? (\r\n <div className=\"mb-4\">\r\n <ErrorDisplay key={error.message} error={error} />\r\n </div>\r\n ) : null;\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n {banner}\r\n <div className=\"rounded-lg shadow-md border border-gray-200\">\r\n <div className=\"flex items-center justify-center py-20 text-gray-500\">\r\n Chargement...\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n if (!data || data.length === 0) {\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n {banner}\r\n <div className=\"rounded-lg shadow-md border border-gray-200\">\r\n <div className=\"flex items-center justify-center py-20 text-gray-500\">\r\n Aucun élément\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n }\r\n\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n {banner}\r\n <div className=\"flex items-center justify-between mb-2\">\r\n {label && (\r\n <div className=\"text-sm font-semibold text-gray-700\">\r\n {label}: {data.length}\r\n </div>\r\n )}\r\n {printable && (\r\n <button\r\n onClick={() => window.print()}\r\n className=\"flex items-center gap-2 px-4 py-2 text-sm font-medium text-white bg-blue-500 rounded-lg hover:bg-blue-600 transition-colors print:hidden\"\r\n >\r\n <Printer className=\"w-4 h-4\" />\r\n Imprimer\r\n </button>\r\n )}\r\n </div>\r\n <div className=\"rounded-lg shadow-md border border-gray-200\">\r\n <table className=\"w-full table-fixed divide-y divide-gray-200 print:table-fixed\">\r\n <thead className=\"bg-blue-500 rounded-t-lg\">\r\n <tr>\r\n {columns.map((col, index) => (\r\n <th\r\n key={index}\r\n style={{ width: colWidth }}\r\n className={clsx(\r\n \"px-6 py-3 text-left text-xs font-bold text-white uppercase tracking-wider truncate\",\r\n col.excludeFromPrint && \"print:hidden\",\r\n )}\r\n >\r\n {col.header}\r\n </th>\r\n ))}\r\n </tr>\r\n </thead>\r\n <tbody\r\n className={clsx(\r\n \"bg-white divide-y divide-gray-200\",\r\n printable && \"print:hidden\",\r\n )}\r\n >\r\n {displayData.map((row, rowIndex) => (\r\n <tr\r\n key={rowIndex}\r\n className=\"hover:bg-gray-100 transition-colors duration-200\"\r\n >\r\n {columns.map((col, colIndex) => {\r\n const cellContent = col.render\r\n ? col.render(row)\r\n : String(row[col.accessor!]);\r\n const textContent =\r\n typeof cellContent === \"string\" ? cellContent : \"\";\r\n\r\n return (\r\n <td\r\n key={colIndex}\r\n style={{ width: colWidth }}\r\n className={clsx(\r\n \"px-6 py-4 text-sm text-gray-700\",\r\n col.excludeFromPrint && \"print:hidden\",\r\n )}\r\n >\r\n {typeof cellContent === \"string\" ? (\r\n <div\r\n className=\"truncate\"\r\n onMouseEnter={(e) => handleMouseEnter(e, textContent)}\r\n onMouseLeave={handleMouseLeave}\r\n >\r\n {cellContent}\r\n </div>\r\n ) : (\r\n cellContent\r\n )}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n ))}\r\n </tbody>\r\n {printable && (\r\n <tbody className=\"hidden print:table-row-group\">\r\n {data.map((row, rowIndex) => (\r\n <tr key={rowIndex}>\r\n {columns.map((col, colIndex) => {\r\n const cellContent = col.render\r\n ? col.render(row)\r\n : String(row[col.accessor!]);\r\n\r\n return (\r\n <td\r\n key={colIndex}\r\n style={{ width: colWidth }}\r\n className={clsx(\r\n \"px-6 py-4 text-sm text-gray-700\",\r\n col.excludeFromPrint && \"print:hidden\",\r\n )}\r\n >\r\n {cellContent}\r\n </td>\r\n );\r\n })}\r\n </tr>\r\n ))}\r\n </tbody>\r\n )}\r\n </table>\r\n </div>\r\n\r\n {showPagination && totalPages > 1 && (\r\n <div className=\"flex items-center justify-between mt-4 text-sm print:hidden\">\r\n <div className=\"flex items-center gap-2 text-gray-600\">\r\n <span>Lignes par page :</span>\r\n <select\r\n value={perPage}\r\n onChange={(e) => handlePageSizeChange(Number(e.target.value))}\r\n className=\"border border-gray-300 rounded px-2 py-1 text-sm bg-white focus:outline-none focus:ring-2 focus:ring-blue-400\"\r\n >\r\n {pageSizeOptions.map((opt) => (\r\n <option key={opt} value={opt}>\r\n {opt}\r\n </option>\r\n ))}\r\n </select>\r\n </div>\r\n\r\n <div className=\"flex items-center gap-1\">\r\n <button\r\n onClick={() => setPage((p) => Math.max(1, p - 1))}\r\n disabled={safePage <= 1}\r\n className={clsx(\r\n \"p-1.5 rounded transition-colors\",\r\n safePage <= 1\r\n ? \"text-gray-300 cursor-not-allowed\"\r\n : \"text-gray-600 hover:bg-gray-100\",\r\n )}\r\n >\r\n <ChevronLeft className=\"w-4 h-4\" />\r\n </button>\r\n\r\n {paginationRange.map((item, i) =>\r\n item === \"...\" ? (\r\n <span key={`ellipsis-${i}`} className=\"px-2 text-gray-400\">\r\n ...\r\n </span>\r\n ) : (\r\n <button\r\n key={item}\r\n onClick={() => setPage(item)}\r\n className={clsx(\r\n \"min-w-8 px-2 py-1 rounded text-sm font-medium transition-colors\",\r\n item === safePage\r\n ? \"bg-blue-500 text-white\"\r\n : \"text-gray-600 hover:bg-gray-100\",\r\n )}\r\n >\r\n {item}\r\n </button>\r\n ),\r\n )}\r\n\r\n <button\r\n onClick={() => setPage((p) => Math.min(totalPages, p + 1))}\r\n disabled={safePage >= totalPages}\r\n className={clsx(\r\n \"p-1.5 rounded transition-colors\",\r\n safePage >= totalPages\r\n ? \"text-gray-300 cursor-not-allowed\"\r\n : \"text-gray-600 hover:bg-gray-100\",\r\n )}\r\n >\r\n <ChevronRight className=\"w-4 h-4\" />\r\n </button>\r\n </div>\r\n\r\n <div className=\"text-gray-500\">\r\n Page {safePage} sur {totalPages}\r\n </div>\r\n </div>\r\n )}\r\n\r\n {tooltip && (\r\n <div\r\n className=\"fixed z-20 px-3 py-2 text-sm text-white bg-gray-800 rounded-lg shadow-lg pointer-events-none whitespace-nowrap\"\r\n style={{\r\n left: tooltip.x,\r\n top: tooltip.y - 8,\r\n transform: \"translate(-50%, -100%)\",\r\n }}\r\n >\r\n {tooltip.content}\r\n </div>\r\n )}\r\n <style>{`\r\n @media print {\r\n body * { visibility: hidden; }\r\n .w-full.overflow-x-auto { visibility: visible; }\r\n .w-full.overflow-x-auto * { visibility: visible; }\r\n .w-full.overflow-x-auto { position: absolute; left: 0; top: 0; width: 100%; }\r\n }\r\n `}</style>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { X } from \"lucide-react\";\r\nimport { ApiError } from \"../../../utils/src\";\r\nimport { useState } from \"react\";\r\n\r\ninterface ErrorDisplayProps {\r\n error: ApiError | null;\r\n}\r\n\r\nexport function ErrorDisplay({ error }: ErrorDisplayProps) {\r\n const [dismissed, setDismissed] = useState(false);\r\n\r\n if (!error || dismissed) return null;\r\n\r\n return (\r\n <div className=\"w-full overflow-x-auto\">\r\n <div className=\"rounded-lg shadow-md border border-red-200 bg-red-50\">\r\n <div className=\"flex items-start justify-between gap-4 px-4 py-4\">\r\n <div className=\"flex flex-col gap-1\">\r\n <p className=\"text-red-700 font-medium\">Erreur</p>\r\n <p className=\"text-red-600 text-sm\">{error.message}</p>\r\n </div>\r\n <button\r\n onClick={() => setDismissed(true)}\r\n className=\"text-red-400 hover:text-red-600 shrink-0 cursor-pointer\"\r\n >\r\n <X className=\"w-5 h-5\" />\r\n </button>\r\n </div>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport React, { useState, useRef, useEffect } from \"react\";\r\nimport { Ellipsis } from \"lucide-react\";\r\n\r\nexport type TableAction<T> = {\r\n label: string;\r\n icon: React.ReactNode;\r\n callback: (row: T) => void;\r\n color?: string;\r\n};\r\n\r\ntype ActionsMenuProps<T> = {\r\n row: T;\r\n actions: TableAction<T>[];\r\n};\r\n\r\nexport function ActionsMenu<T>({ row, actions }: ActionsMenuProps<T>) {\r\n const [isOpen, setIsOpen] = useState(false);\r\n const [coords, setCoords] = useState({ top: 0, left: 0 });\r\n const buttonRef = useRef<HTMLButtonElement>(null);\r\n const menuRef = useRef<HTMLDivElement>(null);\r\n\r\n // Fermer le menu si clic en dehors\r\n useEffect(() => {\r\n function handleClickOutside(event: MouseEvent) {\r\n if (\r\n menuRef.current &&\r\n buttonRef.current &&\r\n !menuRef.current.contains(event.target as Node) &&\r\n !buttonRef.current.contains(event.target as Node)\r\n ) {\r\n setIsOpen(false);\r\n }\r\n }\r\n\r\n document.addEventListener(\"mousedown\", handleClickOutside);\r\n return () => document.removeEventListener(\"mousedown\", handleClickOutside);\r\n }, []);\r\n\r\n const toggleMenu = () => {\r\n if (buttonRef.current) {\r\n const rect = buttonRef.current.getBoundingClientRect();\r\n const menuWidth = 180;\r\n const menuHeight = actions.length * 40;\r\n\r\n const spaceBelow = window.innerHeight - rect.bottom;\r\n const spaceRight = window.innerWidth - rect.left;\r\n\r\n let top = rect.bottom;\r\n let left = rect.left;\r\n\r\n // If not enough space below, show above\r\n if (spaceBelow < menuHeight + 20) {\r\n top = rect.top - menuHeight;\r\n }\r\n\r\n // If not enough space on the right, align to the left\r\n if (spaceRight < menuWidth + 20) {\r\n left = rect.left - menuWidth + 30;\r\n }\r\n\r\n setCoords({ top, left });\r\n }\r\n setIsOpen(!isOpen);\r\n };\r\n\r\n return (\r\n <>\r\n <button\r\n ref={buttonRef}\r\n onClick={toggleMenu}\r\n className=\"p-1 hover:bg-gray-100 rounded-full\"\r\n >\r\n <Ellipsis className=\"w-5 h-5\" />\r\n </button>\r\n\r\n {isOpen && (\r\n <div\r\n ref={menuRef}\r\n className=\"fixed bg-white border border-gray-200 rounded shadow-lg z-20\"\r\n style={{\r\n top: coords.top,\r\n left: coords.left,\r\n minWidth: 180,\r\n }}\r\n >\r\n {actions.map((action, idx) => (\r\n <button\r\n key={idx}\r\n className={`flex items-center gap-2 px-4 py-2 w-full text-sm hover:bg-gray-100 ${\r\n action.color || \"text-gray-700\"\r\n }`}\r\n onClick={() => {\r\n action.callback(row);\r\n setIsOpen(false);\r\n }}\r\n >\r\n {action.icon}\r\n {action.label}\r\n </button>\r\n ))}\r\n </div>\r\n )}\r\n </>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { X } from \"lucide-react\";\r\nimport React, { useEffect } from \"react\";\r\nimport { createPortal } from \"react-dom\";\r\n\r\ntype ModalProps = {\r\n title: string;\r\n isOpen: boolean;\r\n onClose: () => void;\r\n children: React.ReactNode | ((requestClose: () => void) => React.ReactNode);\r\n};\r\n\r\nexport function Modal({ title, isOpen, onClose, children }: ModalProps) {\r\n const requestClose = () => {\r\n onClose();\r\n };\r\n\r\n useEffect(() => {\r\n if (isOpen) {\r\n document.body.style.overflow = \"hidden\";\r\n }\r\n\r\n return () => {\r\n document.body.style.overflow = \"\";\r\n };\r\n }, [isOpen]);\r\n\r\n useEffect(() => {\r\n function handleEsc(e: KeyboardEvent) {\r\n if (e.key === \"Escape\") {\r\n onClose();\r\n }\r\n }\r\n\r\n if (isOpen) {\r\n document.addEventListener(\"keydown\", handleEsc);\r\n }\r\n\r\n return () => {\r\n document.removeEventListener(\"keydown\", handleEsc);\r\n };\r\n }, [isOpen, onClose]);\r\n\r\n if (!isOpen) return null;\r\n\r\n const content =\r\n typeof children === \"function\" ? children(requestClose) : children;\r\n\r\n return createPortal(\r\n <div className=\"fixed inset-0 z-50 flex items-center justify-center\">\r\n <div\r\n className=\"absolute inset-0 bg-black/20 backdrop-blur-sm\"\r\n onClick={onClose}\r\n />\r\n\r\n <div className=\"relative bg-white rounded-lg shadow-lg w-full max-w-2xl mx-4 p-6 flex flex-col max-h-[85vh]\">\r\n <div className=\"flex items-center justify-between mb-4 border-b-2 border-gray-400 pb-3 sticky top-0 bg-white z-10\">\r\n <h2 className=\"text-lg font-semibold text-gray-900\">{title}</h2>\r\n\r\n <button\r\n onClick={onClose}\r\n className=\"text-gray-500 hover:text-gray-700 text-xl cursor-pointer\"\r\n >\r\n <X />\r\n </button>\r\n </div>\r\n\r\n <div className=\"overflow-y-auto flex-1 min-h-0\">{content}</div>\r\n </div>\r\n </div>,\r\n document.body,\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { useCallback, useEffect, useRef, useState } from \"react\";\r\nimport { ApiError } from \"../../../utils/src/fetcher\";\r\nimport { CircleQuestionMark } from \"lucide-react\";\r\n\r\nconst ERROR_COUNTDOWN = 10;\r\n\r\ninterface ConfirmationProps {\r\n question: string;\r\n messageYes: string;\r\n messageNo: string;\r\n requestClose: () => void;\r\n onAction: () =>\r\n | void\r\n | Promise<void>\r\n | Promise<boolean>\r\n | Promise<{ success: true }>;\r\n isProcessing: boolean;\r\n error: ApiError | null;\r\n resetRequest: () => void;\r\n}\r\n\r\nexport function Confirmation({\r\n question,\r\n messageYes,\r\n messageNo,\r\n requestClose,\r\n onAction,\r\n isProcessing,\r\n error,\r\n resetRequest,\r\n}: ConfirmationProps) {\r\n const [countdown, setCountdown] = useState(0);\r\n const countdownRef = useRef<number | null>(null);\r\n const resetRequestRef = useRef(resetRequest);\r\n\r\n useEffect(() => {\r\n resetRequestRef.current = resetRequest;\r\n }, [resetRequest]);\r\n\r\n const clearCountdown = useCallback(() => {\r\n if (countdownRef.current !== null) {\r\n window.clearInterval(countdownRef.current);\r\n countdownRef.current = null;\r\n }\r\n }, []);\r\n\r\n const resetConfirmationState = useCallback(() => {\r\n clearCountdown();\r\n setCountdown(0);\r\n }, [clearCountdown]);\r\n\r\n const handleResetRequest = useCallback(() => {\r\n resetConfirmationState();\r\n resetRequest();\r\n }, [resetConfirmationState, resetRequest]);\r\n\r\n const handleRequestClose = useCallback(() => {\r\n resetConfirmationState();\r\n resetRequest();\r\n requestClose();\r\n }, [requestClose, resetConfirmationState, resetRequest]);\r\n\r\n const handleAction = useCallback(async () => {\r\n try {\r\n await onAction();\r\n handleRequestClose();\r\n } catch {\r\n // L'erreur est propagée par le parent via la prop `error`.\r\n }\r\n }, [handleRequestClose, onAction]);\r\n\r\n useEffect(() => {\r\n clearCountdown();\r\n\r\n if (!error) {\r\n const resetTimeoutId = window.setTimeout(() => {\r\n setCountdown(0);\r\n }, 0);\r\n\r\n return () => {\r\n window.clearTimeout(resetTimeoutId);\r\n };\r\n }\r\n\r\n const startCountdownTimeoutId = window.setTimeout(() => {\r\n setCountdown(ERROR_COUNTDOWN);\r\n\r\n countdownRef.current = window.setInterval(() => {\r\n setCountdown((previousCountdown) => {\r\n if (previousCountdown <= 1) {\r\n clearCountdown();\r\n window.setTimeout(() => {\r\n resetRequestRef.current();\r\n }, 0);\r\n\r\n return 0;\r\n }\r\n\r\n return previousCountdown - 1;\r\n });\r\n }, 1000);\r\n }, 0);\r\n\r\n return () => {\r\n window.clearTimeout(startCountdownTimeoutId);\r\n clearCountdown();\r\n };\r\n }, [clearCountdown, error]);\r\n\r\n useEffect(() => {\r\n return () => {\r\n clearCountdown();\r\n resetRequestRef.current();\r\n };\r\n }, [clearCountdown]);\r\n\r\n const isErrorVisible = Boolean(error) && countdown > 0;\r\n\r\n if (!question) return null;\r\n\r\n return (\r\n <div className=\"flex flex-col items-center gap-3 z-40\">\r\n <CircleQuestionMark className=\"text-red-500 text-5xl\" />\r\n <h2 className=\"text-xl font-bold text-red-500\">Confirmation requise</h2>\r\n\r\n <p className=\"mt-4 text-md leading-relaxed text-gray-700\">{question}</p>\r\n\r\n <div className=\"mt-6 flex w-full gap-3\">\r\n <button\r\n type=\"button\"\r\n onClick={handleRequestClose}\r\n disabled={isProcessing}\r\n className=\"w-full rounded-lg border border-gray-300 bg-white px-4 py-2 text-sm font-semibold text-gray-700 transition hover:cursor-pointer hover:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-50 disabled:hover:bg-white\"\r\n >\r\n {messageNo}\r\n </button>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={handleAction}\r\n disabled={isProcessing}\r\n className=\"w-full rounded-lg bg-red-400 px-4 py-2 text-sm font-semibold text-white transition hover:cursor-pointer hover:bg-red-500 active:scale-95 disabled:opacity-50 disabled:hover:bg-red-500\"\r\n >\r\n {isProcessing ? \"operation en cours\" : messageYes}\r\n </button>\r\n </div>\r\n\r\n {error && isErrorVisible && (\r\n <div className=\"mt-4 w-full rounded-lg border border-red-200 bg-red-50 p-4 text-left text-sm text-red-700\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div>\r\n <p className=\"font-semibold\">Erreur</p>\r\n <p className=\"mt-1 text-sm\">{error.message}</p>\r\n </div>\r\n\r\n <button\r\n type=\"button\"\r\n onClick={handleResetRequest}\r\n className=\"rounded-full bg-red-100 px-2 py-1 text-xs font-semibold text-red-700 hover:bg-red-200\"\r\n >\r\n Fermer\r\n </button>\r\n </div>\r\n\r\n <p className=\"mt-3 text-xs text-red-600\">\r\n Ce message disparait dans {countdown}s...\r\n </p>\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport React from \"react\";\r\n\r\ntype HeaderContentProps = {\r\n title: string;\r\n description: string;\r\n\r\n actionLabel?: string;\r\n onAction?: () => void;\r\n icon?: React.ReactNode;\r\n};\r\n\r\nexport function HeaderContent({\r\n title,\r\n description,\r\n actionLabel,\r\n onAction,\r\n icon,\r\n}: HeaderContentProps) {\r\n return (\r\n <div className=\"flex flex-col md:flex-row md:items-center md:justify-between gap-4 mb-6\">\r\n <div>\r\n <h1 className=\"text-xl text-blue-600 flex items-center gap-2\">\r\n {title}\r\n </h1>\r\n\r\n {description && (\r\n <p className=\"text-sm text-gray-500 mt-1\">{description}</p>\r\n )}\r\n </div>\r\n\r\n {actionLabel && onAction && (\r\n <button\r\n onClick={onAction}\r\n className=\"font-semibold md:inline-flex items-center gap-2 bg-blue-500 text-white px-4 py-2 rounded-md text-sm hover:bg-blue-700 transition hover:cursor-pointer\"\r\n >\r\n {icon && <span className=\"w-4 h-4\">{icon}</span>}\r\n {actionLabel}\r\n </button>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\n","import React, { useState, useEffect, useRef, useCallback } from \"react\";\r\nimport { ApiError } from \"../../../utils/src/fetcher\";\r\nimport { X } from \"lucide-react\";\r\n\r\ninterface FormProps extends React.FormHTMLAttributes<HTMLFormElement> {\r\n erreurs?: ApiError | null;\r\n onErrorClose?: () => void;\r\n}\r\n\r\nconst Form: React.FC<FormProps> = ({\r\n erreurs,\r\n onErrorClose,\r\n children,\r\n className,\r\n ...props\r\n}) => {\r\n const formClassName = [\"flex flex-col gap-3\", className]\r\n .filter(Boolean)\r\n .join(\" \");\r\n const errorMessage = erreurs?.message || null;\r\n const [showError, setShowError] = useState(!!erreurs);\r\n const [countdown, setCountdown] = useState(erreurs ? 10 : 0);\r\n const [animating, setAnimating] = useState(!!erreurs);\r\n const intervalRef = useRef<number | null>(null);\r\n const hasClosedRef = useRef(false);\r\n\r\n const closeError = useCallback(\r\n (triggerCallback = true) => {\r\n if (intervalRef.current !== null) {\r\n window.clearInterval(intervalRef.current);\r\n intervalRef.current = null;\r\n }\r\n\r\n setShowError(false);\r\n setAnimating(false);\r\n setCountdown(0);\r\n\r\n if (triggerCallback && onErrorClose && !hasClosedRef.current) {\r\n hasClosedRef.current = true;\r\n onErrorClose();\r\n }\r\n },\r\n [onErrorClose],\r\n );\r\n\r\n useEffect(() => {\r\n hasClosedRef.current = false;\r\n\r\n if (!erreurs) {\r\n const closeTimeout = window.setTimeout(() => closeError(false), 0);\r\n return () => {\r\n window.clearTimeout(closeTimeout);\r\n };\r\n }\r\n\r\n const initTimeout = window.setTimeout(() => {\r\n setShowError(true);\r\n setAnimating(true);\r\n setCountdown(10);\r\n }, 0);\r\n\r\n intervalRef.current = window.setInterval(() => {\r\n setCountdown((prev) => {\r\n if (prev <= 1) {\r\n closeError(true);\r\n return 0;\r\n }\r\n return prev - 1;\r\n });\r\n }, 1000);\r\n\r\n return () => {\r\n window.clearTimeout(initTimeout);\r\n if (intervalRef.current !== null) {\r\n window.clearInterval(intervalRef.current);\r\n intervalRef.current = null;\r\n }\r\n };\r\n }, [erreurs, closeError]);\r\n\r\n return (\r\n <>\r\n <form className={formClassName} {...props}>\r\n {children}\r\n </form>\r\n {showError && errorMessage && (\r\n <div\r\n className={`fixed top-0 left-0 right-0 z-[9999] bg-red-500 text-white p-4 rounded-b-md shadow-lg flex justify-between items-center transition-transform duration-300 ${\r\n animating\r\n ? \"transform translate-y-0\"\r\n : \"transform -translate-y-full\"\r\n }`}\r\n >\r\n <span>{errorMessage}</span>\r\n <div className=\"flex items-center\">\r\n <span className=\"mr-2\">{countdown}s</span>\r\n <button onClick={() => closeError(true)}>\r\n <X size={20} />\r\n </button>\r\n </div>\r\n </div>\r\n )}\r\n </>\r\n );\r\n};\r\n\r\nexport { Form };\r\n","export class ApiError extends Error {\r\n public status: number;\r\n public code?: string;\r\n public data?: unknown;\r\n\r\n constructor(params: {\r\n message: string;\r\n status: number;\r\n code?: string;\r\n data?: unknown;\r\n }) {\r\n super(params.message);\r\n this.status = params.status;\r\n this.code = params.code;\r\n this.data = params.data;\r\n }\r\n}\r\n\r\ntype BackendErrorShape = {\r\n code?: string;\r\n status?: number;\r\n message?: string;\r\n};\r\n\r\nexport type FetcherOptions = RequestInit & {\r\n skipJsonParsing?: boolean;\r\n};\r\n\r\nexport async function fetcher<T = unknown>(\r\n url: string,\r\n options: FetcherOptions = {},\r\n): Promise<T> {\r\n const { headers, skipJsonParsing = false, ...rest } = options;\r\n\r\n const response = await fetch(url, {\r\n credentials: \"include\",\r\n headers: {\r\n \"Content-Type\": \"application/json\",\r\n ...headers,\r\n },\r\n ...rest,\r\n });\r\n\r\n let responseData: unknown = null;\r\n const contentType = response.headers.get(\"content-type\");\r\n\r\n if (!skipJsonParsing && contentType?.includes(\"application/json\")) {\r\n responseData = await response.json();\r\n }\r\n\r\n if (!response.ok) {\r\n const backendError = responseData as BackendErrorShape;\r\n\r\n throw new ApiError({\r\n message: backendError?.message || \"Une erreur est survenue\",\r\n status: backendError?.status || response.status,\r\n code: backendError?.code,\r\n data: responseData,\r\n });\r\n }\r\n\r\n return responseData as T;\r\n}\r\n","export class HttpError extends Error {\r\n status: number;\r\n code?: string;\r\n\r\n constructor(message: string, status = 400, code?: string) {\r\n super(message);\r\n\r\n this.name = \"HttpError\";\r\n this.status = status;\r\n this.code = code;\r\n\r\n Object.setPrototypeOf(this, HttpError.prototype);\r\n }\r\n}\r\n","import { HttpError } from \"./http-error\";\r\n\r\nconst GENERIC_MESSAGE = \"Erreur serveur\";\r\n\r\nfunction shouldShowDetails(showDetails?: boolean): boolean {\r\n return showDetails ?? process.env.NODE_ENV !== \"production\";\r\n}\r\n\r\nfunction sanitizedResponse(\r\n message: string,\r\n code: string,\r\n status: number,\r\n showDetails?: boolean,\r\n) {\r\n return Response.json(\r\n {\r\n message: showDetails ? message : GENERIC_MESSAGE,\r\n code: showDetails ? code : \"INTERNAL_ERROR\",\r\n status,\r\n },\r\n { status },\r\n );\r\n}\r\n\r\n/**\r\n * Transforme n'importe quelle erreur en réponse JSON standardisée\r\n * @param error L'erreur levée\r\n * @param defaultStatus Statut HTTP par défaut si non défini\r\n * @param showDetails Force l'affichage des détails (true) ou le mode sécurisé (false). Par défaut : automatique selon NODE_ENV\r\n * @returns Response JSON\r\n */\r\nexport function handleServerError(\r\n error: unknown,\r\n defaultStatus = 500,\r\n showDetails?: boolean,\r\n) {\r\n const details = shouldShowDetails(showDetails);\r\n\r\n console.error(\"Erreur capturée :\", error);\r\n\r\n // Cas HttpError personnalisé — toujours visible (erreur intentionnelle)\r\n if (error instanceof HttpError) {\r\n const status = error.status ?? defaultStatus;\r\n return Response.json(\r\n {\r\n message: error.message,\r\n code: error.code ?? \"INTERNAL_ERROR\",\r\n status,\r\n },\r\n { status },\r\n );\r\n }\r\n\r\n // Cas classique : objet Error\r\n if (error instanceof Error) {\r\n return sanitizedResponse(\r\n error.message,\r\n \"INTERNAL_ERROR\",\r\n defaultStatus,\r\n details,\r\n );\r\n }\r\n\r\n // Cas objet brut ou autre type\r\n if (typeof error === \"object\" && error !== null) {\r\n return sanitizedResponse(\r\n JSON.stringify(error),\r\n \"INTERNAL_ERROR\",\r\n defaultStatus,\r\n details,\r\n );\r\n }\r\n\r\n // Cas fallback : string ou autre\r\n return sanitizedResponse(\r\n String(error),\r\n \"INTERNAL_ERROR\",\r\n defaultStatus,\r\n details,\r\n );\r\n}\r\n"],"mappings":"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","names":["jsx","useState","useState","jsx","jsxs","jsx","jsxs","useState","useState","useEffect","jsx","jsxs","X","useEffect","jsx","jsxs","useCallback","useEffect","useRef","useState","jsx","jsxs","jsx","jsxs","useState","useEffect","useRef","useCallback","X","Fragment","jsx","jsxs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramses1er/cbk-toolkit",
3
- "version": "1.7.0",
3
+ "version": "1.9.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",