@primestyleai/tryon 5.10.177 → 5.10.178

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.
@@ -9530,6 +9530,25 @@ class ApiClient {
9530
9530
  }
9531
9531
  return res.json();
9532
9532
  }
9533
+ async submitTryOnFeedback(input) {
9534
+ const res = await fetch(`${this.baseUrl}/api/v1/tryon/feedback`, {
9535
+ method: "POST",
9536
+ headers: this.headers,
9537
+ body: JSON.stringify({
9538
+ ...input,
9539
+ sessionId: getOrCreateSessionId(),
9540
+ deviceHint: getDeviceHint()
9541
+ })
9542
+ });
9543
+ if (!res.ok) {
9544
+ const data = await res.json().catch(() => ({}));
9545
+ throw new PrimeStyleError(
9546
+ data.message || "Failed to submit try-on feedback",
9547
+ "API_ERROR"
9548
+ );
9549
+ }
9550
+ return res.json();
9551
+ }
9533
9552
  getStreamUrl() {
9534
9553
  const streamUrl = `${this.baseUrl}/api/v1/tryon/stream`;
9535
9554
  return this.apiKey ? `${streamUrl}?key=${encodeURIComponent(this.apiKey)}` : streamUrl;
@@ -10533,6 +10552,24 @@ function logSizeShown(input) {
10533
10552
  fromCache: input.fromCache
10534
10553
  });
10535
10554
  }
10555
+ function logTryOnFeedback(input) {
10556
+ void post("/events/tryon-feedback", {
10557
+ sessionId: getOrCreateSessionId(),
10558
+ deviceHint: getDeviceHint(),
10559
+ jobId: input.jobId,
10560
+ historyEntryId: input.historyEntryId,
10561
+ rating: input.rating,
10562
+ note: input.note,
10563
+ productId: input.productId,
10564
+ productTitle: input.productTitle,
10565
+ productUrl: input.productUrl,
10566
+ recommendedSize: input.recommendedSize,
10567
+ profileLoggedIn: input.profileLoggedIn,
10568
+ profileId: input.profileId,
10569
+ profileName: input.profileName,
10570
+ profileAccessToken: input.profileAccessToken
10571
+ });
10572
+ }
10536
10573
  const ATTR_KEY = "ps_session";
10537
10574
  const PROXY_BASE = "/apps/primestyle";
10538
10575
  const CART_ADD_ENDPOINTS = ["/cart/add.js", "/cart/add"];
@@ -12084,9 +12121,22 @@ const STYLES$1 = `
12084
12121
 
12085
12122
  /* ═══════════ V2 Redesign — Editorial luxury ═══════════ */
12086
12123
  .ps-tryon-v2 {
12087
- display: flex; gap: 1.2vw; flex: 1; min-height: 0;
12124
+ display: flex; align-items: stretch; gap: 1.2vw; flex: 1 1 auto; min-height: 0;
12088
12125
  height: 100%; overflow: hidden;
12089
12126
  }
12127
+ .ps-tryon-v2-media-stack {
12128
+ flex: 0 0 43%;
12129
+ min-width: 0;
12130
+ min-height: 0;
12131
+ display: flex;
12132
+ flex-direction: column;
12133
+ gap: 0.45vw;
12134
+ }
12135
+ .ps-tryon-v2-media-stack .ps-tryon-v2-bg {
12136
+ flex: 1 1 auto;
12137
+ width: 100%;
12138
+ min-height: 0;
12139
+ }
12090
12140
 
12091
12141
  /* Left image column — proper contained display.
12092
12142
  No background — the product/try-on image sits directly on the modal
@@ -12112,12 +12162,43 @@ const STYLES$1 = `
12112
12162
 
12113
12163
  /* Right form panel */
12114
12164
  .ps-tryon-v2-panel {
12115
- flex: 1; min-width: 0;
12165
+ flex: 1 1 0; min-width: 0; min-height: 0;
12116
12166
  display: flex; flex-direction: column;
12117
12167
  padding: 0.2vw 0;
12118
12168
  justify-content: center;
12119
12169
  animation: ps-v2-fade 0.18s ease-out forwards;
12120
12170
  }
12171
+ .ps-tryon-v2-result-panel {
12172
+ align-self: stretch;
12173
+ height: 100%;
12174
+ justify-content: flex-start;
12175
+ gap: 0.55vw;
12176
+ padding-bottom: clamp(8px, 0.72vw, 14px);
12177
+ }
12178
+ .ps-tryon-v2-result-panel .ps-tryon-v2-sep {
12179
+ margin-bottom: 0;
12180
+ }
12181
+ .ps-tryon-v2-result-panel .ps-tryon-sr-cards-v2 {
12182
+ flex: 0 0 auto;
12183
+ min-height: 0;
12184
+ }
12185
+ .ps-tryon-v2-result-panel .ps-tryon-photo-strip {
12186
+ flex: 0 1 auto;
12187
+ min-height: 0;
12188
+ }
12189
+ .ps-tryon-v2-result-panel .ps-tryon-sr-card-v2 {
12190
+ min-height: 10.5vw;
12191
+ }
12192
+ .ps-tryon-v2-result-actions {
12193
+ display: flex;
12194
+ align-items: center;
12195
+ justify-content: space-between;
12196
+ margin-top: auto;
12197
+ padding-top: clamp(8px, 0.65vw, 12px);
12198
+ padding-bottom: 0;
12199
+ gap: 0.5vw;
12200
+ flex-shrink: 0;
12201
+ }
12121
12202
  @keyframes ps-v2-fade {
12122
12203
  0% { opacity: 0; }
12123
12204
  100% { opacity: 1; }
@@ -14253,10 +14334,20 @@ const STYLES$1 = `
14253
14334
  stroke: var(--ps-accent);
14254
14335
  transform: translateY(-1px);
14255
14336
  }
14337
+ .ps-tryon-feedback-star:disabled {
14338
+ cursor: default;
14339
+ }
14340
+ .ps-tryon-feedback-form {
14341
+ display: grid;
14342
+ grid-template-columns: minmax(0, 1fr) auto;
14343
+ gap: 6px;
14344
+ align-items: end;
14345
+ }
14256
14346
  .ps-tryon-feedback-note {
14257
14347
  width: 100%;
14258
14348
  min-width: 0;
14259
- height: clamp(26px, 1.55vw, 32px);
14349
+ min-height: clamp(30px, 1.75vw, 36px);
14350
+ max-height: 78px;
14260
14351
  border: 1px solid #e6eaf2;
14261
14352
  border-radius: clamp(6px, 0.36vw, 8px);
14262
14353
  background: rgba(248, 250, 252, 0.88);
@@ -14264,9 +14355,12 @@ const STYLES$1 = `
14264
14355
  font-family: inherit;
14265
14356
  font-size: clamp(10px, 0.58vw, 12px);
14266
14357
  font-weight: 600;
14267
- padding: 0 clamp(8px, 0.5vw, 10px);
14358
+ line-height: 1.35;
14359
+ padding: clamp(7px, 0.42vw, 9px) clamp(8px, 0.5vw, 10px);
14268
14360
  outline: none;
14269
14361
  box-sizing: border-box;
14362
+ resize: none;
14363
+ overflow-y: auto;
14270
14364
  }
14271
14365
  .ps-tryon-feedback-note::placeholder {
14272
14366
  color: #94a3b8;
@@ -14276,6 +14370,67 @@ const STYLES$1 = `
14276
14370
  border-color: rgba(33,84,239,0.45);
14277
14371
  box-shadow: 0 0 0 3px rgba(33,84,239,0.1);
14278
14372
  }
14373
+ .ps-tryon-feedback-note:disabled {
14374
+ color: #64748b;
14375
+ background: rgba(248, 250, 252, 0.62);
14376
+ cursor: default;
14377
+ }
14378
+ .ps-tryon-feedback-submit {
14379
+ min-height: clamp(30px, 1.75vw, 36px);
14380
+ padding: 0 clamp(9px, 0.55vw, 12px);
14381
+ border: 0;
14382
+ border-radius: clamp(6px, 0.36vw, 8px);
14383
+ background: var(--ps-accent);
14384
+ color: #fff;
14385
+ font-family: inherit;
14386
+ font-size: clamp(10px, 0.56vw, 12px);
14387
+ font-weight: 800;
14388
+ cursor: pointer;
14389
+ white-space: nowrap;
14390
+ }
14391
+ .ps-tryon-feedback-submit:disabled {
14392
+ opacity: 0.48;
14393
+ cursor: default;
14394
+ }
14395
+ .ps-tryon-feedback-status {
14396
+ color: #dc2626;
14397
+ font-size: clamp(10px, 0.56vw, 12px);
14398
+ font-weight: 700;
14399
+ line-height: 1.2;
14400
+ }
14401
+ .ps-result-image-action-bar {
14402
+ width: 100%;
14403
+ display: flex;
14404
+ align-items: center;
14405
+ justify-content: flex-start;
14406
+ gap: clamp(6px, 0.38vw, 9px);
14407
+ flex-wrap: wrap;
14408
+ }
14409
+ .ps-result-image-action {
14410
+ display: inline-flex;
14411
+ align-items: center;
14412
+ justify-content: center;
14413
+ gap: clamp(5px, 0.32vw, 7px);
14414
+ min-height: clamp(30px, 1.75vw, 36px);
14415
+ padding: 0 clamp(10px, 0.65vw, 14px);
14416
+ border-radius: clamp(7px, 0.42vw, 9px);
14417
+ border: 1px solid rgba(226, 232, 240, 0.92);
14418
+ background: #fff;
14419
+ color: var(--ps-text-primary);
14420
+ box-shadow: 0 8px 18px rgba(15, 23, 42, 0.08);
14421
+ font-family: inherit;
14422
+ font-size: clamp(10px, 0.58vw, 12px);
14423
+ font-weight: 800;
14424
+ cursor: pointer;
14425
+ white-space: nowrap;
14426
+ }
14427
+ .ps-result-image-action:hover {
14428
+ border-color: rgba(33,84,239,0.34);
14429
+ color: var(--ps-accent);
14430
+ }
14431
+ .ps-result-image-action svg {
14432
+ flex: 0 0 auto;
14433
+ }
14279
14434
  .ps-tryon-sr-glass-btn {
14280
14435
  background: rgba(255,255,255,0.9); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
14281
14436
  border: 1px solid var(--ps-border-color); border-radius: 0.45vw;
@@ -14571,6 +14726,16 @@ const STYLES$1 = `
14571
14726
  box-sizing: border-box;
14572
14727
  }
14573
14728
  .ps-tryon-drawer-open { transform: translateX(0); }
14729
+ .ps-tryon-history-drawer {
14730
+ inset: 0;
14731
+ height: 100%;
14732
+ min-height: 0;
14733
+ padding: 1.04vw 1.25vw;
14734
+ border-radius: 0;
14735
+ transform: translateY(100%);
14736
+ box-shadow: none;
14737
+ }
14738
+ .ps-tryon-history-drawer.ps-tryon-drawer-open { transform: translateY(0); }
14574
14739
  .ps-tryon-drawer-header { display: flex; align-items: center; gap: 0.52vw; padding-bottom: 0.73vw; margin-bottom: 0.73vw; border-bottom: 1px solid var(--ps-border-color); }
