@fayz-ai/admin 0.43.2 → 0.44.0

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.
Files changed (51) hide show
  1. package/dist/ScheduleEditor-MNHZCQIG.js +6 -0
  2. package/dist/{ScheduleEditor-ZEG6PG3Z.js.map → ScheduleEditor-MNHZCQIG.js.map} +1 -1
  3. package/dist/SubscriptionPage-JWWS44SE.js +9 -0
  4. package/dist/{SubscriptionPage-VXZ37WZZ.js.map → SubscriptionPage-JWWS44SE.js.map} +1 -1
  5. package/dist/{chunk-A5UZL52H.js → chunk-OINP2UYL.js} +3 -3
  6. package/dist/{chunk-A5UZL52H.js.map → chunk-OINP2UYL.js.map} +1 -1
  7. package/dist/{chunk-KP3LNCNP.js → chunk-V2IBAF4O.js} +954 -23
  8. package/dist/chunk-V2IBAF4O.js.map +1 -0
  9. package/dist/{chunk-HOMD2MAG.js → chunk-VH4LLIMH.js} +3 -3
  10. package/dist/{chunk-HOMD2MAG.js.map → chunk-VH4LLIMH.js.map} +1 -1
  11. package/dist/components/connect/useConnectors.d.ts.map +1 -1
  12. package/dist/components/settings/ConnectedCompanySettings.d.ts.map +1 -1
  13. package/dist/crud/archetypes/OrderDeliveryBlock.d.ts +32 -0
  14. package/dist/crud/archetypes/OrderDeliveryBlock.d.ts.map +1 -0
  15. package/dist/crud/archetypes/OrderDetailPage.d.ts +4 -2
  16. package/dist/crud/archetypes/OrderDetailPage.d.ts.map +1 -1
  17. package/dist/crud/archetypes/OrderDetailRail.d.ts +2 -0
  18. package/dist/crud/archetypes/OrderDetailRail.d.ts.map +1 -1
  19. package/dist/crud/archetypes/OrderDetailView.d.ts +11 -1
  20. package/dist/crud/archetypes/OrderDetailView.d.ts.map +1 -1
  21. package/dist/crud/archetypes/OrderFormView.d.ts +10 -2
  22. package/dist/crud/archetypes/OrderFormView.d.ts.map +1 -1
  23. package/dist/crud/archetypes/OrderListView.d.ts +20 -1
  24. package/dist/crud/archetypes/OrderListView.d.ts.map +1 -1
  25. package/dist/crud/archetypes/orderStage.d.ts +16 -0
  26. package/dist/crud/archetypes/orderStage.d.ts.map +1 -0
  27. package/dist/crud/archetypes/orderVocabulary.d.ts.map +1 -1
  28. package/dist/crud/archetypes/useOrderKindTransitions.d.ts +10 -0
  29. package/dist/crud/archetypes/useOrderKindTransitions.d.ts.map +1 -0
  30. package/dist/crud/relation-field.d.ts.map +1 -1
  31. package/dist/index.d.ts +9 -3
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +740 -918
  34. package/dist/index.js.map +1 -1
  35. package/dist/lib/currency.d.ts +33 -5
  36. package/dist/lib/currency.d.ts.map +1 -1
  37. package/dist/lib/format.d.ts.map +1 -1
  38. package/dist/org/context.d.ts.map +1 -1
  39. package/dist/org/index.js +1 -2
  40. package/dist/plugins/createPluginContext.d.ts.map +1 -1
  41. package/dist/theme/utils.d.ts +9 -0
  42. package/dist/theme/utils.d.ts.map +1 -1
  43. package/dist/units/useHouseCurrencySync.d.ts +9 -0
  44. package/dist/units/useHouseCurrencySync.d.ts.map +1 -0
  45. package/dist/units/useUnitBootstrap.d.ts.map +1 -1
  46. package/package.json +6 -6
  47. package/dist/ScheduleEditor-ZEG6PG3Z.js +0 -7
  48. package/dist/SubscriptionPage-VXZ37WZZ.js +0 -9
  49. package/dist/chunk-3C5Q4OGJ.js +0 -375
  50. package/dist/chunk-3C5Q4OGJ.js.map +0 -1
  51. package/dist/chunk-KP3LNCNP.js.map +0 -1
@@ -1,14 +1,15 @@
1
- import { markWorkspaceSwitch, clearOrgSnapshot, useTenant, useTenantOptional, setAutoPick } from './chunk-3C5Q4OGJ.js';
2
- import { persistOrgId, cn, getPersistedOrgId } from './chunk-QOS6UAQ4.js';
1
+ import { usePermissionsStore } from './chunk-UQ2NTFQC.js';
2
+ import { persistOrgId, cn, useOrganizationStore, getPersistedOrgId } from './chunk-QOS6UAQ4.js';
3
3
  import { createClient } from '@supabase/supabase-js';
4
- import { EMPTY_APP_CONFIG, getActiveUnitId, getActiveTenantId, setGlobalSupabaseClient, useTranslation, getSupabaseClientOptional as getSupabaseClientOptional$1 } from '@fayz-ai/core';
4
+ import { EMPTY_APP_CONFIG, resetActiveUnit, setUnitMode, setActiveUnitId, setScopedResources, getSupabaseClientOptional, isKnownMissing, rememberIfMissing, getActiveUnitId, getActiveTenantId, setGlobalSupabaseClient, useTranslation, isImpersonating, errorMessage, emitDomainEvent, setHouseCurrency } from '@fayz-ai/core';
5
5
  import { createDedupedFetch } from '@fayz-ai/sdk';
6
- import * as React2 from 'react';
6
+ import * as React3 from 'react';
7
7
  import { useState, useEffect } from 'react';
8
8
  import { Building2, Check, ShieldCheck } from 'lucide-react';
9
9
  import { create } from 'zustand';
10
10
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
11
11
  import { cn as cn$1, Checkbox, Button } from '@fayz-ai/ui';
12
+ import { useAuthStore, readAppHandoff } from '@fayz-ai/auth';
12
13
 
13
14
  var _client = null;
14
15
  function requestUrl(input) {
@@ -981,6 +982,61 @@ function createMockOrgAdapter(defaultProfiles) {
981
982
  }
982
983
  };
983
984
  }
