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.js CHANGED
@@ -4,13 +4,14 @@ var PrimaryButton = ({
4
4
  loading = false,
5
5
  children,
6
6
  classname = "",
7
+ variant = "full",
7
8
  ...props
8
9
  }) => /* @__PURE__ */ jsx(
9
10
  "button",
10
11
  {
11
12
  type: "submit",
12
13
  disabled: loading || props.disabled,
13
- 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}`,
14
+ 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]"}`,
14
15
  ...props,
15
16
  children: loading ? "Connexion en cours..." : children
16
17
  }
@@ -18,13 +19,14 @@ var PrimaryButton = ({
18
19
  var SecondaryButton = ({
19
20
  loading = false,
20
21
  children,
22
+ variant = "full",
21
23
  ...props
22
24
  }) => /* @__PURE__ */ jsx(
23
25
  "button",
24
26
  {
25
27
  type: "button",
26
28
  disabled: loading || props.disabled,
27
- 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",
29
+ 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]"}`,
28
30
  ...props,
29
31
  children: loading ? "Connexion en cours..." : children
30
32
  }
@@ -35,7 +37,7 @@ var Buttons_default = PrimaryButton;
35
37
  import { jsx as jsx2, jsxs } from "react/jsx-runtime";
36
38
  var Modal = ({ title, description, width, open, onClose, children }) => {
37
39
  if (!open) return null;
38
- return /* @__PURE__ */ jsx2("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ jsxs("div", { className: `bg-white rounded-lg py-4 px-6 mx-4 w-[${width ? width : "60%"}]`, children: [
40
+ return /* @__PURE__ */ jsx2("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ jsxs("div", { className: `bg-white rounded-lg pt-4 px-6 mx-4 `, children: [
39
41
  /* @__PURE__ */ jsxs("div", { className: "flex justify-between items-start mb-6", children: [
40
42
  /* @__PURE__ */ jsxs("div", { children: [
41
43
  /* @__PURE__ */ jsx2("h3", { className: "text-xl font-semibold text-tuatara flex items-center space-x-2", children: /* @__PURE__ */ jsx2("span", { children: title }) }),
@@ -51,7 +53,7 @@ var Modal = ({ title, description, width, open, onClose, children }) => {
51
53
  }
52
54
  )
53
55
  ] }),
54
- /* @__PURE__ */ jsx2("div", { className: "w-full max-h-[80vh] overflow-y-auto mb-4", children })
56
+ /* @__PURE__ */ jsx2("div", { className: "w-full max-h-[80vh] overflow-y-auto mb-1", children })
55
57
  ] }) });
56
58
  };
57
59
  var Modals_default = Modal;
@@ -2545,7 +2547,7 @@ import { useState as useState10, useEffect as useEffect8 } from "react";
2545
2547
 
2546
2548
  // src/components/common/SearchableSelect.tsx
2547
2549
  import { useState as useState9, useRef, useEffect as useEffect7 } from "react";
2548
- import { Search as Search3, ChevronDown, X as X4 } from "lucide-react";
2550
+ import { Search as Search3, ChevronDown, X as X4, RefreshCw, Plus } from "lucide-react";
2549
2551
  import { Fragment as Fragment5, jsx as jsx13, jsxs as jsxs9 } from "react/jsx-runtime";
2550
2552
  var SearchableSelect = ({
2551
2553
  options,
@@ -2556,7 +2558,9 @@ var SearchableSelect = ({
2556
2558
  onRemove,
2557
2559
  disabled = false,
2558
2560
  allowClear = false,
2559
- filterFunction
2561
+ filterFunction,
2562
+ addElement,
2563
+ refresh
2560
2564
  }) => {
2561
2565
  const [isOpen, setIsOpen] = useState9(false);
2562
2566
  const [searchTerm, setSearchTerm] = useState9("");
@@ -2643,20 +2647,43 @@ var SearchableSelect = ({
2643
2647
  }
2644
2648
  ),
2645
2649
  isOpen && /* @__PURE__ */ jsxs9("div", { className: "absolute z-50 w-full mt-1 bg-white border border-gray-200 rounded-lg shadow-lg", children: [
2646
- /* @__PURE__ */ jsx13("div", { className: "p-3 border-b border-gray-200", children: /* @__PURE__ */ jsxs9("div", { className: "relative", children: [
2647
- /* @__PURE__ */ jsx13(Search3, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" }),
2650
+ /* @__PURE__ */ jsxs9("div", { className: "p-3 border-b border-gray-200 flex", children: [
2651
+ /* @__PURE__ */ jsxs9("div", { className: "relative w-full", children: [
2652
+ /* @__PURE__ */ jsx13(Search3, { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400 w-4 h-4" }),
2653
+ /* @__PURE__ */ jsx13(
2654
+ "input",
2655
+ {
2656
+ ref: inputRef,
2657
+ type: "text",
2658
+ placeholder: searchPlaceholder,
2659
+ value: searchTerm,
2660
+ onChange: (e) => setSearchTerm(e.target.value),
2661
+ className: "w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-[#6B7C92] focus:border-transparent"
2662
+ }
2663
+ )
2664
+ ] }),
2648
2665
  /* @__PURE__ */ jsx13(
2649
- "input",
2666
+ "button",
2650
2667
  {
2651
- ref: inputRef,
2652
- type: "text",
2653
- placeholder: searchPlaceholder,
2654
- value: searchTerm,
2655
- onChange: (e) => setSearchTerm(e.target.value),
2656
- className: "w-full pl-10 pr-4 py-2 border border-gray-200 rounded-lg focus:ring-2 focus:ring-[#6B7C92] focus:border-transparent"
2668
+ type: "button",
2669
+ onClick: refresh,
2670
+ disabled,
2671
+ 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",
2672
+ title: "Rafra\xEEchir la liste",
2673
+ children: /* @__PURE__ */ jsx13(RefreshCw, { className: `w-4 h-4 ${disabled ? "animate-spin" : ""}` })
2674
+ }
2675
+ ),
2676
+ addElement && /* @__PURE__ */ jsx13(
2677
+ "button",
2678
+ {
2679
+ type: "button",
2680
+ onClick: addElement,
2681
+ 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",
2682
+ title: "Rafra\xEEchir la liste",
2683
+ children: /* @__PURE__ */ jsx13(Plus, { className: "w-4 h-4" })
2657
2684
  }
2658
2685
  )
2659
- ] }) }),
2686
+ ] }),
2660
2687
  /* @__PURE__ */ jsx13("div", { className: "max-h-60 overflow-y-auto", children: filteredOptions.length > 0 ? filteredOptions.map((option) => /* @__PURE__ */ jsxs9(
2661
2688
  "div",
2662
2689
  {
@@ -2681,7 +2708,7 @@ var SearchableSelect = ({
2681
2708
  };
2682
2709
 
2683
2710
  // src/components/common/ApprovalWorkflow.tsx
2684
- import { X as X5, Plus, Trash2, Users, Loader as Loader2, RotateCcw, Ban, Eye as Eye2, FileText as FileText2, History } from "lucide-react";
2711
+ import { X as X5, Plus as Plus2, Trash2, Users, Loader as Loader2, RotateCcw, Ban, Eye as Eye2, FileText as FileText2, History } from "lucide-react";
2685
2712
  import { Fragment as Fragment6, jsx as jsx14, jsxs as jsxs10 } from "react/jsx-runtime";
2686
2713
  var ApprovalWorkflow = ({
2687
2714
  process,
@@ -2752,7 +2779,7 @@ var ApprovalWorkflow = ({
2752
2779
  const caseInfo = response.data;
2753
2780
  setCaseData(caseInfo);
2754
2781
  setFormData({
2755
- title: caseInfo.title || "",
2782
+ title: caseInfo.title || title,
2756
2783
  file: null,
2757
2784
  description: caseInfo.description || "",
2758
2785
  status: caseInfo.status
@@ -3418,7 +3445,7 @@ var AddStageButton = ({
3418
3445
  onClick: () => setShowModal(true),
3419
3446
  classname: "gap-2",
3420
3447
  children: [
3421
- /* @__PURE__ */ jsx14(Plus, { className: "w-4 h-4" }),
3448
+ /* @__PURE__ */ jsx14(Plus2, { className: "w-4 h-4" }),
3422
3449
  /* @__PURE__ */ jsx14("span", { children: "Ajouter une personne" })
3423
3450
  ]
3424
3451
  }
@@ -3660,6 +3687,630 @@ var useAlert = () => {
3660
3687
  }
3661
3688
  return context;
3662
3689
  };
3690
+
3691
+ // src/components/common/CommonSelect.tsx
3692
+ import { useEffect as useEffect11, useState as useState14 } from "react";
3693
+
3694
+ // src/services/VendorServices.ts
3695
+ var VENDORS_API_URL = `${API_URL}/accounting/vendors/`;
3696
+ var VendorServices = {
3697
+ createVendor: (data, token) => {
3698
+ const payload = { ...data };
3699
+ if (!payload.logo) {
3700
+ delete payload.logo;
3701
+ }
3702
+ return FetchApi.post(`${VENDORS_API_URL}`, payload, token);
3703
+ },
3704
+ getVendor: (id, token) => FetchApi.get(`${VENDORS_API_URL}${id}/`, token),
3705
+ getVendors: (token, params) => FetchApi.get(`${VENDORS_API_URL}?${new URLSearchParams(params).toString()}`, token),
3706
+ updateVendor: (id, data, token) => {
3707
+ const payload = { ...data };
3708
+ if (!payload.logo) {
3709
+ delete payload.logo;
3710
+ }
3711
+ return FetchApi.put(`${VENDORS_API_URL}${id}/`, payload, token);
3712
+ },
3713
+ deleteVendor: (id, token) => FetchApi.delete(`${VENDORS_API_URL}${id}/`, token)
3714
+ };
3715
+
3716
+ // dist/index.js
3717
+ import { jsx as jsx17 } from "react/jsx-runtime";
3718
+ import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
3719
+ import { Link as Link3 } from "react-router-dom";
3720
+ import { jsx as jsx32, jsxs as jsxs22 } from "react/jsx-runtime";
3721
+ import React42, { useState as useState52, useEffect as useEffect42 } from "react";
3722
+ import { useLocation as useLocation3, useNavigate as useNavigate3 } from "react-router-dom";
3723
+ import {
3724
+ Settings as Settings3,
3725
+ ChevronLeft as ChevronLeft3,
3726
+ ChevronRight as ChevronRight2,
3727
+ Search as Search4,
3728
+ Bell as Bell2,
3729
+ User as User2,
3730
+ LogOut as LogOut2,
3731
+ Menu as Menu3,
3732
+ X as X22,
3733
+ Palette as Palette2,
3734
+ DollarSign as DollarSign2,
3735
+ HelpCircle as HelpCircle2,
3736
+ Building2 as Building22
3737
+ } from "lucide-react";
3738
+ import { clsx as clsx2 } from "clsx";
3739
+ import { twMerge as twMerge2 } from "tailwind-merge";
3740
+ import { createContext as createContext5, useContext as useContext5, useState as useState12, useEffect as useEffect9 } from "react";
3741
+ import { jsx as jsx42 } from "react/jsx-runtime";
3742
+ import { createContext as createContext22, useContext as useContext22, useEffect as useEffect22, useState as useState22 } from "react";
3743
+ import { jsx as jsx52 } from "react/jsx-runtime";
3744
+ import { createContext as createContext32, useContext as useContext32, useState as useState32, useCallback as useCallback3 } from "react";
3745
+ import { jsx as jsx62 } from "react/jsx-runtime";
3746
+ import { useState as useState42, useEffect as useEffect32 } from "react";
3747
+ import { jsx as jsx72, jsxs as jsxs32 } from "react/jsx-runtime";
3748
+ import { X as X6, Loader as Loader3, Eye as Eye3, FileText as FileText3, Check as Check2, XCircle as XCircle3, Edit as Edit2, CheckCircle as CheckCircle3, Clock as Clock2, AlertCircle as AlertCircle2, User as UserIcon2, Send as Send2 } from "lucide-react";
3749
+ import { useParams as useParams2, useSearchParams as useSearchParams3 } from "react-router-dom";
3750
+ import { Fragment as Fragment7, jsx as jsx82, jsxs as jsxs42 } from "react/jsx-runtime";
3751
+ import { Fragment as Fragment22, jsx as jsx92, jsxs as jsxs52 } from "react/jsx-runtime";
3752
+ import { useEffect as useEffect52, useState as useState62 } from "react";
3753
+ import { CheckCircle as CheckCircle22, XCircle as XCircle22, AlertTriangle as AlertTriangle2, Info as Info2, X as X32 } from "lucide-react";
3754
+ import { jsx as jsx102, jsxs as jsxs62 } from "react/jsx-runtime";
3755
+ import { ChevronLeft as ChevronLeft22, Download as Download3, Menu as Menu22, Settings as Settings22 } from "lucide-react";
3756
+ import { useState as useState72 } from "react";
3757
+ import { Fragment as Fragment32, jsx as jsx112, jsxs as jsxs72 } from "react/jsx-runtime";
3758
+ import { useEffect as useEffect62, useState as useState82 } from "react";
3759
+ import { useLocation as useLocation22, useNavigate as useNavigate22, useSearchParams as useSearchParams22, Link as Link22 } from "react-router-dom";
3760
+ import { ArrowDownAZ as ArrowDownAZ2, ArrowDownUp as ArrowDownUp2, ArrowUpAZ as ArrowUpAZ2, Download as Download22, Filter as Filter2, MoreVertical as MoreVertical2, Printer as Printer2, Search as Search22 } from "lucide-react";
3761
+ import { Fragment as Fragment42, jsx as jsx122, jsxs as jsxs82 } from "react/jsx-runtime";
3762
+ import { useState as useState102, useEffect as useEffect82 } from "react";
3763
+ import { useState as useState92, useRef as useRef2, useEffect as useEffect72 } from "react";
3764
+ import { Search as Search32, ChevronDown as ChevronDown2, X as X42 } from "lucide-react";
3765
+ import { Fragment as Fragment52, jsx as jsx132, jsxs as jsxs92 } from "react/jsx-runtime";
3766
+ import { X as X52, Plus as Plus3, Trash2 as Trash22, Users as Users2, Loader as Loader22, RotateCcw as RotateCcw2, Ban as Ban2, Eye as Eye22, FileText as FileText22, History as History2 } from "lucide-react";
3767
+ import { Fragment as Fragment62, jsx as jsx142, jsxs as jsxs102 } from "react/jsx-runtime";
3768
+ import { createContext as createContext42, useContext as useContext42, useState as useState112, useCallback as useCallback22 } from "react";
3769
+ import { jsx as jsx152, jsxs as jsxs112 } from "react/jsx-runtime";
3770
+ import { jsx as jsx162, jsxs as jsxs122 } from "react/jsx-runtime";
3771
+ var PrimaryButton2 = ({
3772
+ loading = false,
3773
+ children,
3774
+ classname = "",
3775
+ ...props
3776
+ }) => /* @__PURE__ */ jsx17(
3777
+ "button",
3778
+ {
3779
+ type: "submit",
3780
+ disabled: loading || props.disabled,
3781
+ 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}`,
3782
+ ...props,
3783
+ children: loading ? "Connexion en cours..." : children
3784
+ }
3785
+ );
3786
+ var Buttons_default2 = PrimaryButton2;
3787
+ var Modal2 = ({ title, description, width, open, onClose, children }) => {
3788
+ if (!open) return null;
3789
+ return /* @__PURE__ */ jsx22("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50", children: /* @__PURE__ */ jsxs13("div", { className: `bg-white rounded-lg py-4 px-6 mx-4 w-[${width ? width : "60%"}]`, children: [
3790
+ /* @__PURE__ */ jsxs13("div", { className: "flex justify-between items-start mb-6", children: [
3791
+ /* @__PURE__ */ jsxs13("div", { children: [
3792
+ /* @__PURE__ */ jsx22("h3", { className: "text-xl font-semibold text-tuatara flex items-center space-x-2", children: /* @__PURE__ */ jsx22("span", { children: title }) }),
3793
+ description && /* @__PURE__ */ jsx22("p", { className: "text-sm text-gray-600 mt-1", children: description })
3794
+ ] }),
3795
+ /* @__PURE__ */ jsx22(
3796
+ "button",
3797
+ {
3798
+ onClick: onClose,
3799
+ className: "text-gray-400 hover:text-gray-600 text-xl",
3800
+ "aria-label": "Close modal",
3801
+ children: "\u2715"
3802
+ }
3803
+ )
3804
+ ] }),
3805
+ /* @__PURE__ */ jsx22("div", { className: "w-full max-h-[80vh] overflow-y-auto mb-4", children })
3806
+ ] }) });
3807
+ };
3808
+ var Modals_default2 = Modal2;
3809
+ var InputField2 = ({
3810
+ label,
3811
+ name,
3812
+ type = "text",
3813
+ value,
3814
+ placeholder,
3815
+ required = false,
3816
+ disabled = false,
3817
+ error,
3818
+ onChange,
3819
+ onBlur
3820
+ }) => {
3821
+ return /* @__PURE__ */ jsxs22("div", { className: "flex flex-col gap-1 w-full", children: [
3822
+ label && /* @__PURE__ */ jsxs22("label", { htmlFor: name, className: "block text-gray-700 text-sm font-medium mb-2", children: [
3823
+ label,
3824
+ " ",
3825
+ required && /* @__PURE__ */ jsx32("span", { className: "text-red-500", children: "*" })
3826
+ ] }),
3827
+ /* @__PURE__ */ jsx32(
3828
+ "input",
3829
+ {
3830
+ id: name,
3831
+ name,
3832
+ type,
3833
+ value,
3834
+ placeholder,
3835
+ required,
3836
+ disabled,
3837
+ onChange,
3838
+ onBlur,
3839
+ className: `w-full px-3 py-2 border border-[#D9D9D9] focus:ring-2 focus:ring-[#6A8A82]/20
3840
+ ${error ? "border-red-500" : "border-gray-300"}
3841
+ ${disabled ? "bg-gray-100 cursor-not-allowed" : ""}
3842
+ `
3843
+ }
3844
+ ),
3845
+ error && /* @__PURE__ */ jsx32("p", { className: "text-xs text-red-500", children: error })
3846
+ ] });
3847
+ };
3848
+ var TextInput2 = (props) => {
3849
+ return /* @__PURE__ */ jsx32(InputField2, { ...props, type: "text" });
3850
+ };
3851
+ var ThemeContext2 = createContext5(void 0);
3852
+ var ADDRESS_IP2 = "localhost:8000";
3853
+ var ADDRESS_IP_URL2 = `http://${ADDRESS_IP2}/`;
3854
+ var API_URL2 = `${ADDRESS_IP_URL2}api`;
3855
+ var API_BASE_URL3 = `${API_URL2}/core/auth/`;
3856
+ var SessionContext2 = createContext22(void 0);
3857
+ var API_BASE_URL22 = `${API_URL2}/core/auth/`;
3858
+ var USERS_API_URL2 = `${API_URL2}/core/users/`;
3859
+ var ToastContext2 = createContext32(void 0);
3860
+ var APPROVAL_API_URL2 = `${API_URL2}/approvals/cases/`;
3861
+ var AlertContext2 = createContext42(void 0);
3862
+
3863
+ // src/components/common/FormVendor.tsx
3864
+ import { useState as useState13 } from "react";
3865
+ import { jsx as jsx18, jsxs as jsxs14 } from "react/jsx-runtime";
3866
+ var MinimalVendorForm = ({
3867
+ isOpen,
3868
+ onClose,
3869
+ object,
3870
+ from = "procurement",
3871
+ refresh = () => {
3872
+ }
3873
+ }) => {
3874
+ const [formData, setFormData] = useState13(object || {
3875
+ from_module: from ?? null,
3876
+ legal_name: "",
3877
+ trading_name: ""
3878
+ });
3879
+ const [errors, setErrors] = useState13({});
3880
+ const [loading, setLoading] = useState13(false);
3881
+ const { token } = useSession();
3882
+ const { success, error: showError } = useToast();
3883
+ const handleInputChange = (e) => {
3884
+ const { name, value } = e.target;
3885
+ setFormData((prev) => ({ ...prev, [name]: value }));
3886
+ if (errors[name]) {
3887
+ setErrors((prev) => ({ ...prev, [name]: void 0 }));
3888
+ }
3889
+ };
3890
+ const handleSelectChange = (e) => {
3891
+ const { name, value } = e.target;
3892
+ setFormData((prev) => ({ ...prev, [name]: value }));
3893
+ };
3894
+ const handleTextareaChange = (e) => {
3895
+ const { name, value } = e.target;
3896
+ setFormData((prev) => ({ ...prev, [name]: value }));
3897
+ };
3898
+ const validateForm = () => {
3899
+ const newErrors = {};
3900
+ if (!formData.legal_name?.trim()) {
3901
+ newErrors.legal_name = "La raison sociale est obligatoire";
3902
+ }
3903
+ if (formData.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(formData.email)) {
3904
+ newErrors.email = "Format d'email invalide";
3905
+ }
3906
+ if (formData.iban && formData.iban.length > 0 && formData.iban.length < 15) {
3907
+ newErrors.iban = "Format IBAN invalide";
3908
+ }
3909
+ setErrors(newErrors);
3910
+ return Object.keys(newErrors).length === 0;
3911
+ };
3912
+ const handleSaveVendor = async (entityData) => {
3913
+ try {
3914
+ if (object && object.id) {
3915
+ await VendorServices.updateVendor(object.id, entityData, token);
3916
+ success("Entit\xE9 modifi\xE9e avec succ\xE8s !");
3917
+ } else {
3918
+ await VendorServices.createVendor(entityData, token);
3919
+ success("Entit\xE9 cr\xE9\xE9e avec succ\xE8s !");
3920
+ }
3921
+ refresh();
3922
+ onClose();
3923
+ } catch (error) {
3924
+ console.error(error);
3925
+ showError("Erreur lors de l'enregistrement de l'entit\xE9");
3926
+ }
3927
+ };
3928
+ const handleSubmit = async (e) => {
3929
+ e.preventDefault();
3930
+ if (!validateForm()) return;
3931
+ setLoading(true);
3932
+ try {
3933
+ await handleSaveVendor(formData);
3934
+ } finally {
3935
+ setLoading(false);
3936
+ }
3937
+ };
3938
+ if (!isOpen) return null;
3939
+ return /* @__PURE__ */ jsx18(
3940
+ Modals_default2,
3941
+ {
3942
+ title: "Ajouter un fournisseur",
3943
+ width: "w-[100%]",
3944
+ description: ``,
3945
+ open: isOpen,
3946
+ onClose,
3947
+ children: /* @__PURE__ */ jsxs14("form", { onSubmit: handleSubmit, className: "p-", children: [
3948
+ /* @__PURE__ */ jsx18("div", { className: "space-y-4", children: /* @__PURE__ */ jsxs14("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
3949
+ /* @__PURE__ */ jsx18(
3950
+ TextInput2,
3951
+ {
3952
+ label: "Raison sociale",
3953
+ name: "legal_name",
3954
+ value: formData.legal_name || "",
3955
+ placeholder: "Nom l\xE9gal de l'entit\xE9",
3956
+ required: true,
3957
+ error: errors.legal_name,
3958
+ onChange: handleInputChange
3959
+ }
3960
+ ),
3961
+ /* @__PURE__ */ jsx18(
3962
+ TextInput2,
3963
+ {
3964
+ label: "Nom commercial",
3965
+ name: "trading_name",
3966
+ value: formData.trading_name || "",
3967
+ placeholder: "Nom commercial (optionnel)",
3968
+ onChange: handleInputChange
3969
+ }
3970
+ )
3971
+ ] }) }),
3972
+ /* @__PURE__ */ jsxs14("div", { className: "flex justify-between pt-6 mt-8", children: [
3973
+ /* @__PURE__ */ jsx18(
3974
+ "button",
3975
+ {
3976
+ type: "button",
3977
+ onClick: onClose,
3978
+ className: "px-6 py-2 border border-gray-300 text-gray-700 rounded-lg hover:bg-gray-50 transition-colors",
3979
+ children: "Annuler"
3980
+ }
3981
+ ),
3982
+ /* @__PURE__ */ jsx18(
3983
+ Buttons_default2,
3984
+ {
3985
+ type: "button",
3986
+ onClick: handleSubmit,
3987
+ disabled: loading,
3988
+ children: loading ? "chargement..." : "Enregistrer l'entit\xE9"
3989
+ }
3990
+ )
3991
+ ] })
3992
+ ] })
3993
+ }
3994
+ );
3995
+ };
3996
+
3997
+ // src/services/DepartmentServices.ts
3998
+ var URI = `${API_URL}/core/departments/`;
3999
+ var DepartmentServices = {
4000
+ create: (data) => FetchApi.post(`${URI}`, data),
4001
+ get: (id) => FetchApi.get(`${URI}${id}/`),
4002
+ list: (params) => FetchApi.get(`${URI}?${new URLSearchParams(params).toString()}`),
4003
+ update: (id, data) => FetchApi.put(`${URI}${id}/`, data),
4004
+ delete: (id) => FetchApi.delete(`${URI}${id}/`)
4005
+ };
4006
+
4007
+ // src/services/ProfitCostsServices.ts
4008
+ var URI2 = `${API_URL}/accounting/profit-or-cost-center/`;
4009
+ var COST_URI = `${API_URL}/accounting/cost-center/`;
4010
+ var CostServices = {
4011
+ create: (data) => FetchApi.post(`${COST_URI}`, data),
4012
+ get: (id) => FetchApi.get(`${COST_URI}${id}/`),
4013
+ list: (params) => FetchApi.get(`${COST_URI}?${new URLSearchParams(params).toString()}`),
4014
+ update: (id, data) => FetchApi.put(`${COST_URI}${id}/`, data),
4015
+ delete: (id) => FetchApi.delete(`${COST_URI}${id}/`)
4016
+ };
4017
+ var PROFIT_URI = `${API_URL}/accounting/profit-center/`;
4018
+
4019
+ // src/components/common/CommonSelect.tsx
4020
+ import { jsx as jsx19, jsxs as jsxs15 } from "react/jsx-runtime";
4021
+ var SelectVendor = ({
4022
+ value,
4023
+ onSelect
4024
+ }) => {
4025
+ const [showModal, setShowModal] = useState14(false);
4026
+ const [selectedVendor, setSelectedVendor] = useState14(null);
4027
+ const { token, activeBusinessEntity } = useSession();
4028
+ const [vendors, setVendors] = useState14(() => {
4029
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4030
+ const cached = sessionStorage.getItem(cacheKey);
4031
+ return cached ? JSON.parse(cached) : [];
4032
+ });
4033
+ const [loadingVendors, setLoadingVendors] = useState14(false);
4034
+ useEffect11(() => {
4035
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4036
+ const cached = sessionStorage.getItem(cacheKey);
4037
+ if (!cached) {
4038
+ loadVendors();
4039
+ } else {
4040
+ setVendors(JSON.parse(cached));
4041
+ }
4042
+ }, [activeBusinessEntity?.id]);
4043
+ const getVendorOptions = () => {
4044
+ return vendors.filter((vendor) => vendor.id !== void 0).map((vendor) => ({
4045
+ value: vendor.id,
4046
+ label: `${vendor.legal_name} [${vendor.trading_name}]`
4047
+ }));
4048
+ };
4049
+ const loadVendors = async () => {
4050
+ if (!token) {
4051
+ console.error("Vous devez etre connect\xE9 pour voir les organisations");
4052
+ return;
4053
+ }
4054
+ try {
4055
+ setLoadingVendors(true);
4056
+ const result = await VendorServices.getVendors(token, { business_entity_id: activeBusinessEntity?.id });
4057
+ setVendors(result.data);
4058
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4059
+ sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
4060
+ } catch (error) {
4061
+ console.error(error);
4062
+ } finally {
4063
+ setLoadingVendors(false);
4064
+ }
4065
+ };
4066
+ const handleRefresh = () => {
4067
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4068
+ sessionStorage.removeItem(cacheKey);
4069
+ loadVendors();
4070
+ };
4071
+ return /* @__PURE__ */ jsxs15("div", { children: [
4072
+ /* @__PURE__ */ jsx19("div", { className: "flex justify-between ", children: /* @__PURE__ */ jsx19("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "Ajouter un fournisseur" }) }),
4073
+ /* @__PURE__ */ jsx19(
4074
+ SearchableSelect,
4075
+ {
4076
+ value,
4077
+ options: getVendorOptions(),
4078
+ placeholder: "S\xE9lectionner un fournisseur...",
4079
+ searchPlaceholder: "Rechercher...",
4080
+ onSelect,
4081
+ disabled: loadingVendors,
4082
+ refresh: handleRefresh,
4083
+ addElement: () => {
4084
+ setShowModal(true);
4085
+ }
4086
+ },
4087
+ "fourni" + value
4088
+ ),
4089
+ loadingVendors && /* @__PURE__ */ jsx19("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des fournisseurs..." }),
4090
+ showModal && /* @__PURE__ */ jsx19(
4091
+ MinimalVendorForm,
4092
+ {
4093
+ object: selectedVendor,
4094
+ isOpen: showModal,
4095
+ onClose: () => setShowModal(false),
4096
+ refresh: handleRefresh
4097
+ },
4098
+ `entity-modal-${selectedVendor?.id}`
4099
+ )
4100
+ ] });
4101
+ };
4102
+ var SelectUser = ({
4103
+ value,
4104
+ onSelect
4105
+ }) => {
4106
+ const { token, activeBusinessEntity } = useSession();
4107
+ const [users, setUsers] = useState14(() => {
4108
+ const cacheKey = `users_cache_${activeBusinessEntity?.id || "default"}`;
4109
+ const cached = sessionStorage.getItem(cacheKey);
4110
+ return cached ? JSON.parse(cached) : [];
4111
+ });
4112
+ const [loading, setLoading] = useState14(false);
4113
+ useEffect11(() => {
4114
+ const cacheKey = `users_cache_${activeBusinessEntity?.id || "default"}`;
4115
+ const cached = sessionStorage.getItem(cacheKey);
4116
+ if (!cached) {
4117
+ loadUsers();
4118
+ } else {
4119
+ setUsers(JSON.parse(cached));
4120
+ }
4121
+ }, [activeBusinessEntity?.id]);
4122
+ const loadUsers = async () => {
4123
+ if (!token) return;
4124
+ try {
4125
+ setLoading(true);
4126
+ const result = await UserServices.getUsers(token);
4127
+ setUsers(result.data);
4128
+ } catch (error) {
4129
+ console.error(error);
4130
+ } finally {
4131
+ setLoading(false);
4132
+ }
4133
+ };
4134
+ const handleRefresh = () => {
4135
+ const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
4136
+ sessionStorage.removeItem(cacheKey);
4137
+ loadUsers();
4138
+ };
4139
+ const userFilterFunction = (option, searchTerm) => {
4140
+ const user = users.find((u) => u.id === option.value);
4141
+ if (!user) return false;
4142
+ const searchLower = searchTerm.toLowerCase();
4143
+ return user.first_name?.toLowerCase().includes(searchLower) || user.last_name?.toLowerCase().includes(searchLower) || user.email?.toLowerCase().includes(searchLower);
4144
+ };
4145
+ const getUserOptions = () => {
4146
+ return users.map((user) => ({
4147
+ value: user.id,
4148
+ label: `${user.first_name} ${user.last_name}`,
4149
+ content: /* @__PURE__ */ jsx19("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ jsxs15("div", { className: "flex-1", children: [
4150
+ /* @__PURE__ */ jsxs15("div", { className: "font-medium text-gray-900", children: [
4151
+ user.first_name,
4152
+ " ",
4153
+ user.last_name
4154
+ ] }),
4155
+ /* @__PURE__ */ jsx19("div", { className: "text-sm text-gray-500", children: user.email })
4156
+ ] }) })
4157
+ }));
4158
+ };
4159
+ return /* @__PURE__ */ jsxs15("div", { children: [
4160
+ /* @__PURE__ */ jsx19("div", { className: "flex justify-between ", children: /* @__PURE__ */ jsx19("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner un utilisateur" }) }),
4161
+ /* @__PURE__ */ jsx19(
4162
+ SearchableSelect,
4163
+ {
4164
+ value,
4165
+ options: getUserOptions(),
4166
+ placeholder: "S\xE9lectionner un utilisateur ...",
4167
+ searchPlaceholder: "Rechercher...",
4168
+ onSelect,
4169
+ disabled: loading,
4170
+ refresh: handleRefresh
4171
+ },
4172
+ "user" + value
4173
+ ),
4174
+ loading && /* @__PURE__ */ jsx19("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des utilisateurs..." })
4175
+ ] });
4176
+ };
4177
+ var SelectDepartment = ({
4178
+ value,
4179
+ onSelect
4180
+ }) => {
4181
+ const { token, activeBusinessEntity } = useSession();
4182
+ const [departments, setDepartments] = useState14(() => {
4183
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4184
+ const cached = sessionStorage.getItem(cacheKey);
4185
+ return cached ? JSON.parse(cached) : [];
4186
+ });
4187
+ const [loading, setLoading] = useState14(false);
4188
+ useEffect11(() => {
4189
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4190
+ const cached = sessionStorage.getItem(cacheKey);
4191
+ if (!cached) {
4192
+ loadDepartments();
4193
+ } else {
4194
+ setDepartments(JSON.parse(cached));
4195
+ }
4196
+ }, [activeBusinessEntity?.id]);
4197
+ const loadDepartments = async () => {
4198
+ if (!token) return;
4199
+ try {
4200
+ setLoading(true);
4201
+ const result = await DepartmentServices.list({ business_entity_id: activeBusinessEntity?.id });
4202
+ if (result.success) {
4203
+ setDepartments(result.data);
4204
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4205
+ sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
4206
+ }
4207
+ } catch (error) {
4208
+ console.error(error);
4209
+ } finally {
4210
+ setLoading(false);
4211
+ }
4212
+ };
4213
+ const handleRefresh = () => {
4214
+ const cacheKey = `departments_cache_${activeBusinessEntity?.id || "default"}`;
4215
+ sessionStorage.removeItem(cacheKey);
4216
+ loadDepartments();
4217
+ };
4218
+ const getDepartmentOptions = () => {
4219
+ return departments.map((dept) => ({
4220
+ value: dept.id,
4221
+ label: dept.name
4222
+ }));
4223
+ };
4224
+ return /* @__PURE__ */ jsxs15("div", { children: [
4225
+ /* @__PURE__ */ jsx19("div", { className: "flex justify-between ", children: /* @__PURE__ */ jsx19("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner un d\xE9partement" }) }),
4226
+ /* @__PURE__ */ jsx19(
4227
+ SearchableSelect,
4228
+ {
4229
+ value,
4230
+ options: getDepartmentOptions(),
4231
+ placeholder: "S\xE9lectionner un d\xE9partement ...",
4232
+ searchPlaceholder: "Rechercher...",
4233
+ onSelect,
4234
+ disabled: loading,
4235
+ refresh: handleRefresh
4236
+ },
4237
+ "dept" + value
4238
+ ),
4239
+ loading && /* @__PURE__ */ jsx19("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des d\xE9partements..." })
4240
+ ] });
4241
+ };
4242
+ var SelectCostCenter = ({
4243
+ value,
4244
+ onSelect
4245
+ }) => {
4246
+ const { token, activeBusinessEntity } = useSession();
4247
+ const [costCenters, setCostCenters] = useState14(() => {
4248
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4249
+ const cached = sessionStorage.getItem(cacheKey);
4250
+ return cached ? JSON.parse(cached) : [];
4251
+ });
4252
+ const [loading, setLoading] = useState14(false);
4253
+ useEffect11(() => {
4254
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4255
+ const cached = sessionStorage.getItem(cacheKey);
4256
+ if (!cached) {
4257
+ loadCostCenters();
4258
+ } else {
4259
+ setCostCenters(JSON.parse(cached));
4260
+ }
4261
+ }, [activeBusinessEntity?.id]);
4262
+ const loadCostCenters = async () => {
4263
+ if (!token) return;
4264
+ try {
4265
+ setLoading(true);
4266
+ const result = await CostServices.list({ business_entity_id: activeBusinessEntity?.id });
4267
+ if (result.success) {
4268
+ setCostCenters(result.data);
4269
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4270
+ sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
4271
+ }
4272
+ } catch (error) {
4273
+ console.error(error);
4274
+ } finally {
4275
+ setLoading(false);
4276
+ }
4277
+ };
4278
+ const handleRefresh = () => {
4279
+ const cacheKey = `cost_centers_cache_${activeBusinessEntity?.id || "default"}`;
4280
+ sessionStorage.removeItem(cacheKey);
4281
+ loadCostCenters();
4282
+ };
4283
+ const getCostCenterOptions = () => {
4284
+ return costCenters.map((center) => ({
4285
+ value: center.id,
4286
+ label: `${center.code ? `[${center.code}] ` : ""}${center.name}`,
4287
+ content: /* @__PURE__ */ jsx19("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ jsxs15("div", { className: "flex-1", children: [
4288
+ /* @__PURE__ */ jsx19("div", { className: "font-medium text-gray-900", children: center.name }),
4289
+ center.code && /* @__PURE__ */ jsxs15("div", { className: "text-sm text-gray-500", children: [
4290
+ "Code: ",
4291
+ center.code
4292
+ ] })
4293
+ ] }) })
4294
+ }));
4295
+ };
4296
+ return /* @__PURE__ */ jsxs15("div", { children: [
4297
+ /* @__PURE__ */ jsx19("div", { className: "flex justify-between ", children: /* @__PURE__ */ jsx19("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner un centre de co\xFBt" }) }),
4298
+ /* @__PURE__ */ jsx19(
4299
+ SearchableSelect,
4300
+ {
4301
+ value,
4302
+ options: getCostCenterOptions(),
4303
+ placeholder: "S\xE9lectionner un centre de co\xFBt ...",
4304
+ searchPlaceholder: "Rechercher...",
4305
+ onSelect,
4306
+ disabled: loading,
4307
+ refresh: handleRefresh
4308
+ },
4309
+ "cost" + value
4310
+ ),
4311
+ loading && /* @__PURE__ */ jsx19("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des centres de co\xFBt..." })
4312
+ ] });
4313
+ };
3663
4314
  export {
3664
4315
  Alert_default as Alert,
3665
4316
  AlertProvider,
@@ -3678,7 +4329,11 @@ export {
3678
4329
  Buttons_default as PrimaryButton,
3679
4330
  ModernDoubleSidebarLayout_default as RewiseLayout,
3680
4331
  SecondaryButton,
4332
+ SelectCostCenter,
4333
+ SelectDepartment,
3681
4334
  SelectInput,
4335
+ SelectUser,
4336
+ SelectVendor,
3682
4337
  SessionProvider,
3683
4338
  TextInput,
3684
4339
  ThemeContext_default as ThemeProvider,