14575
14740
  .ps-tryon-drawer-back {
14576
14741
  width: 1.67vw; height: 1.67vw; display: flex; align-items: center; justify-content: center;
@@ -14586,6 +14751,15 @@ const STYLES$1 = `
14586
14751
  font-family: inherit; transition: all 0.2s; flex-shrink: 0; line-height: 1;
14587
14752
  }
14588
14753
  .ps-tryon-drawer-add-btn:hover { border-color: var(--ps-accent); background: rgba(33,84,239,0.1); }
14754
+ .ps-tryon-drawer-close {
14755
+ width: 1.67vw; height: 1.67vw; display: flex; align-items: center; justify-content: center;
14756
+ border: 1.5px solid var(--ps-border-color); border-radius: 0.52vw; background: transparent;
14757
+ cursor: pointer; color: var(--ps-text-secondary); transition: all 0.2s; flex-shrink: 0;
14758
+ }
14759
+ .ps-tryon-drawer-close svg {
14760
+ width: 0.85vw; height: 0.85vw; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round;
14761
+ }
14762
+ .ps-tryon-drawer-close:hover { border-color: var(--ps-accent); color: var(--ps-accent); }
14589
14763
  .ps-tryon-drawer-list { display: flex; flex-direction: column; gap: 0.52vw; max-width: 100%; overflow-x: hidden; }
14590
14764
  .ps-tryon-drawer-empty { text-align: center; padding: 1.67vw 0.83vw; color: var(--ps-text-muted); font-size: 0.73vw; }
14591
14765
 
@@ -14653,6 +14827,101 @@ const STYLES$1 = `
14653
14827
  background: rgba(33,84,239,0.12); border: 1px solid rgba(33,84,239,0.25);
14654
14828
  border-radius: 0.25vw; padding: 0.1vw 0.35vw; margin-top: 0.25vw;
14655
14829
  }
14830
+ .ps-tryon-history-gallery {
14831
+ display: grid;
14832
+ grid-template-columns: repeat(5, minmax(0, 1fr));
14833
+ gap: 0.72vw;
14834
+ }
14835
+ .ps-tryon-history-card {
14836
+ position: relative;
14837
+ min-width: 0;
14838
+ }
14839
+ .ps-tryon-history-card-main {
14840
+ width: 100%;
14841
+ min-width: 0;
14842
+ display: flex;
14843
+ flex-direction: column;
14844
+ gap: 0.34vw;
14845
+ padding: 0;
14846
+ border: 0;
14847
+ background: transparent;
14848
+ color: inherit;
14849
+ font-family: inherit;
14850
+ text-align: left;
14851
+ cursor: pointer;
14852
+ }
14853
+ .ps-tryon-history-card-media {
14854
+ position: relative;
14855
+ width: 100%;
14856
+ aspect-ratio: 3 / 4;
14857
+ border-radius: 0.72vw;
14858
+ overflow: hidden;
14859
+ background: #f4f5f7;
14860
+ border: 1px solid rgba(226, 232, 240, 0.86);
14861
+ box-shadow: 0 10px 26px rgba(15, 23, 42, 0.06);
14862
+ }
14863
+ .ps-tryon-history-card-img,
14864
+ .ps-tryon-history-card-placeholder {
14865
+ width: 100%;
14866
+ height: 100%;
14867
+ object-fit: cover;
14868
+ object-position: center top;
14869
+ display: block;
14870
+ }
14871
+ .ps-tryon-history-card-placeholder {
14872
+ background: linear-gradient(135deg, rgba(241,245,249,1), rgba(226,232,240,0.7));
14873
+ }
14874
+ .ps-tryon-history-card-product {
14875
+ position: absolute;
14876
+ right: 0.42vw;
14877
+ bottom: 0.42vw;
14878
+ width: 28%;
14879
+ aspect-ratio: 1 / 1;
14880
+ border-radius: 0.42vw;
14881
+ object-fit: cover;
14882
+ background: #fff;
14883
+ border: 1px solid rgba(226, 232, 240, 0.92);
14884
+ box-shadow: 0 8px 18px rgba(15, 23, 42, 0.14);
14885
+ }
14886
+ .ps-tryon-history-card-title {
14887
+ color: var(--ps-text-primary);
14888
+ font-size: 0.66vw;
14889
+ font-weight: 750;
14890
+ line-height: 1.25;
14891
+ overflow: hidden;
14892
+ text-overflow: ellipsis;
14893
+ white-space: nowrap;
14894
+ }
14895
+ .ps-tryon-history-card-meta,
14896
+ .ps-tryon-history-card-sections {
14897
+ color: var(--ps-text-muted);
14898
+ font-size: 0.54vw;
14899
+ font-weight: 600;
14900
+ line-height: 1.2;
14901
+ overflow: hidden;
14902
+ text-overflow: ellipsis;
14903
+ white-space: nowrap;
14904
+ }
14905
+ .ps-tryon-history-card-size {
14906
+ align-self: flex-start;
14907
+ color: var(--ps-accent);
14908
+ background: rgba(33,84,239,0.1);
14909
+ border: 1px solid rgba(33,84,239,0.2);
14910
+ border-radius: 999px;
14911
+ padding: 0.14vw 0.45vw;
14912
+ font-size: 0.52vw;
14913
+ font-weight: 800;
14914
+ }
14915
+ .ps-tryon-history-delete.ps-card-delete {
14916
+ position: absolute;
14917
+ top: 0.42vw;
14918
+ right: 0.42vw;
14919
+ width: 1.5vw;
14920
+ height: 1.5vw;
14921
+ border-radius: 999px;
14922
+ background: rgba(255,255,255,0.9);
14923
+ box-shadow: 0 8px 18px rgba(15,23,42,0.12);
14924
+ }
14656
14925
 
14657
14926
  /* Quiz view */
14658
14927
  .ps-tryon-quiz-progress { display: flex; gap: 0.4vw; margin-bottom: 1vw; }
@@ -14740,6 +15009,12 @@ const STYLES$1 = `
14740
15009
  ────────────────────────────────────────────────────────────────── */
14741
15010
  @media (max-width: 768px) {
14742
15011
  .ps-tryon-drawer { padding: 16px 14px; }
15012
+ .ps-tryon-history-drawer {
15013
+ height: 100%;
15014
+ min-height: 0;
15015
+ padding: 16px 14px;
15016
+ border-radius: 0;
15017
+ }
14743
15018
  .ps-tryon-drawer-header { gap: 10px; padding-bottom: 12px; margin-bottom: 12px; }
14744
15019
  .ps-tryon-drawer-back {
14745
15020
  width: 36px; height: 36px; border-radius: 8px;
@@ -14749,6 +15024,10 @@ const STYLES$1 = `
14749
15024
  .ps-tryon-drawer-add-btn {
14750
15025
  width: 32px; height: 32px; border-radius: 8px; font-size: 20px;
14751
15026
  }
15027
+ .ps-tryon-drawer-close {
15028
+ width: 36px; height: 36px; border-radius: 8px;
15029
+ }
15030
+ .ps-tryon-drawer-close svg { width: 18px; height: 18px; }
14752
15031
  .ps-tryon-drawer-list { gap: 10px; }
14753
15032
  .ps-tryon-drawer-empty { padding: 32px 16px; font-size: 14px; }
14754
15033
 
@@ -14800,6 +15079,36 @@ const STYLES$1 = `
14800
15079
  width: 32px; height: 32px; border-radius: 6px;
14801
15080
  }
14802
15081
  .ps-tryon-history-delete svg { width: 16px; height: 16px; }
15082
+ .ps-tryon-history-gallery {
15083
+ grid-template-columns: repeat(2, minmax(0, 1fr));
15084
+ gap: 12px;
15085
+ }
15086
+ .ps-tryon-history-card-media {
15087
+ border-radius: 12px;
15088
+ }
15089
+ .ps-tryon-history-card-product {
15090
+ right: 7px;
15091
+ bottom: 7px;
15092
+ border-radius: 8px;
15093
+ }
15094
+ .ps-tryon-history-card-title {
15095
+ font-size: 13px;
15096
+ }
15097
+ .ps-tryon-history-card-meta,
15098
+ .ps-tryon-history-card-sections {
15099
+ font-size: 11px;
15100
+ }
15101
+ .ps-tryon-history-card-size {
15102
+ padding: 3px 8px;
15103
+ font-size: 10px;
15104
+ }
15105
+ .ps-tryon-history-delete.ps-card-delete {
15106
+ top: 7px;
15107
+ right: 7px;
15108
+ width: 30px;
15109
+ height: 30px;
15110
+ border-radius: 999px;
15111
+ }
14803
15112
  }
14804
15113
 
14805
15114
  /* Profile detail modal — portaled to body, sits ABOVE the main modal
@@ -17350,10 +17659,32 @@ const STYLES$1 = `
17350
17659
  .ps-tryon-feedback-title { font-size: 11px; }
17351
17660
  .ps-tryon-feedback-star { width: 18px; height: 18px; }
17352
17661
  .ps-tryon-feedback-note {
17353
- height: 30px;
17662
+ min-height: 34px;
17663
+ max-height: 86px;
17664
+ border-radius: 8px;
17665
+ font-size: 11px;
17666
+ }
17667
+ .ps-tryon-feedback-form {
17668
+ gap: 6px;
17669
+ }
17670
+ .ps-tryon-feedback-submit {
17671
+ min-height: 34px;
17672
+ padding: 0 10px;
17354
17673
  border-radius: 8px;
17355
17674
  font-size: 11px;
17356
17675
  }
17676
+ .ps-result-image-action-bar {
17677
+ max-width: 360px;
17678
+ justify-content: flex-start;
17679
+ gap: 7px;
17680
+ }
17681
+ .ps-result-image-action {
17682
+ min-height: 34px;
17683
+ padding: 0 11px;
17684
+ border-radius: 10px;
17685
+ font-size: 11px;
17686
+ box-shadow: 0 4px 12px rgba(15, 23, 42, 0.08);
17687
+ }
17357
17688
  }
17358
17689
  .ps-msr-product-img-wrap {
17359
17690
  position: relative; flex-shrink: 0;
@@ -17396,7 +17727,7 @@ const STYLES$1 = `
17396
17727
  .ps-msr-feedback-slot {
17397
17728
  position: absolute;
17398
17729
  left: 10px;
17399
- bottom: 54px;
17730
+ bottom: 10px;
17400
17731
  z-index: 3;
17401
17732
  }
17402
17733
  .ps-msr-media-btn {
@@ -17706,7 +18037,7 @@ const STYLES$1 = `
17706
18037
  flex: 1; min-height: 0;
17707
18038
  overflow-y: auto; -webkit-overflow-scrolling: touch;
17708
18039
  display: flex; flex-direction: column;
17709
- gap: 18px; padding: 8px 16px 32px;
18040
+ gap: 18px; padding: 8px 16px 18px;
17710
18041
  }