985
+
986
+ // src/org/choice.ts
987
+ var AUTOPICK_KEY = "fayz:workspace-autopick";
988
+ var SWITCHING_KEY = "fayz:workspace-switching";
989
+ function markWorkspaceSwitch(orgId) {
990
+ try {
991
+ if (typeof sessionStorage === "undefined") return;
992
+ sessionStorage.setItem(SWITCHING_KEY, orgId);
993
+ } catch {
994
+ }
995
+ }
996
+ function takeWorkspaceSwitch() {
997
+ try {
998
+ if (typeof sessionStorage === "undefined") return null;
999
+ const v = sessionStorage.getItem(SWITCHING_KEY);
1000
+ if (v) sessionStorage.removeItem(SWITCHING_KEY);
1001
+ return v;
1002
+ } catch {
1003
+ return null;
1004
+ }
1005
+ }
1006
+ function getAutoPick() {
1007
+ try {
1008
+ if (typeof localStorage === "undefined") return false;
1009
+ return localStorage.getItem(AUTOPICK_KEY) === "1";
1010
+ } catch {
1011
+ return false;
1012
+ }
1013
+ }
1014
+ function setAutoPick(on) {
1015
+ try {
1016
+ if (typeof localStorage === "undefined") return;
1017
+ if (on) localStorage.setItem(AUTOPICK_KEY, "1");
1018
+ else localStorage.removeItem(AUTOPICK_KEY);
1019
+ } catch {
1020
+ }
1021
+ }
1022
+ function decideWorkspaceChoice({
1023
+ memberships,
1024
+ switchingToId = null,
1025
+ handoffId,
1026
+ pinnedId,
1027
+ autoPick
1028
+ }) {
1029
+ if (memberships.length === 0) return { kind: "none" };
1030
+ const has = (id) => id && memberships.some((m) => m.orgId === id) ? id : null;
1031
+ const switching = has(switchingToId);
1032
+ if (switching) return { kind: "resolved", orgId: switching };
1033
+ const handoff = has(handoffId);
1034
+ if (handoff) return { kind: "resolved", orgId: handoff };
1035
+ if (memberships.length === 1) return { kind: "resolved", orgId: memberships[0].orgId };
1036
+ const pinned = has(pinnedId);
1037
+ if (pinned && autoPick) return { kind: "resolved", orgId: pinned };
1038
+ return { kind: "ask", suggestedId: pinned };
1039
+ }
984
1040
  var initialState = {
985
1041
  config: EMPTY_APP_CONFIG,
986
1042
  tenantId: null,
@@ -1023,9 +1079,9 @@ function OrgMark({ name, logoUrl, className, tone = "sidebar", current = false }
1023
1079
  const identity = useAppConfigStore((state) => state.config.branding?.identity);
1024
1080
  const pick = (key) => typeof identity?.[key] === "string" ? identity[key] : void 0;
1025
1081
  const src = (current ? pick("markUrl") : void 0) ?? logoUrl;
1026
- const [status, setStatus] = React2.useState("loading");
1027
- const imgRef = React2.useRef(null);
1028
- React2.useLayoutEffect(() => {
1082
+ const [status, setStatus] = React3.useState("loading");
1083
+ const imgRef = React3.useRef(null);
1084
+ React3.useLayoutEffect(() => {
1029
1085
  const el = imgRef.current;
1030
1086
  setStatus(el?.complete ? el.naturalWidth > 0 ? "ok" : "error" : "loading");
1031
1087
  }, [src]);
@@ -1075,6 +1131,881 @@ function OrgMark({ name, logoUrl, className, tone = "sidebar", current = false }
1075
1131
  }
1076
1132
  );
1077
1133
  }
1134
+ var UNIT_BOOTSTRAP_OBJECT = "rpc:unit_bootstrap";
1135
+ var UNIT_MODE_OBJECT = "tenants.unit_scoping_enabled";
1136
+ var SCOPED_RESOURCES_OBJECT = "scoped_resources";
1137
+ var UNIT_ACCESS_CHANGED = "core.unit-access.changed";
1138
+ function emitUnitAccessChanged(userId, unitId) {
1139
+ emitDomainEvent(
1140
+ UNIT_ACCESS_CHANGED,
1141
+ { user_id: userId, unit_id: unitId },
1142
+ { tenantId: getActiveTenantId() ?? null, subject: { type: "location", id: unitId } }
1143
+ );
1144
+ }
1145
+ function client() {
1146
+ return getSupabaseClientOptional();
1147
+ }
1148
+ function mapUnit(row) {
1149
+ return {
1150
+ id: row.id,
1151
+ tenantId: row.tenant_id,
1152
+ kind: row.kind ?? "branch",
1153
+ name: row.name,
1154
+ email: row.email ?? void 0,
1155
+ phone: row.phone ?? void 0,
1156
+ address: row.address ?? void 0,
1157
+ city: row.city ?? void 0,
1158
+ state: row.state ?? void 0,
1159
+ country: row.country ?? "BR",
1160
+ postalCode: row.postal_code ?? void 0,
1161
+ isHeadquarters: Boolean(row.is_headquarters),
1162
+ isActive: row.is_active !== false,
1163
+ tags: row.tags ?? [],
1164
+ notes: row.notes ?? void 0,
1165
+ metadata: row.metadata ?? {},
1166
+ createdAt: row.created_at,
1167
+ updatedAt: row.updated_at,
1168
+ parentId: row.parent_id ?? null,
1169
+ code: row.code ?? null,
1170
+ // numeric do Postgres chega como string no PostgREST; a aritmética de
1171
+ // distância precisa de número, e `Number(null)` é 0, que é uma coordenada
1172
+ // real no golfo da Guiné.
1173
+ latitude: row.latitude == null ? null : Number(row.latitude),
1174
+ longitude: row.longitude == null ? null : Number(row.longitude)
1175
+ };
1176
+ }
1177
+ async function fetchUnits(tenantId) {
1178
+ const db = client();
1179
+ if (!db) return [];
1180
+ const { data, error } = await db.from("v_units").select("*").eq("tenant_id", tenantId).order("is_headquarters", { ascending: false }).order("name");
1181
+ if (error) return [];
1182
+ return (data ?? []).map(mapUnit);
1183
+ }
1184
+ async function fetchMyBindings(userId, tenantId) {
1185
+ const db = client();
1186
+ if (!db) return [];
1187
+ const { data, error } = await db.from("v_unit_members").select("location_id, role").eq("user_id", userId).eq("tenant_id", tenantId);
1188
+ if (error) return [];
1189
+ return (data ?? []).map((r) => ({ locationId: r.location_id, role: r.role ?? null }));
1190
+ }
1191
+ async function fetchUnitBootstrap(tenantId, deviceId) {
1192
+ const db = client();
1193
+ if (!db) return null;
1194
+ if (isKnownMissing(UNIT_BOOTSTRAP_OBJECT)) return null;
1195
+ const { data, error } = await db.rpc("unit_bootstrap", {
1196
+ p_tenant_id: tenantId,
1197
+ p_device_id: deviceId ?? null
1198
+ });
1199
+ if (error) {
1200
+ rememberIfMissing(UNIT_BOOTSTRAP_OBJECT, error);
1201
+ return null;
1202
+ }
1203
+ if (!data) return null;
1204
+ const raw = data;
1205
+ return {
1206
+ mode: Boolean(raw.mode),
1207
+ units: (raw.units ?? []).map(mapUnit),
1208
+ bindings: (raw.bindings ?? []).map((r) => ({
1209
+ locationId: r.location_id,
1210
+ role: r.role ?? null
1211
+ })),
1212
+ scoped: Object.fromEntries(
1213
+ Object.entries(raw.scoped ?? {}).map(([table, v]) => [
1214
+ table,
1215
+ { unitColumn: v?.unit_column ?? "unit_id", shareable: v?.shareable !== false }
1216
+ ])
1217
+ ),
1218
+ // user_unit_ids_in walks the tree with UNION over (id, depth): a branch
1219
+ // reached directly AND through its HQ comes back twice.
1220
+ reachable: Array.isArray(raw.reachable) ? [...new Set(raw.reachable)] : void 0,
1221
+ devicePin: { set: Boolean(raw.device_pin_set), unitId: raw.device_pin ?? null },
1222
+ accountPin: { set: Boolean(raw.account_pin_set), unitId: raw.account_pin ?? null }
1223
+ };
1224
+ }
1225
+ async function saveEntryUnit(tenantId, unitId, deviceId) {
1226
+ const db = client();
1227
+ if (!db || !deviceId) return;
1228
+ await db.rpc("set_entry_unit", {
1229
+ p_tenant_id: tenantId,
1230
+ p_unit_id: unitId ?? null,
1231
+ p_device_id: deviceId
1232
+ });
1233
+ }
1234
+ async function fetchUnitMembers(unitId) {
1235
+ const db = client();
1236
+ if (!db) return [];
1237
+ const { data, error } = await db.from("v_unit_members").select("id, user_id, role, created_at").eq("location_id", unitId).order("created_at");
1238
+ if (error) return [];
1239
+ return (data ?? []).map((r) => ({
1240
+ id: r.id,
1241
+ userId: r.user_id,
1242
+ role: r.role ?? null,
1243
+ since: r.created_at ?? null
1244
+ }));
1245
+ }
1246
+ async function fetchMemberActivity(tenantId) {
1247
+ const db = client();
1248
+ if (!db) return {};
1249
+ const { data, error } = await db.rpc("tenant_member_activity", { p_tenant_id: tenantId });
1250
+ if (error) return {};
1251
+ const out = {};
1252
+ for (const r of data ?? []) {
1253
+ out[r.user_id] = {
1254
+ lastSignInAt: r.last_sign_in_at ?? null,
1255
+ signedUpAt: r.signed_up_at ?? null
1256
+ };
1257
+ }
1258
+ return out;
1259
+ }
1260
+ async function fetchMemberUnits(userId, tenantId) {
1261
+ const tenant = tenantId ?? getActiveTenantId();
1262
+ if (!tenant) return [];
1263
+ return fetchMyBindings(userId, tenant);
1264
+ }
1265
+ async function bindUserToUnit(unitId, userId, role) {
1266
+ const db = client();
1267
+ if (!db) throw new Error("sem conex\xE3o");
1268
+ const { error } = await db.rpc("unit_member_set", { p_unit: unitId, p_user: userId, p_role: role });
1269
+ if (error) throw error;
1270
+ emitUnitAccessChanged(userId, unitId);
1271
+ }
1272
+ async function unbindUserFromUnit(unitId, userId) {
1273
+ const db = client();
1274
+ if (!db) throw new Error("sem conex\xE3o");
1275
+ const { error } = await db.rpc("unit_member_remove", { p_unit: unitId, p_user: userId });
1276
+ if (error) throw error;
1277
+ emitUnitAccessChanged(userId, unitId);
1278
+ }
1279
+ async function fetchUserIdForPerson(personId) {
1280
+ const db = client();
1281
+ if (!db) return null;
1282
+ const { data, error } = await db.from("v_team_members").select("user_id").eq("person_id", personId).maybeSingle();
1283
+ if (error || !data) return null;
1284
+ return data.user_id ?? null;
1285
+ }
1286
+ async function fetchScopedResources() {
1287
+ const db = client();
1288
+ if (!db) return {};
1289
+ if (isKnownMissing(SCOPED_RESOURCES_OBJECT)) return {};
1290
+ const { data, error } = await db.from("scoped_resources").select("resource_table, unit_column, shareable");
1291
+ if (error) {
1292
+ rememberIfMissing(SCOPED_RESOURCES_OBJECT, error);
1293
+ return {};
1294
+ }
1295
+ const out = {};
1296
+ for (const r of data ?? []) {
1297
+ out[r.resource_table] = {
1298
+ unitColumn: r.unit_column ?? "unit_id",
1299
+ shareable: r.shareable !== false
1300
+ };
1301
+ }
1302
+ return out;
1303
+ }
1304
+ async function fetchUnitMode(tenantId) {
1305
+ const db = client();
1306
+ if (!db) return { installed: false, on: false };
1307
+ if (isKnownMissing(UNIT_MODE_OBJECT)) return { installed: false, on: false };
1308
+ const { data, error } = await db.from("tenants").select("unit_scoping_enabled").eq("id", tenantId).maybeSingle();
1309
+ if (error) {
1310
+ rememberIfMissing(UNIT_MODE_OBJECT, error);
1311
+ return { installed: false, on: false };
1312
+ }
1313
+ return { installed: true, on: Boolean(data?.unit_scoping_enabled) };
1314
+ }
1315
+ async function setUnitModeRemote(tenantId, on) {
1316
+ const db = client();
1317
+ if (!db) throw new Error("sem conex\xE3o");
1318
+ const { error } = await db.from("tenants").update({ unit_scoping_enabled: on }).eq("id", tenantId);
1319
+ if (error) throw error;
1320
+ }
1321
+ async function bindAllMembersTo(tenantId, unitId) {
1322
+ const db = client();
1323
+ if (!db) return 0;
1324
+ const { data } = await db.from("v_team_members").select("user_id").eq("tenant_id", tenantId);
1325
+ const userIds = (data ?? []).map((m) => m.user_id);
1326
+ if (userIds.length === 0) return 0;
1327
+ for (const userId of userIds) {
1328
+ const { error } = await db.rpc("unit_member_set", { p_unit: unitId, p_user: userId, p_role: null });
1329
+ if (error) throw error;
1330
+ }
1331
+ emitUnitAccessChanged(null, unitId);
1332
+ return userIds.length;
1333
+ }
1334
+ async function countUnboundMembers(tenantId) {
1335
+ const db = client();
1336
+ if (!db) return 0;
1337
+ const { data: members } = await db.from("v_team_members").select("user_id").eq("tenant_id", tenantId);
1338
+ const { data: units } = await db.from("v_units").select("id").eq("tenant_id", tenantId);
1339
+ const unitIds = (units ?? []).map((u) => u.id);
1340
+ if (unitIds.length === 0) return (members ?? []).length;
1341
+ const { data: bound } = await db.from("v_unit_members").select("user_id").in("location_id", unitIds);
1342
+ const boundSet = new Set((bound ?? []).map((b) => b.user_id));
1343
+ return (members ?? []).filter((m) => !boundSet.has(m.user_id)).length;
1344
+ }
1345
+
1346
+ // src/units/cache.ts
1347
+ var STORAGE_KEY2 = "fayz:units-snapshot";
1348
+ var VERSION = 1;
1349
+ var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
1350
+ var MAX_BYTES = 256 * 1024;
1351
+ function storage() {
1352
+ try {
1353
+ if (typeof localStorage === "undefined") return null;
1354
+ return localStorage;
1355
+ } catch {
1356
+ return null;
1357
+ }
1358
+ }
1359
+ function readUnitSnapshot() {
1360
+ const store = storage();
1361
+ if (!store) return null;
1362
+ try {
1363
+ const raw = store.getItem(STORAGE_KEY2);
1364
+ if (!raw) return null;
1365
+ const snapshot = JSON.parse(raw);
1366
+ if (snapshot?.version !== VERSION || !snapshot.tenantId || !snapshot.userId) return null;
1367
+ const age = Date.now() - snapshot.savedAt;
1368
+ if (age < 0 || age > MAX_AGE_MS) {
1369
+ store.removeItem(STORAGE_KEY2);
1370
+ return null;
1371
+ }
1372
+ return snapshot;
1373
+ } catch {
1374
+ return null;
1375
+ }
1376
+ }
1377
+ function saveUnitSnapshot(input) {
1378
+ const store = storage();
1379
+ if (!store) return;
1380
+ try {
1381
+ const raw = JSON.stringify({ ...input, version: VERSION, savedAt: Date.now() });
1382
+ if (raw.length > MAX_BYTES) return;
1383
+ store.setItem(STORAGE_KEY2, raw);
1384
+ } catch {
1385
+ }
1386
+ }
1387
+ function patchUnitSnapshotActive(activeUnitId) {
1388
+ const store = storage();
1389
+ const current = readUnitSnapshot();
1390
+ if (!store || !current) return;
1391
+ try {
1392
+ store.setItem(STORAGE_KEY2, JSON.stringify({ ...current, activeUnitId }));
1393
+ } catch {
1394
+ }
1395
+ }
1396
+ function clearUnitSnapshot() {
1397
+ try {
1398
+ storage()?.removeItem(STORAGE_KEY2);
1399
+ } catch {
1400
+ }
1401
+ }
1402
+
1403
+ // src/units/device.ts
1404
+ var STORAGE_KEY3 = "fayz:device-id";
1405
+ var cached = null;
1406
+ function randomId() {
1407
+ try {
1408
+ if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
1409
+ return crypto.randomUUID();
1410
+ }
1411
+ } catch {
1412
+ }
1413
+ return `d-${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;
1414
+ }
1415
+ function getDeviceId() {
1416
+ if (cached) return cached;
1417
+ try {
1418
+ if (typeof localStorage === "undefined") return void 0;
1419
+ const existing = localStorage.getItem(STORAGE_KEY3);
1420
+ if (existing) {
1421
+ cached = existing;
1422
+ return existing;
1423
+ }
1424
+ const fresh = randomId();
1425
+ localStorage.setItem(STORAGE_KEY3, fresh);
1426
+ cached = fresh;
1427
+ return fresh;
1428
+ } catch {
1429
+ return void 0;
1430
+ }
1431
+ }
1432
+
1433
+ // src/lib/dedup.ts
1434
+ var inflight = /* @__PURE__ */ new Map();
1435
+ function dedup2(key, fn) {
1436
+ const existing = inflight.get(key);
1437
+ if (existing) return existing;
1438
+ const promise = fn().finally(() => {
1439
+ inflight.delete(key);
1440
+ });
1441
+ inflight.set(key, promise);
1442
+ return promise;
1443
+ }
1444
+
1445
+ // src/units/entry.ts
1446
+ function resolveEntry(reachable, pins) {
1447
+ const canStand = (id) => id != null && reachable.includes(id);
1448
+ const ladder = [
1449
+ [pins.device, "device"],
1450
+ [pins.account, "account"]
1451
+ ];
1452
+ for (const [pin, reason] of ladder) {
1453
+ if (!pin?.set) continue;
1454
+ if (pin.unitId === null) return { unitId: void 0, reason: "all", needsChoice: false };
1455
+ if (canStand(pin.unitId)) return { unitId: pin.unitId, reason, needsChoice: false };
1456
+ }
1457
+ if (canStand(pins.legacy)) return { unitId: pins.legacy, reason: "device", needsChoice: false };
1458
+ if (reachable.length === 1) return { unitId: reachable[0], reason: "only", needsChoice: false };
1459
+ return { unitId: void 0, reason: "all", needsChoice: reachable.length > 1 };
1460
+ }
1461
+
1462
+ // src/units/store.ts
1463
+ var LEGACY_KEY = "saas-core:current-location";
1464
+ function legacyPin() {
1465
+ try {
1466
+ return localStorage.getItem(LEGACY_KEY) ?? void 0;
1467
+ } catch {
1468
+ return void 0;
1469
+ }
1470
+ }
1471
+ function buildTree(units) {
1472
+ const nodes = /* @__PURE__ */ new Map();
1473
+ for (const u of units) nodes.set(u.id, { ...u, children: [] });
1474
+ const roots = [];
1475
+ for (const node of nodes.values()) {
1476
+ const parent = node.parentId ? nodes.get(node.parentId) : void 0;
1477
+ if (parent && parent.id !== node.id) parent.children.push(node);
1478
+ else roots.push(node);
1479
+ }
1480
+ return roots;
1481
+ }
1482
+ function expandDown(units, seeds) {
1483
+ const childrenOf = /* @__PURE__ */ new Map();
1484
+ for (const u of units) {
1485
+ if (!u.parentId) continue;
1486
+ const list = childrenOf.get(u.parentId) ?? [];
1487
+ list.push(u.id);
1488
+ childrenOf.set(u.parentId, list);
1489
+ }
1490
+ const out = /* @__PURE__ */ new Set();
1491
+ const queue = [...seeds];
1492
+ while (queue.length > 0) {
1493
+ const id = queue.shift();
1494
+ if (out.has(id)) continue;
1495
+ out.add(id);
1496
+ for (const child of childrenOf.get(id) ?? []) queue.push(child);
1497
+ }
1498
+ return [...out];
1499
+ }
1500
+ function branchesOnly(ids, byId) {
1501
+ return ids.filter((id) => byId[id]?.kind !== "region");
1502
+ }
1503
+ var useUnitStore = create((set, get) => ({
1504
+ units: [],
1505
+ byId: {},
1506
+ tree: [],
1507
+ myUnitIds: [],
1508
+ myBindings: [],
1509
+ activeUnitId: void 0,
1510
+ entryReason: "all",
1511
+ unitMode: false,
1512
+ loading: false,
1513
+ resolved: false,
1514
+ needsChoice: false,
1515
+ loadedFor: null,
1516
+ // Uma chamada por conta, por mais telas que peçam.
1517
+ //
1518
+ // Dez componentes chamam `useUnitBootstrap` — o seletor, a linha de
1519
+ // identidade, o rodapé do registro, a aba de unidades de uma pessoa — e todos
1520
+ // montam no mesmo quadro. A guarda anterior era `loadedFor === tenantId &&
1521
+ // !loading`, que deixa passar exatamente enquanto a primeira chamada está no
1522
+ // ar: o segundo componente via a conta já marcada, via `loading` ligado, e a
1523
+ // condição inteira dava falso. Resultado: uma requisição por tela, todas
1524
+ // idênticas. Juntar cinco viagens numa e depois disparar essa uma cinco vezes
1525
+ // não economiza nada.
1526
+ //
1527
+ // `dedup` é o mesmo utilitário que a tela de equipe já usa: quem chegar
1528
+ // enquanto a primeira está no ar recebe a MESMA promessa em vez de abrir
1529
+ // outra.
1530
+ async load(tenantId, userId) {
1531
+ if (!tenantId) return;
1532
+ if (get().loadedFor === tenantId && !get().loading) return;
1533
+ return dedup2(`units:${tenantId}:${userId ?? ""}`, () => loadOnce(tenantId, userId, set, get));
1534
+ },
1535
+ setActive(unitId, reason = "manual") {
1536
+ setActiveUnitId(unitId);
1537
+ set({ activeUnitId: unitId, entryReason: reason, needsChoice: false });
1538
+ patchUnitSnapshotActive(unitId ?? null);
1539
+ const tenantId = get().loadedFor;
1540
+ if (tenantId) void saveEntryUnit(tenantId, unitId, getDeviceId());
1541
+ },
1542
+ setMode(on) {
1543
+ setUnitMode(on);
1544
+ set({ unitMode: on });
1545
+ if (!on) {
1546
+ setActiveUnitId(void 0);
1547
+ set({ activeUnitId: void 0, entryReason: "all", needsChoice: false });
1548
+ patchUnitSnapshotActive(null);
1549
+ }
1550
+ },
1551
+ reset() {
1552
+ clearUnitSnapshot();
1553
+ resetActiveUnit();
1554
+ set({
1555
+ units: [],
1556
+ byId: {},
1557
+ tree: [],
1558
+ myUnitIds: [],
1559
+ myBindings: [],
1560
+ activeUnitId: void 0,
1561
+ entryReason: "all",
1562
+ unitMode: false,
1563
+ loading: false,
1564
+ resolved: false,
1565
+ needsChoice: false,
1566
+ loadedFor: null
1567
+ });
1568
+ }
1569
+ }));
1570
+ async function loadOnce(tenantId, userId, set, get) {
1571
+ set({ loading: true, loadedFor: tenantId });
1572
+ try {
1573
+ const deviceId = getDeviceId();
1574
+ const boot = await fetchUnitBootstrap(tenantId, deviceId);
1575
+ let mode;
1576
+ let units;
1577
+ let bindings;
1578
+ let scoped;
1579
+ let reachableFromServer;
1580
+ if (boot) {
1581
+ ;
1582
+ [mode, units, bindings, scoped] = [boot.mode, boot.units, boot.bindings, boot.scoped];
1583
+ reachableFromServer = boot.reachable;
1584
+ } else {
1585
+ const modeResult = await fetchUnitMode(tenantId);
1586
+ mode = modeResult.on;
1587
+ if (!modeResult.installed) {
1588
+ units = [];
1589
+ bindings = [];
1590
+ scoped = {};
1591
+ } else {
1592
+ ;
1593
+ [units, bindings, scoped] = await Promise.all([
1594
+ fetchUnits(tenantId),
1595
+ userId ? fetchMyBindings(userId, tenantId) : Promise.resolve([]),
1596
+ mode ? fetchScopedResources() : Promise.resolve({})
1597
+ ]);
1598
+ }
1599
+ }
1600
+ setScopedResources(scoped);
1601
+ const byId = {};
1602
+ for (const u of units) byId[u.id] = u;
1603
+ const reachable = reachableFromServer ? branchesOnly(reachableFromServer.filter((id) => byId[id]), byId) : branchesOnly(expandDown(units, bindings.map((b) => b.locationId)), byId);
1604
+ const entry = resolveEntry(reachable, {
1605
+ device: boot?.devicePin,
1606
+ account: boot?.accountPin,
1607
+ legacy: legacyPin()
1608
+ });
1609
+ setUnitMode(mode);
1610
+ setActiveUnitId(entry.unitId);
1611
+ set({
1612
+ units,
1613
+ byId,
1614
+ tree: buildTree(units),
1615
+ myUnitIds: reachable,
1616
+ myBindings: bindings,
1617
+ unitMode: mode,
1618
+ activeUnitId: entry.unitId,
1619
+ entryReason: entry.reason,
1620
+ needsChoice: entry.needsChoice,
1621
+ loading: false,
1622
+ resolved: true
1623
+ });
1624
+ if (userId) {
1625
+ saveUnitSnapshot({
1626
+ userId,
1627
+ tenantId,
1628
+ mode,
1629
+ units,
1630
+ bindings,
1631
+ myUnitIds: reachable,
1632
+ activeUnitId: entry.unitId ?? null,
1633
+ scoped
1634
+ });
1635
+ }
1636
+ } finally {
1637
+ if (get().loading) set({ loading: false });
1638
+ }
1639
+ }
1640
+ (function hydrate() {
1641
+ const snapshot = readUnitSnapshot();
1642
+ if (!snapshot) return;
1643
+ const org = readOrgSnapshot();
1644
+ if (!org || org.org?.id !== snapshot.tenantId || org.userId !== snapshot.userId) {
1645
+ clearUnitSnapshot();
1646
+ return;
1647
+ }
1648
+ const byId = {};
1649
+ for (const u of snapshot.units) byId[u.id] = u;
1650
+ const active = snapshot.activeUnitId ?? void 0;
1651
+ const standable = active && snapshot.myUnitIds.includes(active) ? active : void 0;
1652
+ setScopedResources(snapshot.scoped);
1653
+ setUnitMode(snapshot.mode);
1654
+ setActiveUnitId(standable);
1655
+ useUnitStore.setState({
1656
+ units: snapshot.units,
1657
+ byId,
1658
+ tree: buildTree(snapshot.units),
1659
+ myUnitIds: snapshot.myUnitIds,
1660
+ myBindings: snapshot.bindings,
1661
+ unitMode: snapshot.mode,
1662
+ activeUnitId: standable,
1663
+ entryReason: standable ? "device" : "all",
1664
+ resolved: true
1665
+ });
1666
+ })();
1667
+
1668
+ // src/units/useHouseCurrencySync.ts
1669
+ function useHouseCurrencySync(orgId, tenantCurrency) {
1670
+ const activeUnitId = useUnitStore((s) => s.activeUnitId);
1671
+ React3.useEffect(() => {
1672
+ if (!orgId) {
1673
+ setHouseCurrency(null);
1674
+ return;
1675
+ }
1676
+ setHouseCurrency(tenantCurrency ?? null);
1677
+ if (!activeUnitId) return;
1678
+ let alive = true;
1679
+ void unitCurrency(orgId, activeUnitId).then((code) => {
1680
+ if (alive && code) setHouseCurrency(code);
1681
+ });
1682
+ return () => {
1683
+ alive = false;
1684
+ };
1685
+ }, [orgId, activeUnitId, tenantCurrency]);
1686
+ }
1687
+ var unitCurrencyCache = /* @__PURE__ */ new Map();
1688
+ function unitCurrency(orgId, unitId) {
1689
+ const key = `${orgId}:${unitId}`;
1690
+ let pending = unitCurrencyCache.get(key);
1691
+ if (!pending) {
1692
+ const client2 = getSupabaseClientOptional();
1693
+ pending = client2 ? Promise.resolve(client2.rpc("my_unit_currency", { p_unit: unitId })).then((res) => res.error || typeof res.data !== "string" ? null : res.data).catch(() => null) : Promise.resolve(null);
1694
+ unitCurrencyCache.set(key, pending);
1695
+ }
1696
+ return pending;
1697
+ }
1698
+
1699
+ // src/org/cache.ts
1700
+ var STORAGE_KEY4 = "fayz:org-snapshot";
1701
+ var VERSION2 = 1;
1702
+ var ORG_CACHE_TTL_MS = 5 * 60 * 1e3;
1703
+ var MAX_AGE_MS2 = 24 * 60 * 60 * 1e3;
1704
+ var MAX_BYTES2 = 512 * 1024;
1705
+ function storage2() {
1706
+ try {
1707
+ if (typeof localStorage === "undefined") return null;
1708
+ return localStorage;
1709
+ } catch {
1710
+ return null;
1711
+ }
1712
+ }
1713
+ function readOrgSnapshot() {
1714
+ const store = storage2();
1715
+ if (!store) return null;
1716
+ try {
1717
+ const raw = store.getItem(STORAGE_KEY4);
1718
+ if (!raw) return null;
1719
+ const snapshot = JSON.parse(raw);
1720
+ if (snapshot?.version !== VERSION2 || !snapshot.org?.id || !snapshot.userId) return null;
1721
+ if (snapshotAge(snapshot) > MAX_AGE_MS2) {
1722
+ store.removeItem(STORAGE_KEY4);
1723
+ return null;
1724
+ }
1725
+ return snapshot;
1726
+ } catch {
1727
+ return null;
1728
+ }
1729
+ }
1730
+ function snapshotAge(snapshot) {
1731
+ const age = Date.now() - snapshot.savedAt;
1732
+ return age < 0 ? Number.POSITIVE_INFINITY : age;
1733
+ }
1734
+ function isSnapshotFresh(snapshot, ttlMs) {
1735
+ return snapshotAge(snapshot) < ttlMs;
1736
+ }
1737
+ function saveOrgSnapshot(input) {
1738
+ write({ ...input, version: VERSION2, savedAt: Date.now() });
1739
+ }
1740
+ function patchOrgSnapshot(input) {
1741
+ const current = readOrgSnapshot();
1742
+ if (!current || current.userId !== input.userId) return;
1743
+ write({ ...input, version: VERSION2, savedAt: current.savedAt });
1744
+ }
1745
+ function clearOrgSnapshot() {
1746
+ try {
1747
+ storage2()?.removeItem(STORAGE_KEY4);
1748
+ } catch {
1749
+ }
1750
+ }
1751
+ function write(snapshot) {
1752
+ const store = storage2();
1753
+ if (!store) return;
1754
+ try {
1755
+ const raw = JSON.stringify(snapshot);
1756
+ if (raw.length > MAX_BYTES2) return;
1757
+ store.setItem(STORAGE_KEY4, raw);
1758
+ } catch {
1759
+ }
1760
+ }
1761
+ var OrgAdapterContext = React3.createContext(null);
1762
+ function useOrgAdapter() {
1763
+ const adapter = React3.useContext(OrgAdapterContext);
1764
+ if (!adapter) {
1765
+ throw new Error("useOrgAdapter must be used within an <OrgProvider>");
1766
+ }
1767
+ return adapter;
1768
+ }
1769
+ function useOrgAdapterOptional() {
1770
+ return React3.useContext(OrgAdapterContext);
1771
+ }
1772
+ var TenantContext = React3.createContext(null);
1773
+ function useTenant() {
1774
+ const ctx = React3.useContext(TenantContext);
1775
+ if (!ctx) {
1776
+ throw new Error("useTenant must be used inside <OrgProvider>");
1777
+ }
1778
+ return ctx;
1779
+ }
1780
+ function useTenantOptional() {
1781
+ return React3.useContext(TenantContext);
1782
+ }
1783
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? React3.useLayoutEffect : React3.useEffect;
1784
+ function OrgProvider({
1785
+ adapter,
1786
+ autoCreate = false,
1787
+ cacheTtlMs = ORG_CACHE_TTL_MS,
1788
+ children
1789
+ }) {
1790
+ const { user, isLoading: authLoading } = useAuthStore();
1791
+ const { currentOrg, userOrgs, loading, setCurrentOrg, paintCurrentOrg, setUserOrgs, setMembers, setLoading, reset } = useOrganizationStore();
1792
+ const setProfiles = usePermissionsStore((s) => s.setProfiles);
1793
+ const setCurrentProfile = usePermissionsStore((s) => s.setCurrentProfile);
1794
+ const setProfileKnownFor = usePermissionsStore((s) => s.setProfileKnownFor);
1795
+ const adapterRef = React3.useRef(adapter);
1796
+ adapterRef.current = adapter;
1797
+ const [snapshot] = React3.useState(
1798
+ () => cacheTtlMs > 0 ? readOrgSnapshot() : null
1799
+ );
1800
+ const loadedForRef = React3.useRef(null);
1801
+ const [settledFor, setSettledFor] = React3.useState(
1802
+ () => snapshot?.org ? snapshot.userId : null
1803
+ );
1804
+ const [orgsReadFor, setOrgsReadFor] = React3.useState(
1805
+ () => snapshot?.org ? snapshot.userId : null
1806
+ );
1807
+ const [loadError, setLoadError] = React3.useState(null);
1808
+ const [retryTick, setRetryTick] = React3.useState(0);
1809
+ const retryOrgs = React3.useCallback(() => {
1810
+ loadedForRef.current = null;
1811
+ setLoadError(null);
1812
+ setRetryTick((n) => n + 1);
1813
+ }, []);
1814
+ const settled = user ? settledFor === user.id : !authLoading;
1815
+ const orgsKnown = !!user && orgsReadFor === user.id;
1816
+ useIsomorphicLayoutEffect(() => {
1817
+ if (!snapshot) return;
1818
+ setUserOrgs(snapshot.userOrgs);
1819
+ paintCurrentOrg(snapshot.org);
1820
+ setMembers(snapshot.members);
1821
+ setProfiles(snapshot.profiles);
1822
+ setCurrentProfile(snapshot.profiles.find((p) => p.id === snapshot.currentProfileId) ?? null);
1823
+ setProfileKnownFor(snapshot.org.id);
1824
+ }, []);
1825
+ React3.useEffect(() => {
1826
+ if (cacheTtlMs <= 0 || !user) return;
1827
+ const uid = user.id;
1828
+ const sync = () => {
1829
+ const org = useOrganizationStore.getState();
1830
+ if (!org.currentOrg) return;
1831
+ const perms = usePermissionsStore.getState();
1832
+ patchOrgSnapshot({
1833
+ userId: uid,
1834
+ org: org.currentOrg,
1835
+ userOrgs: org.userOrgs,
1836
+ members: org.members,
1837
+ profiles: perms.profiles,
1838
+ // realProfile, not currentProfile: an impersonation preview is not
1839
+ // something to cache back as the user's own role.
1840
+ currentProfileId: perms.realProfile?.id ?? null
1841
+ });
1842
+ };
1843
+ const unsubscribeOrg = useOrganizationStore.subscribe(sync);
1844
+ const unsubscribePerms = usePermissionsStore.subscribe(sync);
1845
+ return () => {
1846
+ unsubscribeOrg();
1847
+ unsubscribePerms();
1848
+ };
1849
+ }, [user?.id, cacheTtlMs]);
1850
+ const hydrateOrg = React3.useCallback(
1851
+ async (org, memberships, uid) => {
1852
+ try {
1853
+ const [members, profiles] = await Promise.all([
1854
+ adapterRef.current.listMembers(org.id),
1855
+ adapterRef.current.listProfiles(org.id)
1856
+ ]);
1857
+ setMembers(members);
1858
+ setProfiles(profiles);
1859
+ const myMembership = uid ? members.find((m) => m.userId === uid) : void 0;
1860
+ const profile = profiles.find((p) => p.id === myMembership?.profileId) ?? null;
1861
+ setCurrentProfile(profile);
1862
+ if (cacheTtlMs > 0 && uid) {
1863
+ saveOrgSnapshot({
1864
+ userId: uid,
1865
+ org,
1866
+ userOrgs: memberships,
1867
+ members,
1868
+ profiles,
1869
+ currentProfileId: profile?.id ?? null
1870
+ });
1871
+ }
1872
+ } catch {
1873
+ } finally {
1874
+ setProfileKnownFor(org.id);
1875
+ }
1876
+ },
1877
+ [setMembers, setProfiles, setCurrentProfile, setProfileKnownFor, cacheTtlMs]
1878
+ );
1879
+ React3.useEffect(() => {
1880
+ if (!user) {
1881
+ if (authLoading) return;
1882
+ loadedForRef.current = null;
1883
+ reset();
1884
+ clearOrgSnapshot();
1885
+ setSettledFor(null);
1886
+ setOrgsReadFor(null);
1887
+ return;
1888
+ }
1889
+ const cached2 = snapshot?.userId === user.id ? snapshot : null;
1890
+ if (cached2 && isSnapshotFresh(cached2, cacheTtlMs)) {
1891
+ setSettledFor(user.id);
1892
+ setOrgsReadFor(user.id);
1893
+ return;
1894
+ }
1895
+ if (snapshot && snapshot.userId !== user.id && loadedForRef.current === null) {
1896
+ reset();
1897
+ clearOrgSnapshot();
1898
+ }
1899
+ if (loadedForRef.current === user.id) return;
1900
+ loadedForRef.current = user.id;
1901
+ const silent = !!cached2;
1902
+ let cancelled = false;
1903
+ async function loadOrgs() {
1904
+ if (!silent) setLoading(true);
1905
+ try {
1906
+ let accepted = 0;
1907
+ try {
1908
+ if (!isImpersonating()) accepted = await adapterRef.current.acceptPendingInvites?.() ?? 0;
1909
+ } catch {
1910
+ }
1911
+ if (cancelled) return;
1912
+ let memberships = await adapterRef.current.listUserOrgs(user.id);
1913
+ if (memberships.length === 0 && accepted > 0) {
1914
+ memberships = await adapterRef.current.listUserOrgs(user.id);
1915
+ }
1916
+ for (let attempt = 0; memberships.length === 0 && attempt < 2; attempt++) {
1917
+ await new Promise((resolve) => setTimeout(resolve, 250 * (attempt + 1)));
1918
+ if (cancelled) return;
1919
+ memberships = await adapterRef.current.listUserOrgs(user.id);
1920
+ }
1921
+ if (cancelled) return;
1922
+ setUserOrgs(memberships);
1923
+ setOrgsReadFor(user.id);
1924
+ if (memberships.length === 0 && accepted === 0 && autoCreate) {
1925
+ const newOrg = await adapterRef.current.createOrg(
1926
+ user.fullName ? `${user.fullName}'s Organization` : "My Organization",
1927
+ user.id
1928
+ );
1929
+ if (!cancelled) {
1930
+ const ownMembership = [
1931
+ {
1932
+ orgId: newOrg.id,
1933
+ orgName: newOrg.name,
1934
+ orgSlug: newOrg.slug,
1935
+ profileId: "owner",
1936
+ profileName: "Owner"
1937
+ }
1938
+ ];
1939
+ setUserOrgs(ownMembership);
1940
+ setCurrentOrg(newOrg);
1941
+ await hydrateOrg(newOrg, ownMembership, user.id);
1942
+ }
1943
+ return;
1944
+ }
1945
+ const choice = decideWorkspaceChoice({
1946
+ memberships,
1947
+ // Consumed here, and only here: this is the one boot the marker was
1948
+ // written for, and leaving it behind would pin the next one too.
1949
+ switchingToId: takeWorkspaceSwitch(),
1950
+ handoffId: readAppHandoff()?.tenantId ?? null,
1951
+ pinnedId: getPersistedOrgId(),
1952
+ autoPick: getAutoPick()
1953
+ });
1954
+ if (choice.kind !== "resolved") return;
1955
+ if (!cancelled) {
1956
+ const org = await adapterRef.current.getOrg(choice.orgId);
1957
+ if (!cancelled) {
1958
+ setCurrentOrg(org);
1959
+ await hydrateOrg(org, memberships, user.id);
1960
+ }
1961
+ }
1962
+ } catch (err) {
1963
+ if (!cancelled) setLoadError(errorMessage(err));
1964
+ } finally {
1965
+ if (!cancelled && !silent) setLoading(false);
1966
+ if (!cancelled) setSettledFor(user.id);
1967
+ }
1968
+ }
1969
+ void loadOrgs();
1970
+ return () => {
1971
+ cancelled = true;
1972
+ };
1973
+ }, [user?.id, authLoading, retryTick]);
1974
+ async function switchOrg(orgId) {
1975
+ setLoading(true);
1976
+ try {
1977
+ const org = await adapterRef.current.getOrg(orgId);
1978
+ setCurrentOrg(org);
1979
+ await hydrateOrg(org, useOrganizationStore.getState().userOrgs, user?.id);
1980
+ } finally {
1981
+ setLoading(false);
1982
+ }
1983
+ }
1984
+ async function refreshOrg() {
1985
+ if (!currentOrg) return;
1986
+ setLoading(true);
1987
+ try {
1988
+ const org = await adapterRef.current.getOrg(currentOrg.id);
1989
+ setCurrentOrg(org);
1990
+ await hydrateOrg(org, useOrganizationStore.getState().userOrgs, user?.id);
1991
+ } finally {
1992
+ setLoading(false);
1993
+ }
1994
+ }
1995
+ useHouseCurrencySync(currentOrg?.id, currentOrg?.settings?.currency);
1996
+ const tenantValue = {
1997
+ org: currentOrg,
1998
+ userOrgs,
1999
+ loading,
2000
+ settled,
2001
+ orgsKnown,
2002
+ loadError,
2003
+ retryOrgs,
2004
+ switchOrg,
2005
+ refreshOrg
2006
+ };
2007
+ return /* @__PURE__ */ jsx(OrgAdapterContext.Provider, { value: adapter, children: /* @__PURE__ */ jsx(TenantContext.Provider, { value: tenantValue, children }) });
2008
+ }
1078
2009
 
