esvn-react-barcode-print 1.0.2 → 1.0.4

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.mjs CHANGED
@@ -140,7 +140,10 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
140
140
  labelList = [sampleItem];
141
141
  } else {
142
142
  items.forEach((item) => {
143
- const qty = Math.max(1, Number(item.printQuantity || item.quantity || 1));
143
+ var _a2, _b;
144
+ const rawQty = (_b = (_a2 = item.printQuantity) != null ? _a2 : item.quantity) != null ? _b : 1;
145
+ const parsedQty = typeof rawQty === "number" ? rawQty : parseInt(String(rawQty), 10);
146
+ const qty = Math.max(1, isNaN(parsedQty) ? 1 : parsedQty);
144
147
  for (let i = 0; i < qty; i++) {
145
148
  labelList.push({ ...item, companyName: orgName });
146
149
  }
@@ -152,6 +155,7 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
152
155
  if (labelList.length === 0) {
153
156
  return { html: "", totalStamps: 0, paperLabel, uniqueProducts: items.length };
154
157
  }
158
+ const enabledFieldsCount = (settings.fields || []).filter((f) => f.enabled).length || 4;
155
159
  let cols = 3;
156
160
  let pageSizeCss = "105mm auto";
157
161
  let pageMargin = "0";
@@ -159,9 +163,9 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
159
163
  let labelHeight = "22mm";
160
164
  let labelGap = "1.5mm";
161
165
  let bodyPadding = "1mm";
162
- let stampPadding = "2px 4px";
163
- let dynamicFontSize = "8px";
164
- let barcodeHeight = 16;
166
+ let stampPadding = enabledFieldsCount >= 5 ? "1px 2px" : "1.5px 3px";
167
+ let dynamicFontSize = enabledFieldsCount >= 5 ? "6.8px" : enabledFieldsCount >= 4 ? "7.2px" : "7.8px";
168
+ let barcodeHeight = enabledFieldsCount >= 5 ? 12 : enabledFieldsCount >= 4 ? 14 : 16;
165
169
  let sheetWidth = "105mm";
166
170
  let sheetMinHeight = "60mm";
167
171
  let sheetPadding = "2mm 1mm";
@@ -191,9 +195,9 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
191
195
  labelHeight = "22mm";
192
196
  labelGap = "2mm";
193
197
  bodyPadding = "1mm";
194
- stampPadding = "2px 4px";
195
- dynamicFontSize = "8px";
196
- barcodeHeight = 18;
198
+ stampPadding = enabledFieldsCount >= 5 ? "1px 2px" : "1.5px 3px";
199
+ dynamicFontSize = enabledFieldsCount >= 5 ? "7px" : enabledFieldsCount >= 4 ? "7.5px" : "8px";
200
+ barcodeHeight = enabledFieldsCount >= 5 ? 13 : enabledFieldsCount >= 4 ? 15 : 18;
197
201
  sheetWidth = "80mm";
198
202
  sheetMinHeight = "60mm";
199
203
  sheetPadding = "2mm 1mm";
@@ -207,9 +211,9 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
207
211
  labelHeight = "22mm";
208
212
  labelGap = "1.5mm";
209
213
  bodyPadding = "1mm";
210
- stampPadding = "1px 3px";
211
- dynamicFontSize = "7.5px";
212
- barcodeHeight = 16;
214
+ stampPadding = enabledFieldsCount >= 5 ? "1px 2px" : "1px 3px";
215
+ dynamicFontSize = enabledFieldsCount >= 5 ? "6.8px" : enabledFieldsCount >= 4 ? "7.2px" : "7.6px";
216
+ barcodeHeight = enabledFieldsCount >= 5 ? 12 : enabledFieldsCount >= 4 ? 14 : 16;
213
217
  sheetWidth = "105mm";
214
218
  sheetMinHeight = "60mm";
215
219
  sheetPadding = "2mm 1mm";
@@ -360,6 +364,7 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
360
364
  width: 100%;
361
365
  min-height: ${isTest ? "48mm" : labelHeight === "auto" ? "22mm" : labelHeight};
362
366
  height: ${labelHeight === "auto" ? "auto" : labelHeight};
367
+ max-height: ${isTest ? "none" : labelHeight === "auto" ? "none" : labelHeight};
363
368
  padding: ${stampPadding};
364
369
  display: flex;
365
370
  flex-direction: column;
@@ -389,17 +394,21 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
389
394
  }
390
395
  .lbl-dynamic, .lbl-company, .lbl-code, .lbl-name, .lbl-price {
391
396
  font-size: ${dynamicFontSize};
392
- line-height: 1.2;
397
+ line-height: 1.15;
393
398
  word-break: break-word;
394
- white-space: normal;
395
- margin-bottom: 2px;
399
+ overflow: hidden;
400
+ text-overflow: ellipsis;
401
+ display: -webkit-box;
402
+ -webkit-box-orient: vertical;
403
+ -webkit-line-clamp: ${enabledFieldsCount >= 5 ? 1 : 2};
404
+ margin-bottom: ${enabledFieldsCount >= 5 ? "1px" : "1.5px"};
396
405
  }
397
406
  .code-wrapper {
398
407
  display: flex;
399
408
  flex-direction: column;
400
409
  justify-content: center;
401
410
  align-items: center;
402
- margin: 2px 0;
411
+ margin: ${enabledFieldsCount >= 5 ? "1px 0" : "1.5px 0"};
403
412
  width: 100%;
404
413
  }
405
414
  .barcode-svg-box {
@@ -463,6 +472,8 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
463
472
  .stamp-item {
464
473
  width: 100%;
465
474
  min-height: ${isTest ? "48mm" : labelHeight === "auto" ? "22mm" : labelHeight};
475
+ height: ${isTest ? "auto" : labelHeight === "auto" ? "auto" : labelHeight};
476
+ max-height: ${isTest ? "none" : labelHeight === "auto" ? "none" : labelHeight};
466
477
  padding: ${stampPadding};
467
478
  display: flex;
468
479
  flex-direction: column;
@@ -473,6 +484,7 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
473
484
  border: 1px solid #d8d6de;
474
485
  border-radius: 4px;
475
486
  background: #fff;
487
+ box-sizing: border-box;
476
488
  }
477
489
  .text-left {
478
490
  text-align: left;
@@ -484,17 +496,21 @@ var generatePrintDocument = (settings, items, isTest = false, isPreview = false)
484
496
  }
485
497
  .lbl-dynamic, .lbl-company, .lbl-code, .lbl-name, .lbl-price {
486
498
  font-size: ${dynamicFontSize};
487
- line-height: 1.2;
499
+ line-height: 1.15;
488
500
  word-break: break-word;
489
- white-space: normal;
490
- margin-bottom: 2px;
501
+ overflow: hidden;
502
+ text-overflow: ellipsis;
503
+ display: -webkit-box;
504
+ -webkit-box-orient: vertical;
505
+ -webkit-line-clamp: ${enabledFieldsCount >= 5 ? 1 : 2};
506
+ margin-bottom: ${enabledFieldsCount >= 5 ? "1px" : "1.5px"};
491
507
  }
492
508
  .code-wrapper {
493
509
  display: flex;
494
510
  flex-direction: column;
495
511
  justify-content: center;
496
512
  align-items: center;
497
- margin: 2px 0;
513
+ margin: ${enabledFieldsCount >= 5 ? "1px 0" : "1.5px 0"};
498
514
  width: 100%;
499
515
  }
500
516
  .barcode-svg-box {
@@ -561,7 +577,7 @@ import { QRCodeCanvas } from "qrcode.react";
561
577
  import { Fragment, useRef, useState } from "react";
562
578
  import Barcode from "react-barcode";
563
579
  import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
564
- var PreviewPrint = ({ watch, setValue, sampleItem }) => {
580
+ var PreviewPrint = ({ watch, setValue, sampleData }) => {
565
581
  var _a, _b;
566
582
  const printType = Number((_a = watch("printType")) != null ? _a : 0);
567
583
  const fields = (_b = watch("fields")) != null ? _b : [];
@@ -576,21 +592,23 @@ var PreviewPrint = ({ watch, setValue, sampleItem }) => {
576
592
  return "T\xEAn c\xF4ng ty";
577
593
  }
578
594
  };
579
- const sampleData = sampleItem || {
595
+ const effectiveSampleData = {
596
+ ...sampleData || {},
580
597
  companyName: getOrgName(),
581
- code: "SP-001",
582
- productCode: "SP-001",
583
- name: "S\u1EA3n ph\u1EA9m m\u1EABu",
584
- productName: "S\u1EA3n ph\u1EA9m m\u1EABu",
598
+ code: "SOMI",
599
+ productCode: "SOMI",
600
+ name: "\xC1o s\u01A1 mi nam",
601
+ productName: "\xC1o s\u01A1 mi nam",
585
602
  price: "250.000",
586
603
  unitPrice: "250.000",
587
604
  unitName: "C\xE1i",
588
605
  origin: "Vi\u1EC7t Nam",
589
- categoryRootName: "Danh m\u1EE5c m\u1EABu",
606
+ categoryRootName: "Th\u1EDDi trang nam",
607
+ groupProductName: "Th\u1EDDi trang nam",
590
608
  lotSerial: "LOT-2026",
591
609
  specificationCode: "SIZE-L"
592
610
  };
593
- const barcodeValue = sampleData.code || "SP-001";
611
+ const barcodeValue = "Hang-01";
594
612
  const hinge = watch("hinge");
595
613
  const alignStyle = {
596
614
  display: "flex",
@@ -617,10 +635,12 @@ var PreviewPrint = ({ watch, setValue, sampleItem }) => {
617
635
  const deltaX = moveEvent.clientX - draggingRef.current.startX;
618
636
  const newOffset = Math.max(0, Math.min(180, Math.round(draggingRef.current.initialOffset + deltaX)));
619
637
  const currentFields = watch("fields") || [];
620
- const updatedFields = currentFields.map((f) => {
621
- var _a2;
622
- return f.id === ((_a2 = draggingRef.current) == null ? void 0 : _a2.fieldId) ? { ...f, offsetX: newOffset } : f;
623
- });
638
+ const updatedFields = currentFields.map(
639
+ (f) => {
640
+ var _a2;
641
+ return f.id === ((_a2 = draggingRef.current) == null ? void 0 : _a2.fieldId) ? { ...f, offsetX: newOffset } : f;
642
+ }
643
+ );
624
644
  setValue("fields", updatedFields);
625
645
  };
626
646
  const handleMouseUp = () => {
@@ -717,8 +737,8 @@ var PreviewPrint = ({ watch, setValue, sampleItem }) => {
717
737
  const renderDynamicFields = () => {
718
738
  if (!fields || fields.length === 0) {
719
739
  return /* @__PURE__ */ jsxs(Fragment2, { children: [
720
- /* @__PURE__ */ jsx("div", { style: { ...styles.codeText, ...alignStyle }, children: "SP-001" }),
721
- /* @__PURE__ */ jsx("div", { style: { ...styles.normalText, ...alignStyle }, children: "S\u1EA3n ph\u1EA9m m\u1EABu" }),
740
+ /* @__PURE__ */ jsx("div", { style: { ...styles.codeText, ...alignStyle }, children: "SOMI" }),
741
+ /* @__PURE__ */ jsx("div", { style: { ...styles.normalText, ...alignStyle }, children: "\xC1o s\u01A1 mi nam" }),
722
742
  renderCode(),
723
743
  /* @__PURE__ */ jsx("div", { style: { ...styles.price, ...alignStyle }, children: "Gi\xE1: 250.000" })
724
744
  ] });
@@ -727,7 +747,7 @@ var PreviewPrint = ({ watch, setValue, sampleItem }) => {
727
747
  if (field.type === "barcode") {
728
748
  return renderCode(field);
729
749
  }
730
- const rawVal = field.type === "custom" ? field.customValue || field.label : sampleData[field.key] || sampleData[field.id] || field.label;
750
+ const rawVal = field.type === "custom" ? field.customValue || field.label : effectiveSampleData[field.key] || effectiveSampleData[field.id] || field.label;
731
751
  const prefix = field.prefix || "";
732
752
  const suffix = field.suffix || "";
733
753
  const displayVal = `${prefix}${rawVal}${suffix}`;
@@ -812,15 +832,30 @@ var styles = {
812
832
  dynamicText: {
813
833
  fontSize: 13,
814
834
  color: "#111",
815
- lineHeight: 1.25,
835
+ lineHeight: 1.2,
816
836
  marginBottom: 2,
817
837
  wordBreak: "break-word",
818
- whiteSpace: "normal"
838
+ overflow: "hidden",
839
+ textOverflow: "ellipsis",
840
+ display: "-webkit-box",
841
+ WebkitBoxOrient: "vertical",
842
+ WebkitLineClamp: 2
819
843
  }
820
844
  };
845
+ var preview_print_default = PreviewPrint;
821
846
 
822
847
  // src/components/setting-print.tsx
823
- import * as Icon from "becoxy-icons";
848
+ import {
849
+ ArrowDown,
850
+ ArrowUp,
851
+ ChevronDown,
852
+ ChevronRight,
853
+ Menu,
854
+ Minus,
855
+ Plus,
856
+ Settings,
857
+ Trash2
858
+ } from "becoxy-icons";
824
859
  import { Fragment as Fragment3, useState as useState2 } from "react";
825
860
  import { Controller } from "react-hook-form";
826
861
  import {
@@ -834,11 +869,11 @@ import {
834
869
  Label,
835
870
  UncontrolledDropdown
836
871
  } from "reactstrap";
837
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
838
- var DEFAULT_EXTRA_FIELDS = [
872
+ import { Fragment as Fragment4, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
873
+ var AVAILABLE_EXTRA_FIELDS = [
839
874
  { id: "unitName", key: "unitName", label: "\u0110\u01A1n v\u1ECB t\xEDnh", type: "text", prefix: "\u0110VT: " },
840
875
  { id: "origin", key: "origin", label: "Xu\u1EA5t x\u1EE9", type: "text", prefix: "Xu\u1EA5t x\u1EE9: " },
841
- { id: "categoryRootName", key: "categoryRootName", label: "Nh\xF3m h\xE0ng / Danh m\u1EE5c", type: "text", prefix: "Nh\xF3m: " },
876
+ { id: "categoryRootName", key: "categoryRootName", label: "Nh\xF3m s\u1EA3n ph\u1EA9m", type: "text", prefix: "Nh\xF3m: " },
842
877
  { id: "specificationCode", key: "specificationCode", label: "M\xE3 quy c\xE1ch", type: "text", prefix: "Quy c\xE1ch: " },
843
878
  { id: "lotSerial", key: "lotSerial", label: "S\u1ED1 l\xF4 / Serial", type: "text", prefix: "L\xF4: " },
844
879
  { id: "customText", key: "custom", label: "V\u0103n b\u1EA3n t\xF9y ch\u1EC9nh", type: "custom", customValue: "H\xE0ng ch\xEDnh h\xE3ng" }
@@ -851,7 +886,8 @@ var COLOR_PRESETS = [
851
886
  { label: "X\xE1m", value: "#6c757d" }
852
887
  ];
853
888
  var SettingPrint = (props) => {
854
- const { control, watch, setValue, availableExtraFields = DEFAULT_EXTRA_FIELDS, t = (s) => s } = props;
889
+ const t = props.t || ((key) => key);
890
+ const { control, watch, setValue, availableExtraFields, sampleData } = props;
855
891
  const [openPaperSection, setOpenPaperSection] = useState2(true);
856
892
  const [openInfoSection, setOpenInfoSection] = useState2(true);
857
893
  const [openCustomSection, setOpenCustomSection] = useState2(false);
@@ -892,71 +928,81 @@ var SettingPrint = (props) => {
892
928
  if (exists) {
893
929
  const newFields = fields.map((f) => f.id === fieldTemplate.id ? { ...f, enabled: true } : f);
894
930
  setValue("fields", newFields);
895
- } else {
896
- const newField = {
897
- id: fieldTemplate.id,
898
- key: fieldTemplate.key,
899
- label: fieldTemplate.label,
900
- type: fieldTemplate.type,
901
- enabled: true,
902
- bold: false,
903
- prefix: fieldTemplate.prefix || "",
904
- customValue: fieldTemplate.customValue || ""
905
- };
906
- setValue("fields", [...fields, newField]);
931
+ return;
932
+ }
933
+ const newId = fieldTemplate.id === "customText" ? `custom_${Date.now()}` : fieldTemplate.id;
934
+ const newField = {
935
+ id: newId,
936
+ key: fieldTemplate.key,
937
+ label: fieldTemplate.label,
938
+ type: fieldTemplate.type,
939
+ enabled: true,
940
+ bold: false,
941
+ italic: false,
942
+ underline: false,
943
+ color: "#000000",
944
+ fontSize: 13,
945
+ offsetX: 0,
946
+ prefix: fieldTemplate.prefix,
947
+ customValue: fieldTemplate.customValue || "N\u1ED9i dung t\xF9y ch\u1EC9nh"
948
+ };
949
+ setValue("fields", [...fields, newField], { shouldDirty: true, shouldTouch: true });
950
+ if (fieldTemplate.type === "custom") {
951
+ setExpandedFieldId(newId);
907
952
  }
908
953
  };
909
- const updateFieldProperty = (index, propName, value) => {
954
+ const updateFieldStyle = (index, patch) => {
910
955
  const newFields = [...fields];
911
- newFields[index] = { ...newFields[index], [propName]: value };
912
- setValue("fields", newFields);
956
+ newFields[index] = { ...newFields[index], ...patch };
957
+ setValue("fields", newFields, { shouldDirty: true, shouldTouch: true });
913
958
  };
914
959
  const handleDragStart = (index) => {
915
960
  setDraggedIndex(index);
916
961
  };
917
- const handleDragOver = (e, index) => {
962
+ const handleDragOver = (e) => {
918
963
  e.preventDefault();
919
- if (draggedIndex === null || draggedIndex === index) {
964
+ };
965
+ const handleDrop = (dropIndex) => {
966
+ if (draggedIndex === null || draggedIndex === dropIndex) {
967
+ setDraggedIndex(null);
920
968
  return;
921
969
  }
922
970
  const newFields = [...fields];
923
- const item = newFields.splice(draggedIndex, 1)[0];
924
- newFields.splice(index, 0, item);
925
- setDraggedIndex(index);
971
+ const draggedItem = newFields[draggedIndex];
972
+ newFields.splice(draggedIndex, 1);
973
+ newFields.splice(dropIndex, 0, draggedItem);
926
974
  setValue("fields", newFields);
927
- };
928
- const handleDragEnd = () => {
929
975
  setDraggedIndex(null);
930
976
  };
931
- return /* @__PURE__ */ jsx2(Fragment3, { children: /* @__PURE__ */ jsxs2("div", { className: "d-flex flex-column h-100", style: { gap: "16px", overflowY: "auto", paddingRight: "4px" }, children: [
932
- /* @__PURE__ */ jsxs2("div", { className: "border-bottom pb-1", children: [
933
- /* @__PURE__ */ jsx2("div", { className: "fw-bolder text-dark mb-75", children: t("Lo\u1EA1i m\xE3 in") }),
977
+ return /* @__PURE__ */ jsx2(Fragment3, { children: /* @__PURE__ */ jsxs2("div", { className: "p-1 setting-print-container", style: { fontSize: "13px" }, children: [
978
+ /* @__PURE__ */ jsx2("div", { className: "mb-2", children: /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center mb-1", children: [
979
+ /* @__PURE__ */ jsx2("span", { className: "fw-bolder text-dark me-2", children: t("Lo\u1EA1i tem in") }),
934
980
  /* @__PURE__ */ jsx2(
935
981
  Controller,
936
982
  {
937
983
  name: "printType",
938
984
  control,
939
- render: ({ field: { value, onChange } }) => /* @__PURE__ */ jsxs2("div", { className: "d-flex", style: { gap: "20px" }, children: [
985
+ render: ({ field: { value, onChange } }) => /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "20px" }, children: [
940
986
  /* @__PURE__ */ jsxs2(Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
941
987
  /* @__PURE__ */ jsx2(
942
988
  Input,
943
989
  {
944
990
  type: "radio",
945
- name: "printType",
946
991
  className: "me-50 mt-0",
992
+ name: "printType",
947
993
  checked: Number(value) === 0,
948
994
  onChange: () => onChange(0)
949
995
  }
950
996
  ),
951
- /* @__PURE__ */ jsx2("span", { children: t("M\xE3 v\u1EA1ch (Barcode)") })
997
+ /* @__PURE__ */ jsx2("span", { children: t("M\xE3 v\u1EA1ch") })
952
998
  ] }),
953
999
  /* @__PURE__ */ jsxs2(Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
954
1000
  /* @__PURE__ */ jsx2(
955
1001
  Input,
956
1002
  {
957
1003
  type: "radio",
958
- name: "printType",
959
1004
  className: "me-50 mt-0",
1005
+ name: "printType",
960
1006
  checked: Number(value) === 1,
961
1007
  onChange: () => onChange(1)
962
1008
  }
@@ -966,16 +1012,16 @@ var SettingPrint = (props) => {
966
1012
  ] })
967
1013
  }
968
1014
  )
969
- ] }),
970
- /* @__PURE__ */ jsxs2("div", { className: "border-bottom pb-1", children: [
1015
+ ] }) }),
1016
+ /* @__PURE__ */ jsxs2("div", { className: "mb-2", children: [
971
1017
  /* @__PURE__ */ jsxs2(
972
1018
  "div",
973
1019
  {
974
- className: "d-flex align-items-center justify-content-between cursor-pointer mb-75",
1020
+ className: "d-flex align-items-center cursor-pointer fw-bolder text-dark mb-1",
975
1021
  onClick: () => setOpenPaperSection(!openPaperSection),
976
1022
  children: [
977
- /* @__PURE__ */ jsx2("span", { className: "fw-bolder text-dark", children: t("Kh\u1ED5 gi\u1EA5y in") }),
978
- openPaperSection ? /* @__PURE__ */ jsx2(Icon.ChevronDown, { fontSize: 16 }) : /* @__PURE__ */ jsx2(Icon.ChevronRight, { fontSize: 16 })
1023
+ openPaperSection ? /* @__PURE__ */ jsx2(ChevronDown, { fontSize: 16, className: "me-50" }) : /* @__PURE__ */ jsx2(ChevronRight, { fontSize: 16, className: "me-50" }),
1024
+ /* @__PURE__ */ jsx2("span", { children: t("Ch\u1ECDn kh\u1ED5 gi\u1EA5y") })
979
1025
  ]
980
1026
  }
981
1027
  ),
@@ -1063,138 +1109,221 @@ var SettingPrint = (props) => {
1063
1109
  type: "number",
1064
1110
  min: 1,
1065
1111
  max: 10,
1066
- className: "form-control-sm text-center",
1112
+ className: "form-control-sm me-50 text-center",
1067
1113
  style: { width: "60px" },
1068
1114
  value: stampVal != null ? stampVal : 3,
1069
- onChange: (e) => onStampChange(Math.max(1, Number(e.target.value) || 1))
1115
+ onChange: (e) => onStampChange(Number(e.target.value))
1070
1116
  }
1071
1117
  )
1072
1118
  }
1073
1119
  ),
1074
- /* @__PURE__ */ jsx2("span", { className: "ms-50 small text-muted", children: t("tem/h\xE0ng") })
1120
+ /* @__PURE__ */ jsx2("span", { className: "text-muted", style: { fontSize: "12px" }, children: t("tem/d\xF2ng") })
1075
1121
  ] })
1076
1122
  ] })
1077
1123
  ] })
1078
1124
  }
1079
1125
  ) })
1080
1126
  ] }),
1081
- /* @__PURE__ */ jsxs2("div", { className: "border-bottom pb-1", children: [
1082
- /* @__PURE__ */ jsxs2(
1127
+ /* @__PURE__ */ jsxs2("div", { className: "mb-2", children: [
1128
+ /* @__PURE__ */ jsx2(
1083
1129
  "div",
1084
1130
  {
1085
- className: "d-flex align-items-center justify-content-between cursor-pointer mb-75",
1131
+ className: "d-flex align-items-center justify-content-between cursor-pointer fw-bolder text-dark mb-1",
1086
1132
  onClick: () => setOpenInfoSection(!openInfoSection),
1087
- children: [
1088
- /* @__PURE__ */ jsx2("span", { className: "fw-bolder text-dark", children: t("Th\xF4ng tin tr\xEAn tem") }),
1089
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", children: [
1090
- /* @__PURE__ */ jsx2("small", { className: "text-muted me-50", style: { fontSize: "11px" }, children: t("(K\xE9o th\u1EA3 \u0111\u1EC3 \u0111\u1ED5i v\u1ECB tr\xED)") }),
1091
- openInfoSection ? /* @__PURE__ */ jsx2(Icon.ChevronDown, { fontSize: 16 }) : /* @__PURE__ */ jsx2(Icon.ChevronRight, { fontSize: 16 })
1092
- ] })
1093
- ]
1133
+ children: /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", children: [
1134
+ openInfoSection ? /* @__PURE__ */ jsx2(ChevronDown, { fontSize: 16, className: "me-50" }) : /* @__PURE__ */ jsx2(ChevronRight, { fontSize: 16, className: "me-50" }),
1135
+ /* @__PURE__ */ jsx2("span", { children: t("Th\xF4ng tin hi\u1EC3n th\u1ECB & \u0110\u1ECBnh d\u1EA1ng") })
1136
+ ] })
1094
1137
  }
1095
1138
  ),
1096
- /* @__PURE__ */ jsx2(Collapse, { isOpen: openInfoSection, children: /* @__PURE__ */ jsxs2("div", { className: "d-flex flex-column", style: { gap: "6px" }, children: [
1097
- fields.map((field, index) => {
1139
+ /* @__PURE__ */ jsx2(Collapse, { isOpen: openInfoSection, children: /* @__PURE__ */ jsxs2("div", { className: "ps-1 pe-1", children: [
1140
+ /* @__PURE__ */ jsx2("div", { className: "d-flex flex-column mb-1", style: { gap: "6px" }, children: fields.map((field, idx) => {
1098
1141
  const isExpanded = expandedFieldId === field.id;
1099
- const isDragging = draggedIndex === index;
1142
+ const isBold = field.bold !== false;
1143
+ const isItalic = !!field.italic;
1144
+ const isUnderline = !!field.underline;
1145
+ const currentColor = field.color || "#000000";
1146
+ const currentFontSize = field.fontSize || 13;
1147
+ const currentOffset = field.offsetX || 0;
1100
1148
  return /* @__PURE__ */ jsxs2(
1101
1149
  "div",
1102
1150
  {
1103
- draggable: true,
1104
- onDragStart: () => handleDragStart(index),
1105
- onDragOver: (e) => handleDragOver(e, index),
1106
- onDragEnd: handleDragEnd,
1107
- className: "border rounded p-50",
1151
+ className: "border rounded overflow-hidden",
1108
1152
  style: {
1109
- background: isDragging ? "#e8f0fe" : field.enabled ? "#fff" : "#f9f9f9",
1110
- opacity: isDragging ? 0.6 : 1,
1111
- transition: "background 0.2s",
1112
- boxShadow: isExpanded ? "0 2px 6px rgba(0,0,0,0.08)" : "none"
1153
+ background: field.enabled ? "#f8f9fa" : "#ffffff",
1154
+ borderColor: isExpanded ? "#7367f0" : field.enabled ? "#d8d6de" : "#ebe9f1"
1113
1155
  },
1114
1156
  children: [
1115
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1116
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", children: [
1117
- /* @__PURE__ */ jsx2(
1118
- "span",
1119
- {
1120
- className: "cursor-move text-muted me-50 d-flex align-items-center",
1121
- title: t("K\xE9o \u0111\u1EC3 \u0111\u1ED5i th\u1EE9 t\u1EF1"),
1122
- children: /* @__PURE__ */ jsx2(Icon.Menu, { fontSize: 13 })
1123
- }
1124
- ),
1157
+ /* @__PURE__ */ jsxs2(
1158
+ "div",
1159
+ {
1160
+ draggable: true,
1161
+ onDragStart: () => handleDragStart(idx),
1162
+ onDragOver: handleDragOver,
1163
+ onDrop: () => handleDrop(idx),
1164
+ className: "d-flex align-items-center justify-content-between p-50",
1165
+ style: {
1166
+ cursor: "grab",
1167
+ userSelect: "none",
1168
+ opacity: draggedIndex === idx ? 0.5 : 1
1169
+ },
1170
+ children: [
1171
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "8px" }, children: [
1172
+ /* @__PURE__ */ jsx2(Menu, { fontSize: 14, className: "text-muted", style: { cursor: "grab" } }),
1173
+ /* @__PURE__ */ jsx2(
1174
+ Input,
1175
+ {
1176
+ type: "checkbox",
1177
+ checked: field.enabled,
1178
+ onChange: () => handleToggleField(idx),
1179
+ className: "mt-0"
1180
+ }
1181
+ ),
1182
+ /* @__PURE__ */ jsx2(
1183
+ "span",
1184
+ {
1185
+ style: {
1186
+ fontWeight: isBold ? 700 : 400,
1187
+ fontStyle: isItalic ? "italic" : "normal",
1188
+ textDecoration: isUnderline ? "underline" : "none",
1189
+ color: field.enabled ? currentColor : "#888"
1190
+ },
1191
+ children: field.type === "custom" && field.customValue ? `T\xF9y ch\u1EC9nh: "${field.customValue}"` : t(field.label)
1192
+ }
1193
+ ),
1194
+ currentOffset > 0 && /* @__PURE__ */ jsxs2("span", { className: "badge bg-light-primary text-primary", style: { fontSize: "10px", padding: "2px 4px" }, children: [
1195
+ "+",
1196
+ currentOffset,
1197
+ "px"
1198
+ ] })
1199
+ ] }),
1200
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "6px" }, children: [
1201
+ /* @__PURE__ */ jsx2(
1202
+ Button,
1203
+ {
1204
+ size: "sm",
1205
+ color: "flat-primary",
1206
+ className: "p-0 btn-icon",
1207
+ style: {
1208
+ width: "26px",
1209
+ height: "26px",
1210
+ display: "inline-flex",
1211
+ alignItems: "center",
1212
+ justifyContent: "center",
1213
+ borderRadius: "6px",
1214
+ background: isExpanded ? "#7367f0" : "#f0f0f5",
1215
+ color: isExpanded ? "#ffffff" : "#5e5873",
1216
+ border: "none",
1217
+ boxShadow: isExpanded ? "0 2px 6px rgba(115, 103, 240, 0.4)" : "none",
1218
+ transition: "all 0.15s ease"
1219
+ },
1220
+ onClick: (e) => {
1221
+ e.stopPropagation();
1222
+ setExpandedFieldId(isExpanded ? null : field.id);
1223
+ },
1224
+ title: t("T\xF9y ch\u1EC9nh \u0111\u1ECBnh d\u1EA1ng & L\xF9i l\u1EC1"),
1225
+ children: /* @__PURE__ */ jsx2(Settings, { fontSize: 13 })
1226
+ }
1227
+ ),
1228
+ /* @__PURE__ */ jsx2(
1229
+ Button,
1230
+ {
1231
+ size: "sm",
1232
+ color: "flat-secondary",
1233
+ className: "p-0 btn-icon",
1234
+ style: {
1235
+ width: "26px",
1236
+ height: "26px",
1237
+ display: "inline-flex",
1238
+ alignItems: "center",
1239
+ justifyContent: "center",
1240
+ borderRadius: "6px",
1241
+ background: "#f0f0f5",
1242
+ border: "none"
1243
+ },
1244
+ disabled: idx === 0,
1245
+ onClick: (e) => {
1246
+ e.stopPropagation();
1247
+ handleMoveUp(idx);
1248
+ },
1249
+ title: t("Di chuy\u1EC3n l\xEAn"),
1250
+ children: /* @__PURE__ */ jsx2(ArrowUp, { fontSize: 13 })
1251
+ }
1252
+ ),
1253
+ /* @__PURE__ */ jsx2(
1254
+ Button,
1255
+ {
1256
+ size: "sm",
1257
+ color: "flat-secondary",
1258
+ className: "p-0 btn-icon",
1259
+ style: {
1260
+ width: "26px",
1261
+ height: "26px",
1262
+ display: "inline-flex",
1263
+ alignItems: "center",
1264
+ justifyContent: "center",
1265
+ borderRadius: "6px",
1266
+ background: "#f0f0f5",
1267
+ border: "none"
1268
+ },
1269
+ disabled: idx === fields.length - 1,
1270
+ onClick: (e) => {
1271
+ e.stopPropagation();
1272
+ handleMoveDown(idx);
1273
+ },
1274
+ title: t("Di chuy\u1EC3n xu\u1ED1ng"),
1275
+ children: /* @__PURE__ */ jsx2(ArrowDown, { fontSize: 13 })
1276
+ }
1277
+ ),
1278
+ field.type === "custom" || !["companyName", "productCode", "productName", "barcode", "unitPrice"].includes(field.id) ? /* @__PURE__ */ jsx2(
1279
+ Button,
1280
+ {
1281
+ size: "sm",
1282
+ color: "flat-danger",
1283
+ className: "p-0 btn-icon",
1284
+ style: {
1285
+ width: "26px",
1286
+ height: "26px",
1287
+ display: "inline-flex",
1288
+ alignItems: "center",
1289
+ justifyContent: "center",
1290
+ borderRadius: "6px",
1291
+ background: "#fce8e6",
1292
+ color: "#ea5455",
1293
+ border: "none"
1294
+ },
1295
+ onClick: (e) => {
1296
+ e.stopPropagation();
1297
+ handleDeleteField(idx);
1298
+ },
1299
+ title: t("X\xF3a tr\u01B0\u1EDDng"),
1300
+ children: /* @__PURE__ */ jsx2(Trash2, { fontSize: 13 })
1301
+ }
1302
+ ) : null
1303
+ ] })
1304
+ ]
1305
+ }
1306
+ ),
1307
+ /* @__PURE__ */ jsx2(Collapse, { isOpen: isExpanded, children: /* @__PURE__ */ jsxs2("div", { className: "p-1 border-top bg-white", style: { fontSize: "12px" }, children: [
1308
+ field.type === "custom" && /* @__PURE__ */ jsxs2("div", { className: "mb-1", children: [
1309
+ /* @__PURE__ */ jsxs2("span", { className: "text-muted d-block mb-25 fw-bolder", children: [
1310
+ t("N\u1ED9i dung v\u0103n b\u1EA3n"),
1311
+ ":"
1312
+ ] }),
1125
1313
  /* @__PURE__ */ jsx2(
1126
1314
  Input,
1127
1315
  {
1128
- type: "checkbox",
1129
- id: `chk-field-${field.id}`,
1130
- className: "me-50 mt-0",
1131
- checked: field.enabled,
1132
- onChange: () => handleToggleField(index)
1133
- }
1134
- ),
1135
- /* @__PURE__ */ jsx2(
1136
- Label,
1137
- {
1138
- htmlFor: `chk-field-${field.id}`,
1139
- className: `mb-0 cursor-pointer ${field.enabled ? "fw-bold text-dark" : "text-muted"}`,
1140
- style: { fontSize: "13px" },
1141
- children: field.label
1316
+ type: "text",
1317
+ className: "form-control-sm",
1318
+ placeholder: t("Nh\u1EADp n\u1ED9i dung (vd: Hotline: 1900..., H\xE0ng ch\xEDnh h\xE3ng, v.v.)"),
1319
+ value: field.customValue || "",
1320
+ onChange: (e) => updateFieldStyle(idx, { customValue: e.target.value })
1142
1321
  }
1143
1322
  )
1144
1323
  ] }),
1145
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "3px" }, children: [
1146
- /* @__PURE__ */ jsx2(
1147
- Button,
1148
- {
1149
- color: "flat-secondary",
1150
- className: "btn-icon p-0",
1151
- style: { width: "22px", height: "22px" },
1152
- onClick: () => handleMoveUp(index),
1153
- disabled: index === 0,
1154
- title: t("Di chuy\u1EC3n l\xEAn"),
1155
- children: /* @__PURE__ */ jsx2(Icon.ArrowUp, { fontSize: 12 })
1156
- }
1157
- ),
1158
- /* @__PURE__ */ jsx2(
1159
- Button,
1160
- {
1161
- color: "flat-secondary",
1162
- className: "btn-icon p-0",
1163
- style: { width: "22px", height: "22px" },
1164
- onClick: () => handleMoveDown(index),
1165
- disabled: index === fields.length - 1,
1166
- title: t("Di chuy\u1EC3n xu\u1ED1ng"),
1167
- children: /* @__PURE__ */ jsx2(Icon.ArrowDown, { fontSize: 12 })
1168
- }
1169
- ),
1170
- /* @__PURE__ */ jsx2(
1171
- Button,
1172
- {
1173
- color: "flat-secondary",
1174
- className: "btn-icon p-0",
1175
- style: { width: "22px", height: "22px" },
1176
- onClick: () => setExpandedFieldId(isExpanded ? null : field.id),
1177
- title: t("T\xF9y ch\u1EC9nh \u0111\u1ECBnh d\u1EA1ng"),
1178
- children: /* @__PURE__ */ jsx2(Icon.Settings, { fontSize: 12, className: isExpanded ? "text-primary" : "" })
1179
- }
1180
- ),
1181
- field.type === "custom" && /* @__PURE__ */ jsx2(
1182
- Button,
1183
- {
1184
- color: "flat-danger",
1185
- className: "btn-icon p-0 text-danger",
1186
- style: { width: "22px", height: "22px" },
1187
- onClick: () => handleDeleteField(index),
1188
- title: t("X\xF3a tr\u01B0\u1EDDng"),
1189
- children: /* @__PURE__ */ jsx2(Icon.Trash2, { fontSize: 12 })
1190
- }
1191
- )
1192
- ] })
1193
- ] }),
1194
- isExpanded && /* @__PURE__ */ jsxs2("div", { className: "mt-50 pt-50 border-top ps-1 pe-50", children: [
1195
- field.type !== "barcode" && /* @__PURE__ */ jsxs2("div", { className: "d-flex flex-column", style: { gap: "6px" }, children: [
1196
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1197
- /* @__PURE__ */ jsxs2("span", { className: "small text-muted", children: [
1324
+ field.type !== "barcode" && /* @__PURE__ */ jsxs2(Fragment4, { children: [
1325
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between mb-1", children: [
1326
+ /* @__PURE__ */ jsxs2("span", { className: "text-muted", children: [
1198
1327
  t("Ki\u1EC3u ch\u1EEF"),
1199
1328
  ":"
1200
1329
  ] }),
@@ -1202,189 +1331,191 @@ var SettingPrint = (props) => {
1202
1331
  /* @__PURE__ */ jsx2(
1203
1332
  Button,
1204
1333
  {
1205
- color: field.bold !== false ? "primary" : "outline-secondary",
1206
- className: "btn-icon py-0 px-50",
1207
- onClick: () => updateFieldProperty(index, "bold", field.bold === false),
1208
- title: "In \u0111\u1EADm (Bold)",
1209
- children: /* @__PURE__ */ jsx2("strong", { children: "B" })
1334
+ color: isBold ? "primary" : "outline-secondary",
1335
+ className: "px-50 py-25 fw-bolder",
1336
+ onClick: () => updateFieldStyle(idx, { bold: !isBold }),
1337
+ title: t("In \u0111\u1EADm"),
1338
+ children: "B"
1210
1339
  }
1211
1340
  ),
1212
1341
  /* @__PURE__ */ jsx2(
1213
1342
  Button,
1214
1343
  {
1215
- color: field.italic ? "primary" : "outline-secondary",
1216
- className: "btn-icon py-0 px-50",
1217
- onClick: () => updateFieldProperty(index, "italic", !field.italic),
1218
- title: "In nghi\xEAng (Italic)",
1219
- children: /* @__PURE__ */ jsx2("em", { children: "I" })
1344
+ color: isItalic ? "primary" : "outline-secondary",
1345
+ className: "px-50 py-25 fst-italic",
1346
+ onClick: () => updateFieldStyle(idx, { italic: !isItalic }),
1347
+ title: t("In nghi\xEAng"),
1348
+ children: "I"
1220
1349
  }
1221
1350
  ),
1222
1351
  /* @__PURE__ */ jsx2(
1223
1352
  Button,
1224
1353
  {
1225
- color: field.underline ? "primary" : "outline-secondary",
1226
- className: "btn-icon py-0 px-50",
1227
- onClick: () => updateFieldProperty(index, "underline", !field.underline),
1228
- title: "G\u1EA1ch ch\xE2n (Underline)",
1229
- children: /* @__PURE__ */ jsx2("u", { children: "U" })
1354
+ color: isUnderline ? "primary" : "outline-secondary",
1355
+ className: "px-50 py-25 text-decoration-underline",
1356
+ onClick: () => updateFieldStyle(idx, { underline: !isUnderline }),
1357
+ title: t("G\u1EA1ch ch\xE2n"),
1358
+ children: "U"
1230
1359
  }
1231
1360
  )
1232
1361
  ] })
1233
1362
  ] }),
1234
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1235
- /* @__PURE__ */ jsxs2("span", { className: "small text-muted", children: [
1236
- t("C\u1EE1 ch\u1EEF (px)"),
1363
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between mb-1", children: [
1364
+ /* @__PURE__ */ jsxs2("span", { className: "text-muted", children: [
1365
+ t("C\u1EE1 ch\u1EEF"),
1237
1366
  ":"
1238
1367
  ] }),
1239
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", children: [
1368
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "4px" }, children: [
1240
1369
  /* @__PURE__ */ jsx2(
1241
1370
  Button,
1242
1371
  {
1372
+ size: "sm",
1243
1373
  color: "outline-secondary",
1244
- className: "btn-icon p-0",
1245
- style: { width: "22px", height: "22px" },
1246
- onClick: () => updateFieldProperty(index, "fontSize", Math.max(8, (field.fontSize || 13) - 1)),
1247
- children: /* @__PURE__ */ jsx2(Icon.Minus, { fontSize: 10 })
1374
+ className: "p-0 px-25 btn-icon",
1375
+ onClick: () => updateFieldStyle(idx, { fontSize: Math.max(8, currentFontSize - 1) }),
1376
+ children: /* @__PURE__ */ jsx2(Minus, { fontSize: 12 })
1248
1377
  }
1249
1378
  ),
1250
- /* @__PURE__ */ jsx2("span", { className: "mx-50 small fw-bold", style: { minWidth: "24px", textAlign: "center" }, children: field.fontSize || 13 }),
1379
+ /* @__PURE__ */ jsxs2("span", { className: "fw-bolder px-50 text-center", style: { minWidth: "35px" }, children: [
1380
+ currentFontSize,
1381
+ "px"
1382
+ ] }),
1251
1383
  /* @__PURE__ */ jsx2(
1252
1384
  Button,
1253
1385
  {
1386
+ size: "sm",
1254
1387
  color: "outline-secondary",
1255
- className: "btn-icon p-0",
1256
- style: { width: "22px", height: "22px" },
1257
- onClick: () => updateFieldProperty(index, "fontSize", Math.min(24, (field.fontSize || 13) + 1)),
1258
- children: /* @__PURE__ */ jsx2(Icon.Plus, { fontSize: 10 })
1388
+ className: "p-0 px-25 btn-icon",
1389
+ onClick: () => updateFieldStyle(idx, { fontSize: Math.min(24, currentFontSize + 1) }),
1390
+ children: /* @__PURE__ */ jsx2(Plus, { fontSize: 12 })
1259
1391
  }
1260
1392
  )
1261
1393
  ] })
1262
1394
  ] }),
1263
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1264
- /* @__PURE__ */ jsxs2("span", { className: "small text-muted", children: [
1395
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between mb-1", children: [
1396
+ /* @__PURE__ */ jsxs2("span", { className: "text-muted", children: [
1265
1397
  t("M\xE0u ch\u1EEF"),
1266
1398
  ":"
1267
1399
  ] }),
1268
- /* @__PURE__ */ jsx2("div", { className: "d-flex align-items-center", style: { gap: "4px" }, children: COLOR_PRESETS.map((colorItem) => /* @__PURE__ */ jsx2(
1269
- "div",
1270
- {
1271
- onClick: () => updateFieldProperty(index, "color", colorItem.value),
1272
- title: colorItem.label,
1273
- style: {
1274
- width: "16px",
1275
- height: "16px",
1276
- borderRadius: "50%",
1277
- backgroundColor: colorItem.value,
1278
- cursor: "pointer",
1279
- outline: (field.color || "#000000") === colorItem.value ? "2px solid #7367f0" : "none",
1280
- outlineOffset: "1px"
1400
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "6px" }, children: [
1401
+ COLOR_PRESETS.map((c) => /* @__PURE__ */ jsx2(
1402
+ "div",
1403
+ {
1404
+ onClick: (e) => {
1405
+ e.stopPropagation();
1406
+ updateFieldStyle(idx, { color: c.value });
1407
+ },
1408
+ style: {
1409
+ width: "18px",
1410
+ height: "18px",
1411
+ borderRadius: "50%",
1412
+ background: c.value,
1413
+ cursor: "pointer",
1414
+ border: currentColor === c.value ? "2px solid #7367f0" : "1px solid #ccc",
1415
+ boxShadow: currentColor === c.value ? "0 0 4px #7367f0" : "none"
1416
+ },
1417
+ title: c.label
1418
+ },
1419
+ c.value
1420
+ )),
1421
+ /* @__PURE__ */ jsx2(
1422
+ Input,
1423
+ {
1424
+ type: "color",
1425
+ value: currentColor,
1426
+ onChange: (e) => updateFieldStyle(idx, { color: e.target.value }),
1427
+ style: { width: "24px", height: "22px", padding: 0, border: "none", cursor: "pointer" },
1428
+ title: t("M\xE0u t\u1EF1 ch\u1ECDn")
1281
1429
  }
1282
- },
1283
- colorItem.value
1284
- )) })
1285
- ] }),
1286
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1287
- /* @__PURE__ */ jsxs2("span", { className: "small text-muted", children: [
1288
- t("Ti\u1EC1n t\u1ED1"),
1430
+ )
1431
+ ] })
1432
+ ] })
1433
+ ] }),
1434
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex flex-column mt-50", children: [
1435
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between mb-25", children: [
1436
+ /* @__PURE__ */ jsxs2("span", { className: "text-muted", children: [
1437
+ t("L\xF9i v\xE0o l\u1EC1 tr\xE1i (Th\u1EE5t l\u1EC1)"),
1289
1438
  ":"
1290
1439
  ] }),
1291
- /* @__PURE__ */ jsx2(
1292
- Input,
1293
- {
1294
- type: "text",
1295
- className: "form-control-sm",
1296
- style: { width: "120px" },
1297
- value: field.prefix || "",
1298
- onChange: (e) => updateFieldProperty(index, "prefix", e.target.value),
1299
- placeholder: "VD: Gi\xE1: "
1300
- }
1301
- )
1440
+ /* @__PURE__ */ jsxs2("span", { className: "fw-bolder text-primary", children: [
1441
+ currentOffset,
1442
+ "px"
1443
+ ] })
1302
1444
  ] }),
1303
- field.type === "custom" && /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1304
- /* @__PURE__ */ jsxs2("span", { className: "small text-muted", children: [
1305
- t("N\u1ED9i dung"),
1306
- ":"
1307
- ] }),
1445
+ /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "8px" }, children: [
1308
1446
  /* @__PURE__ */ jsx2(
1309
1447
  Input,
1310
1448
  {
1311
- type: "text",
1312
- className: "form-control-sm",
1313
- style: { width: "140px" },
1314
- value: field.customValue || "",
1315
- onChange: (e) => updateFieldProperty(index, "customValue", e.target.value)
1316
- }
1317
- )
1318
- ] })
1319
- ] }),
1320
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between mt-50", children: [
1321
- /* @__PURE__ */ jsxs2("span", { className: "small text-muted", children: [
1322
- t("L\xF9i l\u1EC1 tr\xE1i (px)"),
1323
- ":"
1324
- ] }),
1325
- /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", children: [
1326
- /* @__PURE__ */ jsx2(
1327
- Button,
1328
- {
1329
- color: "outline-secondary",
1330
- className: "btn-icon p-0",
1331
- style: { width: "22px", height: "22px" },
1332
- onClick: () => updateFieldProperty(index, "offsetX", Math.max(0, (field.offsetX || 0) - 2)),
1333
- children: /* @__PURE__ */ jsx2(Icon.Minus, { fontSize: 10 })
1449
+ type: "range",
1450
+ min: 0,
1451
+ max: 120,
1452
+ step: 2,
1453
+ value: currentOffset,
1454
+ onChange: (e) => updateFieldStyle(idx, { offsetX: Number(e.target.value) }),
1455
+ className: "form-range flex-grow-1"
1334
1456
  }
1335
1457
  ),
1336
- /* @__PURE__ */ jsx2("span", { className: "mx-50 small fw-bold", style: { minWidth: "24px", textAlign: "center" }, children: field.offsetX || 0 }),
1337
- /* @__PURE__ */ jsx2(
1458
+ currentOffset > 0 && /* @__PURE__ */ jsx2(
1338
1459
  Button,
1339
1460
  {
1340
- color: "outline-secondary",
1341
- className: "btn-icon p-0",
1342
- style: { width: "22px", height: "22px" },
1343
- onClick: () => updateFieldProperty(index, "offsetX", Math.min(180, (field.offsetX || 0) + 2)),
1344
- children: /* @__PURE__ */ jsx2(Icon.Plus, { fontSize: 10 })
1461
+ size: "sm",
1462
+ color: "flat-secondary",
1463
+ className: "p-0 px-25 text-muted",
1464
+ style: { fontSize: "11px" },
1465
+ onClick: () => updateFieldStyle(idx, { offsetX: 0 }),
1466
+ title: t("\u0110\u1EB7t l\u1EA1i v\u1EC1 0"),
1467
+ children: t("Reset")
1345
1468
  }
1346
1469
  )
1470
+ ] }),
1471
+ /* @__PURE__ */ jsxs2("small", { className: "text-muted", style: { fontSize: "11px" }, children: [
1472
+ "\u{1F4A1} ",
1473
+ t("B\u1EA1n c\u0169ng c\xF3 th\u1EC3 click & k\xE9o chu\u1ED9t tr\u1EF1c ti\u1EBFp tr\xEAn khung xem tr\u01B0\u1EDBc b\xEAn d\u01B0\u1EDBi.")
1347
1474
  ] })
1348
1475
  ] })
1349
- ] })
1476
+ ] }) })
1350
1477
  ]
1351
1478
  },
1352
1479
  field.id
1353
1480
  );
1354
- }),
1355
- /* @__PURE__ */ jsx2("div", { className: "mt-50", children: /* @__PURE__ */ jsxs2(UncontrolledDropdown, { children: [
1356
- /* @__PURE__ */ jsxs2(DropdownToggle, { color: "outline-primary", size: "sm", className: "w-100 d-flex align-items-center justify-content-center", children: [
1357
- /* @__PURE__ */ jsx2(Icon.Plus, { fontSize: 13, className: "me-50" }),
1358
- t("Th\xEAm tr\u01B0\u1EDDng th\xF4ng tin kh\xE1c")
1481
+ }) }),
1482
+ /* @__PURE__ */ jsx2("div", { className: "d-flex justify-content-start mb-1", children: /* @__PURE__ */ jsxs2(UncontrolledDropdown, { children: [
1483
+ /* @__PURE__ */ jsxs2(DropdownToggle, { color: "primary", outline: true, size: "sm", className: "d-flex align-items-center", children: [
1484
+ /* @__PURE__ */ jsx2(Plus, { fontSize: 14, className: "me-50" }),
1485
+ t("Th\xEAm tr\u01B0\u1EDDng th\xF4ng tin")
1359
1486
  ] }),
1360
- /* @__PURE__ */ jsx2(DropdownMenu, { className: "w-100", children: availableExtraFields.map((extra) => /* @__PURE__ */ jsx2(DropdownItem, { onClick: () => handleAddField(extra), children: extra.label }, extra.id)) })
1487
+ /* @__PURE__ */ jsx2(DropdownMenu, { children: (availableExtraFields || AVAILABLE_EXTRA_FIELDS).map((item) => /* @__PURE__ */ jsx2(
1488
+ DropdownItem,
1489
+ {
1490
+ onClick: () => handleAddField(item),
1491
+ children: t(item.label)
1492
+ },
1493
+ item.id
1494
+ )) })
1361
1495
  ] }) })
1362
1496
  ] }) })