17711
18042
  /* Topbar: back arrow + section name in uppercase */
17712
18043
  .ps-msd-topbar {
@@ -19697,6 +20028,55 @@ const STYLES$1 = `
19697
20028
  object-fit: contain; display: block;
19698
20029
  }
19699
20030
 
20031
+ .ps-msd-actions {
20032
+ position: sticky;
20033
+ bottom: -1px;
20034
+ z-index: 5;
20035
+ display: flex;
20036
+ align-items: center;
20037
+ gap: 10px;
20038
+ flex-shrink: 0;
20039
+ margin: auto -16px -18px;
20040
+ padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
20041
+ background: rgba(255,255,255,0.96);
20042
+ border-top: 1px solid var(--ps-border-subtle);
20043
+ backdrop-filter: blur(10px);
20044
+ -webkit-backdrop-filter: blur(10px);
20045
+ }
20046
+ .ps-msd-action-back {
20047
+ flex: 0 0 auto;
20048
+ font-size: 13px !important;
20049
+ padding: 10px 6px !important;
20050
+ }
20051
+ .ps-msd-primary-cta {
20052
+ flex: 1 1 0;
20053
+ min-width: 0;
20054
+ display: flex;
20055
+ align-items: center;
20056
+ justify-content: center;
20057
+ gap: 6px;
20058
+ padding: 12px 16px;
20059
+ border: 0;
20060
+ border-radius: 10px;
20061
+ background: var(--ps-accent);
20062
+ color: #fff;
20063
+ font-family: inherit;
20064
+ font-size: 14px;
20065
+ font-weight: 700;
20066
+ cursor: pointer;
20067
+ white-space: nowrap;
20068
+ }
20069
+ .ps-msd-primary-cta.ps-compact {
20070
+ flex: 0 0 auto;
20071
+ min-width: 88px;
20072
+ padding: 10px 14px;
20073
+ font-size: 13px;
20074
+ }
20075
+ .ps-msd-primary-cta:disabled {
20076
+ opacity: 0.6;
20077
+ cursor: default;
20078
+ }
20079
+
19700
20080
  /* RECOMMENDED SIZE card */
19701
20081
  .ps-msd-card {
19702
20082
  background: var(--ps-bg-primary);
@@ -20990,7 +21370,7 @@ function ProfileEditView({
20990
21370
  ] })
20991
21371
  ] });
20992
21372
  }
20993
- function HistoryResultThumb({ entry }) {
21373
+ function HistoryResultThumb({ entry, className = "ps-tryon-history-result-img" }) {
20994
21374
  const [blobUrl, setBlobUrl] = reactExports.useState(null);
20995
21375
  reactExports.useEffect(() => {
20996
21376
  let alive = true;
@@ -21009,7 +21389,7 @@ function HistoryResultThumb({ entry }) {
21009
21389
  }, [entry.id, entry.hasResult, entry.resultImageUrl]);
21010
21390
  const src = entry.resultImageUrl || blobUrl;
21011
21391
  if (!src) return null;
21012
- return /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src, alt: "", className: "ps-tryon-history-result-img" });
21392
+ return /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src, alt: "", className });
21013
21393
  }
21014
21394
  function DrawerPanel({
21015
21395
  drawer,
@@ -21034,14 +21414,15 @@ function DrawerPanel({
21034
21414
  setProfiles((prev) => [newProfile, ...prev]);
21035
21415
  setCreatingProfile(false);
21036
21416
  };
21037
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-tryon-drawer${drawer ? " ps-tryon-drawer-open" : ""}`, children: [
21417
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-tryon-drawer${drawer ? " ps-tryon-drawer-open" : ""}${drawer === "history" ? " ps-tryon-history-drawer" : ""}`, children: [
21038
21418
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-drawer-header", children: [
21039
21419
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-drawer-back", onClick: () => {
21040
21420
  setCreatingProfile(false);
21041
21421
  setDrawer(null);
21042
21422
  }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeftIcon, {}) }),
21043
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-drawer-title", children: creatingProfile ? t2("New Profile") : drawer === "profiles" ? t2("My Profiles") : t2("History") }),
21044
- drawer === "profiles" && !creatingProfile && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-drawer-add-btn", onClick: () => setCreatingProfile(true), children: "+" })
21423
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-drawer-title", children: creatingProfile ? t2("New Profile") : drawer === "profiles" ? t2("My Profiles") : t2("Your try-on history") }),
21424
+ drawer === "profiles" && !creatingProfile && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-drawer-add-btn", onClick: () => setCreatingProfile(true), children: "+" }),
21425
+ drawer === "history" && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-drawer-close", onClick: () => setDrawer(null), "aria-label": t2("Close"), children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 6l12 12M18 6L6 18" }) }) })
21045
21426
  ] }),
21046
21427
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-drawer-list", children: drawer === "profiles" && creatingProfile ? /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileEditView, { onSave: handleCreateProfile, onCancel: () => setCreatingProfile(false), t: t2 }) : drawer === "profiles" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
21047
21428
  /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-drawer-create", onClick: () => setCreatingProfile(true), children: [
@@ -21063,33 +21444,25 @@ function DrawerPanel({
21063
21444
  /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRightIcon, {})
21064
21445
  ] }, p2.id))
21065
21446
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: history.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-drawer-empty", children: t2("No history yet.") }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
21066
- history.map((entry, idx) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-item ps-tryon-history-clickable", onClick: () => restoreHistory(entry), children: [
21067
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-images", children: [
21068
- entry.productImage && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: entry.productImage, alt: "", className: "ps-tryon-history-thumb" }),
21069
- /* @__PURE__ */ jsxRuntimeExports.jsx(HistoryResultThumb, { entry })
21070
- ] }),
21071
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-info", children: [
21072
- /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-history-product", children: entry.productTitle || t2("Product") }),
21073
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-meta", children: [
21447
+ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-history-gallery", children: history.map((entry, idx) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-card", children: [
21448
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-tryon-history-card-main", onClick: () => restoreHistory(entry), children: [
21449
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-card-media", children: [
21450
+ entry.resultImageUrl || entry.hasResult ? /* @__PURE__ */ jsxRuntimeExports.jsx(HistoryResultThumb, { entry, className: "ps-tryon-history-card-img" }) : entry.productImage ? /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: entry.productImage, alt: "", className: "ps-tryon-history-card-img" }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-history-card-placeholder" }),
21451
+ entry.productImage && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: entry.productImage, alt: "", className: "ps-tryon-history-card-product" })
21452
+ ] }),
21453
+ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-history-card-title", children: entry.productTitle || t2("Product") }),
21454
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ps-tryon-history-card-meta", children: [
21074
21455
  entry.profileName ? `${entry.profileName} · ` : "",
21075
21456
  new Date(entry.date).toLocaleDateString()
21076
21457
  ] }),
21077
- entry.recommendedSize && !isMultiSection(entry) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-history-sizing", children: [
21078
- /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-history-size-badge", children: entry.recommendedSize }),
21079
- entry.reasoning && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-history-sizing-reason", children: entry.reasoning })
21080
- ] }),
21081
- isMultiSection(entry) && entry.sizingResult?.sections && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-history-sections", children: Object.entries(entry.sizingResult.sections).map(([name, sec]) => /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ps-tryon-history-section-chip", children: [
21082
- name,
21083
- ": ",
21084
- sec.recommendedSize
21085
- ] }, name)) }),
21086
- (entry.resultImageUrl || entry.hasResult) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-history-tryon-badge", children: t2("Try-on") })
21458
+ entry.recommendedSize && !isMultiSection(entry) && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-history-card-size", children: entry.recommendedSize }),
21459
+ isMultiSection(entry) && entry.sizingResult?.sections && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-history-card-sections", children: Object.entries(entry.sizingResult.sections).slice(0, 3).map(([name, sec]) => `${name}: ${sec.recommendedSize}`).join(" / ") })
21087
21460
  ] }),
21088
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-history-delete", onClick: (e) => {
21461
+ /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-history-delete ps-card-delete", onClick: (e) => {
21089
21462
  e.stopPropagation();
21090
21463
  setHistory((prev) => prev.filter((_, i) => i !== idx));
21091
- }, children: /* @__PURE__ */ jsxRuntimeExports.jsx(TrashIcon, {}) })
21092
- ] }, entry.id)),
21464
+ }, "aria-label": t2("Delete"), children: /* @__PURE__ */ jsxRuntimeExports.jsx(TrashIcon, {}) })
21465
+ ] }, entry.id)) }),
21093
21466
  /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-drawer-clear", onClick: () => setHistory([]), children: t2("Clear All") })
21094
21467
  ] }) }) })
21095
21468
  ] });
@@ -21741,29 +22114,6 @@ function CameraIcon() {
21741
22114
  /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "13", r: "4" })
21742
22115
  ] });
21743
22116
  }
21744
- function FitLinesIcon() {
21745
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
21746
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
21747
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
21748
- /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "9", r: "2" }),
21749
- /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "15", r: "2" })
21750
- ] });
21751
- }
21752
- function FullSizeIcon() {
21753
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
21754
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
21755
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16 3h3a2 2 0 0 1 2 2v3" }),
21756
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 21H5a2 2 0 0 1-2-2v-3" }),
21757
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
21758
- ] });
21759
- }
21760
- function DownloadIcon() {
21761
- return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
21762
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
21763
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7 10l5 5 5-5" }),
21764
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 15V3" })
21765
- ] });
21766
- }
21767
22117
  function MultiSectionMobile({
21768
22118
  productImage,
21769
22119
  productTitle,
@@ -21784,6 +22134,8 @@ function MultiSectionMobile({
21784
22134
  onToggleLines,
21785
22135
  onOpenImage,
21786
22136
  onDownload,
22137
+ imageActionBar,
22138
+ feedbackSlot,
21787
22139
  onImageLoad,
21788
22140
  profileCompletionCta,
21789
22141
  t: t2
@@ -21794,6 +22146,7 @@ function MultiSectionMobile({
21794
22146
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msr-scroll", children: [
21795
22147
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-eyebrow", children: t2("Sizing Profile") }),
21796
22148
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msr-product", children: [
22149
+ showingTryOn && imageActionBar,
21797
22150
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-msr-product-img-wrap${showingTryOn ? " ps-tryon" : ""}`, children: [
21798
22151
  /* @__PURE__ */ jsxRuntimeExports.jsx(
21799
22152
  "img",
@@ -21808,29 +22161,7 @@ function MultiSectionMobile({
21808
22161
  ),
21809
22162
  showLines && overlayNode,
21810
22163
  tryOnProcessing && tryOnStartedAt != null && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt, t: t2 }),
21811
- showingTryOn && onToggleLines && /* @__PURE__ */ jsxRuntimeExports.jsxs(
21812
- "button",
21813
- {
21814
- type: "button",
21815
- className: "ps-msr-fit-toggle",
21816
- onClick: onToggleLines,
21817
- "aria-pressed": !!showLines,
21818
- children: [
21819
- /* @__PURE__ */ jsxRuntimeExports.jsx(FitLinesIcon, {}),
21820
- showLines ? t2("Hide Fit") : t2("Show Fit")
21821
- ]
21822
- }
21823
- ),
21824
- showingTryOn && (onOpenImage || onDownload) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msr-media-actions", children: [
21825
- onOpenImage && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-msr-media-btn", onClick: onOpenImage, children: [
21826
- /* @__PURE__ */ jsxRuntimeExports.jsx(FullSizeIcon, {}),
21827
- t2("Full Size")
21828
- ] }),
21829
- onDownload && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-msr-media-btn", onClick: onDownload, children: [
21830
- /* @__PURE__ */ jsxRuntimeExports.jsx(DownloadIcon, {}),
21831
- t2("Download")
21832
- ] })
21833
- ] })
22164
+ showingTryOn && feedbackSlot
21834
22165
  ] }),
