@ramses1er/cbk-toolkit 1.9.0 → 1.10.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
@@ -122,6 +122,39 @@ interface FormProps extends React__default.FormHTMLAttributes<HTMLFormElement> {
122
122
  }
123
123
  declare const Form: React__default.FC<FormProps>;
124
124
 
125
+ interface FieldContainerProps {
126
+ children: React__default.ReactNode;
127
+ className?: string;
128
+ }
129
+ declare function FieldContainer({ children, className }: FieldContainerProps): React__default.JSX.Element;
130
+
131
+ interface LabelProps extends Omit<React__default.LabelHTMLAttributes<HTMLLabelElement>, "required"> {
132
+ required?: boolean;
133
+ }
134
+ declare const Label: React__default.ForwardRefExoticComponent<LabelProps & React__default.RefAttributes<HTMLLabelElement>>;
135
+
136
+ declare const Input: React__default.ForwardRefExoticComponent<React__default.InputHTMLAttributes<HTMLInputElement> & React__default.RefAttributes<HTMLInputElement>>;
137
+
138
+ declare const Select: React__default.ForwardRefExoticComponent<React__default.SelectHTMLAttributes<HTMLSelectElement> & React__default.RefAttributes<HTMLSelectElement>>;
139
+
140
+ declare const Option: React__default.ForwardRefExoticComponent<React__default.OptionHTMLAttributes<HTMLOptionElement> & React__default.RefAttributes<HTMLOptionElement>>;
141
+
142
+ declare const TextArea: React__default.ForwardRefExoticComponent<React__default.TextareaHTMLAttributes<HTMLTextAreaElement> & React__default.RefAttributes<HTMLTextAreaElement>>;
143
+
144
+ declare const DatePicker: React__default.ForwardRefExoticComponent<React__default.InputHTMLAttributes<HTMLInputElement> & React__default.RefAttributes<HTMLInputElement>>;
145
+
146
+ interface LoadingProps {
147
+ text: string;
148
+ }
149
+ declare function Loading(props: LoadingProps): React$1.JSX.Element;
150
+
151
+ interface data {
152
+ textAvant: string;
153
+ textAp: string;
154
+ onSubmit: boolean;
155
+ }
156
+ declare function LoaderSubmit(props: data): React$1.JSX.Element;
157
+
125
158
  declare class HttpError extends Error {
126
159
  status: number;
127
160
  code?: string;
@@ -137,4 +170,4 @@ declare class HttpError extends Error {
137
170
  */
138
171
  declare function handleServerError(error: unknown, defaultStatus?: number, showDetails?: boolean): Response;
139
172
 
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 };
173
+ export { ActionsMenu, ApiError, type Column, Confirmation, DatePicker, type FetcherOptions, FieldContainer, Form, HeaderContent, HttpError, Input, Label, LoaderSubmit, Loading, Modal, type NavItem, Option, Select, SideNav, type SideNavProps, type SideNavStaticConfig, Table, type TableAction, TextArea, createSideNav, fetcher, handleServerError };
package/dist/index.js CHANGED
@@ -923,6 +923,151 @@ var Form = ({
923
923
  ] });
924
924
  };
925
925
 
926
+ // packages/ui/src/forms/field-container.tsx
927
+ import { jsx as jsx10 } from "react/jsx-runtime";
928
+ function FieldContainer({ children, className }) {
929
+ return /* @__PURE__ */ jsx10("div", { className: `flex flex-col gap-2 mb-3 relative ${className ?? ""}`, children: /* @__PURE__ */ jsx10("div", { className: "flex flex-col gap-1", children }) });
930
+ }
931
+
932
+ // packages/ui/src/forms/label.tsx
933
+ import React4 from "react";
934
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
935
+ var Label = React4.forwardRef(
936
+ ({ required, children, className, ...props }, ref) => {
937
+ return /* @__PURE__ */ jsxs9(
938
+ "label",
939
+ {
940
+ ref,
941
+ className: `font-semibold text-gray-600 block ${className ?? ""}`.trim(),
942
+ ...props,
943
+ children: [
944
+ children,
945
+ required ? /* @__PURE__ */ jsx11("span", { className: "text-red-500 ml-1", children: "*" }) : null
946
+ ]
947
+ }
948
+ );
949
+ }
950
+ );
951
+ Label.displayName = "Label";
952
+
953
+ // packages/ui/src/forms/input.tsx
954
+ import React5, { useState as useState7 } from "react";
955
+ import { Eye, EyeOff } from "lucide-react";
956
+ import { jsx as jsx12, jsxs as jsxs10 } from "react/jsx-runtime";
957
+ var Input = React5.forwardRef(({ type, className, ...props }, ref) => {
958
+ const [showPassword, setShowPassword] = useState7(false);
959
+ const isPassword = type === "password";
960
+ const inputType = isPassword ? showPassword ? "text" : "password" : type;
961
+ return /* @__PURE__ */ jsxs10("div", { className: "relative", children: [
962
+ /* @__PURE__ */ jsx12(
963
+ "input",
964
+ {
965
+ ref,
966
+ type: inputType,
967
+ className: `w-full px-3 py-2 pr-10 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 ${className || ""}`,
968
+ ...props
969
+ }
970
+ ),
971
+ isPassword && /* @__PURE__ */ jsx12(
972
+ "button",
973
+ {
974
+ type: "button",
975
+ onClick: () => setShowPassword(!showPassword),
976
+ className: "absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-gray-700",
977
+ children: showPassword ? /* @__PURE__ */ jsx12(EyeOff, { size: 20 }) : /* @__PURE__ */ jsx12(Eye, { size: 20 })
978
+ }
979
+ )
980
+ ] });
981
+ });
982
+ Input.displayName = "Input";
983
+
984
+ // packages/ui/src/forms/select.tsx
985
+ import React6 from "react";
986
+ import { jsx as jsx13 } from "react/jsx-runtime";
987
+ var Select = React6.forwardRef(({ className, ...props }, ref) => {
988
+ return /* @__PURE__ */ jsx13(
989
+ "select",
990
+ {
991
+ ref,
992
+ className: `w-full px-3 py-2 pr-10 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 bg-white cursor-pointer appearance-none bg-no-repeat bg-right bg-contain ${className || ""}`,
993
+ style: {
994
+ backgroundImage: `url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e")`,
995
+ backgroundPosition: "right 0.75rem center",
996
+ backgroundSize: "1.25em 1.25em"
997
+ },
998
+ ...props
999
+ }
1000
+ );
1001
+ });
1002
+ Select.displayName = "Select";
1003
+ var Option = React6.forwardRef(({ ...props }, ref) => {
1004
+ return /* @__PURE__ */ jsx13("option", { ref, ...props });
1005
+ });
1006
+ Option.displayName = "Option";
1007
+
1008
+ // packages/ui/src/forms/textarea.tsx
1009
+ import React7 from "react";
1010
+ import { jsx as jsx14 } from "react/jsx-runtime";
1011
+ var TextArea = React7.forwardRef(({ ...props }, ref) => {
1012
+ return /* @__PURE__ */ jsx14(
1013
+ "textarea",
1014
+ {
1015
+ ref,
1016
+ className: "w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 resize-none",
1017
+ ...props
1018
+ }
1019
+ );
1020
+ });
1021
+ TextArea.displayName = "TextArea";
1022
+
1023
+ // packages/ui/src/forms/date-picker.tsx
1024
+ import React8 from "react";
1025
+ import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
1026
+ var DatePicker = React8.forwardRef(({ className, placeholder, required, ...props }, ref) => {
1027
+ return /* @__PURE__ */ jsxs11("div", { className: "relative", children: [
1028
+ /* @__PURE__ */ jsx15(
1029
+ "input",
1030
+ {
1031
+ ref,
1032
+ type: "date",
1033
+ required: required ?? true,
1034
+ className: `peer w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 ${className ?? ""}`,
1035
+ ...props
1036
+ }
1037
+ ),
1038
+ /* @__PURE__ */ jsx15("span", { className: "absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 pointer-events-none peer-valid:hidden md:hidden", children: placeholder ?? "jj/mm/aaaa" })
1039
+ ] });
1040
+ });
1041
+ DatePicker.displayName = "DatePicker";
1042
+
1043
+ // packages/ui/src/loaders/loading.tsx
1044
+ import { Loader } from "lucide-react";
1045
+ import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
1046
+ function Loading(props) {
1047
+ return /* @__PURE__ */ jsx16("div", { className: "flex items-center justify-center", children: /* @__PURE__ */ jsxs12("div", { className: "flex flex-col items-center gap-4", children: [
1048
+ /* @__PURE__ */ jsx16(Loader, { className: "animate-spin", size: 40 }),
1049
+ /* @__PURE__ */ jsx16("p", { className: "text-gray-600 text-md font-medium", children: props.text })
1050
+ ] }) });
1051
+ }
1052
+
1053
+ // packages/ui/src/loaders/loader-submit.tsx
1054
+ import { LoaderCircle } from "lucide-react";
1055
+ import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs13 } from "react/jsx-runtime";
1056
+ function LoaderSubmit(props) {
1057
+ return /* @__PURE__ */ jsx17(Fragment3, { children: props.onSubmit ? /* @__PURE__ */ jsxs13("div", { className: "flex flex-row gap-2 items-center", children: [
1058
+ /* @__PURE__ */ jsx17(LoaderCircle, { className: "animate-spin text-gray-500" }),
1059
+ /* @__PURE__ */ jsx17("p", { className: "text-gray-500 font-semibold", children: props.textAp })
1060
+ ] }) : /* @__PURE__ */ jsx17(
1061
+ "button",
1062
+ {
1063
+ type: "submit",
1064
+ className: "bg-blue-500 text-white px-6 py-2 rounded-md hover:bg-blue-700 hover:cursor-pointer transition-colors duration-300 font-semibold shadow-md",
1065
+ disabled: props.onSubmit,
1066
+ children: props.textAvant
1067
+ }
1068
+ ) });
1069
+ }
1070
+
926
1071
  // packages/utils/src/fetcher.ts
