@streamoid/settings 0.4.2 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -58,6 +58,27 @@ var SiconKey = ({ color = "currentColor", strokeWidth = 1.25, size = 24, ...prop
58
58
  };
59
59
  var SiconKey_default = SiconKey;
60
60
 
61
+ // src/languages.ts
62
+ var USER_LANGUAGES = [
63
+ { code: "en", label: "English" },
64
+ { code: "es", label: "Spanish" },
65
+ { code: "fr", label: "French" },
66
+ { code: "pt", label: "Portuguese" },
67
+ { code: "hi", label: "Hindi" },
68
+ { code: "kn", label: "Kannada" },
69
+ { code: "te", label: "Telugu" },
70
+ { code: "ta", label: "Tamil" },
71
+ { code: "mr", label: "Marathi" },
72
+ { code: "gu", label: "Gujarati" },
73
+ { code: "bn", label: "Bengali" },
74
+ { code: "ar", label: "Arabic" }
75
+ ];
76
+ var DEFAULT_USER_LANGUAGE = "en";
77
+ function userLanguageLabel(code) {
78
+ const resolved = (code || "").trim() || DEFAULT_USER_LANGUAGE;
79
+ return USER_LANGUAGES.find((lang) => lang.code === resolved)?.label ?? resolved;
80
+ }
81
+
61
82
  // src/workspace-modal.tsx
62
83
  import { useState, useRef as useRef2, useEffect as useEffect2 } from "react";
63
84
 
@@ -2412,6 +2433,24 @@ var svg_rodctpja6f_default = {
2412
2433
  p83fc200: "M2.25 12.25C2.25 6.72715 6.72715 2.25 12.25 2.25C17.7728 2.25 22.25 6.72715 22.25 12.25C22.25 17.7728 17.7728 22.25 12.25 22.25C6.72715 22.25 2.25 17.7728 2.25 12.25Z"
2413
2434
  };
2414
2435
 
2436
+ // src/team-types.ts
2437
+ var APP_KEYS = [
2438
+ "artifax",
2439
+ "photogenix",
2440
+ "returns",
2441
+ "catalogix"
2442
+ ];
2443
+ var DEFAULT_PERMISSIONS = {
2444
+ artifax: true,
2445
+ photogenix: true,
2446
+ catalogix: true,
2447
+ returns: true,
2448
+ canUseCredits: true,
2449
+ canInviteUser: true,
2450
+ role: "admin",
2451
+ catalogixStores: []
2452
+ };
2453
+
2415
2454
  // src/invite-update-modal.tsx
2416
2455
  import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
2417
2456
  var T6 = {
@@ -2518,6 +2557,7 @@ function InviteUpdateModal({
2518
2557
  mode,
2519
2558
  userEmail = "email@domain.in",
2520
2559
  stores = [],
2560
+ hiddenApps = [],
2521
2561
  allowSubmitWithoutChanges = false,
2522
2562
  initialPermissions,
2523
2563
  onClose,
@@ -2532,25 +2572,35 @@ function InviteUpdateModal({
2532
2572
  const [role, setRole] = useState5("admin");
2533
2573
  const [canUseCredits, setCanUseCredits] = useState5(false);
2534
2574
  const [canInviteUser, setCanInviteUser] = useState5(false);
2535
- const [artifaxOn, setArtifaxOn] = useState5(true);
2536
- const [photogenixOn, setPhotogenixOn] = useState5(true);
2537
- const [catalogixOn, setCatalogixOn] = useState5(true);
2538
- const [returnsOn, setReturnsOn] = useState5(true);
2575
+ const [artifaxOn, setArtifaxOn] = useState5(!hiddenApps.includes("artifax"));
2576
+ const [photogenixOn, setPhotogenixOn] = useState5(
2577
+ !hiddenApps.includes("photogenix")
2578
+ );
2579
+ const [catalogixOn, setCatalogixOn] = useState5(
2580
+ !hiddenApps.includes("catalogix")
2581
+ );
2582
+ const [returnsOn, setReturnsOn] = useState5(!hiddenApps.includes("returns"));
2539
2583
  const [storeSearch, setStoreSearch] = useState5("");
2540
2584
  const [selectedStores, setSelectedStores] = useState5(/* @__PURE__ */ new Set());
2541
2585
  const filteredStores = stores.filter(
2542
2586
  (s) => (s.name || s._id).toLowerCase().includes(storeSearch.toLowerCase())
2543
2587
  );
2588
+ const hiddenKey = [...hiddenApps].sort().join(",");
2544
2589
  useEffect5(() => {
2590
+ const hidden = new Set(hiddenKey ? hiddenKey.split(",") : []);
2545
2591
  if (open && initialPermissions) {
2546
2592
  setRole(initialPermissions.role);
2547
2593
  setCanUseCredits(initialPermissions.canUseCredits);
2548
2594
  setCanInviteUser(initialPermissions.canInviteUser);
2549
- setArtifaxOn(initialPermissions.artifax);
2550
- setPhotogenixOn(initialPermissions.photogenix);
2551
- setCatalogixOn(initialPermissions.catalogix);
2552
- setReturnsOn(initialPermissions.returns);
2553
- setSelectedStores(new Set(initialPermissions.catalogixStores));
2595
+ setArtifaxOn(!hidden.has("artifax") && initialPermissions.artifax);
2596
+ setPhotogenixOn(
2597
+ !hidden.has("photogenix") && initialPermissions.photogenix
2598
+ );
2599
+ setCatalogixOn(!hidden.has("catalogix") && initialPermissions.catalogix);
2600
+ setReturnsOn(!hidden.has("returns") && initialPermissions.returns);
2601
+ setSelectedStores(
2602
+ new Set(hidden.has("catalogix") ? [] : initialPermissions.catalogixStores)
2603
+ );
2554
2604
  }
2555
2605
  if (!open) {
2556
2606
  setEmailValue("");
@@ -2558,21 +2608,32 @@ function InviteUpdateModal({
2558
2608
  setRole("admin");
2559
2609
  setCanUseCredits(true);
2560
2610
  setCanInviteUser(true);
2561
- setArtifaxOn(true);
2562
- setPhotogenixOn(true);
2563
- setCatalogixOn(true);
2564
- setReturnsOn(true);
2611
+ setArtifaxOn(!hidden.has("artifax"));
2612
+ setPhotogenixOn(!hidden.has("photogenix"));
2613
+ setCatalogixOn(!hidden.has("catalogix"));
2614
+ setReturnsOn(!hidden.has("returns"));
2565
2615
  setStoreSearch("");
2566
2616
  setSelectedStores(/* @__PURE__ */ new Set());
2567
2617
  }
2568
- }, [open, initialPermissions]);
2618
+ }, [open, initialPermissions, hiddenKey]);
2569
2619
  if (!open) return null;
2570
2620
  const isInvite = mode === "invite";
2571
2621
  const hasEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(emailValue.trim());
2572
- const isSubmitDisabled = isInvite ? !hasEmail : !(allowSubmitWithoutChanges || hasChanges);
2573
2622
  function markChanged() {
2574
2623
  setHasChanges(true);
2575
2624
  }
2625
+ const shownApps = APP_KEYS.filter((key) => !hiddenApps.includes(key));
2626
+ const showsApp = (key) => shownApps.includes(key);
2627
+ const appToggles = {
2628
+ artifax: artifaxOn,
2629
+ photogenix: photogenixOn,
2630
+ returns: returnsOn,
2631
+ catalogix: catalogixOn
2632
+ };
2633
+ const notLastShown = (key) => shownApps[shownApps.length - 1] !== key;
2634
+ const appValue = (key) => role === "admin" || showsApp(key) ? appToggles[key] : false;
2635
+ const grantsNoApp = role === "member" && shownApps.length > 0 && !shownApps.some((key) => appToggles[key]);
2636
+ const isSubmitDisabled = isInvite ? !hasEmail || grantsNoApp : !(allowSubmitWithoutChanges || hasChanges);
2576
2637
  function toggleStore(storeId) {
2577
2638
  setSelectedStores((prev) => {
2578
2639
  const next = new Set(prev);
@@ -2930,7 +2991,7 @@ function InviteUpdateModal({
2930
2991
  ]
2931
2992
  }
2932
2993
  ),
2933
- role !== "admin" && /* @__PURE__ */ jsxs8(
2994
+ role !== "admin" && shownApps.length > 0 && /* @__PURE__ */ jsxs8(
2934
2995
  "div",
2935
2996
  {
2936
2997
  className: "flex flex-col items-start justify-center shrink-0 w-full",
@@ -2946,8 +3007,8 @@ function InviteUpdateModal({
2946
3007
  borderRadius: T6.r3xl
2947
3008
  },
2948
3009
  children: [
2949
- /* @__PURE__ */ jsxs8("div", { className: "shrink-0 w-full relative", children: [
2950
- /* @__PURE__ */ jsx10(
3010
+ showsApp("artifax") && /* @__PURE__ */ jsx10(Fragment5, { children: /* @__PURE__ */ jsxs8("div", { className: "shrink-0 w-full relative", children: [
3011
+ notLastShown("artifax") && /* @__PURE__ */ jsx10(
2951
3012
  "div",
2952
3013
  {
2953
3014
  "aria-hidden": true,
@@ -3040,9 +3101,9 @@ function InviteUpdateModal({
3040
3101
  ]
3041
3102
  }
3042
3103
  ) })
3043
- ] }),
3044
- /* @__PURE__ */ jsxs8("div", { className: "shrink-0 w-full relative", children: [
3045
- /* @__PURE__ */ jsx10(
3104
+ ] }) }),
3105
+ showsApp("photogenix") && /* @__PURE__ */ jsx10(Fragment5, { children: /* @__PURE__ */ jsxs8("div", { className: "shrink-0 w-full relative", children: [
3106
+ notLastShown("photogenix") && /* @__PURE__ */ jsx10(
3046
3107
  "div",
3047
3108
  {
3048
3109
  "aria-hidden": true,
@@ -3135,234 +3196,179 @@ function InviteUpdateModal({
3135
3196
  ]
3136
3197
  }
3137
3198
  ) })
3138
- ] }),
3139
- /* @__PURE__ */ jsx10("div", { className: "shrink-0 w-full", children: /* @__PURE__ */ jsx10("div", { className: "flex flex-col justify-center size-full", children: /* @__PURE__ */ jsx10(
3199
+ ] }) }),
3200
+ showsApp("returns") && /* @__PURE__ */ jsx10(Fragment5, { children: /* @__PURE__ */ jsx10(
3140
3201
  "div",
3141
3202
  {
3142
- className: "flex flex-col items-start justify-center w-full",
3143
- style: { padding: T6.sp3xl, gap: T6.sp3xl },
3144
- children: /* @__PURE__ */ jsxs8(
3203
+ className: "shrink-0 w-full",
3204
+ style: notLastShown("returns") ? { borderBottom: `1px solid ${T6.borderSubtle}` } : void 0,
3205
+ children: /* @__PURE__ */ jsx10("div", { className: "flex flex-col justify-center size-full", children: /* @__PURE__ */ jsx10(
3145
3206
  "div",
3146
3207
  {
3147
- className: "flex items-center shrink-0 w-full",
3148
- style: { gap: T6.sp3xl },
3149
- children: [
3150
- /* @__PURE__ */ jsxs8(
3151
- "div",
3152
- {
3153
- className: "flex flex-1 min-w-0 items-center",
3154
- style: { gap: T6.spXl },
3155
- children: [
3156
- /* @__PURE__ */ jsx10(
3157
- "div",
3158
- {
3159
- className: "shrink-0 flex items-center",
3160
- style: {
3161
- background: T6.fillHover,
3162
- borderRadius: T6.rXl,
3163
- padding: T6.spMd
3164
- },
3165
- children: /* @__PURE__ */ jsx10(
3166
- SiconArrowLeftRight,
3208
+ className: "flex flex-col items-start justify-center w-full",
3209
+ style: { padding: T6.sp3xl, gap: T6.sp3xl },
3210
+ children: /* @__PURE__ */ jsxs8(
3211
+ "div",
3212
+ {
3213
+ className: "flex items-center shrink-0 w-full",
3214
+ style: { gap: T6.sp3xl },
3215
+ children: [
3216
+ /* @__PURE__ */ jsxs8(
3217
+ "div",
3218
+ {
3219
+ className: "flex flex-1 min-w-0 items-center",
3220
+ style: { gap: T6.spXl },
3221
+ children: [
3222
+ /* @__PURE__ */ jsx10(
3223
+ "div",
3167
3224
  {
3168
- className: "w-6 h-6",
3169
- color: T6.primary
3225
+ className: "shrink-0 flex items-center",
3226
+ style: {
3227
+ background: T6.fillHover,
3228
+ borderRadius: T6.rXl,
3229
+ padding: T6.spMd
3230
+ },
3231
+ children: /* @__PURE__ */ jsx10(
3232
+ SiconArrowLeftRight,
3233
+ {
3234
+ className: "w-6 h-6",
3235
+ color: T6.primary
3236
+ }
3237
+ )
3238
+ }
3239
+ ),
3240
+ /* @__PURE__ */ jsxs8(
3241
+ "div",
3242
+ {
3243
+ className: "flex flex-1 min-w-0 flex-col items-start overflow-hidden text-ellipsis whitespace-nowrap",
3244
+ style: { opacity: returnsOn ? 1 : 0.5 },
3245
+ children: [
3246
+ /* @__PURE__ */ jsx10(
3247
+ "p",
3248
+ {
3249
+ className: "w-full overflow-hidden shrink-0",
3250
+ style: {
3251
+ fontFamily: T6.font,
3252
+ fontSize: T6.fsSm,
3253
+ fontWeight: 500,
3254
+ lineHeight: T6.lhSm,
3255
+ color: T6.primary
3256
+ },
3257
+ children: "Returns"
3258
+ }
3259
+ ),
3260
+ /* @__PURE__ */ jsx10(
3261
+ "p",
3262
+ {
3263
+ className: "w-full overflow-hidden shrink-0",
3264
+ style: {
3265
+ fontFamily: T6.font,
3266
+ fontSize: T6.fsXs,
3267
+ fontWeight: 400,
3268
+ lineHeight: T6.lhXs,
3269
+ color: T6.tertiary
3270
+ },
3271
+ children: "Raise SPF claims for Marketplaces"
3272
+ }
3273
+ )
3274
+ ]
3170
3275
  }
3171
3276
  )
3277
+ ]
3278
+ }
3279
+ ),
3280
+ /* @__PURE__ */ jsx10(
3281
+ ToggleSwitch,
3282
+ {
3283
+ active: returnsOn,
3284
+ onClick: () => {
3285
+ setReturnsOn(!returnsOn);
3286
+ markChanged();
3172
3287
  }
3173
- ),
3174
- /* @__PURE__ */ jsxs8(
3175
- "div",
3176
- {
3177
- className: "flex flex-1 min-w-0 flex-col items-start overflow-hidden text-ellipsis whitespace-nowrap",
3178
- style: { opacity: returnsOn ? 1 : 0.5 },
3179
- children: [
3180
- /* @__PURE__ */ jsx10(
3181
- "p",
3182
- {
3183
- className: "w-full overflow-hidden shrink-0",
3184
- style: {
3185
- fontFamily: T6.font,
3186
- fontSize: T6.fsSm,
3187
- fontWeight: 500,
3188
- lineHeight: T6.lhSm,
3189
- color: T6.primary
3190
- },
3191
- children: "Returns"
3192
- }
3193
- ),
3194
- /* @__PURE__ */ jsx10(
3195
- "p",
3196
- {
3197
- className: "w-full overflow-hidden shrink-0",
3198
- style: {
3199
- fontFamily: T6.font,
3200
- fontSize: T6.fsXs,
3201
- fontWeight: 400,
3202
- lineHeight: T6.lhXs,
3203
- color: T6.tertiary
3204
- },
3205
- children: "Raise SPF claims for Marketplaces"
3206
- }
3207
- )
3208
- ]
3209
- }
3210
- )
3211
- ]
3212
- }
3213
- ),
3214
- /* @__PURE__ */ jsx10(
3215
- ToggleSwitch,
3216
- {
3217
- active: returnsOn,
3218
- onClick: () => {
3219
- setReturnsOn(!returnsOn);
3220
- markChanged();
3221
- }
3222
- }
3223
- )
3224
- ]
3288
+ }
3289
+ )
3290
+ ]
3291
+ }
3292
+ )
3225
3293
  }
3226
- )
3294
+ ) })
3227
3295
  }
3228
- ) }) }),
3229
- /* @__PURE__ */ jsx10("div", { className: "shrink-0 w-full", children: /* @__PURE__ */ jsx10("div", { className: "flex flex-col justify-center size-full", children: /* @__PURE__ */ jsxs8(
3296
+ ) }),
3297
+ showsApp("catalogix") && /* @__PURE__ */ jsx10(Fragment5, { children: /* @__PURE__ */ jsx10(
3230
3298
  "div",
3231
3299
  {
3232
- className: "flex flex-col items-start justify-center w-full",
3233
- style: { padding: T6.sp3xl, gap: T6.sp3xl },
3234
- children: [
3235
- /* @__PURE__ */ jsxs8(
3236
- "div",
3237
- {
3238
- className: "flex items-center shrink-0 w-full",
3239
- style: { gap: T6.sp3xl },
3240
- children: [
3241
- /* @__PURE__ */ jsxs8(
3242
- "div",
3243
- {
3244
- className: "flex flex-1 min-w-0 items-center",
3245
- style: { gap: T6.spXl },
3246
- children: [
3247
- /* @__PURE__ */ jsx10(
3248
- "div",
3249
- {
3250
- className: "shrink-0 flex items-center",
3251
- style: {
3252
- background: T6.fillHover,
3253
- borderRadius: T6.rXl,
3254
- padding: T6.spMd
3255
- },
3256
- children: /* @__PURE__ */ jsx10(
3257
- SiconArtifacts,
3258
- {
3259
- className: "w-6 h-6",
3260
- color: T6.primary
3261
- }
3262
- )
3263
- }
3264
- ),
3265
- /* @__PURE__ */ jsxs8(
3266
- "div",
3267
- {
3268
- className: "flex flex-1 min-w-0 flex-col items-start overflow-hidden text-ellipsis whitespace-nowrap",
3269
- style: { opacity: catalogixOn ? 1 : 0.5 },
3270
- children: [
3271
- /* @__PURE__ */ jsx10(
3272
- "p",
3273
- {
3274
- className: "w-full overflow-hidden shrink-0",
3275
- style: {
3276
- fontFamily: T6.font,
3277
- fontSize: T6.fsSm,
3278
- fontWeight: 500,
3279
- lineHeight: T6.lhSm,
3280
- color: T6.primary
3281
- },
3282
- children: "Catalogix"
3283
- }
3284
- ),
3285
- /* @__PURE__ */ jsx10(
3286
- "p",
3287
- {
3288
- className: "w-full overflow-hidden shrink-0",
3289
- style: {
3290
- fontFamily: T6.font,
3291
- fontSize: T6.fsXs,
3292
- fontWeight: 400,
3293
- lineHeight: T6.lhXs,
3294
- color: T6.tertiary
3295
- },
3296
- children: "Centralized product and asset management for every storefront"
3297
- }
3298
- )
3299
- ]
3300
- }
3301
- )
3302
- ]
3303
- }
3304
- ),
3305
- /* @__PURE__ */ jsx10(
3306
- ToggleSwitch,
3307
- {
3308
- active: catalogixOn,
3309
- onClick: () => {
3310
- setCatalogixOn(!catalogixOn);
3311
- markChanged();
3312
- }
3313
- }
3314
- )
3315
- ]
3316
- }
3317
- ),
3318
- catalogixOn && /* @__PURE__ */ jsx10(
3319
- "div",
3320
- {
3321
- className: "shrink-0 w-full",
3322
- style: {
3323
- background: T6.canvasBase,
3324
- borderRadius: T6.r3xl
3325
- },
3326
- children: /* @__PURE__ */ jsxs8(
3300
+ className: "shrink-0 w-full",
3301
+ style: notLastShown("catalogix") ? { borderBottom: `1px solid ${T6.borderSubtle}` } : void 0,
3302
+ children: /* @__PURE__ */ jsx10("div", { className: "flex flex-col justify-center size-full", children: /* @__PURE__ */ jsxs8(
3303
+ "div",
3304
+ {
3305
+ className: "flex flex-col items-start justify-center w-full",
3306
+ style: { padding: T6.sp3xl, gap: T6.sp3xl },
3307
+ children: [
3308
+ /* @__PURE__ */ jsxs8(
3327
3309
  "div",
3328
3310
  {
3329
- className: "flex flex-col items-start w-full",
3330
- style: { padding: T6.sp3xl, gap: T6.spMd },
3311
+ className: "flex items-center shrink-0 w-full",
3312
+ style: { gap: T6.sp3xl },
3331
3313
  children: [
3332
3314
  /* @__PURE__ */ jsxs8(
3333
3315
  "div",
3334
3316
  {
3335
- className: "flex items-center justify-center shrink-0 w-full",
3336
- style: { gap: T6.spMd },
3317
+ className: "flex flex-1 min-w-0 items-center",
3318
+ style: { gap: T6.spXl },
3337
3319
  children: [
3338
3320
  /* @__PURE__ */ jsx10(
3339
- "p",
3321
+ "div",
3340
3322
  {
3341
- className: "flex-1 min-w-0 overflow-hidden whitespace-nowrap",
3323
+ className: "shrink-0 flex items-center",
3342
3324
  style: {
3343
- fontFamily: T6.font,
3344
- fontSize: T6.fsSm,
3345
- fontWeight: 400,
3346
- lineHeight: T6.lhSm,
3347
- color: T6.primary
3325
+ background: T6.fillHover,
3326
+ borderRadius: T6.rXl,
3327
+ padding: T6.spMd
3348
3328
  },
3349
- children: "Store access"
3329
+ children: /* @__PURE__ */ jsx10(
3330
+ SiconArtifacts,
3331
+ {
3332
+ className: "w-6 h-6",
3333
+ color: T6.primary
3334
+ }
3335
+ )
3350
3336
  }
3351
3337
  ),
3352
3338
  /* @__PURE__ */ jsxs8(
3353
- "p",
3339
+ "div",
3354
3340
  {
3355
- className: "shrink-0 overflow-hidden text-right",
3356
- style: {
3357
- fontFamily: T6.font,
3358
- fontSize: T6.fsXs,
3359
- fontWeight: 400,
3360
- lineHeight: T6.lhXs,
3361
- color: T6.muted
3362
- },
3341
+ className: "flex flex-1 min-w-0 flex-col items-start overflow-hidden text-ellipsis whitespace-nowrap",
3342
+ style: { opacity: catalogixOn ? 1 : 0.5 },
3363
3343
  children: [
3364
- selectedStores.size,
3365
- " Selected"
3344
+ /* @__PURE__ */ jsx10(
3345
+ "p",
3346
+ {
3347
+ className: "w-full overflow-hidden shrink-0",
3348
+ style: {
3349
+ fontFamily: T6.font,
3350
+ fontSize: T6.fsSm,
3351
+ fontWeight: 500,
3352
+ lineHeight: T6.lhSm,
3353
+ color: T6.primary
3354
+ },
3355
+ children: "Catalogix"
3356
+ }
3357
+ ),
3358
+ /* @__PURE__ */ jsx10(
3359
+ "p",
3360
+ {
3361
+ className: "w-full overflow-hidden shrink-0",
3362
+ style: {
3363
+ fontFamily: T6.font,
3364
+ fontSize: T6.fsXs,
3365
+ fontWeight: 400,
3366
+ lineHeight: T6.lhXs,
3367
+ color: T6.tertiary
3368
+ },
3369
+ children: "Centralized product and asset management for every storefront"
3370
+ }
3371
+ )
3366
3372
  ]
3367
3373
  }
3368
3374
  )
@@ -3370,27 +3376,42 @@ function InviteUpdateModal({
3370
3376
  }
3371
3377
  ),
3372
3378
  /* @__PURE__ */ jsx10(
3373
- "div",
3379
+ ToggleSwitch,
3374
3380
  {
3375
- className: "shrink-0 w-full",
3376
- style: {
3377
- background: T6.fillPlus,
3378
- height: 48,
3379
- borderRadius: T6.r3xl
3380
- },
3381
- children: /* @__PURE__ */ jsx10("div", { className: "flex flex-row items-center size-full", children: /* @__PURE__ */ jsxs8(
3381
+ active: catalogixOn,
3382
+ onClick: () => {
3383
+ setCatalogixOn(!catalogixOn);
3384
+ markChanged();
3385
+ }
3386
+ }
3387
+ )
3388
+ ]
3389
+ }
3390
+ ),
3391
+ catalogixOn && /* @__PURE__ */ jsx10(
3392
+ "div",
3393
+ {
3394
+ className: "shrink-0 w-full",
3395
+ style: {
3396
+ background: T6.canvasBase,
3397
+ borderRadius: T6.r3xl
3398
+ },
3399
+ children: /* @__PURE__ */ jsxs8(
3400
+ "div",
3401
+ {
3402
+ className: "flex flex-col items-start w-full",
3403
+ style: { padding: T6.sp3xl, gap: T6.spMd },
3404
+ children: [
3405
+ /* @__PURE__ */ jsxs8(
3382
3406
  "div",
3383
3407
  {
3384
- className: "flex items-center relative size-full",
3385
- style: {
3386
- padding: T6.spXl,
3387
- gap: T6.sp3xl
3388
- },
3408
+ className: "flex items-center justify-center shrink-0 w-full",
3409
+ style: { gap: T6.spMd },
3389
3410
  children: [
3390
3411
  /* @__PURE__ */ jsx10(
3391
- "input",
3412
+ "p",
3392
3413
  {
3393
- className: "flex-1 min-w-0 bg-transparent border-none outline-none",
3414
+ className: "flex-1 min-w-0 overflow-hidden whitespace-nowrap",
3394
3415
  style: {
3395
3416
  fontFamily: T6.font,
3396
3417
  fontSize: T6.fsSm,
@@ -3398,97 +3419,153 @@ function InviteUpdateModal({
3398
3419
  lineHeight: T6.lhSm,
3399
3420
  color: T6.primary
3400
3421
  },
3401
- placeholder: "Search stores...",
3402
- value: storeSearch,
3403
- onChange: (e) => setStoreSearch(e.target.value)
3422
+ children: "Store access"
3404
3423
  }
3405
3424
  ),
3406
- /* @__PURE__ */ jsx10(
3407
- SiconSearch,
3408
- {
3409
- className: "w-6 h-6",
3410
- color: T6.primary
3411
- }
3412
- )
3413
- ]
3414
- }
3415
- ) })
3416
- }
3417
- ),
3418
- /* @__PURE__ */ jsx10(
3419
- "div",
3420
- {
3421
- className: "shrink-0 w-full",
3422
- style: {
3423
- background: T6.fillPlus,
3424
- borderRadius: T6.r3xl
3425
- },
3426
- children: /* @__PURE__ */ jsxs8(
3427
- "div",
3428
- {
3429
- className: "flex flex-col items-start w-full",
3430
- style: {
3431
- padding: T6.sp3xl,
3432
- gap: T6.spXl
3433
- },
3434
- children: [
3435
- filteredStores.map((store) => /* @__PURE__ */ jsxs8(
3436
- "div",
3437
- {
3438
- className: "flex items-center shrink-0 w-full cursor-pointer",
3439
- style: { gap: T6.spMd },
3440
- onClick: () => toggleStore(store._id),
3441
- children: [
3442
- /* @__PURE__ */ jsx10(
3443
- "p",
3444
- {
3445
- className: "flex-1 min-w-0",
3446
- style: {
3447
- fontFamily: T6.font,
3448
- fontSize: T6.fsSm,
3449
- fontWeight: 400,
3450
- lineHeight: T6.lhSm,
3451
- color: T6.primary
3452
- },
3453
- children: store.name || store._id
3454
- }
3455
- ),
3456
- /* @__PURE__ */ jsx10(
3457
- CheckboxSvg,
3458
- {
3459
- checked: selectedStores.has(store._id)
3460
- }
3461
- )
3462
- ]
3463
- },
3464
- store._id
3465
- )),
3466
- filteredStores.length === 0 && /* @__PURE__ */ jsx10(
3425
+ /* @__PURE__ */ jsxs8(
3467
3426
  "p",
3468
3427
  {
3428
+ className: "shrink-0 overflow-hidden text-right",
3469
3429
  style: {
3470
3430
  fontFamily: T6.font,
3471
- fontSize: T6.fsSm,
3431
+ fontSize: T6.fsXs,
3472
3432
  fontWeight: 400,
3473
- lineHeight: T6.lhSm,
3433
+ lineHeight: T6.lhXs,
3474
3434
  color: T6.muted
3475
3435
  },
3476
- children: "No stores found"
3436
+ children: [
3437
+ selectedStores.size,
3438
+ " Selected"
3439
+ ]
3477
3440
  }
3478
3441
  )
3479
3442
  ]
3480
3443
  }
3444
+ ),
3445
+ /* @__PURE__ */ jsx10(
3446
+ "div",
3447
+ {
3448
+ className: "shrink-0 w-full",
3449
+ style: {
3450
+ background: T6.fillPlus,
3451
+ height: 48,
3452
+ borderRadius: T6.r3xl
3453
+ },
3454
+ children: /* @__PURE__ */ jsx10("div", { className: "flex flex-row items-center size-full", children: /* @__PURE__ */ jsxs8(
3455
+ "div",
3456
+ {
3457
+ className: "flex items-center relative size-full",
3458
+ style: {
3459
+ padding: T6.spXl,
3460
+ gap: T6.sp3xl
3461
+ },
3462
+ children: [
3463
+ /* @__PURE__ */ jsx10(
3464
+ "input",
3465
+ {
3466
+ className: "flex-1 min-w-0 bg-transparent border-none outline-none",
3467
+ style: {
3468
+ fontFamily: T6.font,
3469
+ fontSize: T6.fsSm,
3470
+ fontWeight: 400,
3471
+ lineHeight: T6.lhSm,
3472
+ color: T6.primary
3473
+ },
3474
+ placeholder: "Search stores...",
3475
+ value: storeSearch,
3476
+ onChange: (e) => setStoreSearch(e.target.value)
3477
+ }
3478
+ ),
3479
+ /* @__PURE__ */ jsx10(
3480
+ SiconSearch,
3481
+ {
3482
+ className: "w-6 h-6",
3483
+ color: T6.primary
3484
+ }
3485
+ )
3486
+ ]
3487
+ }
3488
+ ) })
3489
+ }
3490
+ ),
3491
+ /* @__PURE__ */ jsx10(
3492
+ "div",
3493
+ {
3494
+ className: "shrink-0 w-full",
3495
+ style: {
3496
+ background: T6.fillPlus,
3497
+ borderRadius: T6.r3xl
3498
+ },
3499
+ children: /* @__PURE__ */ jsxs8(
3500
+ "div",
3501
+ {
3502
+ className: "flex flex-col items-start w-full",
3503
+ style: {
3504
+ padding: T6.sp3xl,
3505
+ gap: T6.spXl
3506
+ },
3507
+ children: [
3508
+ filteredStores.map((store) => /* @__PURE__ */ jsxs8(
3509
+ "div",
3510
+ {
3511
+ className: "flex items-center shrink-0 w-full cursor-pointer",
3512
+ style: { gap: T6.spMd },
3513
+ onClick: () => toggleStore(store._id),
3514
+ children: [
3515
+ /* @__PURE__ */ jsx10(
3516
+ "p",
3517
+ {
3518
+ className: "flex-1 min-w-0",
3519
+ style: {
3520
+ fontFamily: T6.font,
3521
+ fontSize: T6.fsSm,
3522
+ fontWeight: 400,
3523
+ lineHeight: T6.lhSm,
3524
+ color: T6.primary
3525
+ },
3526
+ children: store.name || store._id
3527
+ }
3528
+ ),
3529
+ /* @__PURE__ */ jsx10(
3530
+ CheckboxSvg,
3531
+ {
3532
+ checked: selectedStores.has(
3533
+ store._id
3534
+ )
3535
+ }
3536
+ )
3537
+ ]
3538
+ },
3539
+ store._id
3540
+ )),
3541
+ filteredStores.length === 0 && /* @__PURE__ */ jsx10(
3542
+ "p",
3543
+ {
3544
+ style: {
3545
+ fontFamily: T6.font,
3546
+ fontSize: T6.fsSm,
3547
+ fontWeight: 400,
3548
+ lineHeight: T6.lhSm,
3549
+ color: T6.muted
3550
+ },
3551
+ children: "No stores found"
3552
+ }
3553
+ )
3554
+ ]
3555
+ }
3556
+ )
3557
+ }
3481
3558
  )
3482
- }
3483
- )
3484
- ]
3559
+ ]
3560
+ }
3561
+ )
3485
3562
  }
3486
3563
  )
3487
- }
3488
- )
3489
- ]
3564
+ ]
3565
+ }
3566
+ ) })
3490
3567
  }
3491
- ) }) })
3568
+ ) })
3492
3569
  ]
3493
3570
  }
3494
3571
  )
@@ -3535,11 +3612,15 @@ function InviteUpdateModal({
3535
3612
  role,
3536
3613
  canUseCredits,
3537
3614
  canInviteUser,
3538
- artifax: artifaxOn,
3539
- photogenix: photogenixOn,
3540
- catalogix: catalogixOn,
3541
- returns: returnsOn,
3542
- catalogixStores: Array.from(selectedStores)
3615
+ artifax: appValue("artifax"),
3616
+ photogenix: appValue("photogenix"),
3617
+ catalogix: appValue("catalogix"),
3618
+ returns: appValue("returns"),
3619
+ // Stores ride on Catalogix, so they follow it: a
3620
+ // hidden Catalogix grants no app and therefore no
3621
+ // storefronts. Keeping them would leave a member
3622
+ // scoped to stores in a product they cannot open.
3623
+ catalogixStores: role === "admin" || showsApp("catalogix") ? Array.from(selectedStores) : []
3543
3624
  };
3544
3625
  if (isInvite && onInvite) {
3545
3626
  onInvite(perms, emailValue.trim());
@@ -4292,7 +4373,8 @@ function TeamsContent({
4292
4373
  onInviteOpenChange,
4293
4374
  workspaceName,
4294
4375
  workspaceImageUrl,
4295
- organizationName
4376
+ organizationName,
4377
+ hiddenApps
4296
4378
  } = {}) {
4297
4379
  const { auth, api, organization, workspace, toast } = useSettingsAdapters();
4298
4380
  const user = auth.user;
@@ -4764,6 +4846,7 @@ function TeamsContent({
4764
4846
  mode: modal.mode,
4765
4847
  userEmail: modal.target?.userEmail,
4766
4848
  stores: allStores,
4849
+ hiddenApps,
4767
4850
  allowSubmitWithoutChanges: modal.target?.kind === "invite",
4768
4851
  initialPermissions: currentMemberPermissions,
4769
4852
  onClose: closeModal,
@@ -10568,13 +10651,134 @@ function SpecializationDropdown({
10568
10651
  }
10569
10652
  );
10570
10653
  }
10654
+ function LanguageDropdown({
10655
+ value,
10656
+ onChange,
10657
+ disabled
10658
+ }) {
10659
+ const [open, setOpen] = useState14(false);
10660
+ const containerRef = useRef7(null);
10661
+ useEffect12(() => {
10662
+ if (!open) return;
10663
+ function handleMouseDown(e) {
10664
+ if (containerRef.current && !containerRef.current.contains(e.target)) {
10665
+ setOpen(false);
10666
+ }
10667
+ }
10668
+ function handleKeyDown(e) {
10669
+ if (e.key === "Escape") setOpen(false);
10670
+ }
10671
+ document.addEventListener("mousedown", handleMouseDown);
10672
+ document.addEventListener("keydown", handleKeyDown);
10673
+ return () => {
10674
+ document.removeEventListener("mousedown", handleMouseDown);
10675
+ document.removeEventListener("keydown", handleKeyDown);
10676
+ };
10677
+ }, [open]);
10678
+ return /* @__PURE__ */ jsxs18(
10679
+ "div",
10680
+ {
10681
+ ref: containerRef,
10682
+ className: "w-full",
10683
+ style: { position: "relative" },
10684
+ children: [
10685
+ /* @__PURE__ */ jsx20("style", { children: DROPDOWN_TRIGGER_STYLES }),
10686
+ /* @__PURE__ */ jsx20(
10687
+ "div",
10688
+ {
10689
+ className: "spec-dropdown-trigger",
10690
+ "data-disabled": disabled ? "true" : "false",
10691
+ onClick: () => !disabled && setOpen((v) => !v),
10692
+ "aria-haspopup": "listbox",
10693
+ "aria-expanded": open,
10694
+ children: /* @__PURE__ */ jsx20(
10695
+ ScTextField,
10696
+ {
10697
+ label: "Language",
10698
+ labelGroup: "label",
10699
+ value: userLanguageLabel(value),
10700
+ placeholderFilled: "Select language",
10701
+ tfGroup: "icon-right",
10702
+ tfRightIcon: /* @__PURE__ */ jsx20(
10703
+ "span",
10704
+ {
10705
+ style: {
10706
+ display: "flex",
10707
+ alignItems: "center",
10708
+ justifyContent: "center",
10709
+ transform: open ? "rotate(180deg)" : "none",
10710
+ transition: "transform 120ms ease-out"
10711
+ },
10712
+ children: /* @__PURE__ */ jsx20(SiconDown, {})
10713
+ }
10714
+ ),
10715
+ className: "sc-text-field-full-width",
10716
+ style: { width: "100%" },
10717
+ readOnly: true,
10718
+ disabled
10719
+ }
10720
+ )
10721
+ }
10722
+ ),
10723
+ open && /* @__PURE__ */ jsx20(
10724
+ "div",
10725
+ {
10726
+ role: "listbox",
10727
+ style: {
10728
+ position: "absolute",
10729
+ top: "calc(100% + 4px)",
10730
+ left: 0,
10731
+ right: 0,
10732
+ zIndex: 50,
10733
+ // The list is longer than the specialization one, so it scrolls
10734
+ // rather than running off the bottom of the panel.
10735
+ maxHeight: 280,
10736
+ overflowY: "auto",
10737
+ background: "var(--alias-surface-subtle, #1a1a1a)",
10738
+ border: "0.5px solid var(--alias-border-subtle, #242424)",
10739
+ borderRadius: "var(--radius-4xl, 18px)",
10740
+ padding: "var(--spacing-md, 8px)",
10741
+ display: "flex",
10742
+ flexDirection: "column",
10743
+ gap: 8,
10744
+ boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
10745
+ backdropFilter: "blur(42px)"
10746
+ },
10747
+ children: USER_LANGUAGES.map((lang) => {
10748
+ const isActive = lang.code === value;
10749
+ return /* @__PURE__ */ jsx20(
10750
+ ScMenuOptions,
10751
+ {
10752
+ text: lang.label,
10753
+ icon: /* @__PURE__ */ jsx20(Fragment12, {}),
10754
+ hover: isActive ? "true" : "false",
10755
+ variant: "default",
10756
+ role: "option",
10757
+ "aria-selected": isActive,
10758
+ onClick: () => {
10759
+ onChange(lang.code);
10760
+ setOpen(false);
10761
+ },
10762
+ style: { width: "100%", cursor: "pointer" }
10763
+ },
10764
+ lang.code
10765
+ );
10766
+ })
10767
+ }
10768
+ )
10769
+ ]
10770
+ }
10771
+ );
10772
+ }
10571
10773
  function ProfileTab() {
10572
10774
  const { auth, imageUpload, toast } = useSettingsAdapters();
10573
10775
  const user = auth.user;
10574
10776
  const derivedName = user?.name ?? "";
10575
10777
  const derivedSpec = user?.userSpecialization ?? "";
10778
+ const derivedLanguage = user?.language?.trim() || DEFAULT_USER_LANGUAGE;
10576
10779
  const [fullName, setFullName] = useState14(derivedName);
10577
10780
  const [selectedSpec, setSelectedSpec] = useState14(derivedSpec);
10781
+ const [selectedLanguage, setSelectedLanguage] = useState14(derivedLanguage);
10578
10782
  const [saving, setSaving] = useState14(false);
10579
10783
  const [imageSaving, setImageSaving] = useState14(false);
10580
10784
  const [imagePreview, setImagePreview] = useState14(
@@ -10585,7 +10789,7 @@ function ProfileTab() {
10585
10789
  const profileImage = imagePreview ?? getUserProfileImage(user);
10586
10790
  const profileInitial = profileDisplayName.charAt(0).toUpperCase();
10587
10791
  const disableAllActions = saving || imageSaving;
10588
- const dirty = fullName.trim() !== derivedName || selectedSpec !== derivedSpec;
10792
+ const dirty = fullName.trim() !== derivedName || selectedSpec !== derivedSpec || selectedLanguage !== derivedLanguage;
10589
10793
  useEffect12(() => {
10590
10794
  setFullName(derivedName);
10591
10795
  setImagePreview(void 0);
@@ -10593,6 +10797,9 @@ function ProfileTab() {
10593
10797
  useEffect12(() => {
10594
10798
  setSelectedSpec(derivedSpec);
10595
10799
  }, [derivedSpec]);
10800
+ useEffect12(() => {
10801
+ setSelectedLanguage(derivedLanguage);
10802
+ }, [derivedLanguage]);
10596
10803
  const handleSave = async () => {
10597
10804
  if (disableAllActions || !dirty) return;
10598
10805
  setSaving(true);
@@ -10600,6 +10807,8 @@ function ProfileTab() {
10600
10807
  const patch = {};
10601
10808
  if (fullName.trim() !== derivedName) patch.name = fullName.trim();
10602
10809
  if (selectedSpec !== derivedSpec) patch.userSpecialization = selectedSpec;
10810
+ if (selectedLanguage !== derivedLanguage)
10811
+ patch.language = selectedLanguage;
10603
10812
  await auth.updateProfile(patch);
10604
10813
  await auth.refreshProfile();
10605
10814
  toast.success("Profile updated");
@@ -10819,6 +11028,17 @@ function ProfileTab() {
10819
11028
  }
10820
11029
  ) })
10821
11030
  ] }),
11031
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11032
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20(
11033
+ LanguageDropdown,
11034
+ {
11035
+ value: selectedLanguage,
11036
+ onChange: setSelectedLanguage,
11037
+ disabled: disableAllActions
11038
+ }
11039
+ ) }),
11040
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0" })
11041
+ ] }),
10822
11042
  /* @__PURE__ */ jsx20("div", { className: "w-full", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx20(
10823
11043
  ScTextField,
10824
11044
  {
@@ -11091,19 +11311,22 @@ function ReferralTab() {
11091
11311
  function SettingsContent({
11092
11312
  adapters,
11093
11313
  activeTab = "profile",
11094
- onClose
11314
+ onClose,
11315
+ hiddenApps
11095
11316
  }) {
11096
11317
  return /* @__PURE__ */ jsx20(SettingsAdaptersProvider, { adapters, children: /* @__PURE__ */ jsx20(
11097
11318
  SettingsContentInner,
11098
11319
  {
11099
11320
  activeTab,
11100
- onClose: onClose ?? adapters.navigation.close
11321
+ onClose: onClose ?? adapters.navigation.close,
11322
+ hiddenApps
11101
11323
  }
11102
11324
  ) });
11103
11325
  }
11104
11326
  function SettingsContentInner({
11105
11327
  activeTab,
11106
- onClose
11328
+ onClose,
11329
+ hiddenApps
11107
11330
  }) {
11108
11331
  const {
11109
11332
  auth: _auth,
@@ -11771,7 +11994,8 @@ function SettingsContentInner({
11771
11994
  onInviteOpenChange: setTeamInviteOpen,
11772
11995
  workspaceName: workspaceScopeName,
11773
11996
  workspaceImageUrl: currentWorkspaceData?.imageUrl,
11774
- organizationName: organizationScopeName
11997
+ organizationName: organizationScopeName,
11998
+ hiddenApps
11775
11999
  }
11776
12000
  ) }),
11777
12001
  activeTab === "workspaceList" && /* @__PURE__ */ jsx20(
@@ -11910,24 +12134,14 @@ function SettingsContentInner({
11910
12134
  }
11911
12135
  );
11912
12136
  }
11913
-
11914
- // src/team-types.ts
11915
- var DEFAULT_PERMISSIONS = {
11916
- artifax: true,
11917
- photogenix: true,
11918
- catalogix: true,
11919
- returns: true,
11920
- canUseCredits: true,
11921
- canInviteUser: true,
11922
- role: "admin",
11923
- catalogixStores: []
11924
- };
11925
12137
  export {
12138
+ APP_KEYS,
11926
12139
  BillingContent,
11927
12140
  BuyCreditsModal,
11928
12141
  ConfirmDeleteModal,
11929
12142
  ConfirmLeaveModal,
11930
12143
  DEFAULT_PERMISSIONS,
12144
+ DEFAULT_USER_LANGUAGE,
11931
12145
  ExportDateModal,
11932
12146
  InviteUpdateModal,
11933
12147
  MemberListFrame,
@@ -11952,11 +12166,13 @@ export {
11952
12166
  TeamsContent,
11953
12167
  TokensContent,
11954
12168
  URL_TO_TAB,
12169
+ USER_LANGUAGES,
11955
12170
  WorkspaceGeneralTab,
11956
12171
  WorkspaceListTab,
11957
12172
  WorkspaceModal,
11958
12173
  WorkspaceTab,
11959
12174
  countLabel,
11960
12175
  resolveSettingsTabFromPath,
11961
- useSettingsAdapters
12176
+ useSettingsAdapters,
12177
+ userLanguageLabel
11962
12178
  };