21835
22166
  /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-msr-product-name", children: productTitle })
21836
22167
  ] }),
@@ -22041,10 +22372,36 @@ function ProfileCompletionCta({
22041
22372
  }
22042
22373
  );
22043
22374
  }
22044
- function TryOnExperienceFeedback({ t: t2, isMobile }) {
22375
+ function TryOnExperienceFeedback({
22376
+ t: t2,
22377
+ isMobile,
22378
+ onSubmit
22379
+ }) {
22045
22380
  const [rating, setRating] = reactExports.useState(0);
22046
22381
  const [note, setNote] = reactExports.useState("");
22047
22382
  const [expanded, setExpanded] = reactExports.useState(false);
22383
+ const [status, setStatus] = reactExports.useState("idle");
22384
+ const noteRef = reactExports.useRef(null);
22385
+ const canEdit = status !== "submitting" && status !== "sent";
22386
+ const canSubmit = (rating > 0 || note.trim().length > 0) && canEdit;
22387
+ const resizeNote = reactExports.useCallback((node) => {
22388
+ if (!node) return;
22389
+ node.style.height = "auto";
22390
+ node.style.height = `${Math.min(node.scrollHeight, isMobile ? 86 : 78)}px`;
22391
+ }, [isMobile]);
22392
+ reactExports.useEffect(() => {
22393
+ resizeNote(noteRef.current);
22394
+ }, [note, resizeNote]);
22395
+ const submitFeedback = reactExports.useCallback(async () => {
22396
+ if (!canSubmit) return;
22397
+ setStatus("submitting");
22398
+ try {
22399
+ await onSubmit?.({ rating: rating || void 0, note: note.trim() || void 0 });
22400
+ setStatus("sent");
22401
+ } catch {
22402
+ setStatus("error");
22403
+ }
22404
+ }, [canSubmit, note, onSubmit, rating]);
22048
22405
  if (!expanded) {
22049
22406
  return /* @__PURE__ */ jsxRuntimeExports.jsxs(
22050
22407
  "button",
@@ -22078,7 +22435,12 @@ function TryOnExperienceFeedback({ t: t2, isMobile }) {
22078
22435
  {
22079
22436
  type: "button",
22080
22437
  className: `ps-tryon-feedback-star${value <= rating ? " is-active" : ""}`,
22081
- onClick: () => setRating(value),
22438
+ onClick: () => {
22439
+ if (!canEdit) return;
22440
+ setRating(value);
22441
+ setStatus("idle");
22442
+ },
22443
+ disabled: !canEdit,
22082
22444
  role: "radio",
22083
22445
  "aria-checked": rating === value,
22084
22446
  "aria-label": `${value} ${t2("stars")}`,
@@ -22087,16 +22449,76 @@ function TryOnExperienceFeedback({ t: t2, isMobile }) {
22087
22449
  value
22088
22450
  )) })
22089
22451
  ] }),
22090
- /* @__PURE__ */ jsxRuntimeExports.jsx(
22091
- "input",
22092
- {
22093
- className: "ps-tryon-feedback-note",
22094
- value: note,
22095
- onChange: (event) => setNote(event.target.value),
22096
- placeholder: t2("Optional note"),
22097
- maxLength: 120
22098
- }
22099
- )
22452
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-feedback-form", children: [
22453
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
22454
+ "textarea",
22455
+ {
22456
+ ref: noteRef,
22457
+ className: "ps-tryon-feedback-note",
22458
+ value: note,
22459
+ onChange: (event) => {
22460
+ if (!canEdit) return;
22461
+ setNote(event.target.value);
22462
+ setStatus("idle");
22463
+ resizeNote(event.currentTarget);
22464
+ },
22465
+ disabled: !canEdit,
22466
+ placeholder: t2("Optional note"),
22467
+ maxLength: 1e3,
22468
+ rows: 1
22469
+ }
22470
+ ),
22471
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
22472
+ "button",
22473
+ {
22474
+ type: "button",
22475
+ className: "ps-tryon-feedback-submit",
22476
+ onClick: submitFeedback,
22477
+ disabled: !canSubmit,
22478
+ "aria-label": t2("Send feedback"),
22479
+ children: status === "submitting" ? t2("Sending") : status === "sent" ? t2("Sent") : t2("Send")
22480
+ }
22481
+ )
22482
+ ] }),
22483
+ status === "error" && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-feedback-status", children: t2("Couldn't send. Try again.") })
22484
+ ] });
22485
+ }
22486
+ function ResultImageActionBar({
22487
+ showLines,
22488
+ canShowFit,
22489
+ onToggleFit,
22490
+ onOpenImage,
22491
+ onDownload,
22492
+ t: t2
22493
+ }) {
22494
+ if (!canShowFit && !onOpenImage && !onDownload) return null;
22495
+ return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-result-image-action-bar", children: [
22496
+ canShowFit && onToggleFit && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-result-image-action", onClick: onToggleFit, children: [
22497
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
22498
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
22499
+ /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
22500
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "9", r: "2" }),
22501
+ /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "15", r: "2" })
22502
+ ] }),
22503
+ showLines ? t2("Hide Fit") : t2("Show Fit")
22504
+ ] }),
22505
+ onOpenImage && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-result-image-action", onClick: onOpenImage, children: [
22506
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
22507
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
22508
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16 3h3a2 2 0 0 1 2 2v3" }),
22509
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 21H5a2 2 0 0 1-2-2v-3" }),
22510
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
22511
+ ] }),
22512
+ t2("Full Size")
22513
+ ] }),
22514
+ onDownload && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-result-image-action", onClick: onDownload, children: [
22515
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "13", height: "13", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.3", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
22516
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
22517
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7 10l5 5 5-5" }),
22518
+ /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 15V3" })
22519
+ ] }),
22520
+ t2("Download")
22521
+ ] })
22100
22522
  ] });
22101
22523
  }
22102
22524
  function garmentIconForSection(name) {
@@ -22623,12 +23045,14 @@ function SectionDetailView({
22623
23045
  onImageLoad,
22624
23046
  onOpenImage,
22625
23047
  onDownload,
23048
+ onFeedbackSubmit,
22626
23049
  onTryOn,
22627
23050
  tryOnProcessing,
22628
23051
  tryOnStartedAt,
22629
23052
  backLabel,
22630
23053
  internationalSizes,
22631
23054
  continueLabel,
23055
+ onContinue,
22632
23056
  renderRaw = false,
22633
23057
  sectionFound,
22634
23058
  allSizes,
@@ -22905,14 +23329,19 @@ function SectionDetailView({
22905
23329
  });
22906
23330
  return isFootwear ? rows.filter((row) => isFootLengthMeasurement(row.area)) : rows;
22907
23331
  }, [sectionResult, lengthEntry, userMeasurements, renderRaw, allSizes, displaySize, selectedLength, isFootwear]);
23332
+ const activeFitKeyRef = reactExports.useRef("");
22908
23333
  reactExports.useEffect(() => {
22909
23334
  if (!onActiveFitChange) return;
22910
- onActiveFitChange(fitRows.map((r2) => ({
23335
+ const nextRows = fitRows.map((r2) => ({
22911
23336
  area: r2.area,
22912
23337
  userNum: r2.userNum ?? 0,
22913
23338
  chartLabel: r2.chartLabel ?? "",
22914
23339
  fit: r2.fit ?? "good"
22915
- })));
23340
+ }));
23341
+ const nextKey = JSON.stringify(nextRows);
23342
+ if (activeFitKeyRef.current === nextKey) return;
23343
+ activeFitKeyRef.current = nextKey;
23344
+ onActiveFitChange(nextRows);
22916
23345
  }, [fitRows, onActiveFitChange]);
22917
23346
  const allowsLengthDisplay = !renderRaw && !isFootwear;
22918
23347
  const secAny = sectionResult;
@@ -23054,62 +23483,38 @@ function SectionDetailView({
23054
23483
  ] }),
23055
23484
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-msd-topbar-spacer" })
23056
23485
  ] }),
23057
- productImage && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-msd-image${isTryOnImage ? " ps-tryon" : ""}`, children: [
23058
- /* @__PURE__ */ jsxRuntimeExports.jsx(
23059
- "img",
23060
- {
23061
- src: productImage,
23062
- alt: productTitle || "",
23063
- className: "ps-msd-image-img",
23064
- onLoad: onImageLoad,
23065
- onClick: isTryOnImage && onOpenImage ? onOpenImage : void 0,
23066
- style: isTryOnImage && onOpenImage ? { cursor: "zoom-in" } : void 0
23067
- }
23068
- ),
23069
- showLines && (renderOverlayWithFit ? renderOverlayWithFit(fitRows.map((r2) => ({
23070
- area: r2.area,
23071
- userNum: r2.userNum ?? 0,
23072
- chartLabel: r2.chartLabel ?? "",
23073
- fit: r2.fit ?? "good"
23074
- }))) : overlayNode),
23075
- tryOnProcessing && tryOnStartedAt != null && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt, t: t2 }),
23076
- isTryOnImage && !isFootwear && onToggleLines && /* @__PURE__ */ jsxRuntimeExports.jsxs(
23077
- "button",
23486
+ productImage && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
23487
+ isTryOnImage && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(
23488
+ ResultImageActionBar,
23078
23489
  {
23079
- type: "button",
23080
- className: "ps-msr-fit-toggle",
23081
- onClick: onToggleLines,
23082
- "aria-pressed": !!showLines,
23083
- children: [
23084
- /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
23085
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
23086
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
23087
- /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "9", r: "2" }),
23088
- /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "15", r: "2" })
23089
- ] }),
23090
- showLines ? t2("Hide Fit") : t2("Show Fit")
23091
- ]
23490
+ showLines: !!showLines,
23491
+ canShowFit: !isFootwear && !!onToggleLines,
23492
+ onToggleFit: onToggleLines,
23493
+ onOpenImage,
23494
+ onDownload,
23495
+ t: t2
23092
23496
  }
23093
23497
  ),
23094
- isTryOnImage && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-feedback-slot", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, isMobile: true }) }),
23095
- isTryOnImage && (onOpenImage || onDownload) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msr-media-actions", children: [
23096
- onOpenImage && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-msr-media-btn", onClick: onOpenImage, children: [
23097
- /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
23098
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 3H5a2 2 0 0 0-2 2v3" }),
23099
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16 3h3a2 2 0 0 1 2 2v3" }),
23100
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M8 21H5a2 2 0 0 1-2-2v-3" }),
23101
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M16 21h3a2 2 0 0 0 2-2v-3" })
23102
- ] }),
23103
- t2("Full Size")
23104
- ] }),
23105
- onDownload && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-msr-media-btn", onClick: onDownload, children: [
23106
- /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.4", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [
23107
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
23108
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M7 10l5 5 5-5" }),
23109
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 15V3" })
23110
- ] }),
23111
- t2("Download")
23112
- ] })
23498
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-msd-image${isTryOnImage ? " ps-tryon" : ""}`, children: [
23499
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
23500
+ "img",
23501
+ {
23502
+ src: productImage,
23503
+ alt: productTitle || "",
23504
+ className: "ps-msd-image-img",
23505
+ onLoad: onImageLoad,
23506
+ onClick: isTryOnImage && onOpenImage ? onOpenImage : void 0,
23507
+ style: isTryOnImage && onOpenImage ? { cursor: "zoom-in" } : void 0
23508
+ }
23509
+ ),
23510
+ showLines && (renderOverlayWithFit ? renderOverlayWithFit(fitRows.map((r2) => ({
23511
+ area: r2.area,
23512
+ userNum: r2.userNum ?? 0,
23513
+ chartLabel: r2.chartLabel ?? "",
23514
+ fit: r2.fit ?? "good"
23515
+ }))) : overlayNode),
23516
+ tryOnProcessing && tryOnStartedAt != null && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt, t: t2 }),
23517
+ isTryOnImage && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-feedback-slot", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, isMobile: true, onSubmit: onFeedbackSubmit }) })
23113
23518
  ] })
