ptechcore_ui 1.0.14 → 1.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -46,7 +46,11 @@ __export(index_exports, {
46
46
  PrimaryButton: () => Buttons_default,
47
47
  RewiseLayout: () => ModernDoubleSidebarLayout_default,
48
48
  SecondaryButton: () => SecondaryButton,
49
+ SelectCostCenter: () => SelectCostCenter,
50
+ SelectDepartment: () => SelectDepartment,
49
51
  SelectInput: () => SelectInput,
52
+ SelectUser: () => SelectUser,
53
+ SelectVendor: () => SelectVendor,
50
54
  SessionProvider: () => SessionProvider,
51
55
  TextInput: () => TextInput,
52
56
  ThemeProvider: () => ThemeContext_default,
@@ -65,13 +69,14 @@ var PrimaryButton = ({
65
69
  loading = false,
66
70
  children,
67
71
  classname = "",
72
+ variant = "full",
68
73
  ...props
69
74
  }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
70
75
  "button",
71
76
  {
72
77
  type: "submit",
73
78
  disabled: loading || props.disabled,
74
- className: `px-4 py-2 text-sm bg-[#6A8A82] text-white rounded-lg hover:bg-[#5A7A72] transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex justify-center items-center ${classname}`,
79
+ className: `px-4 py-2 text-sm rounded-lg hover:bg-opacity-80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex justify-center items-center ${classname} ${variant === "full" ? "bg-[#6A8A82] text-white" : variant === "outline" ? "border border-[#6A8A82] text-[#6A8A82] bg-transparent" : "bg-transparent text-[#6A8A82]"}`,
75
80
  ...props,
76
81
  children: loading ? "Connexion en cours..." : children
77
82
  }
@@ -79,13 +84,14 @@ var PrimaryButton = ({
79
84
  var SecondaryButton = ({
80
85
  loading = false,
81
86
  children,
87
+ variant = "full",
82
88
  ...props
83
89
  }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
84
90
  "button",
85
91
  {
86
92
  type: "button",
87
93
  disabled: loading || props.disabled,
88
- className: "px-4 py-2 bg-[#B87333] text-white rounded-lg hover:bg-[#A66B2A] transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center",
94
+ className: `px-4 py-2 rounded-lg hover:bg-opacity-80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center ${variant === "full" ? "bg-[#B87333] text-white" : variant === "outline" ? "border border-[#B87333] text-[#B87333] bg-transparent" : "bg-transparent text-[#B87333]"}`,
89
95
  ...props,
90
96
  children: loading ? "Connexion en cours..." : children
91
97
  }
@@ -96,7 +102,7 @@ var Buttons_default = PrimaryButton;
96
102
  var import_jsx_runtime2 = require("react/jsx-runtime");
97
103
  var Modal = ({ title, description, width, open, onClose, children }) => {
98
104
  if (!open) return null;
99
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `bg-white rounded-lg py-4 px-6 mx-4 w-[${width ? width : "60%"}]`, children: [
105
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `bg-white rounded-lg pt-4 px-6 mx-4 `, children: [
100
106
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex justify-between items-start mb-6", children: [
101
107
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
102
108
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h3", { className: "text-xl font-semibold text-tuatara flex items-center space-x-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: title }) }),
@@ -112,7 +118,7 @@ var Modal = ({ title, description, width, open, onClose, children }) => {
112
118
  }
113
119
  )
114
120
  ] }),
115
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-full max-h-[80vh] overflow-y-auto mb-4", children })
121
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "w-full max-h-[80vh] overflow-y-auto mb-1", children })
116
122
  ] }) });
117
123
  };
118
124
  var Modals_default = Modal;