1079
2010
  // src/org/workspace-search.ts
1080
2011
  var WORKSPACE_SEARCH_THRESHOLD = 8;
@@ -1104,16 +2035,16 @@ function WorkspaceChooser({ memberships, suggestedId, onCancel }) {
1104
2035
  return !v || v === key ? fallback : v;
1105
2036
  };
1106
2037
  const { switchOrg } = useTenant();
1107
- const [selected, setSelected] = React2.useState(
2038
+ const [selected, setSelected] = React3.useState(
1108
2039
  suggestedId ?? memberships[0]?.orgId ?? null
1109
2040
  );
1110
- const [remember, setRemember] = React2.useState(false);
1111
- const [query, setQuery] = React2.useState("");
1112
- const search = React2.useMemo(
2041
+ const [remember, setRemember] = React3.useState(false);
2042
+ const [query, setQuery] = React3.useState("");
2043
+ const search = React3.useMemo(
1113
2044
  () => searchWorkspaces(memberships, query, selected, 12),
1114
2045
  [memberships, query, selected]
1115
2046
  );
1116
- const [entering, setEntering] = React2.useState(false);
2047
+ const [entering, setEntering] = React3.useState(false);
1117
2048
  const enter = async (orgId) => {
1118
2049
  if (entering) return;
1119
2050
  setEntering(true);
@@ -1216,7 +2147,7 @@ function WorkspaceChooser({ memberships, suggestedId, onCancel }) {
1216
2147
  ) })
1217
2148
  ] }) });