23114
23519
  ] }),
23115
23520
  false,
@@ -23274,14 +23679,13 @@ function SectionDetailView({
23274
23679
  t2("based on your measurements and the garment's tailoring chart.")
23275
23680
  ] }) }),
23276
23681
  profileCompletionCta && /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, isMobile: true, t: t2 }),
23277
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", gap: 10, padding: "12px 0 4px", flexShrink: 0, alignItems: "center" }, children: [
23682
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msd-actions", children: [
23278
23683
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
23279
23684
  "button",
23280
23685
  {
23281
23686
  type: "button",
23282
- className: "ps-bp-back-btn",
23687
+ className: "ps-bp-back-btn ps-msd-action-back",
23283
23688
  onClick: onBack,
23284
- style: { fontSize: 13, padding: "10px 6px", flexShrink: 0 },
23285
23689
  children: [
23286
23690
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
23287
23691
  " ",
@@ -23295,25 +23699,7 @@ function SectionDetailView({
23295
23699
  type: "button",
23296
23700
  onClick: onTryOn,
23297
23701
  disabled: tryOnProcessing,
23298
- style: {
23299
- flex: "1 1 0",
23300
- minWidth: 0,
23301
- padding: "12px 16px",
23302
- borderRadius: 10,
23303
- background: "var(--ps-accent)",
23304
- color: "white",
23305
- border: "none",
23306
- fontSize: 14,
23307
- fontWeight: 700,
23308
- fontFamily: "inherit",
23309
- cursor: tryOnProcessing ? "default" : "pointer",
23310
- opacity: tryOnProcessing ? 0.6 : 1,
23311
- display: "flex",
23312
- alignItems: "center",
23313
- justifyContent: "center",
23314
- gap: 6,
23315
- whiteSpace: "nowrap"
23316
- },
23702
+ className: "ps-msd-primary-cta",
23317
23703
  children: [
23318
23704
  /* @__PURE__ */ jsxRuntimeExports.jsx(CameraIcon$1, { size: 14 }),
23319
23705
  tryOnProcessing ? `${t2("Generating try-on…")}${tryOnElapsedS > 0 ? ` ${tryOnElapsedS}s` : ""}` : t2("Try It On")
@@ -23324,24 +23710,7 @@ function SectionDetailView({
23324
23710
  {
23325
23711
  type: "button",
23326
23712
  onClick: onBack,
23327
- style: {
23328
- flex: isCompactMobileContinue ? "0 0 auto" : "1 1 0",
23329
- minWidth: isCompactMobileContinue ? 88 : 0,
23330
- padding: isCompactMobileContinue ? "10px 14px" : "12px 16px",
23331
- borderRadius: 10,
23332
- background: "var(--ps-accent)",
23333
- color: "white",
23334
- border: "none",
23335
- fontSize: isCompactMobileContinue ? 13 : 14,
23336
- fontWeight: 700,
23337
- fontFamily: "inherit",
23338
- cursor: "pointer",
23339
- display: "flex",
23340
- alignItems: "center",
23341
- justifyContent: "center",
23342
- gap: 6,
23343
- whiteSpace: "nowrap"
23344
- },
23713
+ className: `ps-msd-primary-cta${isCompactMobileContinue ? " ps-compact" : ""}`,
23345
23714
  children: [
23346
23715
  continueLabel || t2("Continue"),
23347
23716
  " →"
@@ -23564,7 +23933,7 @@ function SectionDetailView({
23564
23933
  ) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
23565
23934
  "button",
23566
23935
  {
23567
- onClick: onBack,
23936
+ onClick: continueLabel ? onContinue || onBack : onBack,
23568
23937
  style: {
23569
23938
  padding: "0.45vw 1.2vw",
23570
23939
  borderRadius: "0.4vw",
@@ -23600,11 +23969,14 @@ function SizeResultView({
23600
23969
  productImages,
23601
23970
  productCarouselItems,
23602
23971
  productTitle,
23972
+ productUrl,
23603
23973
  productMaterial,
23604
23974
  productDescription,
23605
23975
  sizingUnit,
23606
23976
  setView,
23607
23977
  handleDownload,
23978
+ onContinueShopping,
23979
+ onTryOnFeedbackSubmit,
23608
23980
  selectedFile,
23609
23981
  previewUrl,
23610
23982
  handleFileSelect,
@@ -24123,6 +24495,7 @@ function SizeResultView({
24123
24495
  return lengthEntries.find((le2) => le2.section.headers.some((h) => /height|altezza|estatura|\(cm\)/i.test(h))) || null;
24124
24496
  })(),
24125
24497
  onBack: () => setActiveSection(null),
24498
+ onContinue: onContinueShopping || onClose,
24126
24499
  internationalSizes: entry.secResult?.internationalSizes,
24127
24500
  productImage: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24128
24501
  productTitle,
@@ -24134,6 +24507,7 @@ function SizeResultView({
24134
24507
  onToggleLines: suppressFitOverlayActions ? void 0 : () => setShowLines(!showLines),
24135
24508
  onOpenImage: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0,
24136
24509
  onDownload: resultImageUrl && !tryOnProcessing ? handleDownload : void 0,
24510
+ onFeedbackSubmit: onTryOnFeedbackSubmit,
24137
24511
  onImageLoad: handleImgLoad,
24138
24512
  overlayNode: tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
24139
24513
  /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
@@ -24172,20 +24546,34 @@ function SizeResultView({
24172
24546
  ] });
24173
24547
  }
24174
24548
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2", children: [
24175
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
24176
- /* @__PURE__ */ jsxRuntimeExports.jsx(
24177
- "img",
24549
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-media-stack", children: [
24550
+ resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(
24551
+ ResultImageActionBar,
24178
24552
  {
24179
- src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24180
- alt: productTitle,
24181
- className: "ps-tryon-v2-bg-img",
24182
- onLoad: handleImgLoad,
24183
- style: resultImageUrl && !tryOnProcessing ? { cursor: "zoom-in" } : void 0,
24184
- onClick: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0
24553
+ showLines: !!showLines,
24554
+ canShowFit: !suppressFitOverlayActions,
24555
+ onToggleFit: () => setShowLines(!showLines),
24556
+ onOpenImage: () => setZoomImageUrl(resultImageUrl),
24557
+ onDownload: handleDownload,
24558
+ t: t2
24185
24559
  }
24186
24560
  ),
24187
- tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
24188
- /* @__PURE__ */ jsxRuntimeExports.jsx(RegenScanOverlay, { active: !!tryOnProcessing })
24561
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
24562
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
24563
+ "img",
24564
+ {
24565
+ src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24566
+ alt: productTitle,
24567
+ className: "ps-tryon-v2-bg-img",
24568
+ onLoad: handleImgLoad,
24569
+ style: resultImageUrl && !tryOnProcessing ? { cursor: "zoom-in" } : void 0,
24570
+ onClick: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0
24571
+ }
24572
+ ),
24573
+ tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
24574
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RegenScanOverlay, { active: !!tryOnProcessing }),
24575
+ resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, onSubmit: onTryOnFeedbackSubmit }) })
24576
+ ] })
24189
24577
  ] }),
24190
24578
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel", children: [
24191
24579
  mismatchNotice,
@@ -24207,9 +24595,11 @@ function SizeResultView({
24207
24595
  return lengthEntries.find((le2) => le2.section.headers.some((h) => /height|altezza|estatura|\(cm\)/i.test(h))) || null;
24208
24596
  })(),
24209
24597
  onBack: () => setActiveSection(null),
24598
+ onContinue: onContinueShopping || onClose,
24210
24599
  internationalSizes: entry.secResult?.internationalSizes,
24211
24600
  tryOnProcessing,
24212
24601
  tryOnStartedAt,
24602
+ onFeedbackSubmit: onTryOnFeedbackSubmit,
24213
24603
  t: t2,
24214
24604
  isFootwear: measurementType === "foot",
24215
24605
  userGender: shoeUserGender,
@@ -24248,11 +24638,23 @@ function SizeResultView({
24248
24638
  setGuideFile(selectedFile || null);
24249
24639
  setShowPhotoGuide(true);
24250
24640
  },
24251
- onClose,
24641
+ onClose: onContinueShopping || onClose,
24252
24642
  showLines,
24253
24643
  onToggleLines: suppressFitOverlayActions ? void 0 : () => setShowLines(!showLines),
24254
24644
  onOpenImage: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0,
24255
24645
  onDownload: resultImageUrl && !tryOnProcessing ? handleDownload : void 0,
24646
+ imageActionBar: resultImageUrl && !tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsx(
24647
+ ResultImageActionBar,
24648
+ {
24649
+ showLines: !!showLines,
24650
+ canShowFit: !suppressFitOverlayActions,
24651
+ onToggleFit: () => setShowLines(!showLines),
24652
+ onOpenImage: () => setZoomImageUrl(resultImageUrl),
24653
+ onDownload: handleDownload,
24654
+ t: t2
24655
+ }
24656
+ ) : null,
24657
+ feedbackSlot: resultImageUrl && !tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-feedback-slot", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, isMobile: true, onSubmit: onTryOnFeedbackSubmit }) }) : null,
24256
24658
  onImageLoad: handleImgLoad,
24257
24659
  profileCompletionCta: profileCompletionCta ? /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, isMobile: true, t: t2 }) : null,
24258
24660
  overlayNode: resultImageUrl && poseReady && poseLines ? /* @__PURE__ */ jsxRuntimeExports.jsx(
@@ -24285,60 +24687,55 @@ function SizeResultView({
24285
24687
  ) : (
24286
24688
  /* ── Desktop section picker: split layout — image left, image cards right ── */
24287
24689
  /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2", children: [
24288
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
24289
- /* @__PURE__ */ jsxRuntimeExports.jsx(
24290
- "img",
24690
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-media-stack", children: [
24691
+ resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(
24692
+ ResultImageActionBar,
24291
24693
  {
24292
- src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24293
- alt: productTitle,
24294
- className: "ps-tryon-v2-bg-img",
24295
- onLoad: handleImgLoad,
24296
- style: resultImageUrl && !tryOnProcessing ? { cursor: "zoom-in" } : void 0,
24297
- onClick: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0
24694
+ showLines: !!showLines,
24695
+ canShowFit: !suppressFitOverlayActions,
24696
+ onToggleFit: () => setShowLines(!showLines),
24697
+ onOpenImage: () => setZoomImageUrl(resultImageUrl),
24698
+ onDownload: handleDownload,
24699
+ t: t2
24298
24700
  }
24299
24701
  ),
24300
- tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
24301
- /* @__PURE__ */ jsxRuntimeExports.jsx(RegenScanOverlay, { active: !!tryOnProcessing }),
24302
- resultImageUrl && !tryOnProcessing && poseReady && poseLines && /* @__PURE__ */ jsxRuntimeExports.jsx(MeasurementOverlay, { lines: poseLines, fitRows: (() => {
24303
- const all = [...sizingResult?.matchDetails || []];
24304
- if (sizingResult?.sections) {
24305
- for (const sec of Object.values(sizingResult.sections)) {
24306
- if (sec.matchDetails) all.push(...sec.matchDetails);
24702
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
24703
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
24704
+ "img",
24705
+ {
24706
+ src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24707
+ alt: productTitle,
24708
+ className: "ps-tryon-v2-bg-img",
24709
+ onLoad: handleImgLoad,
24710
+ style: resultImageUrl && !tryOnProcessing ? { cursor: "zoom-in" } : void 0,
24711
+ onClick: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0
24307
24712
  }
24308
- }
24309
- const seen = /* @__PURE__ */ new Set();
24310
- return all.filter((m2) => {
24311
- const k2 = m2.measurement.toLowerCase();
24312
- if (seen.has(k2)) return false;
24313
- seen.add(k2);
24314
- return true;
24315
- }).map((m2) => ({ area: m2.measurement, userNum: parseFloat(m2.userValue) || 0, chartLabel: m2.chartRange || "", fit: m2.fit }));
24316
- })(), show: showLines, imgWidth: imgDims.w, imgHeight: imgDims.h }),
24317
- resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-img-actions", children: [
24318
- /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2 }),
24319
- !suppressFitOverlayActions && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setShowLines(!showLines), children: [
24320
- /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", style: { marginRight: "0.3vw" }, children: [
24321
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "9", x2: "20", y2: "9" }),
24322
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "4", y1: "15", x2: "20", y2: "15" }),
24323
- /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "7", cy: "9", r: "2" }),
24324
- /* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "17", cy: "15", r: "2" })
24325
- ] }),
24326
- showLines ? t2("Hide Fit") : t2("Show Fit")
24327
- ] }),
24328
- suppressFitOverlayActions && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setZoomImageUrl(resultImageUrl), children: t2("Full Size") }),
24329
- /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-sr-glass-btn", onClick: handleDownload, children: [
24330
- /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", style: { marginRight: "0.3vw" }, children: [
24331
- /* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
24332
- /* @__PURE__ */ jsxRuntimeExports.jsx("polyline", { points: "7 10 12 15 17 10" }),
24333
- /* @__PURE__ */ jsxRuntimeExports.jsx("line", { x1: "12", y1: "15", x2: "12", y2: "3" })
24334
- ] }),
24335
- t2("Download")
24336
- ] })
24713
+ ),
24714
+ tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
24715
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RegenScanOverlay, { active: !!tryOnProcessing }),
24716
+ resultImageUrl && !tryOnProcessing && poseReady && poseLines && /* @__PURE__ */ jsxRuntimeExports.jsx(MeasurementOverlay, { lines: poseLines, fitRows: (() => {
24717
+ const all = [...sizingResult?.matchDetails || []];
24718
+ if (sizingResult?.sections) {
24719
+ for (const sec of Object.values(sizingResult.sections)) {
24720
+ if (sec.matchDetails) all.push(...sec.matchDetails);
24721
+ }
24722
+ }
24723
+ const seen = /* @__PURE__ */ new Set();
24724
+ return all.filter((m2) => {
24725
+ const k2 = m2.measurement.toLowerCase();
24726
+ if (seen.has(k2)) return false;
24727
+ seen.add(k2);
24728
+ return true;
24729
+ }).map((m2) => ({ area: m2.measurement, userNum: parseFloat(m2.userValue) || 0, chartLabel: m2.chartRange || "", fit: m2.fit }));
24730
+ })(), show: showLines, imgWidth: imgDims.w, imgHeight: imgDims.h }),
24731
+ resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, onSubmit: onTryOnFeedbackSubmit }) })
24337
24732
  ] })