@@ -2603,7 +2609,9 @@ var SearchableSelect = ({
2603
2609
  onRemove,
2604
2610
  disabled = false,
2605
2611
  allowClear = false,
2606
- filterFunction
2612
+ filterFunction,
2613
+ addElement,
2614
+ refresh
2607
2615
  }) => {
2608
2616
  const [isOpen, setIsOpen] = (0, import_react9.useState)(false);
2609
2617
  const [searchTerm, setSearchTerm] = (0, import_react9.useState)("");
@@ -2690,20 +2698,43 @@ var SearchableSelect = ({
2690
2698
  }
2691
2699
  ),
2692
2700
  isOpen && /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg", children: [
2693
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "p-3 border-b border-gray-200", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative", children: [
2694
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" }),
2701
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "p-3 border-b border-gray-200 flex", children: [
2702
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "relative w-full", children: [
2703
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Search, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" }),
2704
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2705
+ "input",
2706
+ {
2707
+ ref: inputRef,
2708
+ type: "text",
2709
+ placeholder: searchPlaceholder,
2710
+ value: searchTerm,
2711
+ onChange: (e) => setSearchTerm(e.target.value),
2712
+ className: "w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-[#6B7C92] focus:border-transparent"
2713
+ }
2714
+ )
2715
+ ] }),
2695
2716
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2696
- "input",
2717
+ "button",
2697
2718
  {
2698
- ref: inputRef,
2699
- type: "text",
2700
- placeholder: searchPlaceholder,
2701
- value: searchTerm,
2702
- onChange: (e) => setSearchTerm(e.target.value),
2703
- className: "w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-[#6B7C92] focus:border-transparent"
2719
+ type: "button",
2720
+ onClick: refresh,
2721
+ disabled,
2722
+ className: "px-3 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
2723
+ title: "Rafra\xEEchir la liste",
2724
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.RefreshCw, { className: `w-4 h-4 ${disabled ? "animate-spin" : ""}` })
2725
+ }
2726
+ ),
2727
+ addElement && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2728
+ "button",
2729
+ {
2730
+ type: "button",
2731
+ onClick: addElement,
2732
+ className: "px-3 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors disabled:opacity-50 disabled:cursor-not-allowed",
2733
+ title: "Rafra\xEEchir la liste",
2734
+ children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_lucide_react6.Plus, { className: "w-4 h-4" })
2704
2735
  }
2705
2736
  )
2706
- ] }) }),
2737
+ ] }),
2707
2738
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
2708
2739
  "div",