1218
2149
  }
1219
- var getSupabaseClientOptional = () => getSupabaseClientOptional$1();
2150
+ var getSupabaseClientOptional3 = () => getSupabaseClientOptional();
1220
2151
 
1221
2152
  // src/app/useDomainTenant.ts
1222
2153
  var LOCAL = /^(localhost|127\.0\.0\.1|\[::1\])$/;
@@ -1232,7 +2163,7 @@ function useDomainTenant() {
1232
2163
  const [resolving, setResolving] = useState(true);
1233
2164
  useEffect(() => {
1234
2165
  const host = resolveHostname();
1235
- const supabase = getSupabaseClientOptional();
2166
+ const supabase = getSupabaseClientOptional3();
1236
2167
  if (!host || !supabase) {
1237
2168
  setResolving(false);
1238
2169
  return;
@@ -1267,8 +2198,8 @@ function WorkspaceChooserGate({ fallback, children }) {
1267
2198
  const tenant = useTenantOptional();
1268
2199
  const { tenant: byDomain, resolving: resolvingDomain } = useDomainTenant();
1269
2200
  const switchOrg = tenant?.switchOrg;
1270
- const entering = React2.useRef(false);
1271
- React2.useEffect(() => {
2201
+ const entering = React3.useRef(false);
2202
+ React3.useEffect(() => {
1272
2203
  if (!byDomain || !tenant?.orgsKnown || tenant.org || !switchOrg || entering.current) return;
1273
2204
  if (!tenant.userOrgs.some((m) => m.orgId === byDomain.tenantId)) return;
1274
2205
  entering.current = true;
@@ -1310,7 +2241,7 @@ function WorkspaceSwitching({ orgName, orgLogoUrl, onDone }) {
1310
2241
  const v = t(key);
1311
2242
  return !v || v === key ? fallback : v;
1312
2243
  };
1313
- const steps = React2.useMemo(
2244
+ const steps = React3.useMemo(
1314
2245
  () => [
1315
2246
  tr("organization.switching.step1", "Alterando organiza\xE7\xE3o"),
1316
2247
  tr("organization.switching.step2", "Garantindo seguran\xE7a dos dados"),
@@ -1319,10 +2250,10 @@ function WorkspaceSwitching({ orgName, orgLogoUrl, onDone }) {
1319
2250
  // eslint-disable-next-line react-hooks/exhaustive-deps
1320
2251
  []
1321
2252
  );
1322
- const [step, setStep] = React2.useState(0);
1323
- const doneRef = React2.useRef(onDone);
2253
+ const [step, setStep] = React3.useState(0);
2254
+ const doneRef = React3.useRef(onDone);
1324
2255
  doneRef.current = onDone;
1325
- React2.useEffect(() => {
2256
+ React3.useEffect(() => {
1326
2257
  const id = window.setInterval(() => {
1327
2258
  setStep((s) => {
1328
2259
  if (s < steps.length - 1) return s + 1;
@@ -1399,6 +2330,6 @@ function WorkspaceSwitchingHost() {
1399
2330
  );
1400
2331
  }
1401
2332
 
1402
- export { OrgMark, WorkspaceChooser, WorkspaceChooserGate, WorkspaceSwitching, WorkspaceSwitchingHost, activePluginIds, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, getFayzSupabaseClient, getFayzSupabaseClientOptional, getSupabaseClientOptional, hasPlugin, orgInitials, resolveAppId, searchWorkspaces, useAppConfigStore, useWorkspaceSwitchingStore };
1403
- //# sourceMappingURL=chunk-KP3LNCNP.js.map
1404
- //# sourceMappingURL=chunk-KP3LNCNP.js.map
2333
+ export { ORG_CACHE_TTL_MS, OrgMark, OrgProvider, UNIT_ACCESS_CHANGED, WorkspaceChooser, WorkspaceChooserGate, WorkspaceSwitching, WorkspaceSwitchingHost, activePluginIds, bindAllMembersTo, bindUserToUnit, clearOrgSnapshot, countUnboundMembers, createFayzSupabaseClient, createMockOrgAdapter, createSupabaseOrgAdapter, decideWorkspaceChoice, dedup2 as dedup, fetchMemberActivity, fetchMemberUnits, fetchUnitMembers, fetchUserIdForPerson, getAutoPick, getFayzSupabaseClient, getFayzSupabaseClientOptional, getSupabaseClientOptional3 as getSupabaseClientOptional, hasPlugin, markWorkspaceSwitch, orgInitials, readOrgSnapshot, resolveAppId, searchWorkspaces, setAutoPick, setUnitModeRemote, takeWorkspaceSwitch, unbindUserFromUnit, useAppConfigStore, useOrgAdapter, useOrgAdapterOptional, useTenant, useTenantOptional, useUnitStore, useWorkspaceSwitchingStore };
2334
+ //# sourceMappingURL=chunk-V2IBAF4O.js.map
2335
+ //# sourceMappingURL=chunk-V2IBAF4O.js.map