ptechcore_ui 1.0.27 → 1.0.30
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 +576 -40
- package/dist/index.d.cts +213 -1
- package/dist/index.d.ts +213 -1
- package/dist/index.js +562 -40
- package/package.json +58 -57
package/dist/index.cjs
CHANGED
|
@@ -39,7 +39,10 @@ __export(index_exports, {
|
|
|
39
39
|
AuthServices: () => AuthServices,
|
|
40
40
|
CHOICES: () => Choices_default,
|
|
41
41
|
CountrySelector: () => CountrySelector,
|
|
42
|
+
DataTable: () => DataTable,
|
|
42
43
|
DateInput: () => DateInput,
|
|
44
|
+
DocumentFooter: () => DocumentFooter,
|
|
45
|
+
DocumentHeader: () => DocumentHeader,
|
|
43
46
|
EntityFileManager: () => EntityFileManager,
|
|
44
47
|
FDrawer: () => FDrawer,
|
|
45
48
|
FetchApi: () => FetchApi,
|
|
@@ -47,33 +50,44 @@ __export(index_exports, {
|
|
|
47
50
|
FileManager: () => FileManager,
|
|
48
51
|
FileManagerProvider: () => FileManagerProvider,
|
|
49
52
|
ForeignCurrencySelector: () => ForeignCurrencySelector,
|
|
53
|
+
InfoBox: () => InfoBox,
|
|
50
54
|
InputField: () => InputField,
|
|
51
55
|
InvoiceTypeSelector: () => InvoiceTypeSelector,
|
|
52
56
|
LegalFormSelector: () => LegalFormSelector,
|
|
53
57
|
Modal: () => Modals_default,
|
|
54
58
|
NumberInput: () => NumberInput,
|
|
59
|
+
PRINT_GREEN: () => PRINT_GREEN,
|
|
55
60
|
Pages: () => Pages_default,
|
|
56
61
|
PaymentMethodSelector: () => PaymentMethodSelector,
|
|
57
62
|
PrimaryButton: () => Buttons_default,
|
|
63
|
+
PrintPreview: () => PrintPreview,
|
|
64
|
+
PrintableDocument: () => PrintableDocument,
|
|
58
65
|
RewiseLayout: () => ModernDoubleSidebarLayout_default,
|
|
59
66
|
SecondaryButton: () => SecondaryButton,
|
|
60
67
|
SelectCostCenter: () => SelectCostCenter,
|
|
61
68
|
SelectDepartment: () => SelectDepartment,
|
|
62
69
|
SelectInput: () => SelectInput,
|
|
70
|
+
SelectUnit: () => SelectUnit,
|
|
63
71
|
SelectUser: () => SelectUser,
|
|
64
72
|
SelectVendor: () => SelectVendor,
|
|
65
73
|
SessionProvider: () => SessionProvider,
|
|
74
|
+
SignatureSection: () => SignatureSection,
|
|
66
75
|
TaxSelector: () => TaxSelector,
|
|
67
76
|
TemplateFNESelector: () => TemplateFNESelector,
|
|
68
77
|
TextInput: () => TextInput,
|
|
69
78
|
ThemeProvider: () => ThemeContext_default,
|
|
70
79
|
ToastContainer: () => Toast_default,
|
|
71
80
|
ToastProvider: () => ToastProvider,
|
|
81
|
+
TotalsSection: () => TotalsSection,
|
|
82
|
+
UnitServices: () => UnitServices,
|
|
72
83
|
UserServices: () => UserServices,
|
|
73
84
|
fileManagerApi: () => fileManagerApi,
|
|
85
|
+
formatCurrency: () => formatCurrency,
|
|
74
86
|
formatDate: () => formatDate,
|
|
87
|
+
formatDateFR: () => formatDateFR,
|
|
75
88
|
formatFileSize: () => formatFileSize,
|
|
76
89
|
getFileIcon: () => getFileIcon,
|
|
90
|
+
numberToWords: () => numberToWords,
|
|
77
91
|
useAlert: () => useAlert,
|
|
78
92
|
useFileManager: () => useFileManager,
|
|
79
93
|
useFileManagerApi: () => useFileManagerApi,
|
|
@@ -95,9 +109,9 @@ var PrimaryButton = ({
|
|
|
95
109
|
{
|
|
96
110
|
type: "submit",
|
|
97
111
|
disabled: loading || props.disabled,
|
|
98
|
-
className: `px-4 py-2 text-sm rounded-lg hover:
|
|
112
|
+
className: `px-4 py-2 text-sm rounded-lg hover:opacity-80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex justify-center items-center ${classname} ${variant === "full" ? "bg-[var(--color-primary)] text-[var(--color-text-inverse)]" : variant === "outline" ? "border border-[var(--color-primary)] text-[var(--color-primary)] bg-transparent" : "bg-transparent text-[var(--color-primary)]"}`,
|
|
99
113
|
...props,
|
|
100
|
-
children: loading ? "
|
|
114
|
+
children: loading ? "Chargement..." : children
|
|
101
115
|
}
|
|
102
116
|
);
|
|
103
117
|
var SecondaryButton = ({
|
|
@@ -110,9 +124,9 @@ var SecondaryButton = ({
|
|
|
110
124
|
{
|
|
111
125
|
type: "button",
|
|
112
126
|
disabled: loading || props.disabled,
|
|
113
|
-
className: `px-4 py-2 rounded-lg hover:
|
|
127
|
+
className: `px-4 py-2 text-sm rounded-lg hover:opacity-80 transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center ${variant === "full" ? "bg-[var(--color-secondary)] text-[var(--color-text-inverse)]" : variant === "outline" ? "border border-[var(--color-secondary)] text-[var(--color-secondary)] bg-transparent" : "bg-transparent text-[var(--color-secondary)]"}`,
|
|
114
128
|
...props,
|
|
115
|
-
children: loading ? "
|
|
129
|
+
children: loading ? "Chargement..." : children
|
|
116
130
|
}
|
|
117
131
|
);
|
|
118
132
|
var Buttons_default = PrimaryButton;
|
|
@@ -120,7 +134,7 @@ var Buttons_default = PrimaryButton;
|
|
|
120
134
|
// src/components/common/Modals.tsx
|
|
121
135
|
var import_react_dom = require("react-dom");
|
|
122
136
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
123
|
-
var Modal = ({ title, description, width = "max-w-md", open, onClose, children }) => {
|
|
137
|
+
var Modal = ({ title, description, width = "max-w-md", minContentHeight, open, onClose, children }) => {
|
|
124
138
|
if (!open) return null;
|
|
125
139
|
const modalContent = /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-[9999]", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: `bg-[var(--color-surface)] rounded-lg p-6 mx-4 w-full ${width}`, children: [
|
|
126
140
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex justify-between items-start mb-6", children: [
|
|
@@ -138,7 +152,14 @@ var Modal = ({ title, description, width = "max-w-md", open, onClose, children }
|
|
|
138
152
|
}
|
|
139
153
|
)
|
|
140
154
|
] }),
|
|
141
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
155
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
156
|
+
"div",
|
|
157
|
+
{
|
|
158
|
+
className: "w-full max-h-[80vh] overflow-y-auto",
|
|
159
|
+
style: minContentHeight ? { minHeight: minContentHeight } : void 0,
|
|
160
|
+
children
|
|
161
|
+
}
|
|
162
|
+
)
|
|
142
163
|
] }) });
|
|
143
164
|
return (0, import_react_dom.createPortal)(modalContent, document.body);
|
|
144
165
|
};
|
|
@@ -160,10 +181,10 @@ var InputField = ({
|
|
|
160
181
|
onBlur
|
|
161
182
|
}) => {
|
|
162
183
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col gap-1 w-full", children: [
|
|
163
|
-
label && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { htmlFor: name, className: "block text-
|
|
184
|
+
label && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("label", { htmlFor: name, className: "block text-[var(--color-text-secondary)] text-sm font-medium mb-2", children: [
|
|
164
185
|
label,
|
|
165
186
|
" ",
|
|
166
|
-
required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-
|
|
187
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[var(--color-error)]", children: "*" })
|
|
167
188
|
] }),
|
|
168
189
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
169
190
|
"input",
|
|
@@ -177,13 +198,15 @@ var InputField = ({
|
|
|
177
198
|
disabled,
|
|
178
199
|
onChange,
|
|
179
200
|
onBlur,
|
|
180
|
-
className: `w-full px-3 py-2 border
|
|
181
|
-
|
|
182
|
-
|
|
201
|
+
className: `w-full px-3 py-2 border rounded-lg text-sm
|
|
202
|
+
bg-[var(--color-surface)] text-[var(--color-text-primary)]
|
|
203
|
+
focus:ring-2 focus:ring-[var(--color-primary)]/20 focus:border-[var(--color-primary)] focus:outline-none
|
|
204
|
+
${error ? "border-[var(--color-error)]" : "border-[var(--color-border)]"}
|
|
205
|
+
${disabled ? "bg-[var(--color-background)] cursor-not-allowed opacity-60" : ""}
|
|
183
206
|
`
|
|
184
207
|
}
|
|
185
208
|
),
|
|
186
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-
|
|
209
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-[var(--color-error)]", children: error })
|
|
187
210
|
] });
|
|
188
211
|
};
|
|
189
212
|
var TextInput = (props) => {
|
|
@@ -213,11 +236,11 @@ var SelectInput = ({
|
|
|
213
236
|
"label",
|
|
214
237
|
{
|
|
215
238
|
htmlFor: name,
|
|
216
|
-
className: "block text-
|
|
239
|
+
className: "block text-[var(--color-text-secondary)] text-sm font-medium mb-2",
|
|
217
240
|
children: [
|
|
218
241
|
label,
|
|
219
242
|
" ",
|
|
220
|
-
required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-
|
|
243
|
+
required && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-[var(--color-error)]", children: "*" })
|
|
221
244
|
]
|
|
222
245
|
}
|
|
223
246
|
),
|
|
@@ -232,9 +255,10 @@ var SelectInput = ({
|
|
|
232
255
|
onChange,
|
|
233
256
|
onBlur,
|
|
234
257
|
className: `w-full px-4 py-2 border rounded-lg text-sm
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
${
|
|
258
|
+
bg-[var(--color-surface)] text-[var(--color-text-primary)]
|
|
259
|
+
focus:outline-none focus:ring-2 focus:ring-[var(--color-primary)]/20 focus:border-[var(--color-primary)]
|
|
260
|
+
${error ? "border-[var(--color-error)]" : "border-[var(--color-border)]"}
|
|
261
|
+
${disabled ? "bg-[var(--color-background)] cursor-not-allowed opacity-60" : ""}
|
|
238
262
|
`,
|
|
239
263
|
children: [
|
|
240
264
|
defaultValue !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value: "", children: typeof defaultValue === "string" ? defaultValue : "S\xE9lectionnez une option" }),
|
|
@@ -242,7 +266,7 @@ var SelectInput = ({
|
|
|
242
266
|
]
|
|
243
267
|
}
|
|
244
268
|
),
|
|
245
|
-
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-
|
|
269
|
+
error && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-[var(--color-error)]", children: error })
|
|
246
270
|
] });
|
|
247
271
|
};
|
|
248
272
|
var addressIpformMedia = "http://localhost:8000/media/";
|
|
@@ -874,6 +898,7 @@ var AuthServices = {
|
|
|
874
898
|
addUser: (payload) => FetchApi.post(`${API_BASE_URL}add-user/`, payload),
|
|
875
899
|
login: (payload) => FetchApi.post(`${API_BASE_URL}login/`, payload),
|
|
876
900
|
getUserInformations: (token) => FetchApi.get(`${API_BASE_URL}user-informations/`, token),
|
|
901
|
+
getUserInformationsByOldId: (id) => FetchApi.get(`${API_BASE_URL}user-informations-by-old-id/${id}/`),
|
|
877
902
|
logout: () => FetchApi.post(`${API_BASE_URL}logout/`)
|
|
878
903
|
};
|
|
879
904
|
|
|
@@ -917,13 +942,31 @@ var SessionProvider = ({ children }) => {
|
|
|
917
942
|
const [isLoading, setIsLoading] = (0, import_react2.useState)(true);
|
|
918
943
|
const [showAuthModal, setShowAuthModal] = (0, import_react2.useState)(false);
|
|
919
944
|
(0, import_react2.useEffect)(() => {
|
|
920
|
-
const
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
945
|
+
const initializeSession = async () => {
|
|
946
|
+
const params = new URLSearchParams(window.location.search);
|
|
947
|
+
const tkn = params.get("tkn");
|
|
948
|
+
if (tkn) {
|
|
949
|
+
localStorage.setItem("token", tkn);
|
|
950
|
+
setToken(tkn);
|
|
951
|
+
window.history.replaceState({}, document.title, window.location.pathname);
|
|
952
|
+
}
|
|
953
|
+
const old_rewise_user_id = params.get("rewise_user_id");
|
|
954
|
+
if (old_rewise_user_id) {
|
|
955
|
+
try {
|
|
956
|
+
const res = await AuthServices.getUserInformationsByOldId(parseInt(old_rewise_user_id));
|
|
957
|
+
const result = res;
|
|
958
|
+
if (result.success === true) {
|
|
959
|
+
setLoggedUser(result.data.user);
|
|
960
|
+
setActiveBusinessEntity(
|
|
961
|
+
result.data.user.centers_access.find((item) => parseInt(String(item.id)) === parseInt(saved_center_id)) || result.data.user.centers_access[0] || null
|
|
962
|
+
);
|
|
963
|
+
}
|
|
964
|
+
} catch (error) {
|
|
965
|
+
console.error("Failed to refresh session:", error);
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
initializeSession();
|
|
927
970
|
}, []);
|
|
928
971
|
const [vendors, setVendors] = (0, import_react2.useState)(() => {
|
|
929
972
|
const cacheKey = `vendors_cache_${activeBusinessEntity?.id || "default"}`;
|
|
@@ -971,6 +1014,21 @@ var SessionProvider = ({ children }) => {
|
|
|
971
1014
|
localStorage.removeItem("token");
|
|
972
1015
|
setToken(null);
|
|
973
1016
|
};
|
|
1017
|
+
const refreshSession = async () => {
|
|
1018
|
+
if (!token) return;
|
|
1019
|
+
try {
|
|
1020
|
+
const res = await AuthServices.getUserInformations(token);
|
|
1021
|
+
const result = res;
|
|
1022
|
+
if (result.success === true) {
|
|
1023
|
+
setLoggedUser(result.data.user);
|
|
1024
|
+
setActiveBusinessEntity(
|
|
1025
|
+
result.data.user.centers_access.find((item) => parseInt(String(item.id)) === parseInt(saved_center_id)) || result.data.user.centers_access[0] || null
|
|
1026
|
+
);
|
|
1027
|
+
}
|
|
1028
|
+
} catch (error) {
|
|
1029
|
+
console.error("Failed to refresh session:", error);
|
|
1030
|
+
}
|
|
1031
|
+
};
|
|
974
1032
|
(0, import_react2.useEffect)(() => {
|
|
975
1033
|
if (token) {
|
|
976
1034
|
AuthServices.getUserInformations(token).then((res) => {
|
|
@@ -1003,6 +1061,7 @@ var SessionProvider = ({ children }) => {
|
|
|
1003
1061
|
logout,
|
|
1004
1062
|
showAuthModal,
|
|
1005
1063
|
setShowAuthModal,
|
|
1064
|
+
refreshSession,
|
|
1006
1065
|
vendors,
|
|
1007
1066
|
setVendors,
|
|
1008
1067
|
loadingVendors,
|
|
@@ -1077,16 +1136,17 @@ var ToastProvider = ({ children }) => {
|
|
|
1077
1136
|
const addToast = (0, import_react3.useCallback)((toast) => {
|
|
1078
1137
|
const id = generateId();
|
|
1079
1138
|
const defaultDuration = toast.type === "error" ? 7e3 : 3e3;
|
|
1139
|
+
const duration = toast.duration ?? defaultDuration;
|
|
1080
1140
|
const newToast = {
|
|
1141
|
+
...toast,
|
|
1081
1142
|
id,
|
|
1082
|
-
duration
|
|
1083
|
-
...toast
|
|
1143
|
+
duration
|
|
1084
1144
|
};
|
|
1085
1145
|
setToasts((prev) => [...prev, newToast]);
|
|
1086
|
-
if (
|
|
1146
|
+
if (duration > 0) {
|
|
1087
1147
|
setTimeout(() => {
|
|
1088
|
-
|
|
1089
|
-
},
|
|
1148
|
+
setToasts((prev) => prev.filter((t) => t.id !== id));
|
|
1149
|
+
}, duration);
|
|
1090
1150
|
}
|
|
1091
1151
|
}, []);
|
|
1092
1152
|
const removeToast = (0, import_react3.useCallback)((id) => {
|
|
@@ -3473,6 +3533,16 @@ var Pages = ({
|
|
|
3473
3533
|
};
|
|
3474
3534
|
var Pages_default = Pages;
|
|
3475
3535
|
|
|
3536
|
+
// src/services/UnitServices.ts
|
|
3537
|
+
var URI = `${API_URL}/crm/units/`;
|
|
3538
|
+
var UnitServices = {
|
|
3539
|
+
create: (data) => FetchApi.post(`${URI}`, data),
|
|
3540
|
+
get: (id) => FetchApi.get(`${URI}${id}/`),
|
|
3541
|
+
list: (params) => FetchApi.get(`${URI}?${new URLSearchParams(params).toString()}`),
|
|
3542
|
+
update: (id, data) => FetchApi.put(`${URI}${id}/`, data),
|
|
3543
|
+
delete: (id) => FetchApi.delete(`${URI}${id}/`)
|
|
3544
|
+
};
|
|
3545
|
+
|
|
3476
3546
|
// src/components/common/FDrawer.tsx
|
|
3477
3547
|
var import_react8 = __toESM(require("react"), 1);
|
|
3478
3548
|
var import_react_router_dom4 = require("react-router-dom");
|
|
@@ -5354,7 +5424,7 @@ var ApprovalWorkflow = ({
|
|
|
5354
5424
|
if (CustomBtn) {
|
|
5355
5425
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
|
|
5356
5426
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CustomBtn, { onClick: open_modal }),
|
|
5357
|
-
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Modals_default, { open: isOpen, onClose: close_modal, title, children: formulaire() })
|
|
5427
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(Modals_default, { open: isOpen, onClose: close_modal, title, width: "max-w-lg", children: formulaire() })
|
|
5358
5428
|
] });
|
|
5359
5429
|
}
|
|
5360
5430
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_jsx_runtime14.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
@@ -5552,7 +5622,7 @@ var AddStageButton = ({
|
|
|
5552
5622
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
|
|
5553
5623
|
Modals_default,
|
|
5554
5624
|
{
|
|
5555
|
-
width: "",
|
|
5625
|
+
width: "max-w-lg",
|
|
5556
5626
|
title: "Ajouter une personne",
|
|
5557
5627
|
description: "S\xE9lectionnez un utilisateur interne ou ajoutez un validateur externe",
|
|
5558
5628
|
open: showModal,
|
|
@@ -5871,7 +5941,7 @@ var MinimalVendorForm = ({
|
|
|
5871
5941
|
Modals_default,
|
|
5872
5942
|
{
|
|
5873
5943
|
title: "Ajouter un fournisseur",
|
|
5874
|
-
width: "w-
|
|
5944
|
+
width: "max-w-2xl",
|
|
5875
5945
|
description: ``,
|
|
5876
5946
|
open: isOpen,
|
|
5877
5947
|
onClose,
|
|
@@ -5926,17 +5996,17 @@ var MinimalVendorForm = ({
|
|
|
5926
5996
|
};
|
|
5927
5997
|
|
|
5928
5998
|
// src/services/DepartmentServices.ts
|
|
5929
|
-
var
|
|
5999
|
+
var URI2 = `${API_URL}/core/departments/`;
|
|
5930
6000
|
var DepartmentServices = {
|
|
5931
|
-
create: (data) => FetchApi.post(`${
|
|
5932
|
-
get: (id) => FetchApi.get(`${
|
|
5933
|
-
list: (params) => FetchApi.get(`${
|
|
5934
|
-
update: (id, data) => FetchApi.put(`${
|
|
5935
|
-
delete: (id) => FetchApi.delete(`${
|
|
6001
|
+
create: (data) => FetchApi.post(`${URI2}`, data),
|
|
6002
|
+
get: (id) => FetchApi.get(`${URI2}${id}/`),
|
|
6003
|
+
list: (params) => FetchApi.get(`${URI2}?${new URLSearchParams(params).toString()}`),
|
|
6004
|
+
update: (id, data) => FetchApi.put(`${URI2}${id}/`, data),
|
|
6005
|
+
delete: (id) => FetchApi.delete(`${URI2}${id}/`)
|
|
5936
6006
|
};
|
|
5937
6007
|
|
|
5938
6008
|
// src/services/ProfitCostsServices.ts
|
|
5939
|
-
var
|
|
6009
|
+
var URI3 = `${API_URL}/accounting/profit-or-cost-center/`;
|
|
5940
6010
|
var COST_URI = `${API_URL}/accounting/cost-center/`;
|
|
5941
6011
|
var CostServices = {
|
|
5942
6012
|
create: (data) => FetchApi.post(`${COST_URI}`, data),
|
|
@@ -6243,6 +6313,80 @@ var SelectCostCenter = ({
|
|
|
6243
6313
|
loading && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des centres de co\xFBt..." })
|
|
6244
6314
|
] });
|
|
6245
6315
|
};
|
|
6316
|
+
var SelectUnit = ({
|
|
6317
|
+
value,
|
|
6318
|
+
onSelect
|
|
6319
|
+
}) => {
|
|
6320
|
+
const { token, activeBusinessEntity } = useSession();
|
|
6321
|
+
const [units, setUnits] = (0, import_react13.useState)(() => {
|
|
6322
|
+
const cacheKey = `units_cache_${activeBusinessEntity?.id || "default"}`;
|
|
6323
|
+
const cached = sessionStorage.getItem(cacheKey);
|
|
6324
|
+
return cached ? JSON.parse(cached) : [];
|
|
6325
|
+
});
|
|
6326
|
+
const [loading, setLoading] = (0, import_react13.useState)(false);
|
|
6327
|
+
(0, import_react13.useEffect)(() => {
|
|
6328
|
+
const cacheKey = `units_cache_${activeBusinessEntity?.id || "default"}`;
|
|
6329
|
+
const cached = sessionStorage.getItem(cacheKey);
|
|
6330
|
+
if (!cached) {
|
|
6331
|
+
loadUnits();
|
|
6332
|
+
} else {
|
|
6333
|
+
setUnits(JSON.parse(cached));
|
|
6334
|
+
}
|
|
6335
|
+
}, [activeBusinessEntity?.id]);
|
|
6336
|
+
const loadUnits = async () => {
|
|
6337
|
+
if (!token) return;
|
|
6338
|
+
try {
|
|
6339
|
+
setLoading(true);
|
|
6340
|
+
const result = await UnitServices.list({ business_entity_id: activeBusinessEntity?.id });
|
|
6341
|
+
if (result.success) {
|
|
6342
|
+
setUnits(result.data);
|
|
6343
|
+
const cacheKey = `units_cache_${activeBusinessEntity?.id || "default"}`;
|
|
6344
|
+
sessionStorage.setItem(cacheKey, JSON.stringify(result.data));
|
|
6345
|
+
}
|
|
6346
|
+
} catch (error) {
|
|
6347
|
+
console.error(error);
|
|
6348
|
+
} finally {
|
|
6349
|
+
setLoading(false);
|
|
6350
|
+
}
|
|
6351
|
+
};
|
|
6352
|
+
const handleRefresh = () => {
|
|
6353
|
+
const cacheKey = `units_cache_${activeBusinessEntity?.id || "default"}`;
|
|
6354
|
+
sessionStorage.removeItem(cacheKey);
|
|
6355
|
+
loadUnits();
|
|
6356
|
+
};
|
|
6357
|
+
const getUnitOptions = () => {
|
|
6358
|
+
return units.map((unit) => ({
|
|
6359
|
+
value: unit.id,
|
|
6360
|
+
label: `${unit.code ? `[${unit.code}] ` : ""}${unit.name || "Sans nom"}`,
|
|
6361
|
+
object: unit,
|
|
6362
|
+
content: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex items-center space-x-3", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex-1", children: [
|
|
6363
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "font-medium text-gray-900", children: unit.name || "Sans nom" }),
|
|
6364
|
+
unit.code && /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "text-sm text-gray-500", children: [
|
|
6365
|
+
"Code: ",
|
|
6366
|
+
unit.code
|
|
6367
|
+
] }),
|
|
6368
|
+
unit.location && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "text-xs text-gray-400", children: unit.location })
|
|
6369
|
+
] }) })
|
|
6370
|
+
}));
|
|
6371
|
+
};
|
|
6372
|
+
return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { children: [
|
|
6373
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)("div", { className: "flex justify-between ", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("label", { className: "block text-sm font-medium text-gray-700 mb-2", children: "S\xE9lectionner une unit\xE9" }) }),
|
|
6374
|
+
/* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
|
|
6375
|
+
SearchableSelect,
|
|
6376
|
+
{
|
|
6377
|
+
value,
|
|
6378
|
+
options: getUnitOptions(),
|
|
6379
|
+
placeholder: "S\xE9lectionner une unit\xE9 ...",
|
|
6380
|
+
searchPlaceholder: "Rechercher...",
|
|
6381
|
+
onSelect,
|
|
6382
|
+
disabled: loading,
|
|
6383
|
+
refresh: handleRefresh
|
|
6384
|
+
},
|
|
6385
|
+
"unit" + value
|
|
6386
|
+
),
|
|
6387
|
+
loading && /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("p", { className: "text-sm text-gray-500 mt-2", children: "Chargement des unit\xE9s..." })
|
|
6388
|
+
] });
|
|
6389
|
+
};
|
|
6246
6390
|
|
|
6247
6391
|
// src/components/common/Choices.tsx
|
|
6248
6392
|
var import_jsx_runtime19 = require("react/jsx-runtime");
|
|
@@ -8254,6 +8398,384 @@ var EntityFileManager = ({
|
|
|
8254
8398
|
}
|
|
8255
8399
|
) });
|
|
8256
8400
|
};
|
|
8401
|
+
|
|
8402
|
+
// src/components/common/PrintPreview.tsx
|
|
8403
|
+
var import_react23 = __toESM(require("react"), 1);
|
|
8404
|
+
var import_react_to_print = require("react-to-print");
|
|
8405
|
+
var import_lucide_react18 = require("lucide-react");
|
|
8406
|
+
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
8407
|
+
var PrintableDocument = ({
|
|
8408
|
+
children,
|
|
8409
|
+
className = "",
|
|
8410
|
+
style = {}
|
|
8411
|
+
}) => {
|
|
8412
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8413
|
+
"div",
|
|
8414
|
+
{
|
|
8415
|
+
className: `bg-white text-gray-900 ${className}`,
|
|
8416
|
+
style: {
|
|
8417
|
+
fontFamily: "Arial, sans-serif",
|
|
8418
|
+
fontSize: "11px",
|
|
8419
|
+
...style
|
|
8420
|
+
},
|
|
8421
|
+
children
|
|
8422
|
+
}
|
|
8423
|
+
);
|
|
8424
|
+
};
|
|
8425
|
+
var PrintPreview = ({
|
|
8426
|
+
children,
|
|
8427
|
+
isOpen,
|
|
8428
|
+
onClose,
|
|
8429
|
+
title = "Aper\xE7u avant impression",
|
|
8430
|
+
documentName = "document",
|
|
8431
|
+
pageWidth = "210mm",
|
|
8432
|
+
pageMinHeight = "297mm",
|
|
8433
|
+
orientation = "portrait",
|
|
8434
|
+
onAfterPrint,
|
|
8435
|
+
onBeforePrint
|
|
8436
|
+
}) => {
|
|
8437
|
+
const printRef = (0, import_react23.useRef)(null);
|
|
8438
|
+
const [zoom, setZoom] = import_react23.default.useState(100);
|
|
8439
|
+
const handlePrint = (0, import_react_to_print.useReactToPrint)({
|
|
8440
|
+
contentRef: printRef,
|
|
8441
|
+
documentTitle: documentName,
|
|
8442
|
+
onAfterPrint: () => {
|
|
8443
|
+
onAfterPrint?.();
|
|
8444
|
+
},
|
|
8445
|
+
onBeforePrint
|
|
8446
|
+
});
|
|
8447
|
+
const handleZoomIn = () => {
|
|
8448
|
+
setZoom((prev) => Math.min(prev + 10, 150));
|
|
8449
|
+
};
|
|
8450
|
+
const handleZoomOut = () => {
|
|
8451
|
+
setZoom((prev) => Math.max(prev - 10, 50));
|
|
8452
|
+
};
|
|
8453
|
+
if (!isOpen) return null;
|
|
8454
|
+
const pageStyles = {
|
|
8455
|
+
width: orientation === "portrait" ? pageWidth : pageMinHeight,
|
|
8456
|
+
minHeight: orientation === "portrait" ? pageMinHeight : pageWidth,
|
|
8457
|
+
transform: `scale(${zoom / 100})`,
|
|
8458
|
+
transformOrigin: "top center",
|
|
8459
|
+
transition: "transform 0.2s ease"
|
|
8460
|
+
};
|
|
8461
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "fixed inset-0 z-50 overflow-hidden print:hidden", children: [
|
|
8462
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8463
|
+
"div",
|
|
8464
|
+
{
|
|
8465
|
+
className: "absolute inset-0 bg-black/50 backdrop-blur-sm",
|
|
8466
|
+
onClick: onClose
|
|
8467
|
+
}
|
|
8468
|
+
),
|
|
8469
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "relative h-full flex flex-col", children: [
|
|
8470
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "bg-white border-b shadow-sm px-6 py-3 flex items-center justify-between z-10", children: [
|
|
8471
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("h3", { className: "text-lg font-semibold text-gray-900", children: title }),
|
|
8472
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-3", children: [
|
|
8473
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-1 bg-gray-100 rounded-lg px-2 py-1", children: [
|
|
8474
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8475
|
+
"button",
|
|
8476
|
+
{
|
|
8477
|
+
onClick: handleZoomOut,
|
|
8478
|
+
className: "p-1 hover:bg-gray-200 rounded transition-colors",
|
|
8479
|
+
title: "Zoom arri\xE8re",
|
|
8480
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react18.ZoomOut, { className: "w-4 h-4 text-gray-600" })
|
|
8481
|
+
}
|
|
8482
|
+
),
|
|
8483
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("span", { className: "text-sm text-gray-600 min-w-[3rem] text-center", children: [
|
|
8484
|
+
zoom,
|
|
8485
|
+
"%"
|
|
8486
|
+
] }),
|
|
8487
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8488
|
+
"button",
|
|
8489
|
+
{
|
|
8490
|
+
onClick: handleZoomIn,
|
|
8491
|
+
className: "p-1 hover:bg-gray-200 rounded transition-colors",
|
|
8492
|
+
title: "Zoom avant",
|
|
8493
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react18.ZoomIn, { className: "w-4 h-4 text-gray-600" })
|
|
8494
|
+
}
|
|
8495
|
+
)
|
|
8496
|
+
] }),
|
|
8497
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
8498
|
+
"button",
|
|
8499
|
+
{
|
|
8500
|
+
onClick: () => handlePrint(),
|
|
8501
|
+
className: "px-4 py-2 bg-blue-600 text-white text-sm font-medium rounded-lg hover:bg-blue-700 transition-colors flex items-center gap-2",
|
|
8502
|
+
children: [
|
|
8503
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react18.Printer, { className: "w-4 h-4" }),
|
|
8504
|
+
"Imprimer"
|
|
8505
|
+
]
|
|
8506
|
+
}
|
|
8507
|
+
),
|
|
8508
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
8509
|
+
"button",
|
|
8510
|
+
{
|
|
8511
|
+
onClick: () => handlePrint(),
|
|
8512
|
+
className: "px-4 py-2 bg-green-600 text-white text-sm font-medium rounded-lg hover:bg-green-700 transition-colors flex items-center gap-2",
|
|
8513
|
+
children: [
|
|
8514
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react18.Download, { className: "w-4 h-4" }),
|
|
8515
|
+
"PDF"
|
|
8516
|
+
]
|
|
8517
|
+
}
|
|
8518
|
+
),
|
|
8519
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8520
|
+
"button",
|
|
8521
|
+
{
|
|
8522
|
+
onClick: onClose,
|
|
8523
|
+
className: "p-2 hover:bg-gray-100 rounded-full transition-colors",
|
|
8524
|
+
title: "Fermer",
|
|
8525
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react18.X, { className: "w-5 h-5 text-gray-500" })
|
|
8526
|
+
}
|
|
8527
|
+
)
|
|
8528
|
+
] })
|
|
8529
|
+
] }),
|
|
8530
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex-1 overflow-auto bg-gray-200 p-6", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "flex justify-center", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8531
|
+
"div",
|
|
8532
|
+
{
|
|
8533
|
+
ref: printRef,
|
|
8534
|
+
className: "bg-white shadow-xl",
|
|
8535
|
+
style: pageStyles,
|
|
8536
|
+
children
|
|
8537
|
+
}
|
|
8538
|
+
) }) })
|
|
8539
|
+
] })
|
|
8540
|
+
] });
|
|
8541
|
+
};
|
|
8542
|
+
var PRINT_GREEN = "#2d7d46";
|
|
8543
|
+
var DocumentHeader = ({
|
|
8544
|
+
companyName,
|
|
8545
|
+
address,
|
|
8546
|
+
phone,
|
|
8547
|
+
email,
|
|
8548
|
+
website,
|
|
8549
|
+
documentTitle,
|
|
8550
|
+
documentNumber,
|
|
8551
|
+
date,
|
|
8552
|
+
extraInfo = []
|
|
8553
|
+
}) => {
|
|
8554
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex justify-between items-start mb-6 p-8 pb-0", children: [
|
|
8555
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex-1", children: [
|
|
8556
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "mb-2", children: [
|
|
8557
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8558
|
+
"h1",
|
|
8559
|
+
{
|
|
8560
|
+
className: "text-xl font-bold tracking-wider text-gray-800",
|
|
8561
|
+
style: { letterSpacing: "0.15em" },
|
|
8562
|
+
children: companyName.toUpperCase()
|
|
8563
|
+
}
|
|
8564
|
+
),
|
|
8565
|
+
address && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs text-gray-600 mt-1", children: address })
|
|
8566
|
+
] }),
|
|
8567
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "text-xs text-gray-600 space-y-0.5 mt-3", children: [
|
|
8568
|
+
phone && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { children: phone }),
|
|
8569
|
+
email && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { children: email }),
|
|
8570
|
+
website && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { children: website })
|
|
8571
|
+
] })
|
|
8572
|
+
] }),
|
|
8573
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "text-right", children: [
|
|
8574
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8575
|
+
"h2",
|
|
8576
|
+
{
|
|
8577
|
+
className: "text-4xl font-bold mb-4",
|
|
8578
|
+
style: { color: PRINT_GREEN },
|
|
8579
|
+
children: documentTitle
|
|
8580
|
+
}
|
|
8581
|
+
),
|
|
8582
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("table", { className: "ml-auto text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tbody", { children: [
|
|
8583
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
|
|
8584
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "text-gray-600 pr-4 py-0.5", children: "Date" }),
|
|
8585
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "font-medium border-b border-gray-300 pl-2 py-0.5", children: date })
|
|
8586
|
+
] }),
|
|
8587
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
|
|
8588
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "text-gray-600 pr-4 py-0.5", children: "N\xB0" }),
|
|
8589
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "font-medium border-b border-gray-300 pl-2 py-0.5", children: documentNumber })
|
|
8590
|
+
] }),
|
|
8591
|
+
extraInfo.map((info, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tr", { children: [
|
|
8592
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "text-gray-600 pr-4 py-0.5", children: info.label }),
|
|
8593
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("td", { className: "font-medium border-b border-gray-300 pl-2 py-0.5", children: info.value })
|
|
8594
|
+
] }, index))
|
|
8595
|
+
] }) })
|
|
8596
|
+
] })
|
|
8597
|
+
] });
|
|
8598
|
+
};
|
|
8599
|
+
var InfoBox = ({
|
|
8600
|
+
title,
|
|
8601
|
+
children,
|
|
8602
|
+
variant = "green"
|
|
8603
|
+
}) => {
|
|
8604
|
+
const headerBg = variant === "green" ? PRINT_GREEN : "#6b7280";
|
|
8605
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
8606
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8607
|
+
"div",
|
|
8608
|
+
{
|
|
8609
|
+
className: "text-white text-xs font-semibold py-1.5 px-3 rounded-t",
|
|
8610
|
+
style: { backgroundColor: headerBg },
|
|
8611
|
+
children: title
|
|
8612
|
+
}
|
|
8613
|
+
),
|
|
8614
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border border-gray-300 border-t-0 p-3 min-h-[80px]", children })
|
|
8615
|
+
] });
|
|
8616
|
+
};
|
|
8617
|
+
function DataTable({
|
|
8618
|
+
columns,
|
|
8619
|
+
data,
|
|
8620
|
+
minEmptyRows = 0,
|
|
8621
|
+
keyExtractor
|
|
8622
|
+
}) {
|
|
8623
|
+
const emptyRowsCount = Math.max(0, minEmptyRows - data.length);
|
|
8624
|
+
const getNestedValue = (obj, path) => {
|
|
8625
|
+
return path.split(".").reduce((acc, part) => acc && acc[part], obj);
|
|
8626
|
+
};
|
|
8627
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("table", { className: "w-full border-collapse", children: [
|
|
8628
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tr", { style: { backgroundColor: PRINT_GREEN }, children: columns.map((col, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8629
|
+
"th",
|
|
8630
|
+
{
|
|
8631
|
+
className: "text-white text-xs font-semibold py-2 px-2 border border-gray-400",
|
|
8632
|
+
style: {
|
|
8633
|
+
width: col.width,
|
|
8634
|
+
textAlign: col.align || "left"
|
|
8635
|
+
},
|
|
8636
|
+
children: col.header
|
|
8637
|
+
},
|
|
8638
|
+
index
|
|
8639
|
+
)) }) }),
|
|
8640
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("tbody", { children: [
|
|
8641
|
+
data.map((item, rowIndex) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tr", { className: "border-b border-gray-300", children: columns.map((col, colIndex) => {
|
|
8642
|
+
const value = typeof col.key === "string" ? getNestedValue(item, col.key) : item[col.key];
|
|
8643
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8644
|
+
"td",
|
|
8645
|
+
{
|
|
8646
|
+
className: "py-2 px-2 text-xs text-gray-900 border-l border-r border-gray-300",
|
|
8647
|
+
style: { textAlign: col.align || "left" },
|
|
8648
|
+
children: col.render ? col.render(value, item, rowIndex) : value
|
|
8649
|
+
},
|
|
8650
|
+
colIndex
|
|
8651
|
+
);
|
|
8652
|
+
}) }, keyExtractor(item, rowIndex))),
|
|
8653
|
+
Array.from({ length: emptyRowsCount }).map((_, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tr", { className: "border-b border-gray-300", children: columns.map((_2, colIndex) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8654
|
+
"td",
|
|
8655
|
+
{
|
|
8656
|
+
className: "py-2 px-2 border-l border-r border-gray-300",
|
|
8657
|
+
children: "\xA0"
|
|
8658
|
+
},
|
|
8659
|
+
colIndex
|
|
8660
|
+
)) }, `empty-${index}`))
|
|
8661
|
+
] })
|
|
8662
|
+
] });
|
|
8663
|
+
}
|
|
8664
|
+
var TotalsSection = ({
|
|
8665
|
+
rows,
|
|
8666
|
+
amountInWords
|
|
8667
|
+
}) => {
|
|
8668
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "w-64", children: [
|
|
8669
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("table", { className: "w-full text-xs", children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("tbody", { children: rows.map((row, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
8670
|
+
"tr",
|
|
8671
|
+
{
|
|
8672
|
+
className: row.isTotal ? "" : "border-b border-gray-200",
|
|
8673
|
+
children: [
|
|
8674
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8675
|
+
"td",
|
|
8676
|
+
{
|
|
8677
|
+
className: `py-1.5 px-2 ${row.isTotal ? "font-semibold text-gray-900" : "text-gray-600"}`,
|
|
8678
|
+
children: row.label
|
|
8679
|
+
}
|
|
8680
|
+
),
|
|
8681
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
8682
|
+
"td",
|
|
8683
|
+
{
|
|
8684
|
+
className: `py-1.5 px-2 text-right font-medium`,
|
|
8685
|
+
style: row.isTotal ? {
|
|
8686
|
+
backgroundColor: PRINT_GREEN,
|
|
8687
|
+
color: "white",
|
|
8688
|
+
fontWeight: "bold"
|
|
8689
|
+
} : { color: row.valueColor },
|
|
8690
|
+
children: row.value
|
|
8691
|
+
}
|
|
8692
|
+
)
|
|
8693
|
+
]
|
|
8694
|
+
},
|
|
8695
|
+
index
|
|
8696
|
+
)) }) }),
|
|
8697
|
+
amountInWords && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "mt-2 text-xs text-gray-600 italic text-center px-2", children: amountInWords })
|
|
8698
|
+
] });
|
|
8699
|
+
};
|
|
8700
|
+
var SignatureSection = ({
|
|
8701
|
+
date,
|
|
8702
|
+
leftLabel = "Signature Client",
|
|
8703
|
+
rightLabel = "Cachet et signature",
|
|
8704
|
+
rightName
|
|
8705
|
+
}) => {
|
|
8706
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "grid grid-cols-2 gap-8 mt-12 pt-4 px-8", children: [
|
|
8707
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { children: [
|
|
8708
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs text-gray-600 mb-1", children: "Date:" }),
|
|
8709
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "border-b border-gray-400 w-32 mb-4 text-xs", children: date || "" }),
|
|
8710
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("p", { className: "text-xs text-gray-600 mb-1", children: [
|
|
8711
|
+
leftLabel,
|
|
8712
|
+
":"
|
|
8713
|
+
] }),
|
|
8714
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "h-16 border-b border-gray-400 w-48" })
|
|
8715
|
+
] }),
|
|
8716
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "text-right", children: [
|
|
8717
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs text-gray-600 mb-2", children: rightLabel }),
|
|
8718
|
+
rightName && /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { className: "text-xs font-medium text-gray-900 mb-2", children: rightName }),
|
|
8719
|
+
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "inline-block border-2 border-dashed border-gray-300 rounded-full w-24 h-24" })
|
|
8720
|
+
] })
|
|
8721
|
+
] });
|
|
8722
|
+
};
|
|
8723
|
+
var DocumentFooter = ({ lines }) => {
|
|
8724
|
+
return /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "mt-8 pt-3 border-t border-gray-300 text-center text-xs text-gray-500 px-8 pb-8", children: lines.map((line, index) => /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("p", { children: line }, index)) });
|
|
8725
|
+
};
|
|
8726
|
+
var numberToWords = (num) => {
|
|
8727
|
+
if (num === 0) return "z\xE9ro";
|
|
8728
|
+
const units = ["", "un", "deux", "trois", "quatre", "cinq", "six", "sept", "huit", "neuf", "dix", "onze", "douze", "treize", "quatorze", "quinze", "seize", "dix-sept", "dix-huit", "dix-neuf"];
|
|
8729
|
+
const tens = ["", "", "vingt", "trente", "quarante", "cinquante", "soixante", "soixante", "quatre-vingt", "quatre-vingt"];
|
|
8730
|
+
const convertHundreds = (n) => {
|
|
8731
|
+
if (n < 20) return units[n];
|
|
8732
|
+
if (n < 100) {
|
|
8733
|
+
const ten = Math.floor(n / 10);
|
|
8734
|
+
const unit = n % 10;
|
|
8735
|
+
if (ten === 7 || ten === 9) {
|
|
8736
|
+
return tens[ten] + "-" + units[10 + unit];
|
|
8737
|
+
}
|
|
8738
|
+
return tens[ten] + (unit ? "-" + units[unit] : ten === 8 ? "s" : "");
|
|
8739
|
+
}
|
|
8740
|
+
const hundred = Math.floor(n / 100);
|
|
8741
|
+
const rest = n % 100;
|
|
8742
|
+
return (hundred === 1 ? "cent" : units[hundred] + " cent") + (rest ? " " + convertHundreds(rest) : hundred > 1 && rest === 0 ? "s" : "");
|
|
8743
|
+
};
|
|
8744
|
+
const convertThousands = (n) => {
|
|
8745
|
+
if (n < 1e3) return convertHundreds(n);
|
|
8746
|
+
const thousands = Math.floor(n / 1e3);
|
|
8747
|
+
const rest = n % 1e3;
|
|
8748
|
+
return (thousands === 1 ? "mille" : convertHundreds(thousands) + " mille") + (rest ? " " + convertHundreds(rest) : "");
|
|
8749
|
+
};
|
|
8750
|
+
const convertMillions = (n) => {
|
|
8751
|
+
if (n < 1e6) return convertThousands(n);
|
|
8752
|
+
const millions = Math.floor(n / 1e6);
|
|
8753
|
+
const rest = n % 1e6;
|
|
8754
|
+
return convertHundreds(millions) + " million" + (millions > 1 ? "s" : "") + (rest ? " " + convertThousands(rest) : "");
|
|
8755
|
+
};
|
|
8756
|
+
return convertMillions(Math.floor(num));
|
|
8757
|
+
};
|
|
8758
|
+
var formatDateFR = (date, format = "short") => {
|
|
8759
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
8760
|
+
if (format === "short") {
|
|
8761
|
+
return d.toLocaleDateString("fr-FR", {
|
|
8762
|
+
day: "2-digit",
|
|
8763
|
+
month: "2-digit",
|
|
8764
|
+
year: "numeric"
|
|
8765
|
+
});
|
|
8766
|
+
}
|
|
8767
|
+
return d.toLocaleDateString("fr-FR", {
|
|
8768
|
+
day: "numeric",
|
|
8769
|
+
month: "long",
|
|
8770
|
+
year: "numeric"
|
|
8771
|
+
});
|
|
8772
|
+
};
|
|
8773
|
+
var formatCurrency = (amount, currency = "XOF", showDecimals = false) => {
|
|
8774
|
+
return amount.toLocaleString("fr-FR", {
|
|
8775
|
+
minimumFractionDigits: showDecimals ? 2 : 0,
|
|
8776
|
+
maximumFractionDigits: showDecimals ? 2 : 0
|
|
8777
|
+
}) + (currency ? ` ${currency}` : "");
|
|
8778
|
+
};
|
|
8257
8779
|
// Annotate the CommonJS export names for ESM import in node:
|
|
8258
8780
|
0 && (module.exports = {
|
|
8259
8781
|
Alert,
|
|
@@ -8266,7 +8788,10 @@ var EntityFileManager = ({
|
|
|
8266
8788
|
AuthServices,
|
|
8267
8789
|
CHOICES,
|
|
8268
8790
|
CountrySelector,
|
|
8791
|
+
DataTable,
|
|
8269
8792
|
DateInput,
|
|
8793
|
+
DocumentFooter,
|
|
8794
|
+
DocumentHeader,
|
|
8270
8795
|
EntityFileManager,
|
|
8271
8796
|
FDrawer,
|
|
8272
8797
|
FetchApi,
|
|
@@ -8274,33 +8799,44 @@ var EntityFileManager = ({
|
|
|
8274
8799
|
FileManager,
|
|
8275
8800
|
FileManagerProvider,
|
|
8276
8801
|
ForeignCurrencySelector,
|
|
8802
|
+
InfoBox,
|
|
8277
8803
|
InputField,
|
|
8278
8804
|
InvoiceTypeSelector,
|
|
8279
8805
|
LegalFormSelector,
|
|
8280
8806
|
Modal,
|
|
8281
8807
|
NumberInput,
|
|
8808
|
+
PRINT_GREEN,
|
|
8282
8809
|
Pages,
|
|
8283
8810
|
PaymentMethodSelector,
|
|
8284
8811
|
PrimaryButton,
|
|
8812
|
+
PrintPreview,
|
|
8813
|
+
PrintableDocument,
|
|
8285
8814
|
RewiseLayout,
|
|
8286
8815
|
SecondaryButton,
|
|
8287
8816
|
SelectCostCenter,
|
|
8288
8817
|
SelectDepartment,
|
|
8289
8818
|
SelectInput,
|
|
8819
|
+
SelectUnit,
|
|
8290
8820
|
SelectUser,
|
|
8291
8821
|
SelectVendor,
|
|
8292
8822
|
SessionProvider,
|
|
8823
|
+
SignatureSection,
|
|
8293
8824
|
TaxSelector,
|
|
8294
8825
|
TemplateFNESelector,
|
|
8295
8826
|
TextInput,
|
|
8296
8827
|
ThemeProvider,
|
|
8297
8828
|
ToastContainer,
|
|
8298
8829
|
ToastProvider,
|
|
8830
|
+
TotalsSection,
|
|
8831
|
+
UnitServices,
|
|
8299
8832
|
UserServices,
|
|
8300
8833
|
fileManagerApi,
|
|
8834
|
+
formatCurrency,
|
|
8301
8835
|
formatDate,
|
|
8836
|
+
formatDateFR,
|
|
8302
8837
|
formatFileSize,
|
|
8303
8838
|
getFileIcon,
|
|
8839
|
+
numberToWords,
|
|
8304
8840
|
useAlert,
|
|
8305
8841
|
useFileManager,
|
|
8306
8842
|
useFileManagerApi,
|