1363
1497
  ] }),
1364
- /* @__PURE__ */ jsxs2("div", { className: "border-bottom pb-1", children: [
1498
+ /* @__PURE__ */ jsxs2("div", { className: "mb-2", children: [
1365
1499
  /* @__PURE__ */ jsxs2(
1366
1500
  "div",
1367
1501
  {
1368
- className: "d-flex align-items-center justify-content-between cursor-pointer mb-75",
1502
+ className: "d-flex align-items-center cursor-pointer fw-bolder text-dark mb-1",
1369
1503
  onClick: () => setOpenCustomSection(!openCustomSection),
1370
1504
  children: [
1371
- /* @__PURE__ */ jsx2("span", { className: "fw-bolder text-dark", children: t("C\u0103n ch\u1EC9nh l\u1EC1") }),
1372
- openCustomSection ? /* @__PURE__ */ jsx2(Icon.ChevronDown, { fontSize: 16 }) : /* @__PURE__ */ jsx2(Icon.ChevronRight, { fontSize: 16 })
1505
+ openCustomSection ? /* @__PURE__ */ jsx2(ChevronDown, { fontSize: 16, className: "me-50" }) : /* @__PURE__ */ jsx2(ChevronRight, { fontSize: 16, className: "me-50" }),
1506
+ /* @__PURE__ */ jsx2("span", { children: t("T\xF9y ch\u1EC9nh gi\u1EA5y in") })
1373
1507
  ]
1374
1508
  }
1375
1509
  ),
1376
- /* @__PURE__ */ jsx2(Collapse, { isOpen: openCustomSection, children: /* @__PURE__ */ jsx2("div", { className: "d-flex flex-column ps-1", style: { gap: "8px" }, children: /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center justify-content-between", children: [
1377
- /* @__PURE__ */ jsxs2("span", { className: "small text-dark", children: [
1378
- t("C\u0103n l\u1EC1 ch\u1EEF"),
1379
- ":"
1380
- ] }),
1510
+ /* @__PURE__ */ jsx2(Collapse, { isOpen: openCustomSection, children: /* @__PURE__ */ jsx2("div", { className: "ps-1", children: /* @__PURE__ */ jsxs2("div", { className: "mb-1", children: [
1511
+ /* @__PURE__ */ jsx2("span", { className: "text-muted d-block mb-50", style: { fontSize: "12px" }, children: t("C\u0103n l\u1EC1 n\u1ED9i dung tem") }),
1381
1512
  /* @__PURE__ */ jsx2(
1382
1513
  Controller,
1383
1514
  {
1384
1515
  name: "hinge",
1385
1516
  control,
1386
- render: ({ field: { value, onChange } }) => /* @__PURE__ */ jsxs2("div", { className: "d-flex", style: { gap: "15px" }, children: [
1387
- /* @__PURE__ */ jsxs2(Label, { className: "d-flex align-items-center mb-0 cursor-pointer small", children: [
1517
+ render: ({ field: { value, onChange } }) => /* @__PURE__ */ jsxs2("div", { className: "d-flex align-items-center", style: { gap: "20px" }, children: [
1518
+ /* @__PURE__ */ jsxs2(Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
1388
1519
  /* @__PURE__ */ jsx2(
1389
1520
  Input,
1390
1521
  {
@@ -1397,7 +1528,7 @@ var SettingPrint = (props) => {
1397
1528
  ),
1398
1529
  /* @__PURE__ */ jsx2("span", { children: t("C\u0103n tr\xE1i") })
1399
1530
  ] }),
1400
- /* @__PURE__ */ jsxs2(Label, { className: "d-flex align-items-center mb-0 cursor-pointer small", children: [
1531
+ /* @__PURE__ */ jsxs2(Label, { className: "d-flex align-items-center mb-0 cursor-pointer", children: [
1401
1532
  /* @__PURE__ */ jsx2(
1402
1533
  Input,
1403
1534
  {
@@ -1420,13 +1551,13 @@ var SettingPrint = (props) => {
1420
1551
  /* @__PURE__ */ jsx2("span", { children: t("Xem tr\u01B0\u1EDBc m\u1EABu in") }),
1421
1552
  /* @__PURE__ */ jsx2("small", { className: "text-muted fw-normal", style: { fontSize: "11px" }, children: t("(K\xE9o chu\u1ED9t tr\xEAn d\xF2ng \u0111\u1EC3 d\u1ECBch l\u1EC1)") })
1422
1553
  ] }),
1423
- /* @__PURE__ */ jsx2("div", { className: "d-flex justify-content-center", children: /* @__PURE__ */ jsx2(PreviewPrint, { watch, setValue }) })
1554
+ /* @__PURE__ */ jsx2("div", { className: "d-flex justify-content-center", children: /* @__PURE__ */ jsx2(preview_print_default, { watch, setValue, sampleData }) })
1424
1555
  ] })
1425
1556
  ] }) });
1426
1557
  };
1427
1558
 
1428
1559
  // src/components/modal-preview-print.tsx
1429
- import * as Icon2 from "becoxy-icons";
1560
+ import * as Icon from "becoxy-icons";
1430
1561
  import { useEffect, useRef as useRef2, useState as useState3 } from "react";
1431
1562
  import { Badge, Button as Button2, ButtonGroup as ButtonGroup2, Modal, ModalBody, ModalFooter } from "reactstrap";
1432
1563
  import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
@@ -1481,10 +1612,10 @@ var ModalPreviewPrint = ({
1481
1612
  children: [
1482
1613
  /* @__PURE__ */ jsxs3("div", { className: "modal-header d-flex align-items-center justify-content-between px-1_5 py-1 mb-0 border-bottom bg-white", children: [
1483
1614
  /* @__PURE__ */ jsxs3("div", { className: "d-flex align-items-center", children: [
1484
- /* @__PURE__ */ jsx3(Icon2.Printer, { fontSize: 18, className: "text-primary me-50" }),
1615
+ /* @__PURE__ */ jsx3(Icon.Printer, { fontSize: 18, className: "text-primary me-50" }),
1485
1616
  /* @__PURE__ */ jsx3("h5", { className: "modal-title m-0 fw-bolder text-dark", children: t("Xem tr\u01B0\u1EDBc b\u1EA3n in m\xE3 v\u1EA1ch") })
1486
1617
  ] }),
1487
- /* @__PURE__ */ jsx3("div", { className: "cursor-pointer", onClick: toggle, children: /* @__PURE__ */ jsx3(Icon2.X, { fontSize: 20 }) })
1618
+ /* @__PURE__ */ jsx3("div", { className: "cursor-pointer", onClick: toggle, children: /* @__PURE__ */ jsx3(Icon.X, { fontSize: 20 }) })
1488
1619
  ] }),
1489
1620
  /* @__PURE__ */ jsxs3(
1490
1621
  "div",
@@ -1554,7 +1685,7 @@ var ModalPreviewPrint = ({
1554
1685
  style: { width: "22px", height: "22px" },
1555
1686
  onClick: handleZoomOut,
1556
1687
  title: t("Thu nh\u1ECF"),
1557
- children: /* @__PURE__ */ jsx3(Icon2.Minus, { fontSize: 14 })
1688
+ children: /* @__PURE__ */ jsx3(Icon.Minus, { fontSize: 14 })
1558
1689
  }
1559
1690
  ),
1560
1691
  /* @__PURE__ */ jsxs3(
@@ -1578,7 +1709,7 @@ var ModalPreviewPrint = ({
1578
1709
  style: { width: "22px", height: "22px" },
1579
1710
  onClick: handleZoomIn,
1580
1711
  title: t("Ph\xF3ng to"),
1581
- children: /* @__PURE__ */ jsx3(Icon2.Plus, { fontSize: 14 })
1712
+ children: /* @__PURE__ */ jsx3(Icon.Plus, { fontSize: 14 })
1582
1713
  }
1583
1714
  )
1584
1715
  ] })
@@ -1609,7 +1740,7 @@ var ModalPreviewPrint = ({
1609
1740
  onClick: onPrint,
1610
1741
  className: "d-flex align-items-center",
1611
1742
  children: [
1612
- /* @__PURE__ */ jsx3(Icon2.Printer, { fontSize: 14, className: "me-50" }),
1743
+ /* @__PURE__ */ jsx3(Icon.Printer, { fontSize: 14, className: "me-50" }),
1613
1744
  t("In")
1614
1745
  ]
1615
1746
  }
@@ -1622,8 +1753,8 @@ var ModalPreviewPrint = ({
1622
1753
  };
1623
1754
 
1624
1755
  // src/components/modal-barcode-print.tsx
1625
- import * as Icon3 from "becoxy-icons";
1626
- import { Fragment as Fragment4, useState as useState4 } from "react";
1756
+ import * as Icon2 from "becoxy-icons";
1757
+ import { Fragment as Fragment5, useEffect as useEffect2, useState as useState4 } from "react";
1627
1758
  import { useForm } from "react-hook-form";
1628
1759
  import { Button as Button3, Col, Modal as Modal2, ModalBody as ModalBody2, Row } from "reactstrap";
1629
1760
  import Swal from "sweetalert2";
@@ -1644,8 +1775,10 @@ var ModalBarcodePrint = ({
1644
1775
  dataSelected,
1645
1776
  setDataSelected,
1646
1777
  dataItem,
1778
+ initialFields,
1647
1779
  defaultFields = DEFAULT_PRINT_FIELDS,
1648
1780
  availableExtraFields,
1781
+ sampleData,
1649
1782
  renderTable,
1650
1783
  children,
1651
1784
  windowSize,
@@ -1654,6 +1787,7 @@ var ModalBarcodePrint = ({
1654
1787
  notifyError = (msg) => alert(msg),
1655
1788
  notifySuccess = (msg) => console.log(msg)
1656
1789
  }) => {
1790
+ const effectiveDefaultFields = initialFields || defaultFields;
1657
1791
  const defaultValues = {
1658
1792
  printType: 0,
1659
1793
  paperSize: 2,
@@ -1665,13 +1799,18 @@ var ModalBarcodePrint = ({
1665
1799
  unitPrice: true,
1666
1800
  printSample: 3,
1667
1801
  hinge: false,
1668
- fields: defaultFields
1802
+ fields: effectiveDefaultFields
1669
1803
  };
1670
1804
  const [openPreviewModal, setOpenPreviewModal] = useState4(false);
1671
1805
  const { control, watch, setValue, reset, getValues, formState: { errors } } = useForm({
1672
1806
  mode: "onChange",
1673
1807
  defaultValues
1674
1808
  });
1809
+ useEffect2(() => {
1810
+ if (initialFields && initialFields.length > 0) {
1811
+ setValue("fields", initialFields);
1812
+ }
1813
+ }, [initialFields]);
1675
1814
  const handleTestPrint = () => {
1676
1815
  const settings = getValues();
1677
1816
  const targetItems = dataSelected.length > 0 ? dataSelected : dataItem ? [dataItem] : [];
@@ -1720,25 +1859,25 @@ var ModalBarcodePrint = ({
1720
1859
  const renderFooterButtons = () => {
1721
1860
  return /* @__PURE__ */ jsxs4("div", { className: "d-flex align-items-center", style: { gap: "10px" }, children: [
1722
1861
  /* @__PURE__ */ jsxs4(Button3, { color: "primary", onClick: handleResetDefault, className: "d-flex align-items-center text-white", children: [
1723
- /* @__PURE__ */ jsx4(Icon3.OutlineReply, { fontSize: 14, className: "me-50" }),
1862
+ /* @__PURE__ */ jsx4(Icon2.OutlineReply, { fontSize: 14, className: "me-50" }),
1724
1863
  t("Thi\u1EBFt l\u1EADp l\u1EA1i")
1725
1864
  ] }),
1726
1865
  /* @__PURE__ */ jsxs4(Button3, { color: "info", outline: true, onClick: handleOpenPreview, className: "d-flex align-items-center", children: [
1727
- /* @__PURE__ */ jsx4(Icon3.Eye, { fontSize: 14, className: "me-50" }),
1866
+ /* @__PURE__ */ jsx4(Icon2.Eye, { fontSize: 14, className: "me-50" }),
1728
1867
  t("Xem tr\u01B0\u1EDBc")
1729
1868
  ] }),
1730
1869
  /* @__PURE__ */ jsxs4(Button3, { color: "secondary", outline: true, onClick: handleTestPrint, className: "d-flex align-items-center", children: [
1731
- /* @__PURE__ */ jsx4(Icon3.Printer, { fontSize: 14, className: "me-50" }),
1870
+ /* @__PURE__ */ jsx4(Icon2.Printer, { fontSize: 14, className: "me-50" }),
1732
1871
  t("In th\u1EED")
1733
1872
  ] }),
1734
1873
  /* @__PURE__ */ jsxs4(Button3, { color: "primary", onClick: handleRealPrint, className: "d-flex align-items-center", children: [
1735
- /* @__PURE__ */ jsx4(Icon3.Printer, { fontSize: 14, className: "me-50" }),
1874
+ /* @__PURE__ */ jsx4(Icon2.Printer, { fontSize: 14, className: "me-50" }),
1736
1875
  t("In")
1737
1876
  ] }),
1738
1877
  /* @__PURE__ */ jsx4(Button3, { color: "secondary", onClick: toggle, outline: true, children: t("Close") })
1739
1878
  ] });
1740
1879
  };
1741
- return /* @__PURE__ */ jsxs4(Fragment4, { children: [
1880
+ return /* @__PURE__ */ jsxs4(Fragment5, { children: [
1742
1881
  /* @__PURE__ */ jsxs4(
1743
1882
  Modal2,
1744
1883
  {
@@ -1750,10 +1889,10 @@ var ModalBarcodePrint = ({
1750
1889
  children: [
1751
1890
  /* @__PURE__ */ jsxs4("div", { className: "modal-header d-flex align-items-center justify-content-between p-1 mb-0 border-bottom bg-white flex-shrink-0", children: [
1752
1891
  /* @__PURE__ */ jsxs4("div", { className: "d-flex align-items-center", children: [
1753
- /* @__PURE__ */ jsx4(Icon3.Printer, { fontSize: 18, className: "text-primary me-50" }),
1892
+ /* @__PURE__ */ jsx4(Icon2.Printer, { fontSize: 18, className: "text-primary me-50" }),
1754
1893
  /* @__PURE__ */ jsx4("h5", { className: "modal-title m-0 fw-bolder text-dark", children: t(title) })
1755
1894
  ] }),
1756
- /* @__PURE__ */ jsx4("div", { className: "cursor-pointer", onClick: toggle, children: /* @__PURE__ */ jsx4(Icon3.X, { fontSize: 20 }) })
1895
+ /* @__PURE__ */ jsx4("div", { className: "cursor-pointer", onClick: toggle, children: /* @__PURE__ */ jsx4(Icon2.X, { fontSize: 20 }) })
1757
1896
  ] }),
1758
1897
  /* @__PURE__ */ jsx4(ModalBody2, { className: "p-1 flex-grow-1 overflow-hidden", style: { background: "#f8f9fa" }, children: /* @__PURE__ */ jsxs4(Row, { className: "g-1 h-100", children: [
1759
1898
  /* @__PURE__ */ jsx4(Col, { lg: 4, md: 12, xs: 12, className: "h-100 overflow-hidden", children: /* @__PURE__ */ jsxs4(
@@ -1771,6 +1910,7 @@ var ModalBarcodePrint = ({
1771
1910
  setValue,
1772
1911
  errors,
1773
1912
  availableExtraFields,
1913
+ sampleData,
1774
1914
  t
1775
1915
  }
1776
1916
  ) })