@primestyleai/tryon 5.8.45 → 5.8.47
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/react/index.js +196 -43
- package/dist/storefront/primestyle-tryon.js +196 -43
- package/package.json +4 -1
package/dist/react/index.js
CHANGED
|
@@ -238,7 +238,8 @@ function computeMeasurements(lm, imageWidth, imageHeight) {
|
|
|
238
238
|
return pxDist * pxToMm;
|
|
239
239
|
};
|
|
240
240
|
const pd = mmBetween(lm.leftIrisCenter, lm.rightIrisCenter);
|
|
241
|
-
const
|
|
241
|
+
const innerEyeGap = mmBetween(lm.leftInnerEye, lm.rightInnerEye);
|
|
242
|
+
const bridgeWidth = innerEyeGap / 1.6;
|
|
242
243
|
const faceWidth = mmBetween(lm.leftTragus, lm.rightTragus);
|
|
243
244
|
const templeLengthLeft = mmBetween(lm.leftTragus, lm.leftOuterEye);
|
|
244
245
|
const templeLengthRight = mmBetween(lm.rightTragus, lm.rightOuterEye);
|
|
@@ -7950,10 +7951,12 @@ const fitLabelFn = (fit, t) => fit === "good" ? t("perfect fit") : fit === "too-
|
|
|
7950
7951
|
const lengthFitLabelFn = (fit, t) => fit === "good" ? t("perfect fit") : fit === "too-tight" ? t("too short") : fit === "tight" ? t("short") : fit === "a-bit-tight" ? t("a bit short") : fit === "too-loose" ? t("too long") : fit === "loose" ? t("long") : t("a bit long");
|
|
7951
7952
|
function convertNum(n, from, to) {
|
|
7952
7953
|
if (from === to || !n || isNaN(n)) return n;
|
|
7954
|
+
if (from === "mm" || to === "mm") return n;
|
|
7953
7955
|
return from === "cm" ? Math.round(n / 2.54 * 10) / 10 : Math.round(n * 2.54 * 10) / 10;
|
|
7954
7956
|
}
|
|
7955
7957
|
function convertLabel(label, from, to) {
|
|
7956
7958
|
if (from === to) return label;
|
|
7959
|
+
if (from === "mm" || to === "mm") return label;
|
|
7957
7960
|
const conv = (n) => convertNum(n, from, to);
|
|
7958
7961
|
const rangeMatch = label.match(/^(\d+\.?\d*)\s*[-–]\s*(\d+\.?\d*)$/);
|
|
7959
7962
|
if (rangeMatch) return `${conv(parseFloat(rangeMatch[1]))}-${conv(parseFloat(rangeMatch[2]))}`;
|
|
@@ -7994,7 +7997,8 @@ function SectionDetailView({
|
|
|
7994
7997
|
}) {
|
|
7995
7998
|
const recSize = sectionResult?.recommendedSize || "";
|
|
7996
7999
|
const [selectedSize, setSelectedSize] = useState(null);
|
|
7997
|
-
const
|
|
8000
|
+
const unitLblLower = unitLbl.toLowerCase();
|
|
8001
|
+
const displayUnitId = unitLblLower.includes("mm") ? "mm" : unitLblLower.includes("cm") ? "cm" : "in";
|
|
7998
8002
|
const fromUnit = chartUnit || displayUnitId;
|
|
7999
8003
|
const dNum = (n) => convertNum(n, fromUnit, displayUnitId);
|
|
8000
8004
|
const dLabel = (s) => convertLabel(s, fromUnit, displayUnitId);
|
|
@@ -8632,8 +8636,9 @@ function SizeResultView({
|
|
|
8632
8636
|
userHeightCm,
|
|
8633
8637
|
t
|
|
8634
8638
|
}) {
|
|
8635
|
-
const
|
|
8636
|
-
const
|
|
8639
|
+
const resultUnitRaw = (sizingResult?.unit || sizingUnit || "").toString().toLowerCase();
|
|
8640
|
+
const resultUnit = resultUnitRaw === "mm" ? "mm" : resultUnitRaw === "cm" ? "cm" : "in";
|
|
8641
|
+
const unitLbl = resultUnit === "mm" ? t("mm") : sizingUnit === "cm" ? t("cm") : t("in");
|
|
8637
8642
|
const [editVals, setEditVals] = useState({});
|
|
8638
8643
|
const pRange = pRangeFn;
|
|
8639
8644
|
const cellVal = useCallback((row, colIdx, header) => {
|
|
@@ -12485,6 +12490,7 @@ function AccessorySizeView({
|
|
|
12485
12490
|
const [photoPreview, setPhotoPreview] = useState(null);
|
|
12486
12491
|
const [photoFile, setPhotoFile] = useState(null);
|
|
12487
12492
|
const [photoBase64, setPhotoBase64] = useState(null);
|
|
12493
|
+
const [ageConfirmed, setAgeConfirmed] = useState(null);
|
|
12488
12494
|
const handlePhotoSelect = useCallback(async (e) => {
|
|
12489
12495
|
const file = e.target.files?.[0];
|
|
12490
12496
|
if (!file) return;
|
|
@@ -12526,6 +12532,10 @@ function AccessorySizeView({
|
|
|
12526
12532
|
submitSizing("exact");
|
|
12527
12533
|
};
|
|
12528
12534
|
const handlePhotoSubmit = () => {
|
|
12535
|
+
if (ageConfirmed !== true) {
|
|
12536
|
+
setError(t("Please confirm that the person in the photo is 18 or older before uploading."));
|
|
12537
|
+
return;
|
|
12538
|
+
}
|
|
12529
12539
|
if (!photoFile || !photoBase64) {
|
|
12530
12540
|
setError(t("Please upload a photo"));
|
|
12531
12541
|
return;
|
|
@@ -12580,7 +12590,7 @@ function AccessorySizeView({
|
|
|
12580
12590
|
className: "ps-bpm-value-input",
|
|
12581
12591
|
value: values[f.key],
|
|
12582
12592
|
onChange: (e) => updateValue(f.key, e.target.value),
|
|
12583
|
-
placeholder: sizingUnit
|
|
12593
|
+
placeholder: f.placeholder[sizingUnit] || f.placeholder.cm || f.placeholder.in || "",
|
|
12584
12594
|
step: f.step ?? 0.5,
|
|
12585
12595
|
min: f.min,
|
|
12586
12596
|
max: f.max
|
|
@@ -12625,38 +12635,180 @@ function AccessorySizeView({
|
|
|
12625
12635
|
/* ── Photo step — identical to BodyProfileView photo step ── */
|
|
12626
12636
|
/* @__PURE__ */ jsxs("div", { className: "ps-bp-wrapper", style: { display: "flex", flexDirection: "column", width: "100%", height: "100%" }, children: [
|
|
12627
12637
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "1.2vw", padding: "1.5vw", width: "100%", flex: 1, minHeight: "20vw", alignItems: "stretch" }, children: [
|
|
12628
|
-
/* @__PURE__ */
|
|
12629
|
-
|
|
12630
|
-
|
|
12631
|
-
|
|
12632
|
-
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12637
|
-
|
|
12638
|
-
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12647
|
-
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
|
|
12655
|
-
|
|
12656
|
-
|
|
12657
|
-
|
|
12658
|
-
|
|
12659
|
-
|
|
12638
|
+
/* @__PURE__ */ jsxs("div", { style: { flex: 1, position: "relative", display: "flex" }, children: [
|
|
12639
|
+
/* @__PURE__ */ jsx(
|
|
12640
|
+
"div",
|
|
12641
|
+
{
|
|
12642
|
+
onClick: () => {
|
|
12643
|
+
if (!photoPreview && ageConfirmed === true) fileInputRef.current?.click();
|
|
12644
|
+
},
|
|
12645
|
+
style: {
|
|
12646
|
+
flex: 1,
|
|
12647
|
+
display: "flex",
|
|
12648
|
+
flexDirection: "column",
|
|
12649
|
+
alignItems: "center",
|
|
12650
|
+
justifyContent: "center",
|
|
12651
|
+
border: photoPreview ? "2px solid var(--ps-accent)" : "2px dashed var(--ps-border-color)",
|
|
12652
|
+
borderRadius: "0.5vw",
|
|
12653
|
+
cursor: photoPreview ? "default" : ageConfirmed === true ? "pointer" : "not-allowed",
|
|
12654
|
+
position: "relative",
|
|
12655
|
+
background: "var(--ps-bg-secondary)",
|
|
12656
|
+
transition: "border-color 0.2s",
|
|
12657
|
+
overflow: "hidden",
|
|
12658
|
+
filter: !photoPreview && ageConfirmed !== true ? "blur(6px) saturate(0.7)" : void 0,
|
|
12659
|
+
pointerEvents: !photoPreview && ageConfirmed !== true ? "none" : void 0
|
|
12660
|
+
},
|
|
12661
|
+
children: photoPreview ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12662
|
+
/* @__PURE__ */ jsx("img", { src: photoPreview, alt: "preview", style: { width: "100%", height: "100%", objectFit: "contain" } }),
|
|
12663
|
+
/* @__PURE__ */ jsx("button", { onClick: (e) => {
|
|
12664
|
+
e.stopPropagation();
|
|
12665
|
+
handleRemovePhoto();
|
|
12666
|
+
}, style: { position: "absolute", top: "0.5vw", right: "0.5vw", width: "1.4vw", height: "1.4vw", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "none", color: "#fff", fontSize: "0.7vw", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }, children: "×" })
|
|
12667
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
12668
|
+
/* @__PURE__ */ jsx(UploadIcon, { size: 32 }),
|
|
12669
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.85vw", fontWeight: 600, color: "var(--ps-text-primary)", marginTop: "0.5vw" }, children: isCloseUp ? t("Upload close-up photo") : t("Upload your photo") }),
|
|
12670
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6vw", color: "var(--ps-text-muted)", marginTop: "0.2vw" }, children: isCloseUp ? t("Click or drag a close-up face photo") : t("Click or drag a full-body photo") }),
|
|
12671
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.5vw", color: "var(--ps-text-dim)", marginTop: "0.4vw" }, children: "JPEG, PNG (max 10MB)" })
|
|
12672
|
+
] })
|
|
12673
|
+
}
|
|
12674
|
+
),
|
|
12675
|
+
!photoPreview && ageConfirmed === null && /* @__PURE__ */ jsx(
|
|
12676
|
+
"div",
|
|
12677
|
+
{
|
|
12678
|
+
role: "dialog",
|
|
12679
|
+
style: {
|
|
12680
|
+
position: "absolute",
|
|
12681
|
+
inset: 0,
|
|
12682
|
+
display: "flex",
|
|
12683
|
+
alignItems: "center",
|
|
12684
|
+
justifyContent: "center",
|
|
12685
|
+
padding: "1vw",
|
|
12686
|
+
background: "rgba(255,255,255,0.55)",
|
|
12687
|
+
backdropFilter: "blur(8px)",
|
|
12688
|
+
WebkitBackdropFilter: "blur(8px)",
|
|
12689
|
+
borderRadius: "0.5vw",
|
|
12690
|
+
zIndex: 2
|
|
12691
|
+
},
|
|
12692
|
+
children: /* @__PURE__ */ jsxs("div", { style: {
|
|
12693
|
+
width: "100%",
|
|
12694
|
+
maxWidth: "min(420px, 22vw)",
|
|
12695
|
+
padding: "1.4vw 1.6vw",
|
|
12696
|
+
background: "#FFFFFF",
|
|
12697
|
+
border: "1px solid var(--ps-border-subtle)",
|
|
12698
|
+
borderRadius: "0.9vw",
|
|
12699
|
+
boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25), 0 8px 16px -8px rgba(17,24,39,0.15)",
|
|
12700
|
+
display: "flex",
|
|
12701
|
+
flexDirection: "column",
|
|
12702
|
+
alignItems: "center",
|
|
12703
|
+
textAlign: "center",
|
|
12704
|
+
gap: "0.75vw"
|
|
12705
|
+
}, children: [
|
|
12706
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ps-accent)" }, children: t("AGE VERIFICATION") }),
|
|
12707
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.95vw", fontWeight: 600, lineHeight: 1.35, color: "var(--ps-text-primary)" }, children: t("Is the person in this photo 18 years or older?") }),
|
|
12708
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "0.65vw", width: "100%", marginTop: "0.4vw" }, children: [
|
|
12709
|
+
/* @__PURE__ */ jsx(
|
|
12710
|
+
"button",
|
|
12711
|
+
{
|
|
12712
|
+
type: "button",
|
|
12713
|
+
onClick: () => {
|
|
12714
|
+
setAgeConfirmed(true);
|
|
12715
|
+
setError("");
|
|
12716
|
+
},
|
|
12717
|
+
style: {
|
|
12718
|
+
flex: 1,
|
|
12719
|
+
padding: "0.75vw 1vw",
|
|
12720
|
+
borderRadius: "999px",
|
|
12721
|
+
background: "var(--ps-accent)",
|
|
12722
|
+
color: "#FFFFFF",
|
|
12723
|
+
border: "1.5px solid var(--ps-accent)",
|
|
12724
|
+
fontFamily: "inherit",
|
|
12725
|
+
fontSize: "0.78vw",
|
|
12726
|
+
fontWeight: 700,
|
|
12727
|
+
cursor: "pointer"
|
|
12728
|
+
},
|
|
12729
|
+
children: t("Yes")
|
|
12730
|
+
}
|
|
12731
|
+
),
|
|
12732
|
+
/* @__PURE__ */ jsx(
|
|
12733
|
+
"button",
|
|
12734
|
+
{
|
|
12735
|
+
type: "button",
|
|
12736
|
+
onClick: () => setAgeConfirmed(false),
|
|
12737
|
+
style: {
|
|
12738
|
+
flex: 1,
|
|
12739
|
+
padding: "0.75vw 1vw",
|
|
12740
|
+
borderRadius: "999px",
|
|
12741
|
+
background: "transparent",
|
|
12742
|
+
color: "var(--ps-text-primary)",
|
|
12743
|
+
border: "1.5px solid var(--ps-border-color)",
|
|
12744
|
+
fontFamily: "inherit",
|
|
12745
|
+
fontSize: "0.78vw",
|
|
12746
|
+
fontWeight: 700,
|
|
12747
|
+
cursor: "pointer"
|
|
12748
|
+
},
|
|
12749
|
+
children: t("No")
|
|
12750
|
+
}
|
|
12751
|
+
)
|
|
12752
|
+
] })
|
|
12753
|
+
] })
|
|
12754
|
+
}
|
|
12755
|
+
),
|
|
12756
|
+
!photoPreview && ageConfirmed === false && /* @__PURE__ */ jsx(
|
|
12757
|
+
"div",
|
|
12758
|
+
{
|
|
12759
|
+
role: "alert",
|
|
12760
|
+
style: {
|
|
12761
|
+
position: "absolute",
|
|
12762
|
+
inset: 0,
|
|
12763
|
+
display: "flex",
|
|
12764
|
+
alignItems: "center",
|
|
12765
|
+
justifyContent: "center",
|
|
12766
|
+
padding: "1vw",
|
|
12767
|
+
background: "rgba(255,255,255,0.55)",
|
|
12768
|
+
backdropFilter: "blur(8px)",
|
|
12769
|
+
WebkitBackdropFilter: "blur(8px)",
|
|
12770
|
+
borderRadius: "0.5vw",
|
|
12771
|
+
zIndex: 2
|
|
12772
|
+
},
|
|
12773
|
+
children: /* @__PURE__ */ jsxs("div", { style: {
|
|
12774
|
+
width: "100%",
|
|
12775
|
+
maxWidth: "min(420px, 22vw)",
|
|
12776
|
+
padding: "1.4vw 1.6vw",
|
|
12777
|
+
background: "#FFFFFF",
|
|
12778
|
+
border: "1px solid rgba(192,38,38,0.35)",
|
|
12779
|
+
borderRadius: "0.9vw",
|
|
12780
|
+
boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25)",
|
|
12781
|
+
display: "flex",
|
|
12782
|
+
flexDirection: "column",
|
|
12783
|
+
alignItems: "center",
|
|
12784
|
+
textAlign: "center",
|
|
12785
|
+
gap: "0.75vw"
|
|
12786
|
+
}, children: [
|
|
12787
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "#C02626" }, children: t("UPLOAD NOT ALLOWED") }),
|
|
12788
|
+
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.95vw", fontWeight: 600, lineHeight: 1.35, color: "var(--ps-text-primary)" }, children: t("For your safety, we cannot process photos of people under 18.") }),
|
|
12789
|
+
/* @__PURE__ */ jsx(
|
|
12790
|
+
"button",
|
|
12791
|
+
{
|
|
12792
|
+
type: "button",
|
|
12793
|
+
onClick: () => setAgeConfirmed(null),
|
|
12794
|
+
style: {
|
|
12795
|
+
padding: "0.75vw 1.4vw",
|
|
12796
|
+
borderRadius: "999px",
|
|
12797
|
+
background: "transparent",
|
|
12798
|
+
color: "var(--ps-text-primary)",
|
|
12799
|
+
border: "1.5px solid var(--ps-border-color)",
|
|
12800
|
+
fontFamily: "inherit",
|
|
12801
|
+
fontSize: "0.78vw",
|
|
12802
|
+
fontWeight: 700,
|
|
12803
|
+
cursor: "pointer"
|
|
12804
|
+
},
|
|
12805
|
+
children: t("Go back")
|
|
12806
|
+
}
|
|
12807
|
+
)
|
|
12808
|
+
] })
|
|
12809
|
+
}
|
|
12810
|
+
)
|
|
12811
|
+
] }),
|
|
12660
12812
|
/* @__PURE__ */ jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "0.6vw", justifyContent: "center" }, children: [
|
|
12661
12813
|
/* @__PURE__ */ jsx("div", { style: { fontSize: "0.85vw", fontWeight: 700, color: "var(--ps-text-primary)", marginBottom: "0.3vw" }, children: t("How to take the best photo") }),
|
|
12662
12814
|
/* @__PURE__ */ jsxs("div", { style: { background: "#ddfbe7", borderRadius: "0.5vw", padding: "0.6vw 0.8vw" }, children: [
|
|
@@ -12761,7 +12913,7 @@ function AccessorySizeView({
|
|
|
12761
12913
|
className: "ps-bp-inline-input",
|
|
12762
12914
|
value: values[f.key],
|
|
12763
12915
|
onChange: (e) => updateValue(f.key, e.target.value),
|
|
12764
|
-
placeholder: sizingUnit
|
|
12916
|
+
placeholder: f.placeholder[sizingUnit] || f.placeholder.cm || f.placeholder.in || "",
|
|
12765
12917
|
step: f.step ?? 0.5,
|
|
12766
12918
|
min: f.min,
|
|
12767
12919
|
max: f.max
|
|
@@ -12866,7 +13018,8 @@ const FALLBACK_FACE_FIELDS = [
|
|
|
12866
13018
|
{
|
|
12867
13019
|
key: "lensWidth",
|
|
12868
13020
|
label: "Lens Width",
|
|
12869
|
-
placeholder
|
|
13021
|
+
// `cm` key = mm placeholder (default eyewear unit); `in` key = cm placeholder.
|
|
13022
|
+
placeholder: { mm: "e.g. 52", cm: "e.g. 5.2" },
|
|
12870
13023
|
hint: "Width of one lens",
|
|
12871
13024
|
min: 0,
|
|
12872
13025
|
step: 1
|
|
@@ -12874,7 +13027,7 @@ const FALLBACK_FACE_FIELDS = [
|
|
|
12874
13027
|
{
|
|
12875
13028
|
key: "bridgeWidth",
|
|
12876
13029
|
label: "Bridge",
|
|
12877
|
-
placeholder: {
|
|
13030
|
+
placeholder: { mm: "e.g. 18", cm: "e.g. 1.8" },
|
|
12878
13031
|
hint: "Distance over the nose between lenses",
|
|
12879
13032
|
min: 0,
|
|
12880
13033
|
step: 1
|
|
@@ -12882,15 +13035,15 @@ const FALLBACK_FACE_FIELDS = [
|
|
|
12882
13035
|
{
|
|
12883
13036
|
key: "templeLength",
|
|
12884
13037
|
label: "Arm Length",
|
|
12885
|
-
placeholder: {
|
|
13038
|
+
placeholder: { mm: "e.g. 140", cm: "e.g. 14" },
|
|
12886
13039
|
hint: "Length of the arm from hinge to tip",
|
|
12887
13040
|
min: 0,
|
|
12888
13041
|
step: 1
|
|
12889
13042
|
}
|
|
12890
13043
|
];
|
|
12891
13044
|
const EYEWEAR_UNIT_OPTIONS = [
|
|
12892
|
-
{ label: "
|
|
12893
|
-
{ label: "
|
|
13045
|
+
{ label: "Millimetre", value: "mm" },
|
|
13046
|
+
{ label: "Centimetre", value: "cm" }
|
|
12894
13047
|
];
|
|
12895
13048
|
function buildFieldsFromSizeGuide(sizeGuide) {
|
|
12896
13049
|
const req = sizeGuide?.requiredFields;
|
|
@@ -9700,7 +9700,8 @@ function computeMeasurements(lm, imageWidth, imageHeight) {
|
|
|
9700
9700
|
return pxDist * pxToMm;
|
|
9701
9701
|
};
|
|
9702
9702
|
const pd2 = mmBetween(lm.leftIrisCenter, lm.rightIrisCenter);
|
|
9703
|
-
const
|
|
9703
|
+
const innerEyeGap = mmBetween(lm.leftInnerEye, lm.rightInnerEye);
|
|
9704
|
+
const bridgeWidth = innerEyeGap / 1.6;
|
|
9704
9705
|
const faceWidth = mmBetween(lm.leftTragus, lm.rightTragus);
|
|
9705
9706
|
const templeLengthLeft = mmBetween(lm.leftTragus, lm.leftOuterEye);
|
|
9706
9707
|
const templeLengthRight = mmBetween(lm.rightTragus, lm.rightOuterEye);
|
|
@@ -17374,10 +17375,12 @@ const fitLabelFn = (fit, t2) => fit === "good" ? t2("perfect fit") : fit === "to
|
|
|
17374
17375
|
const lengthFitLabelFn = (fit, t2) => fit === "good" ? t2("perfect fit") : fit === "too-tight" ? t2("too short") : fit === "tight" ? t2("short") : fit === "a-bit-tight" ? t2("a bit short") : fit === "too-loose" ? t2("too long") : fit === "loose" ? t2("long") : t2("a bit long");
|
|
17375
17376
|
function convertNum(n2, from, to) {
|
|
17376
17377
|
if (from === to || !n2 || isNaN(n2)) return n2;
|
|
17378
|
+
if (from === "mm" || to === "mm") return n2;
|
|
17377
17379
|
return from === "cm" ? Math.round(n2 / 2.54 * 10) / 10 : Math.round(n2 * 2.54 * 10) / 10;
|
|
17378
17380
|
}
|
|
17379
17381
|
function convertLabel(label, from, to) {
|
|
17380
17382
|
if (from === to) return label;
|
|
17383
|
+
if (from === "mm" || to === "mm") return label;
|
|
17381
17384
|
const conv = (n2) => convertNum(n2, from, to);
|
|
17382
17385
|
const rangeMatch = label.match(/^(\d+\.?\d*)\s*[-–]\s*(\d+\.?\d*)$/);
|
|
17383
17386
|
if (rangeMatch) return `${conv(parseFloat(rangeMatch[1]))}-${conv(parseFloat(rangeMatch[2]))}`;
|
|
@@ -17418,7 +17421,8 @@ function SectionDetailView({
|
|
|
17418
17421
|
}) {
|
|
17419
17422
|
const recSize = sectionResult?.recommendedSize || "";
|
|
17420
17423
|
const [selectedSize, setSelectedSize] = reactExports.useState(null);
|
|
17421
|
-
const
|
|
17424
|
+
const unitLblLower = unitLbl.toLowerCase();
|
|
17425
|
+
const displayUnitId = unitLblLower.includes("mm") ? "mm" : unitLblLower.includes("cm") ? "cm" : "in";
|
|
17422
17426
|
const fromUnit = chartUnit || displayUnitId;
|
|
17423
17427
|
const dNum = (n2) => convertNum(n2, fromUnit, displayUnitId);
|
|
17424
17428
|
const dLabel = (s) => convertLabel(s, fromUnit, displayUnitId);
|
|
@@ -18056,8 +18060,9 @@ function SizeResultView({
|
|
|
18056
18060
|
userHeightCm,
|
|
18057
18061
|
t: t2
|
|
18058
18062
|
}) {
|
|
18059
|
-
const
|
|
18060
|
-
const
|
|
18063
|
+
const resultUnitRaw = (sizingResult?.unit || sizingUnit || "").toString().toLowerCase();
|
|
18064
|
+
const resultUnit = resultUnitRaw === "mm" ? "mm" : resultUnitRaw === "cm" ? "cm" : "in";
|
|
18065
|
+
const unitLbl = resultUnit === "mm" ? t2("mm") : sizingUnit === "cm" ? t2("cm") : t2("in");
|
|
18061
18066
|
const [editVals, setEditVals] = reactExports.useState({});
|
|
18062
18067
|
const pRange = pRangeFn;
|
|
18063
18068
|
const cellVal = reactExports.useCallback((row, colIdx, header) => {
|
|
@@ -21909,6 +21914,7 @@ function AccessorySizeView({
|
|
|
21909
21914
|
const [photoPreview, setPhotoPreview] = reactExports.useState(null);
|
|
21910
21915
|
const [photoFile, setPhotoFile] = reactExports.useState(null);
|
|
21911
21916
|
const [photoBase64, setPhotoBase64] = reactExports.useState(null);
|
|
21917
|
+
const [ageConfirmed, setAgeConfirmed] = reactExports.useState(null);
|
|
21912
21918
|
const handlePhotoSelect = reactExports.useCallback(async (e) => {
|
|
21913
21919
|
const file = e.target.files?.[0];
|
|
21914
21920
|
if (!file) return;
|
|
@@ -21950,6 +21956,10 @@ function AccessorySizeView({
|
|
|
21950
21956
|
submitSizing("exact");
|
|
21951
21957
|
};
|
|
21952
21958
|
const handlePhotoSubmit = () => {
|
|
21959
|
+
if (ageConfirmed !== true) {
|
|
21960
|
+
setError(t2("Please confirm that the person in the photo is 18 or older before uploading."));
|
|
21961
|
+
return;
|
|
21962
|
+
}
|
|
21953
21963
|
if (!photoFile || !photoBase64) {
|
|
21954
21964
|
setError(t2("Please upload a photo"));
|
|
21955
21965
|
return;
|
|
@@ -22004,7 +22014,7 @@ function AccessorySizeView({
|
|
|
22004
22014
|
className: "ps-bpm-value-input",
|
|
22005
22015
|
value: values[f2.key],
|
|
22006
22016
|
onChange: (e) => updateValue(f2.key, e.target.value),
|
|
22007
|
-
placeholder: sizingUnit
|
|
22017
|
+
placeholder: f2.placeholder[sizingUnit] || f2.placeholder.cm || f2.placeholder.in || "",
|
|
22008
22018
|
step: f2.step ?? 0.5,
|
|
22009
22019
|
min: f2.min,
|
|
22010
22020
|
max: f2.max
|
|
@@ -22049,38 +22059,180 @@ function AccessorySizeView({
|
|
|
22049
22059
|
/* ── Photo step — identical to BodyProfileView photo step ── */
|
|
22050
22060
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-wrapper", style: { display: "flex", flexDirection: "column", width: "100%", height: "100%" }, children: [
|
|
22051
22061
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", gap: "1.2vw", padding: "1.5vw", width: "100%", flex: 1, minHeight: "20vw", alignItems: "stretch" }, children: [
|
|
22052
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
22053
|
-
|
|
22054
|
-
|
|
22055
|
-
|
|
22056
|
-
|
|
22057
|
-
|
|
22058
|
-
|
|
22059
|
-
|
|
22060
|
-
|
|
22061
|
-
|
|
22062
|
-
|
|
22063
|
-
|
|
22064
|
-
|
|
22065
|
-
|
|
22066
|
-
|
|
22067
|
-
|
|
22068
|
-
|
|
22069
|
-
|
|
22070
|
-
|
|
22071
|
-
|
|
22072
|
-
|
|
22073
|
-
|
|
22074
|
-
|
|
22075
|
-
|
|
22076
|
-
|
|
22077
|
-
|
|
22078
|
-
|
|
22079
|
-
|
|
22080
|
-
|
|
22081
|
-
|
|
22082
|
-
|
|
22083
|
-
|
|
22062
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { flex: 1, position: "relative", display: "flex" }, children: [
|
|
22063
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22064
|
+
"div",
|
|
22065
|
+
{
|
|
22066
|
+
onClick: () => {
|
|
22067
|
+
if (!photoPreview && ageConfirmed === true) fileInputRef.current?.click();
|
|
22068
|
+
},
|
|
22069
|
+
style: {
|
|
22070
|
+
flex: 1,
|
|
22071
|
+
display: "flex",
|
|
22072
|
+
flexDirection: "column",
|
|
22073
|
+
alignItems: "center",
|
|
22074
|
+
justifyContent: "center",
|
|
22075
|
+
border: photoPreview ? "2px solid var(--ps-accent)" : "2px dashed var(--ps-border-color)",
|
|
22076
|
+
borderRadius: "0.5vw",
|
|
22077
|
+
cursor: photoPreview ? "default" : ageConfirmed === true ? "pointer" : "not-allowed",
|
|
22078
|
+
position: "relative",
|
|
22079
|
+
background: "var(--ps-bg-secondary)",
|
|
22080
|
+
transition: "border-color 0.2s",
|
|
22081
|
+
overflow: "hidden",
|
|
22082
|
+
filter: !photoPreview && ageConfirmed !== true ? "blur(6px) saturate(0.7)" : void 0,
|
|
22083
|
+
pointerEvents: !photoPreview && ageConfirmed !== true ? "none" : void 0
|
|
22084
|
+
},
|
|
22085
|
+
children: photoPreview ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
22086
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: photoPreview, alt: "preview", style: { width: "100%", height: "100%", objectFit: "contain" } }),
|
|
22087
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: (e) => {
|
|
22088
|
+
e.stopPropagation();
|
|
22089
|
+
handleRemovePhoto();
|
|
22090
|
+
}, style: { position: "absolute", top: "0.5vw", right: "0.5vw", width: "1.4vw", height: "1.4vw", borderRadius: "50%", background: "rgba(0,0,0,0.6)", border: "none", color: "#fff", fontSize: "0.7vw", cursor: "pointer", display: "flex", alignItems: "center", justifyContent: "center" }, children: "×" })
|
|
22091
|
+
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
22092
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(UploadIcon, { size: 32 }),
|
|
22093
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "0.85vw", fontWeight: 600, color: "var(--ps-text-primary)", marginTop: "0.5vw" }, children: isCloseUp ? t2("Upload close-up photo") : t2("Upload your photo") }),
|
|
22094
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "0.6vw", color: "var(--ps-text-muted)", marginTop: "0.2vw" }, children: isCloseUp ? t2("Click or drag a close-up face photo") : t2("Click or drag a full-body photo") }),
|
|
22095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "0.5vw", color: "var(--ps-text-dim)", marginTop: "0.4vw" }, children: "JPEG, PNG (max 10MB)" })
|
|
22096
|
+
] })
|
|
22097
|
+
}
|
|
22098
|
+
),
|
|
22099
|
+
!photoPreview && ageConfirmed === null && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22100
|
+
"div",
|
|
22101
|
+
{
|
|
22102
|
+
role: "dialog",
|
|
22103
|
+
style: {
|
|
22104
|
+
position: "absolute",
|
|
22105
|
+
inset: 0,
|
|
22106
|
+
display: "flex",
|
|
22107
|
+
alignItems: "center",
|
|
22108
|
+
justifyContent: "center",
|
|
22109
|
+
padding: "1vw",
|
|
22110
|
+
background: "rgba(255,255,255,0.55)",
|
|
22111
|
+
backdropFilter: "blur(8px)",
|
|
22112
|
+
WebkitBackdropFilter: "blur(8px)",
|
|
22113
|
+
borderRadius: "0.5vw",
|
|
22114
|
+
zIndex: 2
|
|
22115
|
+
},
|
|
22116
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: {
|
|
22117
|
+
width: "100%",
|
|
22118
|
+
maxWidth: "min(420px, 22vw)",
|
|
22119
|
+
padding: "1.4vw 1.6vw",
|
|
22120
|
+
background: "#FFFFFF",
|
|
22121
|
+
border: "1px solid var(--ps-border-subtle)",
|
|
22122
|
+
borderRadius: "0.9vw",
|
|
22123
|
+
boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25), 0 8px 16px -8px rgba(17,24,39,0.15)",
|
|
22124
|
+
display: "flex",
|
|
22125
|
+
flexDirection: "column",
|
|
22126
|
+
alignItems: "center",
|
|
22127
|
+
textAlign: "center",
|
|
22128
|
+
gap: "0.75vw"
|
|
22129
|
+
}, children: [
|
|
22130
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "var(--ps-accent)" }, children: t2("AGE VERIFICATION") }),
|
|
22131
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { fontSize: "0.95vw", fontWeight: 600, lineHeight: 1.35, color: "var(--ps-text-primary)" }, children: t2("Is the person in this photo 18 years or older?") }),
|
|
22132
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", gap: "0.65vw", width: "100%", marginTop: "0.4vw" }, children: [
|
|
22133
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22134
|
+
"button",
|
|
22135
|
+
{
|
|
22136
|
+
type: "button",
|
|
22137
|
+
onClick: () => {
|
|
22138
|
+
setAgeConfirmed(true);
|
|
22139
|
+
setError("");
|
|
22140
|
+
},
|
|
22141
|
+
style: {
|
|
22142
|
+
flex: 1,
|
|
22143
|
+
padding: "0.75vw 1vw",
|
|
22144
|
+
borderRadius: "999px",
|
|
22145
|
+
background: "var(--ps-accent)",
|
|
22146
|
+
color: "#FFFFFF",
|
|
22147
|
+
border: "1.5px solid var(--ps-accent)",
|
|
22148
|
+
fontFamily: "inherit",
|
|
22149
|
+
fontSize: "0.78vw",
|
|
22150
|
+
fontWeight: 700,
|
|
22151
|
+
cursor: "pointer"
|
|
22152
|
+
},
|
|
22153
|
+
children: t2("Yes")
|
|
22154
|
+
}
|
|
22155
|
+
),
|
|
22156
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22157
|
+
"button",
|
|
22158
|
+
{
|
|
22159
|
+
type: "button",
|
|
22160
|
+
onClick: () => setAgeConfirmed(false),
|
|
22161
|
+
style: {
|
|
22162
|
+
flex: 1,
|
|
22163
|
+
padding: "0.75vw 1vw",
|
|
22164
|
+
borderRadius: "999px",
|
|
22165
|
+
background: "transparent",
|
|
22166
|
+
color: "var(--ps-text-primary)",
|
|
22167
|
+
border: "1.5px solid var(--ps-border-color)",
|
|
22168
|
+
fontFamily: "inherit",
|
|
22169
|
+
fontSize: "0.78vw",
|
|
22170
|
+
fontWeight: 700,
|
|
22171
|
+
cursor: "pointer"
|
|
22172
|
+
},
|
|
22173
|
+
children: t2("No")
|
|
22174
|
+
}
|
|
22175
|
+
)
|
|
22176
|
+
] })
|
|
22177
|
+
] })
|
|
22178
|
+
}
|
|
22179
|
+
),
|
|
22180
|
+
!photoPreview && ageConfirmed === false && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22181
|
+
"div",
|
|
22182
|
+
{
|
|
22183
|
+
role: "alert",
|
|
22184
|
+
style: {
|
|
22185
|
+
position: "absolute",
|
|
22186
|
+
inset: 0,
|
|
22187
|
+
display: "flex",
|
|
22188
|
+
alignItems: "center",
|
|
22189
|
+
justifyContent: "center",
|
|
22190
|
+
padding: "1vw",
|
|
22191
|
+
background: "rgba(255,255,255,0.55)",
|
|
22192
|
+
backdropFilter: "blur(8px)",
|
|
22193
|
+
WebkitBackdropFilter: "blur(8px)",
|
|
22194
|
+
borderRadius: "0.5vw",
|
|
22195
|
+
zIndex: 2
|
|
22196
|
+
},
|
|
22197
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: {
|
|
22198
|
+
width: "100%",
|
|
22199
|
+
maxWidth: "min(420px, 22vw)",
|
|
22200
|
+
padding: "1.4vw 1.6vw",
|
|
22201
|
+
background: "#FFFFFF",
|
|
22202
|
+
border: "1px solid rgba(192,38,38,0.35)",
|
|
22203
|
+
borderRadius: "0.9vw",
|
|
22204
|
+
boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25)",
|
|
22205
|
+
display: "flex",
|
|
22206
|
+
flexDirection: "column",
|
|
22207
|
+
alignItems: "center",
|
|
22208
|
+
textAlign: "center",
|
|
22209
|
+
gap: "0.75vw"
|
|
22210
|
+
}, children: [
|
|
22211
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { fontSize: "0.62vw", fontWeight: 700, letterSpacing: "0.18em", textTransform: "uppercase", color: "#C02626" }, children: t2("UPLOAD NOT ALLOWED") }),
|
|
22212
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { fontSize: "0.95vw", fontWeight: 600, lineHeight: 1.35, color: "var(--ps-text-primary)" }, children: t2("For your safety, we cannot process photos of people under 18.") }),
|
|
22213
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22214
|
+
"button",
|
|
22215
|
+
{
|
|
22216
|
+
type: "button",
|
|
22217
|
+
onClick: () => setAgeConfirmed(null),
|
|
22218
|
+
style: {
|
|
22219
|
+
padding: "0.75vw 1.4vw",
|
|
22220
|
+
borderRadius: "999px",
|
|
22221
|
+
background: "transparent",
|
|
22222
|
+
color: "var(--ps-text-primary)",
|
|
22223
|
+
border: "1.5px solid var(--ps-border-color)",
|
|
22224
|
+
fontFamily: "inherit",
|
|
22225
|
+
fontSize: "0.78vw",
|
|
22226
|
+
fontWeight: 700,
|
|
22227
|
+
cursor: "pointer"
|
|
22228
|
+
},
|
|
22229
|
+
children: t2("Go back")
|
|
22230
|
+
}
|
|
22231
|
+
)
|
|
22232
|
+
] })
|
|
22233
|
+
}
|
|
22234
|
+
)
|
|
22235
|
+
] }),
|
|
22084
22236
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { flex: 1, display: "flex", flexDirection: "column", gap: "0.6vw", justifyContent: "center" }, children: [
|
|
22085
22237
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { fontSize: "0.85vw", fontWeight: 700, color: "var(--ps-text-primary)", marginBottom: "0.3vw" }, children: t2("How to take the best photo") }),
|
|
22086
22238
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { background: "#ddfbe7", borderRadius: "0.5vw", padding: "0.6vw 0.8vw" }, children: [
|
|
@@ -22185,7 +22337,7 @@ function AccessorySizeView({
|
|
|
22185
22337
|
className: "ps-bp-inline-input",
|
|
22186
22338
|
value: values[f2.key],
|
|
22187
22339
|
onChange: (e) => updateValue(f2.key, e.target.value),
|
|
22188
|
-
placeholder: sizingUnit
|
|
22340
|
+
placeholder: f2.placeholder[sizingUnit] || f2.placeholder.cm || f2.placeholder.in || "",
|
|
22189
22341
|
step: f2.step ?? 0.5,
|
|
22190
22342
|
min: f2.min,
|
|
22191
22343
|
max: f2.max
|
|
@@ -22290,7 +22442,8 @@ const FALLBACK_FACE_FIELDS = [
|
|
|
22290
22442
|
{
|
|
22291
22443
|
key: "lensWidth",
|
|
22292
22444
|
label: "Lens Width",
|
|
22293
|
-
placeholder
|
|
22445
|
+
// `cm` key = mm placeholder (default eyewear unit); `in` key = cm placeholder.
|
|
22446
|
+
placeholder: { mm: "e.g. 52", cm: "e.g. 5.2" },
|
|
22294
22447
|
hint: "Width of one lens",
|
|
22295
22448
|
min: 0,
|
|
22296
22449
|
step: 1
|
|
@@ -22298,7 +22451,7 @@ const FALLBACK_FACE_FIELDS = [
|
|
|
22298
22451
|
{
|
|
22299
22452
|
key: "bridgeWidth",
|
|
22300
22453
|
label: "Bridge",
|
|
22301
|
-
placeholder: {
|
|
22454
|
+
placeholder: { mm: "e.g. 18", cm: "e.g. 1.8" },
|
|
22302
22455
|
hint: "Distance over the nose between lenses",
|
|
22303
22456
|
min: 0,
|
|
22304
22457
|
step: 1
|
|
@@ -22306,15 +22459,15 @@ const FALLBACK_FACE_FIELDS = [
|
|
|
22306
22459
|
{
|
|
22307
22460
|
key: "templeLength",
|
|
22308
22461
|
label: "Arm Length",
|
|
22309
|
-
placeholder: {
|
|
22462
|
+
placeholder: { mm: "e.g. 140", cm: "e.g. 14" },
|
|
22310
22463
|
hint: "Length of the arm from hinge to tip",
|
|
22311
22464
|
min: 0,
|
|
22312
22465
|
step: 1
|
|
22313
22466
|
}
|
|
22314
22467
|
];
|
|
22315
22468
|
const EYEWEAR_UNIT_OPTIONS = [
|
|
22316
|
-
{ label: "
|
|
22317
|
-
{ label: "
|
|
22469
|
+
{ label: "Millimetre", value: "mm" },
|
|
22470
|
+
{ label: "Centimetre", value: "cm" }
|
|
22318
22471
|
];
|
|
22319
22472
|
function buildFieldsFromSizeGuide(sizeGuide) {
|
|
22320
22473
|
const req = sizeGuide?.requiredFields;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primestyleai/tryon",
|
|
3
|
-
"version": "5.8.
|
|
3
|
+
"version": "5.8.47",
|
|
4
4
|
"description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/primestyle-tryon.js",
|
|
@@ -60,5 +60,8 @@
|
|
|
60
60
|
"terser": "^5.31.0",
|
|
61
61
|
"typescript": "^5.5.0",
|
|
62
62
|
"vite": "^5.4.0"
|
|
63
|
+
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"@primestyleai/tryon": "^5.8.46"
|
|
63
66
|
}
|
|
64
67
|
}
|