24338
24733
  ] }),
24339
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel", children: [
24340
- /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Perfect Fit") }),
24341
- /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-v2-subtitle", children: t2("Tap any section for detailed breakdown") }),
24734
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel ps-tryon-v2-result-panel", children: [
24735
+ profileCompletionCta ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-profile-head ps-expanded", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, placement: "header", t: t2 }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-result-copy", children: [
24736
+ /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Perfect Fit") }),
24737
+ /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-v2-subtitle", children: t2("Tap any section for detailed breakdown") })
24738
+ ] }),
24342
24739
  mismatchNotice,
24343
24740
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-sep" }),
24344
24741
  /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-cards-v2", children: sectionEntries.map(({ name, secResult }, idx) => {
@@ -24379,8 +24776,7 @@ function SizeResultView({
24379
24776
  sectionImg && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: sectionImg, alt: name, className: "ps-tryon-sr-card-v2-img" })
24380
24777
  ] }, name);
24381
24778
  }) }),
24382
- profileCompletionCta && /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, t: t2 }),
24383
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: "0.5vw", gap: "0.5vw" }, children: [
24779
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-result-actions", children: [
24384
24780
  /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-bp-back-btn", onClick: () => setView("body-profile"), type: "button", children: [
24385
24781
  /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
24386
24782
  " ",
@@ -24391,7 +24787,7 @@ function SizeResultView({
24391
24787
  {
24392
24788
  className: "ps-tryon-v2-cta",
24393
24789
  style: { marginTop: 0 },
24394
- onClick: onClose,
24790
+ onClick: onContinueShopping || onClose,
24395
24791
  children: [
24396
24792
  t2("Continue Shopping"),
24397
24793
  " →"
@@ -24402,7 +24798,7 @@ function SizeResultView({
24402
24798
  {
24403
24799
  className: "ps-tryon-v2-cta",
24404
24800
  style: { marginTop: 0 },
24405
- onClick: onClose,
24801
+ onClick: onContinueShopping || onClose,
24406
24802
  children: [
24407
24803
  t2("Continue Shopping"),
24408
24804
  " →"
@@ -24472,6 +24868,7 @@ function SizeResultView({
24472
24868
  if (resultImageUrl) onResetTryOn?.();
24473
24869
  setView("body-profile");
24474
24870
  },
24871
+ onContinue: onContinueShopping || onClose,
24475
24872
  backLabel: t2("Back"),
24476
24873
  internationalSizes: singleInternationalSizes,
24477
24874
  onTryOn: resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
@@ -24492,6 +24889,7 @@ function SizeResultView({
24492
24889
  onToggleLines: suppressFitOverlayActions ? void 0 : () => setShowLines(!showLines),
24493
24890
  onOpenImage: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0,
24494
24891
  onDownload: resultImageUrl && !tryOnProcessing ? handleDownload : void 0,
24892
+ onFeedbackSubmit: onTryOnFeedbackSubmit,
24495
24893
  onImageLoad: handleImgLoad,
24496
24894
  overlayNode: resultImageUrl && poseReady && poseLines ? /* @__PURE__ */ jsxRuntimeExports.jsx(
24497
24895
  MeasurementOverlay,
@@ -24509,38 +24907,46 @@ function SizeResultView({
24509
24907
  ] });
24510
24908
  }
24511
24909
  return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2", children: [
24512
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
24513
- /* @__PURE__ */ jsxRuntimeExports.jsx(
24514
- "img",
24910
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-media-stack", children: [
24911
+ resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(
24912
+ ResultImageActionBar,
24515
24913
  {
24516
- src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24517
- alt: productTitle,
24518
- className: "ps-tryon-v2-bg-img",
24519
- onLoad: handleImgLoad,
24520
- style: resultImageUrl && !tryOnProcessing ? { cursor: "zoom-in" } : void 0,
24521
- onClick: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0
24522
- }
24523
- ),
24524
- tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
24525
- /* @__PURE__ */ jsxRuntimeExports.jsx(RegenScanOverlay, { active: !!tryOnProcessing }),
24526
- resultImageUrl && !tryOnProcessing && poseReady && poseLines && /* @__PURE__ */ jsxRuntimeExports.jsx(
24527
- MeasurementOverlay,
24528
- {
24529
- lines: poseLines,
24530
- fitRows: activeFitRows.length > 0 ? activeFitRows : (sizingResult?.matchDetails || []).map((m2) => ({ area: m2.measurement, userNum: parseFloat(m2.userValue) || 0, chartLabel: m2.chartRange || "", fit: m2.fit })),
24531
- show: showLines,
24532
- imgWidth: imgDims.w,
24533
- imgHeight: imgDims.h
24914
+ showLines: !!showLines,
24915
+ canShowFit: !suppressFitOverlayActions,
24916
+ onToggleFit: () => setShowLines(!showLines),
24917
+ onOpenImage: () => setZoomImageUrl(resultImageUrl),
24918
+ onDownload: handleDownload,
24919
+ t: t2
24534
24920
  }
24535
24921
  ),
24536
- resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-img-actions", children: [
24537
- /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2 }),
24538
- !suppressFitOverlayActions && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setShowLines(!showLines), children: showLines ? t2("Hide Fit") : t2("Show Fit") }),
24539
- suppressFitOverlayActions && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: () => setZoomImageUrl(resultImageUrl), children: t2("Full Size") }),
24540
- /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: "ps-tryon-sr-glass-btn", onClick: handleDownload, children: t2("Download") })
24922
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-bg", style: { position: "relative" }, children: [
24923
+ /* @__PURE__ */ jsxRuntimeExports.jsx(
24924
+ "img",
24925
+ {
24926
+ src: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
24927
+ alt: productTitle,
24928
+ className: "ps-tryon-v2-bg-img",
24929
+ onLoad: handleImgLoad,
24930
+ style: resultImageUrl && !tryOnProcessing ? { cursor: "zoom-in" } : void 0,
24931
+ onClick: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0
24932
+ }
24933
+ ),
24934
+ tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnGenerationBadge, { tryOnStartedAt: tryOnStartedAt ?? null, t: t2 }),
24935
+ /* @__PURE__ */ jsxRuntimeExports.jsx(RegenScanOverlay, { active: !!tryOnProcessing }),
24936
+ resultImageUrl && !tryOnProcessing && poseReady && poseLines && /* @__PURE__ */ jsxRuntimeExports.jsx(
24937
+ MeasurementOverlay,
24938
+ {
24939
+ lines: poseLines,
24940
+ fitRows: activeFitRows.length > 0 ? activeFitRows : (sizingResult?.matchDetails || []).map((m2) => ({ area: m2.measurement, userNum: parseFloat(m2.userValue) || 0, chartLabel: m2.chartRange || "", fit: m2.fit })),
24941
+ show: showLines,
24942
+ imgWidth: imgDims.w,
24943
+ imgHeight: imgDims.h
24944
+ }
24945
+ ),
24946
+ resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, onSubmit: onTryOnFeedbackSubmit }) })
24541
24947
  ] })