2709
2740
  {
@@ -2799,7 +2830,7 @@ var ApprovalWorkflow = ({
2799
2830
  const caseInfo = response.data;
2800
2831
  setCaseData(caseInfo);
2801
2832
  setFormData({
2802
- title: caseInfo.title || "",
2833
+ title: caseInfo.title || title,
2803
2834
  file: null,
2804
2835
  description: caseInfo.description || "",
2805
2836
  status: caseInfo.status
@@ -3707,6 +3738,616 @@ var useAlert = () => {
3707
3738
  }
3708
3739
  return context;
3709
3740
  };
3741
+
3742
+ // src/components/common/CommonSelect.tsx
3743
+ var import_react24 = require("react");
3744
+
3745
+ // src/services/VendorServices.ts
3746
+ var VENDORS_API_URL = `${API_URL}/accounting/vendors/`;
3747
+ var VendorServices = {
3748
+ createVendor: (data, token) => {
3749
+ const payload = { ...data };
3750
+ if (!payload.logo) {
3751
+ delete payload.logo;
3752
+ }
3753
+ return FetchApi.post(`${VENDORS_API_URL}`, payload, token);
3754
+ },
3755
+ getVendor: (id, token) => FetchApi.get(`${VENDORS_API_URL}${id}/`, token),
3756
+ getVendors: (token, params) => FetchApi.get(`${VENDORS_API_URL}?${new URLSearchParams(params).toString()}`, token),
3757
+ updateVendor: (id, data, token) => {
3758
+ const payload = { ...data };
3759
+ if (!payload.logo) {
3760
+ delete payload.logo;
3761
+ }
3762
+ return FetchApi.put(`${VENDORS_API_URL}${id}/`, payload, token);
3763
+ },
3764
+ deleteVendor: (id, token) => FetchApi.delete(`${VENDORS_API_URL}${id}/`, token)
3765
+ };
3766
+
3767
+ // dist/index.js
3768
+ var import_jsx_runtime17 = require("react/jsx-runtime");
3769
+ var import_jsx_runtime18 = require("react/jsx-runtime");
3770
+ var import_react_router_dom5 = require("react-router-dom");
3771
+ var import_jsx_runtime19 = require("react/jsx-runtime");
3772
+ var import_react12 = __toESM(require("react"), 1);
3773
+ var import_react_router_dom6 = require("react-router-dom");
3774
+ var import_lucide_react8 = require("lucide-react");
3775
+ var import_clsx2 = require("clsx");
3776
+ var import_tailwind_merge2 = require("tailwind-merge");
3777
+ var import_react13 = require("react");
3778
+ var import_jsx_runtime20 = require("react/jsx-runtime");
3779
+ var import_react14 = require("react");
3780
+ var import_jsx_runtime21 = require("react/jsx-runtime");
3781
+ var import_react15 = require("react");
3782
+ var import_jsx_runtime22 = require("react/jsx-runtime");
3783
+ var import_react16 = require("react");
3784
+ var import_jsx_runtime23 = require("react/jsx-runtime");
3785
+ var import_lucide_react9 = require("lucide-react");
3786
+ var import_react_router_dom7 = require("react-router-dom");
3787
+ var import_jsx_runtime24 = require("react/jsx-runtime");
3788
+ var import_jsx_runtime25 = require("react/jsx-runtime");
3789
+ var import_react17 = require("react");
3790
+ var import_lucide_react10 = require("lucide-react");
3791
+ var import_jsx_runtime26 = require("react/jsx-runtime");
3792
+ var import_lucide_react11 = require("lucide-react");
3793
+ var import_react18 = require("react");
3794
+ var import_jsx_runtime27 = require("react/jsx-runtime");
3795
+ var import_react19 = require("react");
3796
+ var import_react_router_dom8 = require("react-router-dom");
3797
+ var import_lucide_react12 = require("lucide-react");
3798
+ var import_jsx_runtime28 = require("react/jsx-runtime");
3799
+ var import_react20 = require("react");
3800
+ var import_react21 = require("react");
3801
+ var import_lucide_react13 = require("lucide-react");
3802
+ var import_jsx_runtime29 = require("react/jsx-runtime");
3803
+ var import_lucide_react14 = require("lucide-react");
3804
+ var import_jsx_runtime30 = require("react/jsx-runtime");
3805
+ var import_react22 = require("react");
3806
+ var import_jsx_runtime31 = require("react/jsx-runtime");
3807
+ var import_jsx_runtime32 = require("react/jsx-runtime");
3808
+ var PrimaryButton2 = ({
3809
+ loading = false,
3810
+ children,
3811
+ classname = "",
3812
+ ...props
3813
+ }) => /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3814
+ "button",
3815
+ {
3816
+ type: "submit",
3817
+ disabled: loading || props.disabled,
3818
+ className: `px-4 py-2 text-sm bg-[#6A8A82] text-white rounded-lg hover:bg-[#5A7A72] transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex justify-center items-center ${classname}`,
3819
+ ...props,
3820
+ children: loading ? "Connexion en cours..." : children
3821
+ }
3822
+ );
3823
+ var Buttons_default2 = PrimaryButton2;
3824
+ var Modal2 = ({ title, description, width, open, onClose, children }) => {
3825
+ if (!open) return null;
3826
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: `bg-white rounded-lg py-4 px-6 mx-4 w-[${width ? width : "60%"}]`, children: [
3827
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex justify-between items-start mb-6", children: [
3828
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
3829
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("h3", { className: "text-xl font-semibold text-tuatara flex items-center space-x-2", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { children: title }) }),
3830
+ description && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-gray-600 mt-1", children: description })
3831
+ ] }),
3832
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
3833
+ "button",
3834
+ {
3835
+ onClick: onClose,
3836
+ className: "text-gray-400 hover:text-gray-600 text-xl",
3837
+ "aria-label": "Close modal",
3838
+ children: "\u2715"
3839
+ }
3840
+ )
3841
+ ] }),
3842
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "w-full max-h-[80vh] overflow-y-auto mb-4", children })
3843
+ ] }) });
3844
+ };
3845
+ var Modals_default2 = Modal2;
3846
+ var InputField2 = ({
3847
+ label,
3848
+ name,
3849
+ type = "text",
3850
+ value,
3851
+ placeholder,
3852
+ required = false,
3853
+ disabled = false,
3854
+ error,
3855
+ onChange,
3856
+ onBlur
3857
+ }) => {
3858
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("div", { className: "flex flex-col gap-1 w-full", children: [
3859
+ label && /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)("label", { htmlFor: name, className: "block text-gray-700 text-sm font-medium mb-2", children: [
3860
+ label,
3861
+ " ",
3862
+ required && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("span", { className: "text-red-500", children: "*" })
3863
+ ] }),
3864
+ /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
3865
+ "input",
3866
+ {
3867
+ id: name,
3868
+ name,
3869
+ type,
3870
+ value,
3871
+ placeholder,
3872
+ required,
3873
+ disabled,
3874
+ onChange,
3875
+ onBlur,
3876
+ className: `w-full px-3 py-2 border border-[#D9D9D9] focus:ring-2 focus:ring-[#6A8A82]/20
3877
+ ${error ? "border-red-500" : "border-gray-300"}
3878
+ ${disabled ? "bg-gray-100 cursor-not-allowed" : ""}
3879
+ `
3880
+ }
3881
+ ),
3882
+ error && /* @__PURE__ */ (0, import_jsx_runtime19.jsx)("p", { className: "text-xs text-red-500", children: error })
3883
+ ] });
3884
+ };
3885
+ var TextInput2 = (props) => {
3886
+ return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(InputField2, { ...props, type: "text" });
3887
+ };
3888
+ var ThemeContext2 = (0, import_react13.createContext)(void 0);
3889
+ var ADDRESS_IP2 = "localhost:8000";
3890
+ var ADDRESS_IP_URL2 = `http://${ADDRESS_IP2}/`;
3891
+ var API_URL2 = `${ADDRESS_IP_URL2}api`;
3892
+ var API_BASE_URL3 = `${API_URL2}/core/auth/`;
3893
+ var SessionContext2 = (0, import_react14.createContext)(void 0);
3894
+ var API_BASE_URL22 = `${API_URL2}/core/auth/`;
3895
+ var USERS_API_URL2 = `${API_URL2}/core/users/`;
3896
+ var ToastContext2 = (0, import_react15.createContext)(void 0);
3897
+ var APPROVAL_API_URL2 = `${API_URL2}/approvals/cases/`;
3898
+ var AlertContext2 = (0, import_react22.createContext)(void 0);
3899
+
3900
+ // src/components/common/FormVendor.tsx
3901
+ var import_react23 = require("react");
3902
+ var import_jsx_runtime33 = require("react/jsx-runtime");
3903
+ var MinimalVendorForm = ({
3904
+ isOpen,
3905
+ onClose,
3906
+ object,
3907
+ from = "procurement",
3908
+ refresh = () => {
3909
+ }
3910
+ }) => {
3911
+ const [formData, setFormData] = (0, import_react23.useState)(object || {
3912
+ from_module: from ?? null,
3913
+ legal_name: "",
3914
+ trading_name: ""
3915
+ });
3916
+ const [errors, setErrors] = (0, import_react23.useState)({});
3917
+ const [loading, setLoading] = (0, import_react23.useState)(false);
3918
+ const { token } = useSession();
3919
+ const { success, error: showError } = useToast();
3920
+ const handleInputChange = (e) => {
3921
+ const { name, value } = e.target;
3922
+ setFormData((prev) => ({ ...prev, [name]: value }));
3923
+ if (errors[name]) {
3924
+ setErrors((prev) => ({ ...prev, [name]: void 0 }));
3925
+ }
3926
+ };
3927
+ const handleSelectChange = (e) => {
3928
+ const { name, value } = e.target;
3929
+ setFormData((prev) => ({ ...prev, [name]: value }));
3930
+ };
3931
+ const handleTextareaChange = (e) => {
3932
+ const { name, value } = e.target;
3933
+ setFormData((prev) => ({ ...prev, [name]: value }));
3934
+ };
3935
+ const validateForm = () => {
3936
+ const newErrors = {};
3937
+ if (!formData.legal_name?.trim()) {
3938
+ newErrors.legal_name = "La raison sociale est obligatoire";
3939
+ }
3940
+ if (formData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
3941
+ newErrors.email = "Format d'email invalide";
3942
+ }
3943
+ if (formData.iban && formData.iban.length > 0 && formData.iban.length < 15) {
3944
+ newErrors.iban = "Format IBAN invalide";
3945
+ }
3946
+ setErrors(newErrors);
3947
+ return Object.keys(newErrors).length === 0;
3948
+ };
3949
+ const handleSaveVendor = async (entityData) => {
3950
+ try {
3951
+ if (object && object.id) {
3952
+ await VendorServices.updateVendor(object.id, entityData, token);
3953
+ success("Entit\xE9 modifi\xE9e avec succ\xE8s !");
3954
+ } else {
3955
+ await VendorServices.createVendor(entityData, token);
3956
+ success("Entit\xE9 cr\xE9\xE9e avec succ\xE8s !");
3957
+ }
3958
+ refresh();
3959
+ onClose();
3960
+ } catch (error) {
3961
+ console.error(error);
3962
+ showError("Erreur lors de l'enregistrement de l'entit\xE9");
3963
+ }
3964
+ };
3965
+ const handleSubmit = async (e) => {
3966
+ e.preventDefault();
3967
+ if (!validateForm()) return;
3968
+ setLoading(true);
3969
+ try {
3970
+ await handleSaveVendor(formData);
3971
+ } finally {
3972
+ setLoading(false);
3973
+ }
3974
+ };
3975
+ if (!isOpen) return null;
3976
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3977
+ Modals_default2,
3978
+ {
3979
+ title: "Ajouter un fournisseur",
3980
+ width: "w-[100%]",
3981
+ description: ``,
3982
+ open: isOpen,
3983
+ onClose,
3984
+ children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("form", { onSubmit: handleSubmit, className: "p-", children: [
3985
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("div", { className: "space-y-4", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3986
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3987
+ TextInput2,
3988
+ {
3989
+ label: "Raison sociale",
3990
+ name: "legal_name",
3991
+ value: formData.legal_name || "",
3992
+ placeholder: "Nom l\xE9gal de l'entit\xE9",
3993
+ required: true,
3994
+ error: errors.legal_name,
3995
+ onChange: handleInputChange
3996
+ }
3997
+ ),
3998
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
3999
+ TextInput2,
4000
+ {
4001
+ label: "Nom commercial",
4002
+ name: "trading_name",
4003
+ value: formData.trading_name || "",
4004
+ placeholder: "Nom commercial (optionnel)",
4005
+ onChange: handleInputChange
4006
+ }
4007
+ )
4008
+ ] }) }),
4009
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)("div", { className: "flex justify-between pt-6 mt-8", children: [
4010
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4011
+ "button",
4012
+ {
4013
+ type: "button",
4014
+ onClick: onClose,
4015
+ className: "px-6 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors",
4016
+ children: "Annuler"
4017
+ }
4018
+ ),
4019
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
4020
+ Buttons_default2,
4021
+ {
4022
+ type: "button",
4023
+ onClick: handleSubmit,
4024
+ disabled: loading,
4025
+ children: loading ? "chargement..." : "Enregistrer l'entit\xE9"
4026
+ }
4027
+ )
4028
+ ] })
4029
+ ] })
4030
+ }
4031
+ );
4032
+ };
4033
+
4034
+ // src/services/DepartmentServices.ts
4035
+ var URI = `${API_URL}/core/departments/`;
4036
+ var DepartmentServices = {
4037
+ create: (data) => FetchApi.post(`${URI}`, data),
4038
+ get: (id) => FetchApi.get(`${URI}${id}/`),
4039
+ list: (params) => FetchApi.get(`${URI}?${new URLSearchParams(params).toString()}`),
4040
+ update: (id, data) => FetchApi.put(`${URI}${id}/`, data),
4041
+ delete: (id) => FetchApi.delete(`${URI}${id}/`)
4042
+ };
4043
+
4044
+ // src/services/ProfitCostsServices.ts
4045
+ var URI2 = `${API_URL}/accounting/profit-or-cost-center/`;
4046
+ var COST_URI = `${API_URL}/accounting/cost-center/`;
4047
+ var CostServices = {
4048
+ create: (data) => FetchApi.post(`${COST_URI}`, data),
4049
+ get: (id) => FetchApi.get(`${COST_URI}${id}/`),
4050
+ list: (params) => FetchApi.get(`${COST_URI}?${new URLSearchParams(params).toString()}`),
4051
+ update: (id, data) => FetchApi.put(`${COST_URI}${id}/`, data),
4052
+ delete: (id) => FetchApi.delete(`${COST_URI}${id}/`)
4053
+ };
4054
+ var PROFIT_URI = `${API_URL}/accounting/profit-center/`;
4055
+
4056
+ // src/components/common/CommonSelect.tsx
4057
+ var import_jsx_runtime34 = require("react/jsx-runtime");
4058
+ var SelectVendor = ({
4059
+ value,
4060
+ onSelect
4061
+ }) => {
4062
+ const [showModal, setShowModal] = (0, import_react24.useState)(false);
4063
+ const [selectedVendor, setSelectedVendor] = (0, import_react24.useState)(null);
4064
+ const { token, activeBusinessEntity } = useSession();
4065
+ const [vendors, setVendors] = (0, import_react24.useState)(() => {
4066
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4067
+ const cached = sessionStorage.getItem(cacheKey);
4068
+ return cached ? JSON.parse(cached) : [];
4069
+ });
4070
+ const [loadingVendors, setLoadingVendors] = (0, import_react24.useState)(false);
4071
+ (0, import_react24.useEffect)(() => {
4072
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4073
+ const cached = sessionStorage.getItem(cacheKey);
4074
+ if (!cached) {
4075
+ loadVendors();
4076
+ } else {
4077
+ setVendors(JSON.parse(cached));
4078
+ }
4079
+ }, [activeBusinessEntity?.id]);
4080
+ const getVendorOptions = () => {
4081
+ return vendors.filter((vendor) => vendor.id !== void 0).map((vendor) => ({
4082
+ value: vendor.id,
4083
+ label: `${vendor.legal_name} [${vendor.trading_name}]`
4084
+ }));
4085
+ };
4086
+ const loadVendors = async () => {
4087
+ if (!token) {
4088
+ console.error("Vous devez etre connect\xE9 pour voir les organisations");
4089
+ return;
4090
+ }
4091
+ try {
4092
+ setLoadingVendors(true);
4093
+ const result = await VendorServices.getVendors(token, { business_entity_id: activeBusinessEntity?.id });
4094
+ setVendors(result.data);
4095
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4096
+ sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
4097
+ } catch (error) {
4098
+ console.error(error);
4099
+ } finally {
4100
+ setLoadingVendors(false);
4101
+ }
4102
+ };
4103
+ const handleRefresh = () => {
4104
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4105
+ sessionStorage.removeItem(cacheKey);
4106
+ loadVendors();
4107
+ };
4108
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
4109
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex justify-between ", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Ajouter un fournisseur" }) }),
4110
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4111
+ SearchableSelect,
4112
+ {
4113
+ value,
4114
+ options: getVendorOptions(),
4115
+ placeholder: "S\xE9lectionner un fournisseur...",
4116
+ searchPlaceholder: "Rechercher...",
4117
+ onSelect,
4118
+ disabled: loadingVendors,
4119
+ refresh: handleRefresh,
4120
+ addElement: () => {
4121
+ setShowModal(true);
4122
+ }
4123
+ },
4124
+ "fourni" + value
4125
+ ),
4126
+ loadingVendors && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des fournisseurs..." }),
4127
+ showModal && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4128
+ MinimalVendorForm,
4129
+ {
4130
+ object: selectedVendor,
4131
+ isOpen: showModal,
4132
+ onClose: () => setShowModal(false),
4133
+ refresh: handleRefresh
4134
+ },
4135
+ `entity-modal-${selectedVendor?.id}`
4136
+ )
4137
+ ] });
4138
+ };
4139
+ var SelectUser = ({
4140
+ value,
4141
+ onSelect
4142
+ }) => {
4143
+ const { token, activeBusinessEntity } = useSession();
4144
+ const [users, setUsers] = (0, import_react24.useState)(() => {
4145
+ const cacheKey = `users_cache_${activeBusinessEntity?.id || "default"}`;
4146
+ const cached = sessionStorage.getItem(cacheKey);
4147
+ return cached ? JSON.parse(cached) : [];
4148
+ });
4149
+ const [loading, setLoading] = (0, import_react24.useState)(false);
4150
+ (0, import_react24.useEffect)(() => {
4151
+ const cacheKey = `users_cache_${activeBusinessEntity?.id || "default"}`;
4152
+ const cached = sessionStorage.getItem(cacheKey);
4153
+ if (!cached) {
4154
+ loadUsers();
4155
+ } else {
4156
+ setUsers(JSON.parse(cached));
4157
+ }
4158
+ }, [activeBusinessEntity?.id]);
4159
+ const loadUsers = async () => {
4160
+ if (!token) return;
4161
+ try {
4162
+ setLoading(true);
4163
+ const result = await UserServices.getUsers(token);
4164
+ setUsers(result.data);
4165
+ } catch (error) {
4166
+ console.error(error);
4167
+ } finally {
4168
+ setLoading(false);
4169
+ }
4170
+ };
4171
+ const handleRefresh = () => {
4172
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4173
+ sessionStorage.removeItem(cacheKey);
4174
+ loadUsers();
4175
+ };
4176
+ const userFilterFunction = (option, searchTerm) => {
4177
+ const user = users.find((u) => u.id === option.value);
4178
+ if (!user) return false;
4179
+ const searchLower = searchTerm.toLowerCase();
4180
+ return user.first_name?.toLowerCase().includes(searchLower) || user.last_name?.toLowerCase().includes(searchLower) || user.email?.toLowerCase().includes(searchLower);
4181
+ };
4182
+ const getUserOptions = () => {
4183
+ return users.map((user) => ({
4184
+ value: user.id,
4185
+ label: `${user.first_name} ${user.last_name}`,
4186
+ content: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex-1", children: [
4187
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "font-medium text-gray-900", children: [
4188
+ user.first_name,
4189
+ " ",
4190
+ user.last_name
4191
+ ] }),
4192
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "text-sm text-gray-500", children: user.email })
4193
+ ] }) })
4194
+ }));
4195
+ };
4196
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
4197
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex justify-between ", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner un utilisateur" }) }),
4198
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4199
+ SearchableSelect,
4200
+ {
4201
+ value,
4202
+ options: getUserOptions(),
4203
+ placeholder: "S\xE9lectionner un utilisateur ...",
4204
+ searchPlaceholder: "Rechercher...",
4205
+ onSelect,
4206
+ disabled: loading,
4207
+ refresh: handleRefresh
4208
+ },
4209
+ "user" + value
4210
+ ),
4211
+ loading && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des utilisateurs..." })
4212
+ ] });
4213
+ };
4214
+ var SelectDepartment = ({
4215
+ value,
4216
+ onSelect
4217
+ }) => {
4218
+ const { token, activeBusinessEntity } = useSession();
4219
+ const [departments, setDepartments] = (0, import_react24.useState)(() => {
4220
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4221
+ const cached = sessionStorage.getItem(cacheKey);
4222
+ return cached ? JSON.parse(cached) : [];
4223
+ });
4224
+ const [loading, setLoading] = (0, import_react24.useState)(false);
4225
+ (0, import_react24.useEffect)(() => {
4226
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4227
+ const cached = sessionStorage.getItem(cacheKey);
4228
+ if (!cached) {
4229
+ loadDepartments();
4230
+ } else {
4231
+ setDepartments(JSON.parse(cached));
4232
+ }
4233
+ }, [activeBusinessEntity?.id]);
4234
+ const loadDepartments = async () => {
4235
+ if (!token) return;
4236
+ try {
4237
+ setLoading(true);
4238
+ const result = await DepartmentServices.list({ business_entity_id: activeBusinessEntity?.id });
4239
+ if (result.success) {
4240
+ setDepartments(result.data);
4241
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4242
+ sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
4243
+ }
4244
+ } catch (error) {
4245
+ console.error(error);
4246
+ } finally {
4247
+ setLoading(false);
4248
+ }
4249
+ };
4250
+ const handleRefresh = () => {
4251
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4252
+ sessionStorage.removeItem(cacheKey);
4253
+ loadDepartments();
4254
+ };
4255
+ const getDepartmentOptions = () => {
4256
+ return departments.map((dept) => ({
4257
+ value: dept.id,
4258
+ label: dept.name
4259
+ }));
4260
+ };
4261
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
4262
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex justify-between ", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner un d\xE9partement" }) }),
4263
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4264
+ SearchableSelect,
4265
+ {
4266
+ value,
4267
+ options: getDepartmentOptions(),
4268
+ placeholder: "S\xE9lectionner un d\xE9partement ...",
4269
+ searchPlaceholder: "Rechercher...",
4270
+ onSelect,
4271
+ disabled: loading,
4272
+ refresh: handleRefresh
4273
+ },
4274
+ "dept" + value
4275
+ ),
4276
+ loading && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des d\xE9partements..." })
4277
+ ] });
4278
+ };
4279
+ var SelectCostCenter = ({
4280
+ value,
4281
+ onSelect
4282
+ }) => {
4283
+ const { token, activeBusinessEntity } = useSession();
4284
+ const [costCenters, setCostCenters] = (0, import_react24.useState)(() => {
4285
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4286
+ const cached = sessionStorage.getItem(cacheKey);
4287
+ return cached ? JSON.parse(cached) : [];
4288
+ });
4289
+ const [loading, setLoading] = (0, import_react24.useState)(false);
4290
+ (0, import_react24.useEffect)(() => {
4291
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4292
+ const cached = sessionStorage.getItem(cacheKey);
4293
+ if (!cached) {
4294
+ loadCostCenters();
4295
+ } else {
4296
+ setCostCenters(JSON.parse(cached));
4297
+ }
4298
+ }, [activeBusinessEntity?.id]);
4299
+ const loadCostCenters = async () => {
4300
+ if (!token) return;
4301
+ try {
4302
+ setLoading(true);
4303
+ const result = await CostServices.list({ business_entity_id: activeBusinessEntity?.id });
4304
+ if (result.success) {
4305
+ setCostCenters(result.data);
4306
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4307
+ sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
4308
+ }
4309
+ } catch (error) {
4310
+ console.error(error);
4311
+ } finally {
4312
+ setLoading(false);
4313
+ }
4314
+ };
4315
+ const handleRefresh = () => {
4316
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4317
+ sessionStorage.removeItem(cacheKey);
4318
+ loadCostCenters();
4319
+ };
4320
+ const getCostCenterOptions = () => {
4321
+ return costCenters.map((center) => ({
4322
+ value: center.id,
4323
+ label: `${center.code ? `[${center.code}] ` : ""}${center.name}`,
4324
+ content: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "flex-1", children: [
4325
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "font-medium text-gray-900", children: center.name }),
4326
+ center.code && /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { className: "text-sm text-gray-500", children: [
4327
+ "Code: ",
4328
+ center.code
4329
+ ] })
4330
+ ] }) })
4331
+ }));
4332
+ };
4333
+ return /* @__PURE__ */ (0, import_jsx_runtime34.jsxs)("div", { children: [
4334
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("div", { className: "flex justify-between ", children: /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner un centre de co\xFBt" }) }),
4335
+ /* @__PURE__ */ (0, import_jsx_runtime34.jsx)(
4336
+ SearchableSelect,
4337
+ {
4338
+ value,
4339
+ options: getCostCenterOptions(),
4340
+ placeholder: "S\xE9lectionner un centre de co\xFBt ...",
4341
+ searchPlaceholder: "Rechercher...",
4342
+ onSelect,
4343
+ disabled: loading,
4344
+ refresh: handleRefresh
4345
+ },
4346
+ "cost" + value
4347
+ ),
4348
+ loading && /* @__PURE__ */ (0, import_jsx_runtime34.jsx)("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des centres de co\xFBt..." })
4349
+ ] });
4350
+ };
3710
4351
  // Annotate the CommonJS export names for ESM import in node:
3711
4352
  0 && (module.exports = {
3712
4353
  Alert,
@@ -3726,7 +4367,11 @@ var useAlert = () => {
3726
4367
  PrimaryButton,
3727
4368
  RewiseLayout,
3728
4369
  SecondaryButton,
4370
+ SelectCostCenter,
4371
+ SelectDepartment,
3729
4372
  SelectInput,
4373
+ SelectUser,
4374
+ SelectVendor,
3730
4375
  SessionProvider,
3731
4376
  TextInput,
3732
4377
  ThemeProvider,