927
1072
  var ApiError = class extends Error {
928
1073
  status;
@@ -1031,12 +1176,21 @@ export {
1031
1176
  ActionsMenu,
1032
1177
  ApiError,
1033
1178
  Confirmation,
1179
+ DatePicker,
1180
+ FieldContainer,
1034
1181
  Form,
1035
1182
  HeaderContent,
1036
1183
  HttpError,
1184
+ Input,
1185
+ Label,
1186
+ LoaderSubmit,
1187
+ Loading,
1037
1188
  Modal,
1189
+ Option,
1190
+ Select,
1038
1191
  SideNav,
1039
1192
  Table,
1193
+ TextArea,
1040
1194
  createSideNav,
1041
1195
  fetcher,
1042
1196
  handleServerError
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/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":";AAEA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAyFK,SAGM,KAHN;AA3DZ,SAAS,SAAS,MAAc,aAAqB;AACnD,SAAO,gBAAgB,QAAQ,YAAY,WAAW,OAAO,GAAG;AAClE;AAEA,SAAS,cAAc,MAAc,aAAqB;AACxD,SAAO,gBAAgB;AACzB;AAEO,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAiB;AACf,QAAM,aAAa,UAAU,KAAK,CAAC,SAAS,SAAS,KAAK,MAAM,WAAW,CAAC;AAC5E,QAAM,cAAc,SAAS,YAAY,SAAS,YAAY;AAC9D,QAAM,CAAC,iBAAiB,kBAAkB,IAAI;AAAA,IAC5C,YAAY,MAAM;AAAA,EACpB;AAEA,QAAM,gBAAgB,CAAC,OAAe;AACpC,uBAAmB,CAAC,SAAU,SAAS,KAAK,OAAO,EAAG;AAAA,EACxD;AAEA,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AAEtD,YAAU,MAAM;AACd,UAAM,eAAe,CAAC,MAAqB;AACzC,UAAI,EAAE,QAAQ,SAAU,iBAAgB,KAAK;AAAA,IAC/C;AACA,aAAS,iBAAiB,WAAW,YAAY;AACjD,WAAO,MAAM,SAAS,oBAAoB,WAAW,YAAY;AAAA,EACnE,GAAG,CAAC,CAAC;AAEL,YAAU,MAAM;AACd,QAAI,cAAc;AAChB,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC,OAAO;AACL,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AACA,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,iBAAiB,MAAM,gBAAgB,KAAK;AAElD,SACE,qBAAC,SAAI,WAAU,qBACb;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,yIACT,eAAe,kBAAkB,mBACnC;AAAA,QAEC;AAAA,mBACC,oBAAC,SAAI,WAAU,sCACb,+BAAC,SAAI,WAAU,oCACZ;AAAA,kBAAM,SACJ,OAAO,MAAM,SAAS,WACrB;AAAA,cAAC;AAAA;AAAA,gBACC,KAAK,MAAM;AAAA,gBACX,KAAK,MAAM,QAAQ;AAAA,gBACnB,WAAU;AAAA;AAAA,YACZ,IAEA,MAAM;AAAA,YAET,MAAM,QACL,oBAAC,OAAE,WAAU,yCACV,gBAAM,MACT;AAAA,aAEJ,GACF;AAAA,UAGF,oBAAC,SAAI,WAAU,8BACb,8BAAC,QAAG,WAAU,aACX,oBAAU,IAAI,CAAC,SAAS;AACvB,kBAAM,SAAS,SAAS,KAAK,MAAM,WAAW;AAC9C,kBAAM,aAAa,oBAAoB,KAAK;AAC5C,kBAAM,cAAc,KAAK,YAAY,KAAK,SAAS,SAAS;AAE5D,mBACE,qBAAC,QACC;AAAA,mCAAC,SAAI,WAAU,2BACb;AAAA;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAM,KAAK;AAAA,oBACX,SAAS;AAAA,oBACT,WAAW,+FACT,SACI,2BACA,iCACN;AAAA,oBAEC;AAAA,2BAAK,SACH,OAAO,KAAK,SAAS,WACpB,oBAAC,UAAK,WAAU,WAAW,eAAK,MAAK,IACnC,eAAe,KAAK,IAAI,IAC1B,KAAK,OAEL;AAAA,wBACE,KAAK;AAAA,wBACL,EAAE,MAAM,GAAG;AAAA,sBACb;AAAA,sBAEH,KAAK;AAAA;AAAA;AAAA,gBACR;AAAA,gBACC,UAAU,eACT;AAAA,kBAAC;AAAA;AAAA,oBACC,SAAS,MAAM,cAAc,KAAK,EAAE;AAAA,oBACpC,WAAW,sCACT,SACI,iCACA,iCACN;AAAA,oBACA,OAAO,aAAa,eAAY;AAAA,oBAE/B,uBACC;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,kDACT,aAAa,aAAa,YAC5B;AAAA,wBAEC;AAAA;AAAA,oBACH,IAEA,oBAAC,UAAK,WAAU,WACb,uBAAa,WAAM,UACtB;AAAA;AAAA,gBAEJ;AAAA,iBAEJ;AAAA,cAEC,UAAU,eACT;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAW,gDACT,aAAa,oBAAoB,iBACnC;AAAA,kBAEA,8BAAC,SAAI,WAAU,mBACb,8BAAC,QAAG,WAAU,4BACX,eAAK,SAAU,IAAI,CAAC,QACnB,oBAAC,QACC;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAM,IAAI;AAAA,sBACV,SAAS;AAAA,sBACT,WAAW,sFACT,cAAc,IAAI,MAAM,WAAW,IAC/B,2BACA,iCACN;AAAA,sBAEC,cAAI;AAAA;AAAA,kBACP,KAXO,IAAI,EAYb,CACD,GACH,GACF;AAAA;AAAA,cACF;AAAA,iBA5EK,KAAK,EA8Ed;AAAA,UAEJ,CAAC,GACH,GACF;AAAA,UAEC,UAAU,OAAO,SAAS,KACzB,oBAAC,SAAI,WAAU,0CACZ,iBAAO,IAAI,CAAC,SACX;AAAA,YAAC;AAAA;AAAA,cAEC,MAAM,KAAK;AAAA,cACX,SAAS;AAAA,cACT,WAAU;AAAA,cAET;AAAA,uBAAO,KAAK,SAAS,WACpB,oBAAC,UAAK,WAAU,WAAW,eAAK,MAAK,IACnC,eAAe,KAAK,IAAI,IAC1B,KAAK,OAEL,cAAc,KAAK,MAA0C;AAAA,kBAC3D,MAAM;AAAA,gBACR,CAAC;AAAA,gBAEF,KAAK;AAAA;AAAA;AAAA,YAdD,KAAK;AAAA,UAeZ,CACD,GACH;AAAA;AAAA;AAAA,IAEJ;AAAA,IAEC,gBACC;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,SAAS;AAAA,QACT,eAAY;AAAA;AAAA,IACd;AAAA,IAGF,qBAAC,SAAI,WAAU,oCACZ;AAAA,qBACC,qBAAC,YAAO,WAAU,gIAChB;AAAA,6BAAC,SAAI,WAAU,2BACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,SAAS,MAAM,gBAAgB,CAAC,YAAY;AAAA,cAC5C,cAAY,eAAe,mBAAmB;AAAA,cAC9C,iBAAe;AAAA,cAEd,yBACC;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,QAAO;AAAA,kBACP,aAAa;AAAA,kBAEb;AAAA,oBAAC;AAAA;AAAA,sBACC,eAAc;AAAA,sBACd,gBAAe;AAAA,sBACf,GAAE;AAAA;AAAA,kBACJ;AAAA;AAAA,cACF,IAEA;AAAA,gBAAC;AAAA;AAAA,kBACC,WAAU;AAAA,kBACV,MAAK;AAAA,kBACL,SAAQ;AAAA,kBACR,QAAO;AAAA,kBACP,aAAa;AAAA,kBAEb;AAAA,oBAAC;AAAA;AAAA,sBACC,eAAc;AAAA,sBACd,gBAAe;AAAA,sBACf,GAAE;AAAA;AAAA,kBACJ;AAAA;AAAA,cACF;AAAA;AAAA,UAEJ;AAAA,UACA,oBAAC,QAAG,WAAU,yCACX,uBACH;AAAA,WACF;AAAA,QACC,OAAO,WACN,oBAAC,UAAK,WAAU,uCACb,gBAAM,SACT;AAAA,SAEJ;AAAA,MAED,CAAC,eACA;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS,MAAM,gBAAgB,CAAC,YAAY;AAAA,UAC5C,cAAY,eAAe,mBAAmB;AAAA,UAC9C,iBAAe;AAAA,UAEd,yBACC;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,QAAO;AAAA,cACP,aAAa;AAAA,cAEb;AAAA,gBAAC;AAAA;AAAA,kBACC,eAAc;AAAA,kBACd,gBAAe;AAAA,kBACf,GAAE;AAAA;AAAA,cACJ;AAAA;AAAA,UACF,IAEA;AAAA,YAAC;AAAA;AAAA,cACC,WAAU;AAAA,cACV,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,QAAO;AAAA,cACP,aAAa;AAAA,cAEb;AAAA,gBAAC;AAAA;AAAA,kBACC,eAAc;AAAA,kBACd,gBAAe;AAAA,kBACf,GAAE;AAAA;AAAA,cACJ;AAAA;AAAA,UACF;AAAA;AAAA,MAEJ;AAAA,MAEF;AAAA,QAAC;AAAA;AAAA,UACC,YAAY,cAAc,cAAc,SAAS;AAAA,UAEhD;AAAA;AAAA,MACH;AAAA,OACF;AAAA,KACF;AAEJ;;;ACzUM,gBAAAA,YAAA;AATC,SAAS,cAAc,QAA6B;AACzD,SAAO,SAAS,kBAAkB;AAAA,IAChC;AAAA,IACA;AAAA,EACF,GAGG;AACD,WACE,gBAAAA,KAAC,WAAS,GAAG,QAAQ,aAClB,UACH;AAAA,EAEJ;AACF;;;ACdA,SAAS,SAAS,aAAa,oBAAoB;AACnD,OAAO,UAAU;AACjB,SAAS,YAAAC,WAAU,SAAS,mBAAmB;;;ACF/C,SAAS,SAAS;AAElB,SAAS,YAAAC,iBAAgB;AAef,SACE,OAAAC,MADF,QAAAC,aAAA;AATH,SAAS,aAAa,EAAE,MAAM,GAAsB;AACzD,QAAM,CAAC,WAAW,YAAY,IAAIF,UAAS,KAAK;AAEhD,MAAI,CAAC,SAAS,UAAW,QAAO;AAEhC,SACE,gBAAAC,KAAC,SAAI,WAAU,0BACb,0BAAAA,KAAC,SAAI,WAAU,wDACb,0BAAAC,MAAC,SAAI,WAAU,oDACb;AAAA,oBAAAA,MAAC,SAAI,WAAU,uBACb;AAAA,sBAAAD,KAAC,OAAE,WAAU,4BAA2B,oBAAM;AAAA,MAC9C,gBAAAA,KAAC,OAAE,WAAU,wBAAwB,gBAAM,SAAQ;AAAA,OACrD;AAAA,IACA,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,SAAS,MAAM,aAAa,IAAI;AAAA,QAChC,WAAU;AAAA,QAEV,0BAAAA,KAAC,KAAE,WAAU,WAAU;AAAA;AAAA,IACzB;AAAA,KACF,GACF,GACF;AAEJ;;;ADyEM,gBAAAE,MAMA,QAAAC,aANA;AA/EN,IAAM,gBAAgB;AAEf,SAAS,MAAS;AAAA,EACvB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX,kBAAkB,CAAC,GAAG,IAAI,EAAE;AAAA,EAC5B,iBAAiB;AACnB,GAAkB;AAChB,QAAM,CAAC,SAAS,UAAU,IAAIC,UAIpB,IAAI;AACd,QAAM,CAAC,MAAM,OAAO,IAAIA,UAAS,CAAC;AAClC,QAAM,CAAC,SAAS,UAAU,IAAIA,UAAS,QAAQ;AAE/C,QAAM,aAAa;AAAA,IACjB,MAAM,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,SAAS,OAAO,CAAC;AAAA,IAClD,CAAC,KAAK,QAAQ,OAAO;AAAA,EACvB;AAEA,QAAM,WAAW,KAAK,IAAI,MAAM,UAAU;AAE1C,QAAM,cAAc;AAAA,IAClB,MAAM,KAAK,OAAO,WAAW,KAAK,SAAS,WAAW,OAAO;AAAA,IAC7D,CAAC,MAAM,UAAU,OAAO;AAAA,EAC1B;AAEA,QAAM,kBAAkB,QAAQ,MAAM;AACpC,UAAM,OAAO,KAAK,MAAM,gBAAgB,CAAC;AACzC,QAAI,QAAQ,KAAK,IAAI,GAAG,WAAW,IAAI;AACvC,QAAI,MAAM,KAAK,IAAI,YAAY,QAAQ,gBAAgB,CAAC;AACxD,QAAI,MAAM,QAAQ,IAAI,eAAe;AACnC,cAAQ,KAAK,IAAI,GAAG,MAAM,gBAAgB,CAAC;AAAA,IAC7C;AACA,UAAM,QAA4B,CAAC;AACnC,QAAI,QAAQ,GAAG;AACb,YAAM,KAAK,CAAC;AACZ,UAAI,QAAQ,EAAG,OAAM,KAAK,KAAK;AAAA,IACjC;AACA,aAAS,IAAI,OAAO,KAAK,KAAK,IAAK,OAAM,KAAK,CAAC;AAC/C,QAAI,MAAM,YAAY;AACpB,UAAI,MAAM,aAAa,EAAG,OAAM,KAAK,KAAK;AAC1C,YAAM,KAAK,UAAU;AAAA,IACvB;AACA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,UAAU,CAAC;AAEzB,QAAM,uBAAuB,YAAY,CAAC,UAAkB;AAC1D,eAAW,KAAK;AAChB,YAAQ,CAAC;AAAA,EACX,GAAG,CAAC,CAAC;AAEL,QAAM,WAAW,QAAQ;AACzB,QAAM,WAAW,WAAW,IAAI,GAAG,KAAK,MAAM,MAAM,QAAQ,CAAC,MAAM;AAEnE,QAAM,mBAAmB,CACvB,GACA,YACG;AACH,UAAM,OAAO,EAAE,cAAc,sBAAsB;AACnD,eAAW;AAAA,MACT;AAAA,MACA,GAAG,KAAK,OAAO,KAAK,QAAQ;AAAA,MAC5B,GAAG,KAAK;AAAA,IACV,CAAC;AAAA,EACH;AAEA,QAAM,mBAAmB,MAAM;AAC7B,eAAW,IAAI;AAAA,EACjB;AAEA,QAAM,SAAS,QACb,gBAAAF,KAAC,SAAI,WAAU,QACb,0BAAAA,KAAC,gBAAiC,SAAf,MAAM,OAAuB,GAClD,IACE;AAEJ,MAAI,SAAS;AACX,WACE,gBAAAC,MAAC,SAAI,WAAU,0BACZ;AAAA;AAAA,MACD,gBAAAD,KAAC,SAAI,WAAU,+CACb,0BAAAA,KAAC,SAAI,WAAU,wDAAuD,2BAEtE,GACF;AAAA,OACF;AAAA,EAEJ;AAEA,MAAI,CAAC,QAAQ,KAAK,WAAW,GAAG;AAC9B,WACE,gBAAAC,MAAC,SAAI,WAAU,0BACZ;AAAA;AAAA,MACD,gBAAAD,KAAC,SAAI,WAAU,+CACb,0BAAAA,KAAC,SAAI,WAAU,wDAAuD,iCAEtE,GACF;AAAA,OACF;AAAA,EAEJ;AAEA,SACE,gBAAAC,MAAC,SAAI,WAAU,0BACZ;AAAA;AAAA,IACD,gBAAAA,MAAC,SAAI,WAAU,0CACZ;AAAA,eACC,gBAAAA,MAAC,SAAI,WAAU,uCACZ;AAAA;AAAA,QAAM;AAAA,QAAG,KAAK;AAAA,SACjB;AAAA,MAED,aACC,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS,MAAM,OAAO,MAAM;AAAA,UAC5B,WAAU;AAAA,UAEV;AAAA,4BAAAD,KAAC,WAAQ,WAAU,WAAU;AAAA,YAAE;AAAA;AAAA;AAAA,MAEjC;AAAA,OAEJ;AAAA,IACA,gBAAAA,KAAC,SAAI,WAAU,+CACb,0BAAAC,MAAC,WAAM,WAAU,iEACf;AAAA,sBAAAD,KAAC,WAAM,WAAU,4BACf,0BAAAA,KAAC,QACE,kBAAQ,IAAI,CAAC,KAAK,UACjB,gBAAAA;AAAA,QAAC;AAAA;AAAA,UAEC,OAAO,EAAE,OAAO,SAAS;AAAA,UACzB,WAAW;AAAA,YACT;AAAA,YACA,IAAI,oBAAoB;AAAA,UAC1B;AAAA,UAEC,cAAI;AAAA;AAAA,QAPA;AAAA,MAQP,CACD,GACH,GACF;AAAA,MACA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,WAAW;AAAA,YACT;AAAA,YACA,aAAa;AAAA,UACf;AAAA,UAEC,sBAAY,IAAI,CAAC,KAAK,aACrB,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,WAAU;AAAA,cAET,kBAAQ,IAAI,CAAC,KAAK,aAAa;AAC9B,sBAAM,cAAc,IAAI,SACpB,IAAI,OAAO,GAAG,IACd,OAAO,IAAI,IAAI,QAAS,CAAC;AAC7B,sBAAM,cACJ,OAAO,gBAAgB,WAAW,cAAc;AAElD,uBACE,gBAAAA;AAAA,kBAAC;AAAA;AAAA,oBAEC,OAAO,EAAE,OAAO,SAAS;AAAA,oBACzB,WAAW;AAAA,sBACT;AAAA,sBACA,IAAI,oBAAoB;AAAA,oBAC1B;AAAA,oBAEC,iBAAO,gBAAgB,WACtB,gBAAAA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAU;AAAA,wBACV,cAAc,CAAC,MAAM,iBAAiB,GAAG,WAAW;AAAA,wBACpD,cAAc;AAAA,wBAEb;AAAA;AAAA,oBACH,IAEA;AAAA;AAAA,kBAhBG;AAAA,gBAkBP;AAAA,cAEJ,CAAC;AAAA;AAAA,YAhCI;AAAA,UAiCP,CACD;AAAA;AAAA,MACH;AAAA,MACC,aACC,gBAAAA,KAAC,WAAM,WAAU,gCACd,eAAK,IAAI,CAAC,KAAK,aACd,gBAAAA,KAAC,QACE,kBAAQ,IAAI,CAAC,KAAK,aAAa;AAC9B,cAAM,cAAc,IAAI,SACpB,IAAI,OAAO,GAAG,IACd,OAAO,IAAI,IAAI,QAAS,CAAC;AAE7B,eACE,gBAAAA;AAAA,UAAC;AAAA;AAAA,YAEC,OAAO,EAAE,OAAO,SAAS;AAAA,YACzB,WAAW;AAAA,cACT;AAAA,cACA,IAAI,oBAAoB;AAAA,YAC1B;AAAA,YAEC;AAAA;AAAA,UAPI;AAAA,QAQP;AAAA,MAEJ,CAAC,KAlBM,QAmBT,CACD,GACH;AAAA,OAEJ,GACF;AAAA,IAEC,kBAAkB,aAAa,KAC9B,gBAAAC,MAAC,SAAI,WAAU,+DACb;AAAA,sBAAAA,MAAC,SAAI,WAAU,yCACb;AAAA,wBAAAD,KAAC,UAAK,+BAAiB;AAAA,QACvB,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO;AAAA,YACP,UAAU,CAAC,MAAM,qBAAqB,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,YAC5D,WAAU;AAAA,YAET,0BAAgB,IAAI,CAAC,QACpB,gBAAAA,KAAC,YAAiB,OAAO,KACtB,iBADU,GAEb,CACD;AAAA;AAAA,QACH;AAAA,SACF;AAAA,MAEA,gBAAAC,MAAC,SAAI,WAAU,2BACb;AAAA,wBAAAD;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,MAAM,QAAQ,CAAC,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC,CAAC;AAAA,YAChD,UAAU,YAAY;AAAA,YACtB,WAAW;AAAA,cACT;AAAA,cACA,YAAY,IACR,qCACA;AAAA,YACN;AAAA,YAEA,0BAAAA,KAAC,eAAY,WAAU,WAAU;AAAA;AAAA,QACnC;AAAA,QAEC,gBAAgB;AAAA,UAAI,CAAC,MAAM,MAC1B,SAAS,QACP,gBAAAA,KAAC,UAA2B,WAAU,sBAAqB,mBAAhD,YAAY,CAAC,EAExB,IAEA,gBAAAA;AAAA,YAAC;AAAA;AAAA,cAEC,SAAS,MAAM,QAAQ,IAAI;AAAA,cAC3B,WAAW;AAAA,gBACT;AAAA,gBACA,SAAS,WACL,2BACA;AAAA,cACN;AAAA,cAEC;AAAA;AAAA,YATI;AAAA,UAUP;AAAA,QAEJ;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,SAAS,MAAM,QAAQ,CAAC,MAAM,KAAK,IAAI,YAAY,IAAI,CAAC,CAAC;AAAA,YACzD,UAAU,YAAY;AAAA,YACtB,WAAW;AAAA,cACT;AAAA,cACA,YAAY,aACR,qCACA;AAAA,YACN;AAAA,YAEA,0BAAAA,KAAC,gBAAa,WAAU,WAAU;AAAA;AAAA,QACpC;AAAA,SACF;AAAA,MAEA,gBAAAC,MAAC,SAAI,WAAU,iBAAgB;AAAA;AAAA,QACvB;AAAA,QAAS;AAAA,QAAM;AAAA,SACvB;AAAA,OACF;AAAA,IAGD,WACC,gBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,WAAU;AAAA,QACV,OAAO;AAAA,UACL,MAAM,QAAQ;AAAA,UACd,KAAK,QAAQ,IAAI;AAAA,UACjB,WAAW;AAAA,QACb;AAAA,QAEC,kBAAQ;AAAA;AAAA,IACX;AAAA,IAEF,gBAAAA,KAAC,WAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,SAON;AAAA,KACJ;AAEJ;;;AElVA,SAAgB,YAAAG,WAAU,QAAQ,aAAAC,kBAAiB;AACnD,SAAS,gBAAgB;AAiErB,mBAMI,OAAAC,MAcI,QAAAC,aApBR;AAnDG,SAAS,YAAe,EAAE,KAAK,QAAQ,GAAwB;AACpE,QAAM,CAAC,QAAQ,SAAS,IAAIH,UAAS,KAAK;AAC1C,QAAM,CAAC,QAAQ,SAAS,IAAIA,UAAS,EAAE,KAAK,GAAG,MAAM,EAAE,CAAC;AACxD,QAAM,YAAY,OAA0B,IAAI;AAChD,QAAM,UAAU,OAAuB,IAAI;AAG3C,EAAAC,WAAU,MAAM;AACd,aAAS,mBAAmB,OAAmB;AAC7C,UACE,QAAQ,WACR,UAAU,WACV,CAAC,QAAQ,QAAQ,SAAS,MAAM,MAAc,KAC9C,CAAC,UAAU,QAAQ,SAAS,MAAM,MAAc,GAChD;AACA,kBAAU,KAAK;AAAA,MACjB;AAAA,IACF;AAEA,aAAS,iBAAiB,aAAa,kBAAkB;AACzD,WAAO,MAAM,SAAS,oBAAoB,aAAa,kBAAkB;AAAA,EAC3E,GAAG,CAAC,CAAC;AAEL,QAAM,aAAa,MAAM;AACvB,QAAI,UAAU,SAAS;AACrB,YAAM,OAAO,UAAU,QAAQ,sBAAsB;AACrD,YAAM,YAAY;AAClB,YAAM,aAAa,QAAQ,SAAS;AAEpC,YAAM,aAAa,OAAO,cAAc,KAAK;AAC7C,YAAM,aAAa,OAAO,aAAa,KAAK;AAE5C,UAAI,MAAM,KAAK;AACf,UAAI,OAAO,KAAK;AAGhB,UAAI,aAAa,aAAa,IAAI;AAChC,cAAM,KAAK,MAAM;AAAA,MACnB;AAGA,UAAI,aAAa,YAAY,IAAI;AAC/B,eAAO,KAAK,OAAO,YAAY;AAAA,MACjC;AAEA,gBAAU,EAAE,KAAK,KAAK,CAAC;AAAA,IACzB;AACA,cAAU,CAAC,MAAM;AAAA,EACnB;AAEA,SACE,gBAAAE,MAAA,YACE;AAAA,oBAAAD;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,SAAS;AAAA,QACT,WAAU;AAAA,QAEV,0BAAAA,KAAC,YAAS,WAAU,WAAU;AAAA;AAAA,IAChC;AAAA,IAEC,UACC,gBAAAA;AAAA,MAAC;AAAA;AAAA,QACC,KAAK;AAAA,QACL,WAAU;AAAA,QACV,OAAO;AAAA,UACL,KAAK,OAAO;AAAA,UACZ,MAAM,OAAO;AAAA,UACb,UAAU;AAAA,QACZ;AAAA,QAEC,kBAAQ,IAAI,CAAC,QAAQ,QACpB,gBAAAC;AAAA,UAAC;AAAA;AAAA,YAEC,WAAW,sEACT,OAAO,SAAS,eAClB;AAAA,YACA,SAAS,MAAM;AACb,qBAAO,SAAS,GAAG;AACnB,wBAAU,KAAK;AAAA,YACjB;AAAA,YAEC;AAAA,qBAAO;AAAA,cACP,OAAO;AAAA;AAAA;AAAA,UAVH;AAAA,QAWP,CACD;AAAA;AAAA,IACH;AAAA,KAEJ;AAEJ;;;ACxGA,SAAS,KAAAC,UAAS;AAClB,SAAgB,aAAAC,kBAAiB;AACjC,SAAS,oBAAoB;AA+CvB,gBAAAC,MAME,QAAAC,aANF;AAtCC,SAAS,MAAM,EAAE,OAAO,QAAQ,SAAS,SAAS,GAAe;AACtE,QAAM,eAAe,MAAM;AACzB,YAAQ;AAAA,EACV;AAEA,EAAAF,WAAU,MAAM;AACd,QAAI,QAAQ;AACV,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAEA,WAAO,MAAM;AACX,eAAS,KAAK,MAAM,WAAW;AAAA,IACjC;AAAA,EACF,GAAG,CAAC,MAAM,CAAC;AAEX,EAAAA,WAAU,MAAM;AACd,aAAS,UAAU,GAAkB;AACnC,UAAI,EAAE,QAAQ,UAAU;AACtB,gBAAQ;AAAA,MACV;AAAA,IACF;AAEA,QAAI,QAAQ;AACV,eAAS,iBAAiB,WAAW,SAAS;AAAA,IAChD;AAEA,WAAO,MAAM;AACX,eAAS,oBAAoB,WAAW,SAAS;AAAA,IACnD;AAAA,EACF,GAAG,CAAC,QAAQ,OAAO,CAAC;AAEpB,MAAI,CAAC,OAAQ,QAAO;AAEpB,QAAM,UACJ,OAAO,aAAa,aAAa,SAAS,YAAY,IAAI;AAE5D,SAAO;AAAA,IACL,gBAAAE,MAAC,SAAI,WAAU,uDACb;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,SAAS;AAAA;AAAA,MACX;AAAA,MAEA,gBAAAC,MAAC,SAAI,WAAU,+FACb;AAAA,wBAAAA,MAAC,SAAI,WAAU,qGACb;AAAA,0BAAAD,KAAC,QAAG,WAAU,uCAAuC,iBAAM;AAAA,UAE3D,gBAAAA;AAAA,YAAC;AAAA;AAAA,cACC,SAAS;AAAA,cACT,WAAU;AAAA,cAEV,0BAAAA,KAACF,IAAA,EAAE;AAAA;AAAA,UACL;AAAA,WACF;AAAA,QAEA,gBAAAE,KAAC,SAAI,WAAU,kCAAkC,mBAAQ;AAAA,SAC3D;AAAA,OACF;AAAA,IACA,SAAS;AAAA,EACX;AACF;;;ACvEA,SAAS,eAAAE,cAAa,aAAAC,YAAW,UAAAC,SAAQ,YAAAC,iBAAgB;AAEzD,SAAS,0BAA0B;AAwH7B,gBAAAC,MAKA,QAAAC,aALA;AAtHN,IAAM,kBAAkB;AAiBjB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsB;AACpB,QAAM,CAAC,WAAW,YAAY,IAAIF,UAAS,CAAC;AAC5C,QAAM,eAAeD,QAAsB,IAAI;AAC/C,QAAM,kBAAkBA,QAAO,YAAY;AAE3C,EAAAD,WAAU,MAAM;AACd,oBAAgB,UAAU;AAAA,EAC5B,GAAG,CAAC,YAAY,CAAC;AAEjB,QAAM,iBAAiBD,aAAY,MAAM;AACvC,QAAI,aAAa,YAAY,MAAM;AACjC,aAAO,cAAc,aAAa,OAAO;AACzC,mBAAa,UAAU;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,CAAC;AAEL,QAAM,yBAAyBA,aAAY,MAAM;AAC/C,mBAAe;AACf,iBAAa,CAAC;AAAA,EAChB,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,qBAAqBA,aAAY,MAAM;AAC3C,2BAAuB;AACvB,iBAAa;AAAA,EACf,GAAG,CAAC,wBAAwB,YAAY,CAAC;AAEzC,QAAM,qBAAqBA,aAAY,MAAM;AAC3C,2BAAuB;AACvB,iBAAa;AACb,iBAAa;AAAA,EACf,GAAG,CAAC,cAAc,wBAAwB,YAAY,CAAC;AAEvD,QAAM,eAAeA,aAAY,YAAY;AAC3C,QAAI;AACF,YAAM,SAAS;AACf,yBAAmB;AAAA,IACrB,QAAQ;AAAA,IAER;AAAA,EACF,GAAG,CAAC,oBAAoB,QAAQ,CAAC;AAEjC,EAAAC,WAAU,MAAM;AACd,mBAAe;AAEf,QAAI,CAAC,OAAO;AACV,YAAM,iBAAiB,OAAO,WAAW,MAAM;AAC7C,qBAAa,CAAC;AAAA,MAChB,GAAG,CAAC;AAEJ,aAAO,MAAM;AACX,eAAO,aAAa,cAAc;AAAA,MACpC;AAAA,IACF;AAEA,UAAM,0BAA0B,OAAO,WAAW,MAAM;AACtD,mBAAa,eAAe;AAE5B,mBAAa,UAAU,OAAO,YAAY,MAAM;AAC9C,qBAAa,CAAC,sBAAsB;AAClC,cAAI,qBAAqB,GAAG;AAC1B,2BAAe;AACf,mBAAO,WAAW,MAAM;AACtB,8BAAgB,QAAQ;AAAA,YAC1B,GAAG,CAAC;AAEJ,mBAAO;AAAA,UACT;AAEA,iBAAO,oBAAoB;AAAA,QAC7B,CAAC;AAAA,MACH,GAAG,GAAI;AAAA,IACT,GAAG,CAAC;AAEJ,WAAO,MAAM;AACX,aAAO,aAAa,uBAAuB;AAC3C,qBAAe;AAAA,IACjB;AAAA,EACF,GAAG,CAAC,gBAAgB,KAAK,CAAC;AAE1B,EAAAA,WAAU,MAAM;AACd,WAAO,MAAM;AACX,qBAAe;AACf,sBAAgB,QAAQ;AAAA,IAC1B;AAAA,EACF,GAAG,CAAC,cAAc,CAAC;AAEnB,QAAM,iBAAiB,QAAQ,KAAK,KAAK,YAAY;AAErD,MAAI,CAAC,SAAU,QAAO;AAEtB,SACE,gBAAAI,MAAC,SAAI,WAAU,yCACb;AAAA,oBAAAD,KAAC,sBAAmB,WAAU,yBAAwB;AAAA,IACtD,gBAAAA,KAAC,QAAG,WAAU,kCAAiC,kCAAoB;AAAA,IAEnE,gBAAAA,KAAC,OAAE,WAAU,8CAA8C,oBAAS;AAAA,IAEpE,gBAAAC,MAAC,SAAI,WAAU,0BACb;AAAA,sBAAAD;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAU;AAAA,UAET;AAAA;AAAA,MACH;AAAA,MAEA,gBAAAA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,SAAS;AAAA,UACT,UAAU;AAAA,UACV,WAAU;AAAA,UAET,yBAAe,uBAAuB;AAAA;AAAA,MACzC;AAAA,OACF;AAAA,IAEC,SAAS,kBACR,gBAAAC,MAAC,SAAI,WAAU,6FACb;AAAA,sBAAAA,MAAC,SAAI,WAAU,0CACb;AAAA,wBAAAA,MAAC,SACC;AAAA,0BAAAD,KAAC,OAAE,WAAU,iBAAgB,oBAAM;AAAA,UACnC,gBAAAA,KAAC,OAAE,WAAU,gBAAgB,gBAAM,SAAQ;AAAA,WAC7C;AAAA,QAEA,gBAAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAS;AAAA,YACT,WAAU;AAAA,YACX;AAAA;AAAA,QAED;AAAA,SACF;AAAA,MAEA,gBAAAC,MAAC,OAAE,WAAU,6BAA4B;AAAA;AAAA,QACZ;AAAA,QAAU;AAAA,SACvC;AAAA,OACF;AAAA,KAEJ;AAEJ;;;ACvJM,SACE,OAAAC,MADF,QAAAC,aAAA;AATC,SAAS,cAAc;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAuB;AACrB,SACE,gBAAAA,MAAC,SAAI,WAAU,2EACb;AAAA,oBAAAA,MAAC,SACC;AAAA,sBAAAD,KAAC,QAAG,WAAU,kDACX,iBACH;AAAA,MAEC,eACC,gBAAAA,KAAC,OAAE,WAAU,8BAA8B,uBAAY;AAAA,OAE3D;AAAA,IAEC,eAAe,YACd,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,SAAS;AAAA,QACT,WAAU;AAAA,QAET;AAAA,kBAAQ,gBAAAD,KAAC,UAAK,WAAU,WAAW,gBAAK;AAAA,UACxC;AAAA;AAAA;AAAA,IACH;AAAA,KAEJ;AAEJ;;;AC3CA,SAAgB,YAAAE,WAAU,aAAAC,YAAW,UAAAC,SAAQ,eAAAC,oBAAmB;AAEhE,SAAS,KAAAC,UAAS;AA+Ed,qBAAAC,WACE,OAAAC,MAaM,QAAAC,aAdR;AAxEJ,IAAM,OAA4B,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,GAAG;AACL,MAAM;AACJ,QAAM,gBAAgB,CAAC,uBAAuB,SAAS,EACpD,OAAO,OAAO,EACd,KAAK,GAAG;AACX,QAAM,eAAe,SAAS,WAAW;AACzC,QAAM,CAAC,WAAW,YAAY,IAAIP,UAAS,CAAC,CAAC,OAAO;AACpD,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,UAAU,KAAK,CAAC;AAC3D,QAAM,CAAC,WAAW,YAAY,IAAIA,UAAS,CAAC,CAAC,OAAO;AACpD,QAAM,cAAcE,QAAsB,IAAI;AAC9C,QAAM,eAAeA,QAAO,KAAK;AAEjC,QAAM,aAAaC;AAAA,IACjB,CAAC,kBAAkB,SAAS;AAC1B,UAAI,YAAY,YAAY,MAAM;AAChC,eAAO,cAAc,YAAY,OAAO;AACxC,oBAAY,UAAU;AAAA,MACxB;AAEA,mBAAa,KAAK;AAClB,mBAAa,KAAK;AAClB,mBAAa,CAAC;AAEd,UAAI,mBAAmB,gBAAgB,CAAC,aAAa,SAAS;AAC5D,qBAAa,UAAU;AACvB,qBAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,EAAAF,WAAU,MAAM;AACd,iBAAa,UAAU;AAEvB,QAAI,CAAC,SAAS;AACZ,YAAM,eAAe,OAAO,WAAW,MAAM,WAAW,KAAK,GAAG,CAAC;AACjE,aAAO,MAAM;AACX,eAAO,aAAa,YAAY;AAAA,MAClC;AAAA,IACF;AAEA,UAAM,cAAc,OAAO,WAAW,MAAM;AAC1C,mBAAa,IAAI;AACjB,mBAAa,IAAI;AACjB,mBAAa,EAAE;AAAA,IACjB,GAAG,CAAC;AAEJ,gBAAY,UAAU,OAAO,YAAY,MAAM;AAC7C,mBAAa,CAAC,SAAS;AACrB,YAAI,QAAQ,GAAG;AACb,qBAAW,IAAI;AACf,iBAAO;AAAA,QACT;AACA,eAAO,OAAO;AAAA,MAChB,CAAC;AAAA,IACH,GAAG,GAAI;AAEP,WAAO,MAAM;AACX,aAAO,aAAa,WAAW;AAC/B,UAAI,YAAY,YAAY,MAAM;AAChC,eAAO,cAAc,YAAY,OAAO;AACxC,oBAAY,UAAU;AAAA,MACxB;AAAA,IACF;AAAA,EACF,GAAG,CAAC,SAAS,UAAU,CAAC;AAExB,SACE,gBAAAM,MAAAF,WAAA,EACE;AAAA,oBAAAC,KAAC,UAAK,WAAW,eAAgB,GAAG,OACjC,UACH;AAAA,IACC,aAAa,gBACZ,gBAAAC;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,4JACT,YACI,4BACA,6BACN;AAAA,QAEA;AAAA,0BAAAD,KAAC,UAAM,wBAAa;AAAA,UACpB,gBAAAC,MAAC,SAAI,WAAU,qBACb;AAAA,4BAAAA,MAAC,UAAK,WAAU,QAAQ;AAAA;AAAA,cAAU;AAAA,eAAC;AAAA,YACnC,gBAAAD,KAAC,YAAO,SAAS,MAAM,WAAW,IAAI,GACpC,0BAAAA,KAACF,IAAA,EAAE,MAAM,IAAI,GACf;AAAA,aACF;AAAA;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;;;ACxGO,IAAM,WAAN,cAAuB,MAAM;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EAEP,YAAY,QAKT;AACD,UAAM,OAAO,OAAO;AACpB,SAAK,SAAS,OAAO;AACrB,SAAK,OAAO,OAAO;AACnB,SAAK,OAAO,OAAO;AAAA,EACrB;AACF;AAYA,eAAsB,QACpB,KACA,UAA0B,CAAC,GACf;AACZ,QAAM,EAAE,SAAS,kBAAkB,OAAO,GAAG,KAAK,IAAI;AAEtD,QAAM,WAAW,MAAM,MAAM,KAAK;AAAA,IAChC,aAAa;AAAA,IACb,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,GAAG;AAAA,IACL;AAAA,IACA,GAAG;AAAA,EACL,CAAC;AAED,MAAI,eAAwB;AAC5B,QAAM,cAAc,SAAS,QAAQ,IAAI,cAAc;AAEvD,MAAI,CAAC,mBAAmB,aAAa,SAAS,kBAAkB,GAAG;AACjE,mBAAe,MAAM,SAAS,KAAK;AAAA,EACrC;AAEA,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,eAAe;AAErB,UAAM,IAAI,SAAS;AAAA,MACjB,SAAS,cAAc,WAAW;AAAA,MAClC,QAAQ,cAAc,UAAU,SAAS;AAAA,MACzC,MAAM,cAAc;AAAA,MACpB,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AC9DO,IAAM,YAAN,MAAM,mBAAkB,MAAM;AAAA,EACnC;AAAA,EACA;AAAA,EAEA,YAAY,SAAiB,SAAS,KAAK,MAAe;AACxD,UAAM,OAAO;AAEb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AAEZ,WAAO,eAAe,MAAM,WAAU,SAAS;AAAA,EACjD;AACF;;;ACXA,IAAM,kBAAkB;AAExB,SAAS,kBAAkB,aAAgC;AACzD,SAAO,eAAe,QAAQ,IAAI,aAAa;AACjD;AAEA,SAAS,kBACP,SACA,MACA,QACA,aACA;AACA,SAAO,SAAS;AAAA,IACd;AAAA,MACE,SAAS,cAAc,UAAU;AAAA,MACjC,MAAM,cAAc,OAAO;AAAA,MAC3B;AAAA,IACF;AAAA,IACA,EAAE,OAAO;AAAA,EACX;AACF;AASO,SAAS,kBACd,OACA,gBAAgB,KAChB,aACA;AACA,QAAM,UAAU,kBAAkB,WAAW;AAE7C,UAAQ,MAAM,wBAAqB,KAAK;AAGxC,MAAI,iBAAiB,WAAW;AAC9B,UAAM,SAAS,MAAM,UAAU;AAC/B,WAAO,SAAS;AAAA,MACd;AAAA,QACE,SAAS,MAAM;AAAA,QACf,MAAM,MAAM,QAAQ;AAAA,QACpB;AAAA,MACF;AAAA,MACA,EAAE,OAAO;AAAA,IACX;AAAA,EACF;AAGA,MAAI,iBAAiB,OAAO;AAC1B,WAAO;AAAA,MACL,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAC/C,WAAO;AAAA,MACL,KAAK,UAAU,KAAK;AAAA,MACpB;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAGA,SAAO;AAAA,IACL,OAAO,KAAK;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;","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"]}
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/ui/src/forms/field-container.tsx","../packages/ui/src/forms/label.tsx","../packages/ui/src/forms/input.tsx","../packages/ui/src/forms/select.tsx","../packages/ui/src/forms/textarea.tsx","../packages/ui/src/forms/date-picker.tsx","../packages/ui/src/loaders/loading.tsx","../packages/ui/src/loaders/loader-submit.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","import React from \"react\";\r\n\r\ninterface FieldContainerProps {\r\n children: React.ReactNode;\r\n className?: string;\r\n}\r\n\r\nexport function FieldContainer({ children, className }: FieldContainerProps) {\r\n return (\r\n <div className={`flex flex-col gap-2 mb-3 relative ${className ?? \"\"}`}>\r\n <div className=\"flex flex-col gap-1\">{children}</div>\r\n </div>\r\n );\r\n}\r\n","import React from \"react\";\r\n\r\ninterface LabelProps extends Omit<\r\n React.LabelHTMLAttributes<HTMLLabelElement>,\r\n \"required\"\r\n> {\r\n required?: boolean;\r\n}\r\n\r\nconst Label = React.forwardRef<HTMLLabelElement, LabelProps>(\r\n ({ required, children, className, ...props }, ref) => {\r\n return (\r\n <label\r\n ref={ref}\r\n className={`font-semibold text-gray-600 block ${className ?? \"\"}`.trim()}\r\n {...props}\r\n >\r\n {children}\r\n {required ? <span className=\"text-red-500 ml-1\">*</span> : null}\r\n </label>\r\n );\r\n },\r\n);\r\n\r\nLabel.displayName = \"Label\";\r\n\r\nexport { Label };\r\n","import React, { useState } from \"react\";\r\nimport { Eye, EyeOff } from \"lucide-react\";\r\n\r\nconst Input = React.forwardRef<\r\n HTMLInputElement,\r\n React.InputHTMLAttributes<HTMLInputElement>\r\n>(({ type, className, ...props }, ref) => {\r\n const [showPassword, setShowPassword] = useState(false);\r\n\r\n const isPassword = type === \"password\";\r\n const inputType = isPassword ? (showPassword ? \"text\" : \"password\") : type;\r\n\r\n return (\r\n <div className=\"relative\">\r\n <input\r\n ref={ref}\r\n type={inputType}\r\n className={`w-full px-3 py-2 pr-10 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 ${className || \"\"}`}\r\n {...props}\r\n />\r\n {isPassword && (\r\n <button\r\n type=\"button\"\r\n onClick={() => setShowPassword(!showPassword)}\r\n className=\"absolute inset-y-0 right-0 pr-3 flex items-center text-gray-500 hover:text-gray-700\"\r\n >\r\n {showPassword ? <EyeOff size={20} /> : <Eye size={20} />}\r\n </button>\r\n )}\r\n </div>\r\n );\r\n});\r\n\r\nInput.displayName = \"Input\";\r\n\r\nexport { Input };\r\n","import React from \"react\";\r\n\r\nconst Select = React.forwardRef<\r\n HTMLSelectElement,\r\n React.SelectHTMLAttributes<HTMLSelectElement>\r\n>(({ className, ...props }, ref) => {\r\n return (\r\n <select\r\n ref={ref}\r\n className={`w-full px-3 py-2 pr-10 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 bg-white cursor-pointer appearance-none bg-no-repeat bg-right bg-contain ${className || \"\"}`}\r\n style={{\r\n backgroundImage: `url(\"data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 20 20'%3e%3cpath stroke='%236b7280' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' d='m6 8 4 4 4-4'/%3e%3c/svg%3e\")`,\r\n backgroundPosition: \"right 0.75rem center\",\r\n backgroundSize: \"1.25em 1.25em\",\r\n }}\r\n {...props}\r\n />\r\n );\r\n});\r\n\r\nSelect.displayName = \"Select\";\r\n\r\nexport { Select };\r\n\r\n// Option Component\r\n\r\nconst Option = React.forwardRef<\r\n HTMLOptionElement,\r\n React.OptionHTMLAttributes<HTMLOptionElement>\r\n>(({ ...props }, ref) => {\r\n return <option ref={ref} {...props} />;\r\n});\r\n\r\nOption.displayName = \"Option\";\r\n\r\nexport { Option };\r\n","import React from \"react\";\r\n\r\nconst TextArea = React.forwardRef<\r\n HTMLTextAreaElement,\r\n React.TextareaHTMLAttributes<HTMLTextAreaElement>\r\n>(({ ...props }, ref) => {\r\n return (\r\n <textarea\r\n ref={ref}\r\n className=\"w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 resize-none\"\r\n {...props}\r\n />\r\n );\r\n});\r\n\r\nTextArea.displayName = \"TextArea\";\r\n\r\nexport { TextArea };\r\n","import React from \"react\";\r\n\r\nconst DatePicker = React.forwardRef<\r\n HTMLInputElement,\r\n React.InputHTMLAttributes<HTMLInputElement>\r\n>(({ className, placeholder, required, ...props }, ref) => {\r\n return (\r\n <div className=\"relative\">\r\n <input\r\n ref={ref}\r\n type=\"date\"\r\n required={required ?? true}\r\n className={`peer w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-gray-500 focus:border-transparent transition duration-200 ${className ?? \"\"}`}\r\n {...props}\r\n />\r\n <span className=\"absolute left-3 top-1/2 -translate-y-1/2 text-gray-400 pointer-events-none peer-valid:hidden md:hidden\">\r\n {placeholder ?? \"jj/mm/aaaa\"}\r\n </span>\r\n </div>\r\n );\r\n});\r\n\r\nDatePicker.displayName = \"DatePicker\";\r\n\r\nexport { DatePicker };\r\n","import { Loader } from \"lucide-react\";\r\n\r\ninterface LoadingProps {\r\n text: string;\r\n}\r\n\r\nexport function Loading(props: LoadingProps) {\r\n return (\r\n <div className=\"flex items-center justify-center\">\r\n <div className=\"flex flex-col items-center gap-4\">\r\n <Loader className=\"animate-spin\" size={40} />\r\n\r\n <p className=\"text-gray-600 text-md font-medium\">{props.text}</p>\r\n </div>\r\n </div>\r\n );\r\n}\r\n","\"use client\";\r\n\r\nimport { LoaderCircle } from \"lucide-react\";\r\n\r\ninterface data {\r\n textAvant: string;\r\n textAp: string;\r\n onSubmit: boolean;\r\n}\r\n\r\nexport function LoaderSubmit(props: data) {\r\n return (\r\n <>\r\n {props.onSubmit ? (\r\n <div className=\"flex flex-row gap-2 items-center\">\r\n <LoaderCircle className=\"animate-spin text-gray-500\" />\r\n <p className=\"text-gray-500 font-semibold\">{props.textAp}</p>\r\n </div>\r\n ) : (\r\n <button\r\n type=\"submit\"\r\n className=\"bg-blue-500 text-white px-6 py-2 rounded-md hover:bg-blue-700 hover:cursor-pointer transition-colors duration-300 font-semibold shadow-md\"\r\n disabled={props.onSubmit}\r\n >\r\n {props.textAvant}\r\n </button>\r\n )}\r\n </>\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","jsx","jsxs","useState","useEffect","useRef","useCallback","X","Fragment","jsx","jsxs","jsx","React","jsx","jsxs","React","useState","jsx","jsxs","React","jsx","React","jsx","React","jsx","React","jsx","jsxs","jsx","jsxs","Fragment","jsx","jsxs"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramses1er/cbk-toolkit",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.js",