24542
24948
  ] }),
24543
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel", children: [
24949
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-tryon-v2-panel${activeSection ? "" : " ps-tryon-v2-result-panel"}`, children: [
24544
24950
  mismatchNotice,
24545
24951
  activeSection === sectionName ? (
24546
24952
  /* DETAIL VIEW — full size table, same as multi-garment */
@@ -24563,12 +24969,14 @@ function SizeResultView({
24563
24969
  setActiveSection(null);
24564
24970
  }
24565
24971
  },
24972
+ onContinue: onContinueShopping || onClose,
24566
24973
  backLabel: t2("Back"),
24567
24974
  internationalSizes: singleInternationalSizes,
24568
24975
  onTryOn: resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
24569
24976
  continueLabel: resultImageUrl ? t2("Continue Shopping") : void 0,
24570
24977
  tryOnProcessing,
24571
24978
  tryOnStartedAt,
24979
+ onFeedbackSubmit: onTryOnFeedbackSubmit,
24572
24980
  t: t2,
24573
24981
  renderRaw: isAccessory,
24574
24982
  isFootwear: measurementType === "foot",
@@ -24616,7 +25024,7 @@ function SizeResultView({
24616
25024
  }
24617
25025
  ) }),
24618
25026
  hasCarousel && /* @__PURE__ */ jsxRuntimeExports.jsx(ProductPhotoCarouselCard, { items: carouselItems.length > 0 ? carouselItems : void 0, photos: productImages, productTitle, t: t2 }),
24619
- /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginTop: "0.5vw", gap: "0.5vw" }, children: [
25027
+ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-result-actions", children: [
24620
25028
  /* @__PURE__ */ jsxRuntimeExports.jsxs(
24621
25029
  "button",
24622
25030
  {
@@ -24633,10 +25041,10 @@ function SizeResultView({
24633
25041
  ]
24634
25042
  }
24635
25043
  ),
24636
- resultImageUrl && !tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-v2-cta", style: { marginTop: 0 }, onClick: onClose, children: [
25044
+ resultImageUrl && !tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-v2-cta", style: { marginTop: 0 }, onClick: onContinueShopping || onClose, children: [
24637
25045
  t2("Continue Shopping"),
24638
25046
  " →"
24639
- ] }) : vtoExcluded ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-v2-cta", style: { marginTop: 0 }, onClick: onClose, children: [
25047
+ ] }) : vtoExcluded ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-v2-cta", style: { marginTop: 0 }, onClick: onContinueShopping || onClose, children: [
24640
25048
  t2("Continue Shopping"),
24641
25049
  " →"
24642
25050
  ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
@@ -31699,6 +32107,13 @@ if (typeof document !== "undefined") {
31699
32107
  }
31700
32108
  }
31701
32109
  const PROFILE_COMPLETION_DRAFT_KEY = "profile_completion_draft";
32110
+ const TRYON_FEEDBACK_SUBMITTED_KEY = "tryon_feedback_submitted";
32111
+ function buildTryOnFeedbackKey(input) {
32112
+ if (input.jobId) return `job:${input.jobId}`;
32113
+ if (input.historyEntryId) return `history:${input.historyEntryId}`;
32114
+ if (input.resultImageUrl) return `result:${input.resultImageUrl.slice(0, 180)}`;
32115
+ return `fallback:${input.productId || input.productTitle || "product"}:${input.recommendedSize || "size"}`;
32116
+ }
31702
32117
  function positiveNumber(value) {
31703
32118
  const n2 = typeof value === "number" ? value : parseFloat(String(value ?? ""));
31704
32119
  return Number.isFinite(n2) && n2 > 0 ? n2 : void 0;
@@ -31782,6 +32197,7 @@ function PrimeStyleTryonInner({
31782
32197
  productCarouselItems,
31783
32198
  garmentReferenceImage,
31784
32199
  productTitle = "Product",
32200
+ productUrl,
31785
32201
  productId,
31786
32202
  productCategory,
31787
32203
  productGender,
@@ -31834,6 +32250,17 @@ function PrimeStyleTryonInner({
31834
32250
  }, [productTagsKey]);
31835
32251
  const effectiveProductImages = stableProductImages.length > 0 ? stableProductImages : void 0;
31836
32252
  const effectiveProductCarouselItems = stableProductCarouselItems.length > 0 ? stableProductCarouselItems : void 0;
32253
+ const effectiveProductUrl = reactExports.useMemo(() => {
32254
+ const source = productUrl?.trim();
32255
+ if (source) {
32256
+ try {
32257
+ return typeof window !== "undefined" ? new URL(source, window.location.origin).href : source;
32258
+ } catch {
32259
+ return source;
32260
+ }
32261
+ }
32262
+ return typeof window !== "undefined" ? window.location.href : void 0;
32263
+ }, [productUrl]);
31837
32264
  const resolvedProductFitType = reactExports.useMemo(
31838
32265
  () => detectProductFitType({
31839
32266
  productFitType,
@@ -32011,12 +32438,15 @@ function PrimeStyleTryonInner({
32011
32438
  const [profileAuthLoadingProvider, setProfileAuthLoadingProvider] = reactExports.useState(null);
32012
32439
  const [history, setHistory] = reactExports.useState(() => lsGet("history", []).map(normalizeHistoryEntry));
32013
32440
  const currentHistoryEntryIdRef = reactExports.useRef(null);
32441
+ const currentTryOnJobIdRef = reactExports.useRef(null);
32442
+ const submittedFeedbackKeysRef = reactExports.useRef(new Set(lsGet(TRYON_FEEDBACK_SUBMITTED_KEY, [])));
32014
32443
  const [mobileMenuOpen, setMobileMenuOpen] = reactExports.useState(false);
32015
32444
  const mobileMenuBtnRef = reactExports.useRef(null);
32016
32445
  const [restoredProductImage, setRestoredProductImage] = reactExports.useState(null);
32017
32446
  const [restoredProductImages, setRestoredProductImages] = reactExports.useState(null);
32018
32447
  const [restoredProductCarouselItems, setRestoredProductCarouselItems] = reactExports.useState(null);
32019
32448
  const [restoredProductTitle, setRestoredProductTitle] = reactExports.useState(null);
32449
+ const [restoredProductUrl, setRestoredProductUrl] = reactExports.useState(null);
32020
32450
  const [activeProfileId, setActiveProfileIdState] = reactExports.useState(() => getActiveProfileId());
32021
32451
  const [estimatingProfileIds, setEstimatingProfileIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
32022
32452
  const [deleteConfirmId, setDeleteConfirmId] = reactExports.useState(null);
@@ -32534,6 +32964,13 @@ function PrimeStyleTryonInner({
32534
32964
  setSizingResult(null);
32535
32965
  setResultImageUrl(null);
32536
32966
  currentHistoryEntryIdRef.current = null;
32967
+ currentTryOnJobIdRef.current = null;
32968
+ setRestoredProductImage(null);
32969
+ setRestoredProductImages(null);
32970
+ setRestoredProductCarouselItems(null);
32971
+ setRestoredProductTitle(null);
32972
+ setRestoredProductUrl(null);
32973
+ setRestoredProductUrl(null);
32537
32974
  setSizingLoading(true);
32538
32975
  setEstimationDone(hasStored);
32539
32976
  if (hasStored) {
@@ -32621,12 +33058,18 @@ function PrimeStyleTryonInner({
32621
33058
  setProfileSaved(false);
32622
33059
  formRef.current = {};
32623
33060
  setFormGender("male");
33061
+ setRestoredProductImage(null);
33062
+ setRestoredProductImages(null);
33063
+ setRestoredProductCarouselItems(null);
33064
+ setRestoredProductTitle(null);
33065
+ setRestoredProductUrl(null);
32624
33066
  if (!tryOnInFlight) {
32625
33067
  setResultImageUrl(null);
32626
33068
  setSizingResult(null);
32627
33069
  historySavedRef.current = false;
32628
33070
  historyTryonSavedRef.current = false;
32629
33071
  currentHistoryEntryIdRef.current = null;
33072
+ currentTryOnJobIdRef.current = null;
32630
33073
  unsubRef.current?.();
32631
33074
  unsubRef.current = null;
32632
33075
  if (pollingRef.current) {
@@ -32731,6 +33174,7 @@ function PrimeStyleTryonInner({
32731
33174
  return;
32732
33175
  }
32733
33176
  if (update.status === "completed" && update.imageUrl) {
33177
+ currentTryOnJobIdRef.current = update.galleryId;
32734
33178
  if (shouldUseShopifyCartAttribution(apiUrl)) {
32735
33179
  setLastCompletedProduct(effectiveProductId ?? null, productTitle || null);
32736
33180
  }
@@ -33039,10 +33483,12 @@ function PrimeStyleTryonInner({
33039
33483
  setSizingResult(null);
33040
33484
  setResultImageUrl(null);
33041
33485
  currentHistoryEntryIdRef.current = null;
33486
+ currentTryOnJobIdRef.current = null;
33042
33487
  setRestoredProductImage(null);
33043
33488
  setRestoredProductImages(null);
33044
33489
  setRestoredProductCarouselItems(null);
33045
33490
  setRestoredProductTitle(null);
33491
+ setRestoredProductUrl(null);
33046
33492
  if (previewUrl) URL.revokeObjectURL(previewUrl);
33047
33493
  setSelectedFile(null);
33048
33494
  selectedFileRef.current = null;
@@ -33108,6 +33554,7 @@ function PrimeStyleTryonInner({
33108
33554
  historySavedRef.current = false;
33109
33555
  historyTryonSavedRef.current = false;
33110
33556
  currentHistoryEntryIdRef.current = null;
33557
+ currentTryOnJobIdRef.current = null;
33111
33558
  setSizingLoading(true);
33112
33559
  setEstimationDone(false);
33113
33560
  setView("size-result");
@@ -33338,6 +33785,7 @@ function PrimeStyleTryonInner({
33338
33785
  selectedFileRef.current = overrideFile;
33339
33786
  }
33340
33787
  completedRef.current = false;
33788
+ currentTryOnJobIdRef.current = null;
33341
33789
  setTryOnProcessing(true);
33342
33790
  setTryOnStartedAt(Date.now());
33343
33791
  const vtoCategory = measurementTypeToVtoCategory(measurementType, resolvedProductFitType);
@@ -33475,6 +33923,7 @@ function PrimeStyleTryonInner({
33475
33923
  modelImageId: modelImageIdRef.current ?? void 0
33476
33924
  }
33477
33925
  );
33926
+ currentTryOnJobIdRef.current = response.jobId;
33478
33927
  if (response.modelImageId) modelImageIdRef.current = response.modelImageId;
33479
33928
  onProcessing?.(response.jobId);
33480
33929
  const usePollingOnly = shouldUseShopifyCartAttribution(apiUrl);
@@ -33545,6 +33994,59 @@ function PrimeStyleTryonInner({
33545
33994
  }).catch(() => window.open(resultImageUrl, "_blank"));
33546
33995
  }
33547
33996
  }, [resultImageUrl]);
33997
+ const handleContinueShopping = reactExports.useCallback(() => {
33998
+ const historyUrl = restoredProductUrl || "";
33999
+ if (historyUrl && typeof window !== "undefined") {
34000
+ try {
34001
+ window.open(new URL(historyUrl, window.location.origin).href, "_blank", "noopener,noreferrer");
34002
+ } catch {
34003
+ window.open(historyUrl, "_blank", "noopener,noreferrer");
34004
+ }
34005
+ }
34006
+ handleClose();
34007
+ }, [handleClose, restoredProductUrl]);
34008
+ const handleTryOnFeedbackSubmit = reactExports.useCallback(async ({ rating, note }) => {
34009
+ const profileLoggedIn = Boolean(profileSession);
34010
+ const activeProfile = profileLoggedIn ? profiles.find((profile) => profile.id === activeProfileId) : null;
34011
+ const jobId = currentTryOnJobIdRef.current ?? void 0;
34012
+ const historyEntryId = currentHistoryEntryIdRef.current ?? void 0;
34013
+ const feedbackKey = buildTryOnFeedbackKey({
34014
+ jobId,
34015
+ historyEntryId,
34016
+ resultImageUrl,
34017
+ productId: effectiveProductId,
34018
+ productTitle: restoredProductTitle || productTitle,
34019
+ recommendedSize: sizingResult?.recommendedSize
34020
+ });
34021
+ if (submittedFeedbackKeysRef.current.has(feedbackKey)) return;
34022
+ submittedFeedbackKeysRef.current.add(feedbackKey);
34023
+ lsSet(TRYON_FEEDBACK_SUBMITTED_KEY, Array.from(submittedFeedbackKeysRef.current).slice(-80));
34024
+ const payload = {
34025
+ jobId,
34026
+ historyEntryId,
34027
+ rating,
34028
+ note: note?.trim() || void 0,
34029
+ productId: effectiveProductId,
34030
+ productTitle: restoredProductTitle || productTitle,
34031
+ productUrl: restoredProductUrl || effectiveProductUrl,
34032
+ recommendedSize: sizingResult?.recommendedSize,
34033
+ profileLoggedIn,
34034
+ profileId: activeProfile?.id,
34035
+ profileName: activeProfile?.name,
34036
+ profileAccessToken: profileSession?.accessToken
34037
+ };
34038
+ if (shouldUseShopifyCartAttribution(apiUrl)) {
34039
+ logTryOnFeedback(payload);
34040
+ return;
34041
+ }
34042
+ try {
34043
+ await apiRef.current?.submitTryOnFeedback(payload);
34044
+ } catch (error) {
34045
+ submittedFeedbackKeysRef.current.delete(feedbackKey);
34046
+ lsSet(TRYON_FEEDBACK_SUBMITTED_KEY, Array.from(submittedFeedbackKeysRef.current).slice(-80));
34047
+ throw error;
34048
+ }
34049
+ }, [activeProfileId, apiUrl, effectiveProductId, effectiveProductUrl, productTitle, profileSession, profiles, restoredProductTitle, restoredProductUrl, resultImageUrl, sizingResult?.recommendedSize]);
33548
34050
  const handleRetry = reactExports.useCallback(() => {
33549
34051
  completedRef.current = false;
33550
34052
  cleanupJob();
@@ -33555,6 +34057,12 @@ function PrimeStyleTryonInner({
33555
34057
  historySavedRef.current = false;
33556
34058
  historyTryonSavedRef.current = false;
33557
34059
  currentHistoryEntryIdRef.current = null;
34060
+ currentTryOnJobIdRef.current = null;
34061
+ setRestoredProductImage(null);
34062
+ setRestoredProductImages(null);
34063
+ setRestoredProductCarouselItems(null);
34064
+ setRestoredProductTitle(null);
34065
+ setRestoredProductUrl(null);
33558
34066
  setErrorMessage(null);
33559
34067
  setSizingMethod(null);
33560
34068
  setSizingResult(null);
@@ -33691,6 +34199,8 @@ function PrimeStyleTryonInner({
33691
34199
  id: id2,
33692
34200
  productId,
33693
34201
  productTitle,
34202
+ productUrl: effectiveProductUrl,
34203
+ jobId: currentTryOnJobIdRef.current ?? void 0,
33694
34204
  productImage,
33695
34205
  productImages: effectiveProductImages?.slice(0, 12),
33696
34206
  productCarouselItems: effectiveProductCarouselItems?.slice(0, 12),
@@ -33725,7 +34235,7 @@ function PrimeStyleTryonInner({
33725
34235
  return next;
33726
34236
  });
33727
34237
  return id2;
33728
- }, [productId, productTitle, productImage, effectiveProductImages, effectiveProductCarouselItems, resultImageUrl, sizingResult, sizeGuide, activeProfileId, profiles, selectedFile]);
34238
+ }, [productId, productTitle, effectiveProductUrl, productImage, effectiveProductImages, effectiveProductCarouselItems, resultImageUrl, sizingResult, sizeGuide, activeProfileId, profiles, selectedFile]);
33729
34239
  const persistHistoryResult = reactExports.useCallback((entryId, imageUrl, cleanupWhenIdle) => {
33730
34240
  void (async () => {
33731
34241
  const durableResultUrl = durableHistoryImageUrl(imageUrl);
@@ -33743,6 +34253,7 @@ function PrimeStyleTryonInner({
33743
34253
  if (entry.id !== entryId) return entry;
33744
34254
  return {
33745
34255
  ...entry,
34256
+ ...currentTryOnJobIdRef.current ? { jobId: currentTryOnJobIdRef.current } : {},
33746
34257
  ...durableResultUrl ? { resultImageUrl: durableResultUrl } : {},
33747
34258
  ...storedResult ? { hasResult: true } : {}
33748
34259
  };
@@ -33798,6 +34309,7 @@ function PrimeStyleTryonInner({
33798
34309
  if (idx < 0) return prev;
33799
34310
  const updated = {
33800
34311
  ...prev[idx],
34312
+ ...currentTryOnJobIdRef.current ? { jobId: currentTryOnJobIdRef.current } : {},
33801
34313
  ...durableResultUrl ? { resultImageUrl: durableResultUrl } : {},
33802
34314
  hasResult: true,
33803
34315
  ...selectedSizes.length ? { selectedSizes } : {}
@@ -33815,6 +34327,7 @@ function PrimeStyleTryonInner({
33815
34327
  historySavedRef.current = false;
33816
34328
  historyTryonSavedRef.current = false;
33817
34329
  currentHistoryEntryIdRef.current = null;
34330
+ currentTryOnJobIdRef.current = null;
33818
34331
  }
33819
34332
  }, [view, sizingResult, resultImageUrl]);
33820
34333
  const restoreHistory = reactExports.useCallback((entry) => {
@@ -33825,6 +34338,7 @@ function PrimeStyleTryonInner({
33825
34338
  historySavedRef.current = true;
33826
34339
  historyTryonSavedRef.current = !!entry.resultImageUrl || !!entry.hasResult;
33827
34340
  currentHistoryEntryIdRef.current = entry.id;
34341
+ currentTryOnJobIdRef.current = entry.jobId || null;
33828
34342
  autoTryOnFiredRef.current = true;
33829
34343
  const isCurrentProductEntry = entry.productId && productId ? entry.productId === productId : !!entry.productTitle && entry.productTitle === productTitle;
33830
34344
  setRestoredProductImage(entry.productImage || null);
@@ -33835,6 +34349,7 @@ function PrimeStyleTryonInner({
33835
34349
  entry.productCarouselItems?.length ? entry.productCarouselItems : isCurrentProductEntry && effectiveProductCarouselItems?.length ? effectiveProductCarouselItems : null
33836
34350
  );
33837
34351
  setRestoredProductTitle(entry.productTitle || null);
34352
+ setRestoredProductUrl(entry.productUrl || null);
33838
34353
  if (entry.sizingResult) {
33839
34354
  setSizingResult(entry.sizingResult);
33840
34355
  } else if (entry.recommendedSize) {
@@ -34072,11 +34587,14 @@ function PrimeStyleTryonInner({
34072
34587
  productImages: restoredProductImages || (restoredProductImage ? [restoredProductImage] : effectiveProductImages),
34073
34588
  productCarouselItems: restoredProductCarouselItems || (restoredProductImage ? void 0 : effectiveProductCarouselItems),
34074
34589
  productTitle: restoredProductTitle || productTitle,
34590
+ productUrl: restoredProductUrl || effectiveProductUrl,
34075
34591
  productMaterial,
34076
34592
  productDescription,
34077
34593
  sizingUnit,
34078
34594
  setView,
34079
34595
  handleDownload,
34596
+ onContinueShopping: handleContinueShopping,
34597
+ onTryOnFeedbackSubmit: handleTryOnFeedbackSubmit,
34080
34598
  selectedFile,
34081
34599
  previewUrl,
34082
34600
  handleFileSelect,
@@ -35018,6 +35536,15 @@ function parseJsonAttr(raw, fallback) {
35018
35536
  return fallback;
35019
35537
  }
35020
35538
  }
35539
+ function resolveProductUrl(raw) {
35540
+ const source = raw || (typeof window !== "undefined" ? window.location.href : "");
35541
+ if (!source) return void 0;
35542
+ try {
35543
+ return new URL(source, window.location.origin).href;
35544
+ } catch {
35545
+ return source;
35546
+ }
35547
+ }
35021
35548
  function buildPropsFromDataAttrs(data) {
35022
35549
  const props = {
35023
35550
  apiUrl: data.proxyUrl || data.apiUrl || "",
@@ -35027,6 +35554,7 @@ function buildPropsFromDataAttrs(data) {
35027
35554
  apiKey: data.apiKey,
35028
35555
  productId: data.productId,
35029
35556
  productTitle: data.productTitle,
35557
+ productUrl: resolveProductUrl(data.productUrl),
35030
35558
  productImage: data.productImage,
35031
35559
  productCarouselItems: parseJsonAttr(data.productCarouselItems, void 0),
35032
35560
  productDescription: data.productDescription,