@basictech/react 0.12.0-beta.3 → 0.12.0-beta.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
@@ -1046,6 +1046,120 @@ function useProjectProfile(enabled = true) {
1046
1046
  return useProjectProfileFor(useRequiredClient(), enabled);
1047
1047
  }
1048
1048
 
1049
+ // src/hooks/invites.ts
1050
+ import { useCallback as useCallback6, useRef as useRef3 } from "react";
1051
+ import {
1052
+ BasicError as BasicError6
1053
+ } from "@basictech/core";
1054
+ function useShareInvitesFor(client, enabled = true) {
1055
+ const snapshot = useClientSnapshot(client);
1056
+ const accountId = snapshot.activeAccount?.id;
1057
+ const currentClient = useRef3(client);
1058
+ currentClient.current = client;
1059
+ const gate = useSignInGate(snapshot);
1060
+ const canLoad = enabled && snapshot.isReady && snapshot.isSignedIn;
1061
+ const result = useAsyncResult(
1062
+ async () => {
1063
+ try {
1064
+ return {
1065
+ client,
1066
+ accountId,
1067
+ data: await client.shares.listInvites(),
1068
+ error: null
1069
+ };
1070
+ } catch (error) {
1071
+ return {
1072
+ client,
1073
+ accountId,
1074
+ data: [],
1075
+ error: toBasicError(error)
1076
+ };
1077
+ }
1078
+ },
1079
+ null,
1080
+ canLoad,
1081
+ !enabled || snapshot.isReady,
1082
+ [client, accountId]
1083
+ );
1084
+ const current = result.data?.client === client && result.data.accountId === accountId ? result.data : null;
1085
+ const resolveContactHandle = useCallback6(
1086
+ (did) => client.shares.resolveContactHandle(did),
1087
+ [client]
1088
+ );
1089
+ const checkAccount = () => {
1090
+ if (currentClient.current !== client || client.getSnapshot().activeAccount?.id !== accountId)
1091
+ throw new BasicError6("ACCOUNT_CHANGED");
1092
+ };
1093
+ async function run(action, refresh = true) {
1094
+ checkAccount();
1095
+ try {
1096
+ const value = await action();
1097
+ checkAccount();
1098
+ return value;
1099
+ } catch (error) {
1100
+ checkAccount();
1101
+ throw error;
1102
+ } finally {
1103
+ if (refresh && currentClient.current === client && client.getSnapshot().activeAccount?.id === accountId)
1104
+ result.refresh();
1105
+ }
1106
+ }
1107
+ return {
1108
+ data: canLoad ? current?.data ?? [] : [],
1109
+ isLoading: enabled && (!snapshot.isReady || canLoad && (result.isLoading || !current)),
1110
+ error: enabled ? gate ?? (canLoad ? current?.error ?? null : null) : null,
1111
+ refresh: result.refresh,
1112
+ get: (id) => run(() => client.shares.getInvite(id), false),
1113
+ accept: (id) => run(() => client.shares.acceptInvite(id)),
1114
+ decline: (id) => run(() => client.shares.declineInvite(id)),
1115
+ delete: (id) => run(() => client.shares.deleteInvite(id)),
1116
+ resolveContactHandle
1117
+ };
1118
+ }
1119
+ function useShareInvites(enabled = true) {
1120
+ return useShareInvitesFor(useRequiredClient(), enabled);
1121
+ }
1122
+
1123
+ // src/hooks/recipients.ts
1124
+ function useShareRecipientsFor(client, dids) {
1125
+ const unique = [...new Set(dids)];
1126
+ const key = JSON.stringify(unique);
1127
+ const result = useAsyncResult(
1128
+ async () => {
1129
+ const handles = await Promise.allSettled(
1130
+ unique.map((did) => client.shares.resolveContactHandle(did))
1131
+ );
1132
+ const failed = handles.find((handle) => handle.status === "rejected");
1133
+ return {
1134
+ client,
1135
+ key,
1136
+ data: unique.map((did, index) => {
1137
+ const handle = handles[index];
1138
+ return {
1139
+ did,
1140
+ handle: handle.status === "fulfilled" ? handle.value : null
1141
+ };
1142
+ }),
1143
+ error: failed ? toBasicError(failed.reason) : null
1144
+ };
1145
+ },
1146
+ null,
1147
+ unique.length > 0,
1148
+ true,
1149
+ [client, key]
1150
+ );
1151
+ const current = result.data?.client === client && result.data.key === key ? result.data : null;
1152
+ return {
1153
+ data: current?.data ?? unique.map((did) => ({ did, handle: null })),
1154
+ isLoading: unique.length > 0 && (result.isLoading || !current),
1155
+ error: result.isLoading ? null : current?.error ?? null,
1156
+ refresh: result.refresh
1157
+ };
1158
+ }
1159
+ function useShareRecipients(dids) {
1160
+ return useShareRecipientsFor(useRequiredClient(), dids);
1161
+ }
1162
+
1049
1163
  // src/create-basic.tsx
1050
1164
  import { jsx as jsx2 } from "react/jsx-runtime";
1051
1165
  function createBasic(config) {
@@ -1078,7 +1192,9 @@ function createBasic(config) {
1078
1192
  useFiles: (query = {}, options = {}) => useFilesFor(useBound(), query, options),
1079
1193
  useStorageInfo: () => useStorageInfoFor(useBound()),
1080
1194
  useMounts: (query = {}) => useMountsFor(useBound(), query),
1081
- useOutgoingShares: () => useOutgoingSharesFor(useBound())
1195
+ useOutgoingShares: () => useOutgoingSharesFor(useBound()),
1196
+ useShareInvites: (enabled) => useShareInvitesFor(useBound(), enabled),
1197
+ useShareRecipients: (dids) => useShareRecipientsFor(useBound(), dids)
1082
1198
  };
1083
1199
  }
1084
1200
 
@@ -1090,15 +1206,123 @@ import {
1090
1206
  isValidElement,
1091
1207
  useContext as useContext3,
1092
1208
  useEffect as useEffect4,
1093
- useRef as useRef3,
1209
+ useRef as useRef4,
1094
1210
  useState as useState4
1095
1211
  } from "react";
1096
1212
  import { Avatar } from "@base-ui/react/avatar";
1097
1213
  import { Dialog } from "@base-ui/react/dialog";
1098
1214
  import { Menu } from "@base-ui/react/menu";
1099
1215
  import { Tabs } from "@base-ui/react/tabs";
1100
- import { BasicError as BasicError6 } from "@basictech/core";
1101
- import { Fragment as Fragment2, jsx as jsx3, jsxs } from "react/jsx-runtime";
1216
+ import { BasicError as BasicError7 } from "@basictech/core";
1217
+
1218
+ // src/avatar-marble.tsx
1219
+ import { useId } from "react";
1220
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
1221
+ var ELEMENTS = 3;
1222
+ var SIZE = 80;
1223
+ var COLORS = ["#92A1C6", "#146A7C", "#F0AB3D", "#C271B4", "#C20D90"];
1224
+ function hashCode(value) {
1225
+ let hash = 0;
1226
+ for (let index = 0; index < value.length; index += 1) {
1227
+ hash = (hash << 5) - hash + value.charCodeAt(index);
1228
+ hash &= hash;
1229
+ }
1230
+ return Math.abs(hash);
1231
+ }
1232
+ function getDigit(value, position) {
1233
+ return Math.floor(value / 10 ** position % 10);
1234
+ }
1235
+ function getUnit(value, range, position) {
1236
+ const unit = value % range;
1237
+ return position && getDigit(value, position) % 2 === 0 ? -unit : unit;
1238
+ }
1239
+ function generateProperties(seed) {
1240
+ const value = hashCode(seed);
1241
+ return Array.from({ length: ELEMENTS }, (_, index) => ({
1242
+ color: COLORS[(value + index) % COLORS.length],
1243
+ translateX: getUnit(value * (index + 1), SIZE / 10, 1),
1244
+ translateY: getUnit(value * (index + 1), SIZE / 10, 2),
1245
+ scale: 1.2 + getUnit(value * (index + 1), SIZE / 20) / 10,
1246
+ rotate: getUnit(value * (index + 1), 360, 1)
1247
+ }));
1248
+ }
1249
+ function MarbleAvatar({ seed }) {
1250
+ const properties = generateProperties(seed);
1251
+ const instanceId = useId().replaceAll(":", "");
1252
+ const maskId = `basic-avatar-mask-${instanceId}`;
1253
+ const filterId = `basic-avatar-filter-${instanceId}`;
1254
+ return /* @__PURE__ */ jsxs(
1255
+ "svg",
1256
+ {
1257
+ viewBox: `0 0 ${SIZE} ${SIZE}`,
1258
+ width: "100%",
1259
+ height: "100%",
1260
+ fill: "none",
1261
+ xmlns: "http://www.w3.org/2000/svg",
1262
+ "aria-hidden": "true",
1263
+ focusable: "false",
1264
+ children: [
1265
+ /* @__PURE__ */ jsx3(
1266
+ "mask",
1267
+ {
1268
+ id: maskId,
1269
+ maskUnits: "userSpaceOnUse",
1270
+ x: "0",
1271
+ y: "0",
1272
+ width: SIZE,
1273
+ height: SIZE,
1274
+ children: /* @__PURE__ */ jsx3("rect", { width: SIZE, height: SIZE, rx: SIZE * 2, fill: "#FFFFFF" })
1275
+ }
1276
+ ),
1277
+ /* @__PURE__ */ jsxs("g", { mask: `url(#${maskId})`, children: [
1278
+ /* @__PURE__ */ jsx3("rect", { width: SIZE, height: SIZE, fill: properties[0].color }),
1279
+ /* @__PURE__ */ jsx3(
1280
+ "path",
1281
+ {
1282
+ filter: `url(#${filterId})`,
1283
+ d: "M32.414 59.35L50.376 70.5H72.5v-71H33.728L26.5 13.381l19.057 27.08L32.414 59.35z",
1284
+ fill: properties[1].color,
1285
+ transform: `translate(${properties[1].translateX} ${properties[1].translateY}) rotate(${properties[1].rotate} ${SIZE / 2} ${SIZE / 2}) scale(${properties[2].scale})`
1286
+ }
1287
+ ),
1288
+ /* @__PURE__ */ jsx3(
1289
+ "path",
1290
+ {
1291
+ filter: `url(#${filterId})`,
1292
+ style: { mixBlendMode: "overlay" },
1293
+ d: "M22.216 24L0 46.75l14.108 38.129L78 86l-3.081-59.276-22.378 4.005 12.972 20.186-23.35 27.395L22.215 24z",
1294
+ fill: properties[2].color,
1295
+ transform: `translate(${properties[2].translateX} ${properties[2].translateY}) rotate(${properties[2].rotate} ${SIZE / 2} ${SIZE / 2}) scale(${properties[2].scale})`
1296
+ }
1297
+ )
1298
+ ] }),
1299
+ /* @__PURE__ */ jsx3("defs", { children: /* @__PURE__ */ jsxs(
1300
+ "filter",
1301
+ {
1302
+ id: filterId,
1303
+ filterUnits: "userSpaceOnUse",
1304
+ colorInterpolationFilters: "sRGB",
1305
+ children: [
1306
+ /* @__PURE__ */ jsx3("feFlood", { floodOpacity: "0", result: "BackgroundImageFix" }),
1307
+ /* @__PURE__ */ jsx3(
1308
+ "feBlend",
1309
+ {
1310
+ in: "SourceGraphic",
1311
+ in2: "BackgroundImageFix",
1312
+ result: "shape"
1313
+ }
1314
+ ),
1315
+ /* @__PURE__ */ jsx3("feGaussianBlur", { stdDeviation: "7", result: "effect1_foregroundBlur" })
1316
+ ]
1317
+ }
1318
+ ) })
1319
+ ]
1320
+ }
1321
+ );
1322
+ }
1323
+
1324
+ // src/components.tsx
1325
+ import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
1102
1326
  var AppearanceContext = createContext2({});
1103
1327
  function accentText(accent) {
1104
1328
  if (!/^#([\da-f]{3}|[\da-f]{6})$/i.test(accent)) return "#fff";
@@ -1125,7 +1349,7 @@ function BasicUIProvider({
1125
1349
  }) {
1126
1350
  const parent = useContext3(AppearanceContext);
1127
1351
  const value = { ...parent, ...appearance };
1128
- return /* @__PURE__ */ jsx3(AppearanceContext.Provider, { value, children: /* @__PURE__ */ jsx3(
1352
+ return /* @__PURE__ */ jsx4(AppearanceContext.Provider, { value, children: /* @__PURE__ */ jsx4(
1129
1353
  "div",
1130
1354
  {
1131
1355
  className: "basic-ui",
@@ -1146,7 +1370,7 @@ function useAppearanceProps() {
1146
1370
  }
1147
1371
  var BasicButton = forwardRef(
1148
1372
  function BasicButton2({ variant = "outline", className = "", type = "button", ...props }, ref) {
1149
- return /* @__PURE__ */ jsx3(
1373
+ return /* @__PURE__ */ jsx4(
1150
1374
  "button",
1151
1375
  {
1152
1376
  ...props,
@@ -1161,8 +1385,8 @@ var BasicButton = forwardRef(
1161
1385
  function useAction() {
1162
1386
  const [pending, setPending] = useState4(false);
1163
1387
  const [error, setError] = useState4(null);
1164
- const busy = useRef3(false);
1165
- const mounted = useRef3(true);
1388
+ const busy = useRef4(false);
1389
+ const mounted = useRef4(true);
1166
1390
  useEffect4(() => {
1167
1391
  mounted.current = true;
1168
1392
  return () => {
@@ -1179,7 +1403,7 @@ function useAction() {
1179
1403
  } catch (cause) {
1180
1404
  if (mounted.current)
1181
1405
  setError(
1182
- cause instanceof BasicError6 && cause.code === "REDIRECT_URI_NOT_REGISTERED" ? "Sign-in is unavailable on this URL. Ask the app owner to register its callback URL in project settings." : cause instanceof Error ? cause.message : "The action failed. Please try again."
1406
+ cause instanceof BasicError7 && cause.code === "REDIRECT_URI_NOT_REGISTERED" ? "Sign-in is unavailable on this URL. Ask the app owner to register its callback URL in project settings." : cause instanceof Error ? cause.message : "The action failed. Please try again."
1183
1407
  );
1184
1408
  } finally {
1185
1409
  busy.current = false;
@@ -1201,8 +1425,8 @@ function AuthButton({
1201
1425
  const auth = supplied ?? live;
1202
1426
  const action = useAction();
1203
1427
  const expired = auth.status === "expired";
1204
- return /* @__PURE__ */ jsxs("span", { className: "basic-action", children: [
1205
- /* @__PURE__ */ jsx3(
1428
+ return /* @__PURE__ */ jsxs2("span", { className: "basic-action", children: [
1429
+ /* @__PURE__ */ jsx4(
1206
1430
  BasicButton,
1207
1431
  {
1208
1432
  ...props,
@@ -1218,29 +1442,42 @@ function AuthButton({
1218
1442
  children: action.pending ? "Please wait\u2026" : children ?? (signOut ? "Sign out" : expired ? "Sign in again" : "Sign in")
1219
1443
  }
1220
1444
  ),
1221
- /* @__PURE__ */ jsx3(ActionError, { error: action.error, onClose: action.clearError })
1445
+ /* @__PURE__ */ jsx4(ActionError, { error: action.error, onClose: action.clearError })
1222
1446
  ] });
1223
1447
  }
1224
1448
  function SignInButton(props) {
1225
- return /* @__PURE__ */ jsx3(AuthButton, { ...props });
1449
+ return /* @__PURE__ */ jsx4(AuthButton, { ...props });
1226
1450
  }
1227
1451
  function SignOutButton(props) {
1228
- return /* @__PURE__ */ jsx3(AuthButton, { ...props, signOut: true });
1452
+ return /* @__PURE__ */ jsx4(AuthButton, { ...props, signOut: true });
1453
+ }
1454
+ var ANONYMOUS_ACCOUNT_NAME = "Local User";
1455
+ function accountName(profile, emptyFallback = "Guest") {
1456
+ if (!profile) return emptyFallback;
1457
+ return profile.name || (profile.kind === "anon" ? ANONYMOUS_ACCOUNT_NAME : displayHandle(profile.handle) || profile.email || "Account");
1458
+ }
1459
+ function avatarSeed(profile) {
1460
+ if (!profile) return "guest";
1461
+ return profile.did || profile.id && `account:${profile.id}` || profile.handle || profile.email || profile.name || "guest";
1229
1462
  }
1230
1463
  function UserAvatar({
1231
1464
  accounts,
1232
1465
  auth,
1233
1466
  projectProfile,
1467
+ invites,
1468
+ showInvites,
1234
1469
  allowAddAccount,
1235
1470
  menuItems,
1236
1471
  ...avatarProps
1237
1472
  }) {
1238
- return /* @__PURE__ */ jsx3(
1473
+ return /* @__PURE__ */ jsx4(
1239
1474
  UserMenu,
1240
1475
  {
1241
1476
  accounts,
1242
1477
  auth,
1243
1478
  projectProfile,
1479
+ invites,
1480
+ showInvites,
1244
1481
  allowAddAccount,
1245
1482
  menuItems,
1246
1483
  sync: avatarProps.sync,
@@ -1254,25 +1491,34 @@ function AccountAvatar({
1254
1491
  size = 32,
1255
1492
  showSyncBadge,
1256
1493
  sync,
1257
- className = "",
1258
- style,
1259
1494
  ...props
1260
1495
  }) {
1261
1496
  const accounts = useAccounts();
1262
1497
  const client = useRequiredClient();
1263
1498
  const profile = supplied === void 0 ? accounts.activeAccount : supplied;
1264
- const name = profile?.name || (profile?.kind === "anon" ? "Local account" : profile?.handle || profile?.email || "Guest");
1265
- const initials = name.trim().split(/\s+/).slice(0, 2).map((part) => Array.from(part)[0]).join("").toUpperCase();
1266
- const avatar = /* @__PURE__ */ jsxs(
1499
+ const avatar = /* @__PURE__ */ jsx4(ProfileAvatar, { ...props, profile, size });
1500
+ return showSyncBadge ?? client.mode === "sync" ? /* @__PURE__ */ jsxs2("span", { className: "basic-avatar-container", children: [
1501
+ avatar,
1502
+ /* @__PURE__ */ jsx4(SyncStatus, { sync, className: "basic-avatar-sync" })
1503
+ ] }) : avatar;
1504
+ }
1505
+ function ProfileAvatar({
1506
+ profile,
1507
+ size = 32,
1508
+ className = "",
1509
+ style,
1510
+ ...props
1511
+ }) {
1512
+ return /* @__PURE__ */ jsxs2(
1267
1513
  Avatar.Root,
1268
1514
  {
1269
1515
  ...props,
1270
1516
  className: `basic-avatar ${className}`,
1271
1517
  style: { width: size, height: size, ...style },
1272
1518
  role: "img",
1273
- "aria-label": props["aria-label"] ?? name,
1519
+ "aria-label": props["aria-label"] ?? accountName(profile),
1274
1520
  children: [
1275
- profile?.picture && /* @__PURE__ */ jsx3(
1521
+ profile?.picture && /* @__PURE__ */ jsx4(
1276
1522
  Avatar.Image,
1277
1523
  {
1278
1524
  src: profile.picture,
@@ -1281,14 +1527,100 @@ function AccountAvatar({
1281
1527
  referrerPolicy: "no-referrer"
1282
1528
  }
1283
1529
  ),
1284
- /* @__PURE__ */ jsx3(Avatar.Fallback, { className: "basic-avatar-fallback", children: initials || "?" })
1530
+ /* @__PURE__ */ jsx4(Avatar.Fallback, { className: "basic-avatar-fallback", children: /* @__PURE__ */ jsx4(MarbleAvatar, { seed: avatarSeed(profile) }) })
1531
+ ]
1532
+ }
1533
+ );
1534
+ }
1535
+ function ShareRecipientAvatar({
1536
+ recipient,
1537
+ ...props
1538
+ }) {
1539
+ return /* @__PURE__ */ jsx4(
1540
+ ProfileAvatar,
1541
+ {
1542
+ title: displayHandle(recipient.handle) || recipient.name || recipient.did,
1543
+ ...props,
1544
+ profile: {
1545
+ ...recipient,
1546
+ name: recipient.name || displayHandle(recipient.handle) || recipient.did,
1547
+ kind: "account"
1548
+ }
1549
+ }
1550
+ );
1551
+ }
1552
+ function ShareRecipientLabel({
1553
+ recipient,
1554
+ size = 24,
1555
+ className = "",
1556
+ ...props
1557
+ }) {
1558
+ const label = displayHandle(recipient.handle) || recipient.name || "Unknown user";
1559
+ return /* @__PURE__ */ jsxs2(
1560
+ "span",
1561
+ {
1562
+ title: recipient.did,
1563
+ ...props,
1564
+ className: `basic-recipient-label ${className}`,
1565
+ children: [
1566
+ /* @__PURE__ */ jsx4(
1567
+ ShareRecipientAvatar,
1568
+ {
1569
+ recipient,
1570
+ size,
1571
+ "aria-hidden": "true",
1572
+ title: void 0
1573
+ }
1574
+ ),
1575
+ /* @__PURE__ */ jsx4("span", { className: "basic-recipient-handle", children: label })
1576
+ ]
1577
+ }
1578
+ );
1579
+ }
1580
+ function ShareRecipientAvatars({
1581
+ recipients,
1582
+ size = 32,
1583
+ max = 4,
1584
+ className = "",
1585
+ ...props
1586
+ }) {
1587
+ const unique = [
1588
+ ...new Map(
1589
+ recipients.map((recipient) => [recipient.did, recipient])
1590
+ ).values()
1591
+ ];
1592
+ const visible = unique.slice(0, Math.max(1, max));
1593
+ const remaining = unique.length - visible.length;
1594
+ return /* @__PURE__ */ jsxs2(
1595
+ "span",
1596
+ {
1597
+ ...props,
1598
+ className: `basic-recipient-avatars ${className}`,
1599
+ role: "group",
1600
+ "aria-label": props["aria-label"] ?? `Shared with ${unique.length} recipients`,
1601
+ children: [
1602
+ visible.map((recipient) => /* @__PURE__ */ jsx4(
1603
+ ShareRecipientAvatar,
1604
+ {
1605
+ recipient,
1606
+ size
1607
+ },
1608
+ recipient.did
1609
+ )),
1610
+ remaining > 0 && /* @__PURE__ */ jsxs2(
1611
+ "span",
1612
+ {
1613
+ className: "basic-recipient-overflow",
1614
+ "aria-label": `${remaining} more recipients`,
1615
+ children: [
1616
+ "+",
1617
+ remaining
1618
+ ]
1619
+ }
1620
+ )
1285
1621
  ]
1286
1622
  }
1287
1623
  );
1288
- return showSyncBadge ?? client.mode === "sync" ? /* @__PURE__ */ jsxs("span", { className: "basic-avatar-container", children: [
1289
- avatar,
1290
- /* @__PURE__ */ jsx3(SyncStatus, { sync, className: "basic-avatar-sync" })
1291
- ] }) : avatar;
1292
1624
  }
1293
1625
  function AuthStatus({
1294
1626
  auth: supplied,
@@ -1299,7 +1631,7 @@ function AuthStatus({
1299
1631
  const auth = supplied ?? live;
1300
1632
  const expired = auth.status === "expired";
1301
1633
  const label = !auth.isReady || auth.status === "bootstrapping" ? "Checking session" : expired ? "Session expired" : auth.status === "recovering" ? "Reconnecting session" : auth.isSignedIn ? "Signed in" : auth.isAnonymous ? "Guest \xB7 local only" : "Signed out";
1302
- return /* @__PURE__ */ jsxs(
1634
+ return /* @__PURE__ */ jsxs2(
1303
1635
  "span",
1304
1636
  {
1305
1637
  ...props,
@@ -1307,7 +1639,7 @@ function AuthStatus({
1307
1639
  className: `basic-status ${className}`,
1308
1640
  "data-tone": expired || auth.error ? "warning" : auth.isSignedIn ? "success" : "neutral",
1309
1641
  children: [
1310
- /* @__PURE__ */ jsx3("span", { className: "basic-dot" }),
1642
+ /* @__PURE__ */ jsx4("span", { className: "basic-dot" }),
1311
1643
  label
1312
1644
  ]
1313
1645
  }
@@ -1337,7 +1669,7 @@ function SyncStatus({
1337
1669
  ended: "Access ended"
1338
1670
  };
1339
1671
  const label = issues ? `${issues} sync ${issues === 1 ? "issue" : "issues"}` : sync.status === "online" && sync.pendingCount ? "Syncing" : labels[sync.status];
1340
- return /* @__PURE__ */ jsxs(
1672
+ return /* @__PURE__ */ jsxs2(
1341
1673
  "span",
1342
1674
  {
1343
1675
  ...props,
@@ -1346,7 +1678,7 @@ function SyncStatus({
1346
1678
  className: `basic-status ${className}`,
1347
1679
  "data-tone": issues || ["error", "stale", "ended"].includes(sync.status) ? "warning" : sync.status === "online" && !sync.pendingCount ? "success" : ["bootstrapping", "connecting"].includes(sync.status) || sync.status === "online" && sync.pendingCount > 0 ? "progress" : "neutral",
1348
1680
  children: [
1349
- /* @__PURE__ */ jsx3("span", { className: "basic-dot" }),
1681
+ /* @__PURE__ */ jsx4("span", { className: "basic-dot" }),
1350
1682
  label,
1351
1683
  sync.pendingCount > 0 && ` \xB7 ${sync.pendingCount} pending`
1352
1684
  ]
@@ -1357,7 +1689,7 @@ function displayHandle(handle) {
1357
1689
  return handle ? `@${handle.replace(/^@+/, "")}` : "";
1358
1690
  }
1359
1691
  function UserButton(props) {
1360
- return /* @__PURE__ */ jsx3(UserMenu, { ...props, trigger: "button" });
1692
+ return /* @__PURE__ */ jsx4(UserMenu, { ...props, trigger: "button" });
1361
1693
  }
1362
1694
  function UserMenu({
1363
1695
  accounts: supplied,
@@ -1369,6 +1701,8 @@ function UserMenu({
1369
1701
  trigger = "avatar",
1370
1702
  avatarProps,
1371
1703
  projectProfile,
1704
+ invites,
1705
+ showInvites,
1372
1706
  allowAddAccount = true,
1373
1707
  className = "",
1374
1708
  accountSettingsUrl,
@@ -1381,17 +1715,17 @@ function UserMenu({
1381
1715
  const action = useAction();
1382
1716
  const [settingsOpen, setSettingsOpen] = useState4(false);
1383
1717
  const [clearAccountId, setClearAccountId] = useState4(null);
1384
- const triggerRef = useRef3(null);
1718
+ const triggerRef = useRef4(null);
1385
1719
  const appearance = useAppearanceProps();
1386
1720
  const expired = auth.status === "expired";
1387
1721
  const active = accounts.activeAccount;
1388
1722
  const otherAccounts = accounts.accounts.filter(
1389
1723
  (account) => account.id !== active?.id
1390
1724
  );
1391
- const name = active?.name || active?.kind !== "anon" && displayHandle(active?.handle) || "Local account";
1392
- return /* @__PURE__ */ jsxs("span", { className: `basic-action ${className}`, children: [
1393
- /* @__PURE__ */ jsxs(Menu.Root, { children: [
1394
- /* @__PURE__ */ jsxs(
1725
+ const name = active ? accountName(active) : "Local account";
1726
+ return /* @__PURE__ */ jsxs2("span", { className: `basic-action ${className}`, children: [
1727
+ /* @__PURE__ */ jsxs2(Menu.Root, { children: [
1728
+ /* @__PURE__ */ jsxs2(
1395
1729
  Menu.Trigger,
1396
1730
  {
1397
1731
  ref: triggerRef,
@@ -1400,7 +1734,7 @@ function UserMenu({
1400
1734
  disabled: !auth.isReady || action.pending,
1401
1735
  "aria-label": "Open user menu",
1402
1736
  children: [
1403
- /* @__PURE__ */ jsx3(
1737
+ /* @__PURE__ */ jsx4(
1404
1738
  AccountAvatar,
1405
1739
  {
1406
1740
  profile: accounts.activeAccount,
@@ -1409,12 +1743,12 @@ function UserMenu({
1409
1743
  ...avatarProps
1410
1744
  }
1411
1745
  ),
1412
- trigger === "button" && /* @__PURE__ */ jsxs(Fragment2, { children: [
1413
- /* @__PURE__ */ jsxs("span", { className: "basic-identity", children: [
1414
- /* @__PURE__ */ jsx3("strong", { children: name }),
1415
- active?.kind !== "anon" && active?.handle && /* @__PURE__ */ jsx3("small", { children: displayHandle(active.handle) })
1746
+ trigger === "button" && /* @__PURE__ */ jsxs2(Fragment2, { children: [
1747
+ /* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
1748
+ /* @__PURE__ */ jsx4("strong", { children: name }),
1749
+ active?.kind !== "anon" && active?.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(active.handle) })
1416
1750
  ] }),
1417
- /* @__PURE__ */ jsx3(
1751
+ /* @__PURE__ */ jsx4(
1418
1752
  "svg",
1419
1753
  {
1420
1754
  className: "basic-chevron",
@@ -1427,16 +1761,16 @@ function UserMenu({
1427
1761
  strokeLinecap: "round",
1428
1762
  strokeLinejoin: "round",
1429
1763
  "aria-hidden": "true",
1430
- children: /* @__PURE__ */ jsx3("path", { d: "m6 9 6 6 6-6" })
1764
+ children: /* @__PURE__ */ jsx4("path", { d: "m6 9 6 6 6-6" })
1431
1765
  }
1432
1766
  )
1433
1767
  ] })
1434
1768
  ]
1435
1769
  }
1436
1770
  ),
1437
- /* @__PURE__ */ jsx3(Menu.Portal, { children: /* @__PURE__ */ jsx3(Menu.Positioner, { sideOffset: 8, className: "basic-positioner", children: /* @__PURE__ */ jsxs(Menu.Popup, { ...appearance, className: "basic-ui basic-menu", children: [
1438
- /* @__PURE__ */ jsxs("div", { className: "basic-menu-profile", children: [
1439
- /* @__PURE__ */ jsx3(
1771
+ /* @__PURE__ */ jsx4(Menu.Portal, { children: /* @__PURE__ */ jsx4(Menu.Positioner, { sideOffset: 8, className: "basic-positioner", children: /* @__PURE__ */ jsxs2(Menu.Popup, { ...appearance, className: "basic-ui basic-menu", children: [
1772
+ /* @__PURE__ */ jsxs2("div", { className: "basic-menu-profile", children: [
1773
+ /* @__PURE__ */ jsx4(
1440
1774
  AccountAvatar,
1441
1775
  {
1442
1776
  profile: active,
@@ -1445,16 +1779,16 @@ function UserMenu({
1445
1779
  showSyncBadge: false
1446
1780
  }
1447
1781
  ),
1448
- /* @__PURE__ */ jsxs("span", { className: "basic-identity", children: [
1449
- /* @__PURE__ */ jsx3("strong", { children: active ? name : "No active account" }),
1450
- active?.kind !== "anon" && active?.handle && /* @__PURE__ */ jsx3("small", { children: displayHandle(active.handle) }),
1451
- /* @__PURE__ */ jsxs("span", { className: "basic-account-statuses", children: [
1452
- expired && /* @__PURE__ */ jsx3("span", { className: "basic-status", "data-tone": "warning", children: "Expired" }),
1453
- showSyncStatus && /* @__PURE__ */ jsx3(SyncStatus, { sync })
1782
+ /* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
1783
+ /* @__PURE__ */ jsx4("strong", { children: active ? name : "No active account" }),
1784
+ active?.kind !== "anon" && active?.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(active.handle) }),
1785
+ /* @__PURE__ */ jsxs2("span", { className: "basic-account-statuses", children: [
1786
+ expired && /* @__PURE__ */ jsx4("span", { className: "basic-status", "data-tone": "warning", children: "Expired" }),
1787
+ showSyncStatus && /* @__PURE__ */ jsx4(SyncStatus, { sync })
1454
1788
  ] })
1455
1789
  ] })
1456
1790
  ] }),
1457
- expired && /* @__PURE__ */ jsx3(
1791
+ expired && /* @__PURE__ */ jsx4(
1458
1792
  Menu.Item,
1459
1793
  {
1460
1794
  className: "basic-menu-item basic-menu-reauth",
@@ -1463,13 +1797,13 @@ function UserMenu({
1463
1797
  children: "Sign in again"
1464
1798
  }
1465
1799
  ),
1466
- /* @__PURE__ */ jsxs(
1800
+ /* @__PURE__ */ jsxs2(
1467
1801
  Menu.Item,
1468
1802
  {
1469
1803
  className: "basic-menu-item basic-manage-account",
1470
1804
  onClick: () => setSettingsOpen(true),
1471
1805
  children: [
1472
- /* @__PURE__ */ jsxs(
1806
+ /* @__PURE__ */ jsxs2(
1473
1807
  "svg",
1474
1808
  {
1475
1809
  className: "basic-menu-icon",
@@ -1483,8 +1817,8 @@ function UserMenu({
1483
1817
  strokeLinejoin: "round",
1484
1818
  "aria-hidden": "true",
1485
1819
  children: [
1486
- /* @__PURE__ */ jsx3("circle", { cx: "12", cy: "7", r: "4" }),
1487
- /* @__PURE__ */ jsx3("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" })
1820
+ /* @__PURE__ */ jsx4("circle", { cx: "12", cy: "7", r: "4" }),
1821
+ /* @__PURE__ */ jsx4("path", { d: "M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" })
1488
1822
  ]
1489
1823
  }
1490
1824
  ),
@@ -1492,30 +1826,30 @@ function UserMenu({
1492
1826
  ]
1493
1827
  }
1494
1828
  ),
1495
- menuItems.map((item) => /* @__PURE__ */ jsxs(
1829
+ menuItems.map((item) => /* @__PURE__ */ jsxs2(
1496
1830
  Menu.Item,
1497
1831
  {
1498
1832
  className: "basic-menu-item",
1499
- render: item.href !== void 0 ? /* @__PURE__ */ jsx3("a", { href: item.href }) : void 0,
1833
+ render: item.href !== void 0 ? /* @__PURE__ */ jsx4("a", { href: item.href }) : void 0,
1500
1834
  disabled: item.disabled || action.pending,
1501
1835
  onClick: () => {
1502
1836
  if (item.onClick) void action.run(item.onClick);
1503
1837
  },
1504
1838
  children: [
1505
- /* @__PURE__ */ jsx3("span", { className: "basic-menu-icon", "aria-hidden": "true", children: item.icon }),
1839
+ /* @__PURE__ */ jsx4("span", { className: "basic-menu-icon", "aria-hidden": "true", children: item.icon }),
1506
1840
  item.label
1507
1841
  ]
1508
1842
  },
1509
1843
  item.id
1510
1844
  )),
1511
- (auth.isSignedIn || expired || active?.kind === "anon") && /* @__PURE__ */ jsxs(
1845
+ (auth.isSignedIn || expired || active?.kind === "anon") && /* @__PURE__ */ jsxs2(
1512
1846
  Menu.Item,
1513
1847
  {
1514
1848
  className: "basic-menu-item basic-menu-signout",
1515
1849
  disabled: action.pending,
1516
1850
  onClick: () => active?.kind === "anon" ? setClearAccountId(active.id) : void action.run(() => auth.signOut()),
1517
1851
  children: [
1518
- /* @__PURE__ */ jsx3(
1852
+ /* @__PURE__ */ jsx4(
1519
1853
  "svg",
1520
1854
  {
1521
1855
  className: "basic-menu-icon",
@@ -1528,25 +1862,25 @@ function UserMenu({
1528
1862
  strokeLinecap: "round",
1529
1863
  strokeLinejoin: "round",
1530
1864
  "aria-hidden": "true",
1531
- children: /* @__PURE__ */ jsx3("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9" })
1865
+ children: /* @__PURE__ */ jsx4("path", { d: "M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4M16 17l5-5-5-5M21 12H9" })
1532
1866
  }
1533
1867
  ),
1534
1868
  active?.kind === "anon" ? "Clear account" : "Sign out"
1535
1869
  ]
1536
1870
  }
1537
1871
  ),
1538
- otherAccounts.length > 0 && /* @__PURE__ */ jsxs(Fragment2, { children: [
1539
- /* @__PURE__ */ jsx3(Menu.Separator, { className: "basic-separator" }),
1540
- /* @__PURE__ */ jsx3("div", { className: "basic-menu-heading", children: "Switch accounts" })
1872
+ otherAccounts.length > 0 && /* @__PURE__ */ jsxs2(Fragment2, { children: [
1873
+ /* @__PURE__ */ jsx4(Menu.Separator, { className: "basic-separator" }),
1874
+ /* @__PURE__ */ jsx4("div", { className: "basic-menu-heading", children: "Switch accounts" })
1541
1875
  ] }),
1542
- otherAccounts.map((account) => /* @__PURE__ */ jsxs(
1876
+ otherAccounts.map((account) => /* @__PURE__ */ jsxs2(
1543
1877
  Menu.Item,
1544
1878
  {
1545
1879
  className: "basic-menu-item",
1546
1880
  disabled: action.pending,
1547
1881
  onClick: () => void action.run(() => accounts.switchAccount(account.id)),
1548
1882
  children: [
1549
- /* @__PURE__ */ jsx3(
1883
+ /* @__PURE__ */ jsx4(
1550
1884
  AccountAvatar,
1551
1885
  {
1552
1886
  profile: account,
@@ -1555,16 +1889,16 @@ function UserMenu({
1555
1889
  showSyncBadge: false
1556
1890
  }
1557
1891
  ),
1558
- /* @__PURE__ */ jsxs("span", { className: "basic-identity", children: [
1559
- /* @__PURE__ */ jsx3("strong", { children: account.name || account.kind !== "anon" && displayHandle(account.handle) || (account.kind === "anon" ? "Local account" : "Account") }),
1560
- account.kind !== "anon" && account.handle && /* @__PURE__ */ jsx3("small", { children: displayHandle(account.handle) })
1892
+ /* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
1893
+ /* @__PURE__ */ jsx4("strong", { children: accountName(account, "Account") }),
1894
+ account.kind !== "anon" && account.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(account.handle) })
1561
1895
  ] }),
1562
- /* @__PURE__ */ jsx3("span", { className: "basic-account-statuses", children: account.auth.status === "expired" ? /* @__PURE__ */ jsx3("span", { className: "basic-status", "data-tone": "warning", children: "Expired" }) : null })
1896
+ /* @__PURE__ */ jsx4("span", { className: "basic-account-statuses", children: account.auth.status === "expired" ? /* @__PURE__ */ jsx4("span", { className: "basic-status", "data-tone": "warning", children: "Expired" }) : null })
1563
1897
  ]
1564
1898
  },
1565
1899
  account.id
1566
1900
  )),
1567
- (allowAddAccount || !auth.isSignedIn && !expired) && /* @__PURE__ */ jsxs(
1901
+ (allowAddAccount || !auth.isSignedIn && !expired) && /* @__PURE__ */ jsxs2(
1568
1902
  Menu.Item,
1569
1903
  {
1570
1904
  className: "basic-menu-item",
@@ -1573,7 +1907,7 @@ function UserMenu({
1573
1907
  () => allowAddAccount ? accounts.addAccount({ signIn: true }) : auth.signIn()
1574
1908
  ),
1575
1909
  children: [
1576
- /* @__PURE__ */ jsx3(
1910
+ /* @__PURE__ */ jsx4(
1577
1911
  "svg",
1578
1912
  {
1579
1913
  className: "basic-menu-icon",
@@ -1585,7 +1919,7 @@ function UserMenu({
1585
1919
  strokeWidth: "1.75",
1586
1920
  strokeLinecap: "round",
1587
1921
  "aria-hidden": "true",
1588
- children: /* @__PURE__ */ jsx3("path", { d: "M12 5v14M5 12h14" })
1922
+ children: /* @__PURE__ */ jsx4("path", { d: "M12 5v14M5 12h14" })
1589
1923
  }
1590
1924
  ),
1591
1925
  "Add account"
@@ -1594,7 +1928,7 @@ function UserMenu({
1594
1928
  )
1595
1929
  ] }) }) })
1596
1930
  ] }),
1597
- /* @__PURE__ */ jsx3(
1931
+ /* @__PURE__ */ jsx4(
1598
1932
  ActionError,
1599
1933
  {
1600
1934
  error: action.error,
@@ -1602,7 +1936,7 @@ function UserMenu({
1602
1936
  finalFocus: triggerRef
1603
1937
  }
1604
1938
  ),
1605
- /* @__PURE__ */ jsx3(
1939
+ /* @__PURE__ */ jsx4(
1606
1940
  Modal,
1607
1941
  {
1608
1942
  open: clearAccountId !== null,
@@ -1613,8 +1947,8 @@ function UserMenu({
1613
1947
  finalFocus: triggerRef,
1614
1948
  title: "Clear local account?",
1615
1949
  description: "This deletes this account\u2019s local data, including unsynced changes. This cannot be undone.",
1616
- children: /* @__PURE__ */ jsxs("div", { className: "basic-actions", children: [
1617
- /* @__PURE__ */ jsx3(
1950
+ children: /* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
1951
+ /* @__PURE__ */ jsx4(
1618
1952
  BasicButton,
1619
1953
  {
1620
1954
  disabled: action.pending,
@@ -1622,7 +1956,7 @@ function UserMenu({
1622
1956
  children: "Cancel"
1623
1957
  }
1624
1958
  ),
1625
- /* @__PURE__ */ jsx3(
1959
+ /* @__PURE__ */ jsx4(
1626
1960
  BasicButton,
1627
1961
  {
1628
1962
  disabled: action.pending,
@@ -1638,7 +1972,7 @@ function UserMenu({
1638
1972
  ] })
1639
1973
  }
1640
1974
  ),
1641
- /* @__PURE__ */ jsx3(
1975
+ /* @__PURE__ */ jsx4(
1642
1976
  AccountSettingsModal,
1643
1977
  {
1644
1978
  auth,
@@ -1649,6 +1983,8 @@ function UserMenu({
1649
1983
  finalFocus: triggerRef,
1650
1984
  accountSettingsUrl,
1651
1985
  projectProfile,
1986
+ invites,
1987
+ showInvites,
1652
1988
  sync
1653
1989
  }
1654
1990
  )
@@ -1659,7 +1995,7 @@ function ActionError({
1659
1995
  onClose,
1660
1996
  finalFocus
1661
1997
  }) {
1662
- return /* @__PURE__ */ jsxs(
1998
+ return /* @__PURE__ */ jsxs2(
1663
1999
  Modal,
1664
2000
  {
1665
2001
  open: !!error,
@@ -1671,8 +2007,8 @@ function ActionError({
1671
2007
  title: "Unable to complete action",
1672
2008
  description: "Your request could not be completed.",
1673
2009
  children: [
1674
- /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: error }),
1675
- /* @__PURE__ */ jsx3(BasicButton, { onClick: onClose, children: "Dismiss" })
2010
+ /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: error }),
2011
+ /* @__PURE__ */ jsx4(BasicButton, { onClick: onClose, children: "Dismiss" })
1676
2012
  ]
1677
2013
  }
1678
2014
  );
@@ -1684,29 +2020,36 @@ function Modal({
1684
2020
  finalFocus,
1685
2021
  title,
1686
2022
  description,
2023
+ hideTitle = false,
1687
2024
  header,
1688
2025
  sectionLabel,
1689
2026
  children
1690
2027
  }) {
1691
2028
  const appearance = useAppearanceProps();
1692
- return /* @__PURE__ */ jsxs(Dialog.Root, { open, onOpenChange, children: [
1693
- trigger !== null && (isValidElement(trigger) ? /* @__PURE__ */ jsx3(Dialog.Trigger, { render: trigger }) : /* @__PURE__ */ jsx3(Dialog.Trigger, { render: /* @__PURE__ */ jsx3(BasicButton, {}), children: trigger ?? title })),
1694
- /* @__PURE__ */ jsxs(Dialog.Portal, { children: [
1695
- /* @__PURE__ */ jsx3(Dialog.Backdrop, { className: "basic-backdrop" }),
1696
- /* @__PURE__ */ jsxs(
2029
+ return /* @__PURE__ */ jsxs2(Dialog.Root, { open, onOpenChange, children: [
2030
+ trigger !== null && (isValidElement(trigger) ? /* @__PURE__ */ jsx4(Dialog.Trigger, { render: trigger }) : /* @__PURE__ */ jsx4(Dialog.Trigger, { render: /* @__PURE__ */ jsx4(BasicButton, {}), children: trigger ?? title })),
2031
+ /* @__PURE__ */ jsxs2(Dialog.Portal, { children: [
2032
+ /* @__PURE__ */ jsx4(Dialog.Backdrop, { className: "basic-backdrop" }),
2033
+ /* @__PURE__ */ jsxs2(
1697
2034
  Dialog.Popup,
1698
2035
  {
1699
2036
  ...appearance,
1700
2037
  finalFocus,
1701
2038
  className: "basic-ui basic-dialog",
1702
2039
  children: [
1703
- /* @__PURE__ */ jsxs(
2040
+ /* @__PURE__ */ jsxs2(
1704
2041
  "div",
1705
2042
  {
1706
- className: `basic-dialog-heading${header ? " basic-dialog-heading-overlay" : ""}`,
2043
+ className: `basic-dialog-heading${header || hideTitle ? " basic-dialog-heading-overlay" : ""}`,
1707
2044
  children: [
1708
- /* @__PURE__ */ jsx3(Dialog.Title, { className: header ? "basic-sr-only" : "basic-title", children: title }),
1709
- /* @__PURE__ */ jsx3(
2045
+ /* @__PURE__ */ jsx4(
2046
+ Dialog.Title,
2047
+ {
2048
+ className: header || hideTitle ? "basic-sr-only" : "basic-title",
2049
+ children: title
2050
+ }
2051
+ ),
2052
+ /* @__PURE__ */ jsx4(
1710
2053
  Dialog.Close,
1711
2054
  {
1712
2055
  className: "basic-button",
@@ -1718,14 +2061,14 @@ function Modal({
1718
2061
  }
1719
2062
  ),
1720
2063
  header,
1721
- /* @__PURE__ */ jsx3(
2064
+ description && /* @__PURE__ */ jsx4(
1722
2065
  Dialog.Description,
1723
2066
  {
1724
2067
  className: header ? "basic-sr-only" : "basic-muted",
1725
2068
  children: description
1726
2069
  }
1727
2070
  ),
1728
- sectionLabel && /* @__PURE__ */ jsx3("div", { className: "basic-modal-section", children: sectionLabel }),
2071
+ sectionLabel && /* @__PURE__ */ jsx4("div", { className: "basic-modal-section", children: sectionLabel }),
1729
2072
  children
1730
2073
  ]
1731
2074
  }
@@ -1738,6 +2081,8 @@ function AccountSettingsModal({
1738
2081
  accounts: suppliedAccounts,
1739
2082
  accountSettingsUrl,
1740
2083
  projectProfile,
2084
+ invites,
2085
+ showInvites = true,
1741
2086
  sync,
1742
2087
  children,
1743
2088
  ...props
@@ -1776,27 +2121,28 @@ function AccountSettingsModal({
1776
2121
  ["Conflicts", String(syncState.conflicts.length)]
1777
2122
  ];
1778
2123
  const diagnostics = JSON.stringify(Object.fromEntries(details), null, 2);
1779
- return /* @__PURE__ */ jsx3(
2124
+ return /* @__PURE__ */ jsx4(
1780
2125
  Modal,
1781
2126
  {
1782
2127
  ...props,
1783
2128
  title: "Account settings",
1784
2129
  description: "Your identity and session on this device.",
1785
- header: /* @__PURE__ */ jsx3(AccountHeader, { account: accounts.activeAccount, sync }),
1786
- children: /* @__PURE__ */ jsxs(Tabs.Root, { defaultValue: "profile", children: [
1787
- /* @__PURE__ */ jsxs(
2130
+ header: /* @__PURE__ */ jsx4(AccountHeader, { account: accounts.activeAccount, sync }),
2131
+ children: /* @__PURE__ */ jsxs2(Tabs.Root, { defaultValue: "profile", children: [
2132
+ /* @__PURE__ */ jsxs2(
1788
2133
  Tabs.List,
1789
2134
  {
1790
2135
  className: "basic-tabs",
1791
2136
  "aria-label": "Account settings sections",
1792
2137
  children: [
1793
- /* @__PURE__ */ jsx3(Tabs.Tab, { value: "profile", children: "Profile" }),
1794
- /* @__PURE__ */ jsx3(Tabs.Tab, { value: "advanced", children: "Advanced" })
2138
+ /* @__PURE__ */ jsx4(Tabs.Tab, { value: "profile", children: "Profile" }),
2139
+ showInvites && /* @__PURE__ */ jsx4(Tabs.Tab, { value: "invites", children: "Share Invites" }),
2140
+ /* @__PURE__ */ jsx4(Tabs.Tab, { value: "advanced", children: "Advanced" })
1795
2141
  ]
1796
2142
  }
1797
2143
  ),
1798
- /* @__PURE__ */ jsxs(Tabs.Panel, { value: "profile", keepMounted: true, children: [
1799
- auth.isSignedIn && /* @__PURE__ */ jsx3(
2144
+ /* @__PURE__ */ jsxs2(Tabs.Panel, { value: "profile", keepMounted: true, children: [
2145
+ auth.isSignedIn && /* @__PURE__ */ jsx4(
1800
2146
  ProjectProfileEditor,
1801
2147
  {
1802
2148
  profile: projectProfile,
@@ -1804,18 +2150,19 @@ function AccountSettingsModal({
1804
2150
  },
1805
2151
  accounts.activeAccount?.id ?? auth.did
1806
2152
  ),
1807
- accountSettingsUrl && /* @__PURE__ */ jsx3("a", { className: "basic-link", href: accountSettingsUrl, children: "Manage profile and security \u2197" }),
2153
+ accountSettingsUrl && /* @__PURE__ */ jsx4("a", { className: "basic-link", href: accountSettingsUrl, children: "Manage profile and security \u2197" }),
1808
2154
  children,
1809
- !auth.isSignedIn && /* @__PURE__ */ jsx3("div", { className: "basic-actions", children: /* @__PURE__ */ jsx3(SignInButton, { auth }) })
2155
+ !auth.isSignedIn && /* @__PURE__ */ jsx4("div", { className: "basic-actions", children: /* @__PURE__ */ jsx4(SignInButton, { auth }) })
1810
2156
  ] }),
1811
- /* @__PURE__ */ jsxs(Tabs.Panel, { value: "advanced", children: [
1812
- /* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "Read-only diagnostics for this account." }),
1813
- /* @__PURE__ */ jsx3("dl", { className: "basic-details", children: details.map(([label, value]) => /* @__PURE__ */ jsxs(Fragment, { children: [
1814
- /* @__PURE__ */ jsx3("dt", { children: label }),
1815
- /* @__PURE__ */ jsx3("dd", { children: value })
2157
+ showInvites && /* @__PURE__ */ jsx4(Tabs.Panel, { value: "invites", children: /* @__PURE__ */ jsx4(ShareInvites, { auth, accounts, invites }) }),
2158
+ /* @__PURE__ */ jsxs2(Tabs.Panel, { value: "advanced", children: [
2159
+ /* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Read-only diagnostics for this account." }),
2160
+ /* @__PURE__ */ jsx4("dl", { className: "basic-details", children: details.map(([label, value]) => /* @__PURE__ */ jsxs2(Fragment, { children: [
2161
+ /* @__PURE__ */ jsx4("dt", { children: label }),
2162
+ /* @__PURE__ */ jsx4("dd", { children: value })
1816
2163
  ] }, label)) }),
1817
- /* @__PURE__ */ jsxs("div", { className: "basic-actions", children: [
1818
- /* @__PURE__ */ jsx3(
2164
+ /* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
2165
+ /* @__PURE__ */ jsx4(
1819
2166
  BasicButton,
1820
2167
  {
1821
2168
  disabled: copyAction.pending,
@@ -1831,9 +2178,9 @@ function AccountSettingsModal({
1831
2178
  children: "Copy to clipboard"
1832
2179
  }
1833
2180
  ),
1834
- copied === diagnostics && /* @__PURE__ */ jsx3("span", { role: "status", className: "basic-muted", children: "Copied" })
2181
+ copied === diagnostics && /* @__PURE__ */ jsx4("span", { role: "status", className: "basic-muted", children: "Copied" })
1835
2182
  ] }),
1836
- copyAction.error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: copyAction.error })
2183
+ copyAction.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: copyAction.error })
1837
2184
  ] })
1838
2185
  ] })
1839
2186
  }
@@ -1843,8 +2190,8 @@ function AccountHeader({
1843
2190
  account,
1844
2191
  sync
1845
2192
  }) {
1846
- return /* @__PURE__ */ jsxs("div", { className: "basic-profile", children: [
1847
- /* @__PURE__ */ jsx3(
2193
+ return /* @__PURE__ */ jsxs2("div", { className: "basic-profile", children: [
2194
+ /* @__PURE__ */ jsx4(
1848
2195
  AccountAvatar,
1849
2196
  {
1850
2197
  profile: account,
@@ -1853,10 +2200,10 @@ function AccountHeader({
1853
2200
  showSyncBadge: false
1854
2201
  }
1855
2202
  ),
1856
- /* @__PURE__ */ jsxs("span", { className: "basic-identity", children: [
1857
- /* @__PURE__ */ jsx3("strong", { children: account?.name || account?.kind !== "anon" && displayHandle(account?.handle) || "Local account" }),
1858
- account?.kind !== "anon" && account?.handle && /* @__PURE__ */ jsx3("small", { children: displayHandle(account.handle) }),
1859
- /* @__PURE__ */ jsx3("span", { className: "basic-account-statuses", children: /* @__PURE__ */ jsx3(SyncStatus, { sync }) })
2203
+ /* @__PURE__ */ jsxs2("span", { className: "basic-identity", children: [
2204
+ /* @__PURE__ */ jsx4("strong", { children: account ? accountName(account) : "Local account" }),
2205
+ account?.kind !== "anon" && account?.handle && /* @__PURE__ */ jsx4("small", { children: displayHandle(account.handle) }),
2206
+ /* @__PURE__ */ jsx4("span", { className: "basic-account-statuses", children: /* @__PURE__ */ jsx4(SyncStatus, { sync }) })
1860
2207
  ] })
1861
2208
  ] });
1862
2209
  }
@@ -1869,7 +2216,7 @@ function ProjectProfileEditor({
1869
2216
  const action = useAction();
1870
2217
  const [draft, setDraft] = useState4({});
1871
2218
  const [saved, setSaved] = useState4(false);
1872
- return /* @__PURE__ */ jsxs(
2219
+ return /* @__PURE__ */ jsxs2(
1873
2220
  "form",
1874
2221
  {
1875
2222
  className: "basic-profile-editor",
@@ -1883,15 +2230,15 @@ function ProjectProfileEditor({
1883
2230
  });
1884
2231
  },
1885
2232
  children: [
1886
- /* @__PURE__ */ jsx3("h3", { className: "basic-section-label", children: "Personal information" }),
1887
- /* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "Only this app sees these overrides. Clear a field to use your universal profile value." }),
1888
- profile.isLoading ? /* @__PURE__ */ jsx3("p", { role: "status", children: "Loading project profile\u2026" }) : profile.error ? /* @__PURE__ */ jsxs(Fragment2, { children: [
1889
- /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: profile.error.message }),
1890
- /* @__PURE__ */ jsx3(BasicButton, { onClick: profile.refresh, children: "Retry profile" })
1891
- ] }) : profile.data && /* @__PURE__ */ jsxs("fieldset", { disabled: !canWrite || action.pending, children: [
1892
- /* @__PURE__ */ jsxs("label", { className: "basic-field", children: [
2233
+ /* @__PURE__ */ jsx4("h3", { className: "basic-section-label", children: "Personal information" }),
2234
+ /* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Only this app sees these overrides. Clear a field to use your universal profile value." }),
2235
+ profile.isLoading ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading project profile\u2026" }) : profile.error ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
2236
+ /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: profile.error.message }),
2237
+ /* @__PURE__ */ jsx4(BasicButton, { onClick: profile.refresh, children: "Retry profile" })
2238
+ ] }) : profile.data && /* @__PURE__ */ jsxs2("fieldset", { disabled: !canWrite || action.pending, children: [
2239
+ /* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
1893
2240
  "Display name",
1894
- /* @__PURE__ */ jsx3(
2241
+ /* @__PURE__ */ jsx4(
1895
2242
  "input",
1896
2243
  {
1897
2244
  className: "basic-input",
@@ -1908,8 +2255,8 @@ function ProjectProfileEditor({
1908
2255
  }
1909
2256
  )
1910
2257
  ] }),
1911
- /* @__PURE__ */ jsxs("div", { className: "basic-actions basic-modal-footer", children: [
1912
- /* @__PURE__ */ jsx3(
2258
+ /* @__PURE__ */ jsxs2("div", { className: "basic-actions basic-modal-footer", children: [
2259
+ /* @__PURE__ */ jsx4(
1913
2260
  BasicButton,
1914
2261
  {
1915
2262
  variant: "ghost",
@@ -1920,7 +2267,7 @@ function ProjectProfileEditor({
1920
2267
  children: "Cancel"
1921
2268
  }
1922
2269
  ),
1923
- /* @__PURE__ */ jsx3(
2270
+ /* @__PURE__ */ jsx4(
1924
2271
  BasicButton,
1925
2272
  {
1926
2273
  type: "submit",
@@ -1931,17 +2278,205 @@ function ProjectProfileEditor({
1931
2278
  )
1932
2279
  ] })
1933
2280
  ] }),
1934
- action.error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: action.error }),
1935
- saved && /* @__PURE__ */ jsx3("p", { role: "status", children: "Project profile saved." })
2281
+ action.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: action.error }),
2282
+ saved && /* @__PURE__ */ jsx4("p", { role: "status", children: "Project profile saved." })
1936
2283
  ]
1937
2284
  }
1938
2285
  );
1939
2286
  }
2287
+ function ShareInvites({
2288
+ auth: suppliedAuth,
2289
+ accounts: suppliedAccounts,
2290
+ invites,
2291
+ className = "",
2292
+ ...props
2293
+ }) {
2294
+ const liveAuth = useAuth();
2295
+ const liveAccounts = useAccounts();
2296
+ const auth = suppliedAuth ?? liveAuth;
2297
+ const accounts = suppliedAccounts ?? liveAccounts;
2298
+ return /* @__PURE__ */ jsxs2(
2299
+ "section",
2300
+ {
2301
+ ...props,
2302
+ className: `basic-invites ${className}`,
2303
+ "aria-label": props["aria-label"] ?? "Share Invites",
2304
+ children: [
2305
+ (!auth.isReady || !auth.isSignedIn) && /* @__PURE__ */ jsx4("h3", { className: "basic-title", children: "Share Invites" }),
2306
+ !auth.isReady ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Checking session\u2026" }) : !auth.isSignedIn ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
2307
+ /* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Sign in to view invites." }),
2308
+ /* @__PURE__ */ jsx4(SignInButton, { auth })
2309
+ ] }) : /* @__PURE__ */ jsx4(
2310
+ ShareInvitesContent,
2311
+ {
2312
+ invites,
2313
+ canWrite: auth.canWrite
2314
+ },
2315
+ accounts.activeAccount?.id ?? auth.did
2316
+ )
2317
+ ]
2318
+ }
2319
+ );
2320
+ }
2321
+ function ShareInvitesContent({
2322
+ invites: supplied,
2323
+ canWrite
2324
+ }) {
2325
+ const live = useShareInvites(supplied === void 0);
2326
+ const invites = supplied ?? live;
2327
+ const action = useAction();
2328
+ const [message, setMessage] = useState4("");
2329
+ const visible = invites.data.filter((invite) => invite.state !== "deleted");
2330
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2331
+ /* @__PURE__ */ jsxs2("div", { className: "basic-section-heading", children: [
2332
+ /* @__PURE__ */ jsx4("h3", { className: "basic-title", children: "Share Invites" }),
2333
+ /* @__PURE__ */ jsx4(
2334
+ BasicButton,
2335
+ {
2336
+ disabled: invites.isLoading || action.pending,
2337
+ onClick: invites.refresh,
2338
+ children: "Refresh"
2339
+ }
2340
+ )
2341
+ ] }),
2342
+ !canWrite && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: "Read-only session. Invite changes are disabled." }),
2343
+ action.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: action.error }),
2344
+ message && /* @__PURE__ */ jsx4("p", { role: "status", children: message }),
2345
+ action.pending && /* @__PURE__ */ jsx4("p", { role: "status", children: "Updating invite\u2026" }),
2346
+ invites.isLoading ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading invites\u2026" }) : invites.error ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: invites.error.message }) : !visible.length ? /* @__PURE__ */ jsx4("p", { className: "basic-empty", children: "No share invites." }) : /* @__PURE__ */ jsx4("ul", { className: "basic-share-list basic-invite-list", children: visible.map((invite) => {
2347
+ const title = invite.display.shareName || invite.display.repoName || "Shared data";
2348
+ return /* @__PURE__ */ jsx4(
2349
+ ShareInviteRow,
2350
+ {
2351
+ invite,
2352
+ title,
2353
+ resolveContactHandle: invites.resolveContactHandle,
2354
+ disabled: !canWrite || action.pending,
2355
+ onDecision: (decision) => void action.run(async () => {
2356
+ setMessage("");
2357
+ await invites[decision](invite.id);
2358
+ setMessage(
2359
+ `${decision === "accept" ? "Accepted" : "Declined"} \u201C${title}\u201D.`
2360
+ );
2361
+ })
2362
+ },
2363
+ invite.id
2364
+ );
2365
+ }) })
2366
+ ] });
2367
+ }
2368
+ function ShareInviteRow({
2369
+ invite,
2370
+ title,
2371
+ resolveContactHandle,
2372
+ disabled,
2373
+ onDecision
2374
+ }) {
2375
+ const did = invite.originOwnerDid;
2376
+ const [sender, setSender] = useState4(null);
2377
+ useEffect4(() => {
2378
+ let active = true;
2379
+ void resolveContactHandle(did).then(
2380
+ (handle2) => {
2381
+ if (active) setSender({ did, handle: handle2 });
2382
+ },
2383
+ () => {
2384
+ if (active) setSender({ did, handle: null });
2385
+ }
2386
+ );
2387
+ return () => {
2388
+ active = false;
2389
+ };
2390
+ }, [did, resolveContactHandle]);
2391
+ const handle = sender?.did === did ? sender.handle : null;
2392
+ const pending = invite.state === "pending";
2393
+ const accepting = invite.state === "accepting";
2394
+ const expiresAt = new Date(invite.acceptBy);
2395
+ const expired = expiresAt.getTime() <= Date.now();
2396
+ const blocked = invite.compatibility.state === "app_connection_required" ? "Connect this app to accept." : invite.compatibility.state === "compatible_repo_required" ? "A compatible repository is required." : null;
2397
+ const status = pending && !expired ? null : (pending || accepting) && expired ? "Expired" : accepting ? "Retry to finish accepting" : invite.state === "accepted" ? "Accepted" : invite.state === "declined" ? "Declined" : "Acceptance rejected";
2398
+ return /* @__PURE__ */ jsxs2("li", { children: [
2399
+ /* @__PURE__ */ jsx4(
2400
+ ShareRecipientAvatar,
2401
+ {
2402
+ recipient: {
2403
+ did,
2404
+ name: handle ? displayHandle(handle) : "Unknown sender"
2405
+ },
2406
+ size: 32
2407
+ }
2408
+ ),
2409
+ /* @__PURE__ */ jsxs2("div", { className: "basic-identity", children: [
2410
+ /* @__PURE__ */ jsx4("strong", { children: title }),
2411
+ /* @__PURE__ */ jsx4("small", { children: handle ? displayHandle(handle) : "Unknown sender" }),
2412
+ /* @__PURE__ */ jsx4("small", { children: invite.role === "editor" ? "Can edit" : "Can view" }),
2413
+ status && /* @__PURE__ */ jsx4("span", { className: "basic-invite-state", children: status }),
2414
+ blocked && (pending || accepting) && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: blocked })
2415
+ ] }),
2416
+ (pending || accepting) && /* @__PURE__ */ jsxs2("div", { className: "basic-invite-actions", children: [
2417
+ /* @__PURE__ */ jsx4(
2418
+ BasicButton,
2419
+ {
2420
+ variant: "solid",
2421
+ disabled: disabled || expired || !!blocked,
2422
+ onClick: () => onDecision("accept"),
2423
+ children: accepting ? "Retry acceptance" : "Accept"
2424
+ }
2425
+ ),
2426
+ pending && /* @__PURE__ */ jsx4(
2427
+ BasicButton,
2428
+ {
2429
+ disabled,
2430
+ onClick: () => onDecision("decline"),
2431
+ children: "Decline"
2432
+ }
2433
+ )
2434
+ ] }),
2435
+ /* @__PURE__ */ jsxs2("details", { className: "basic-invite-details", children: [
2436
+ /* @__PURE__ */ jsx4("summary", { children: "Details" }),
2437
+ /* @__PURE__ */ jsxs2("div", { className: "basic-invite-scope", children: [
2438
+ invite.scope.map((scope, index) => /* @__PURE__ */ jsxs2("div", { children: [
2439
+ /* @__PURE__ */ jsx4("strong", { children: scope.table }),
2440
+ " \xB7",
2441
+ " ",
2442
+ scope.recordIds ? `${scope.recordIds.length} selected records` : "all records",
2443
+ scope.recordIds && /* @__PURE__ */ jsx4("code", { children: scope.recordIds.join(", ") })
2444
+ ] }, index)),
2445
+ /* @__PURE__ */ jsxs2("small", { children: [
2446
+ "Sender DID: ",
2447
+ did
2448
+ ] }),
2449
+ /* @__PURE__ */ jsxs2("small", { children: [
2450
+ "Expires",
2451
+ " ",
2452
+ /* @__PURE__ */ jsxs2("time", { dateTime: invite.acceptBy, children: [
2453
+ expiresAt.toLocaleString("en-US", {
2454
+ dateStyle: "medium",
2455
+ timeStyle: "short",
2456
+ timeZone: "UTC"
2457
+ }),
2458
+ " ",
2459
+ "UTC"
2460
+ ] })
2461
+ ] })
2462
+ ] })
2463
+ ] })
2464
+ ] });
2465
+ }
2466
+ function ShareInvitesModal({
2467
+ auth,
2468
+ accounts,
2469
+ invites,
2470
+ ...props
2471
+ }) {
2472
+ return /* @__PURE__ */ jsx4(Modal, { ...props, title: "Share Invites", hideTitle: true, children: /* @__PURE__ */ jsx4(ShareInvites, { auth, accounts, invites }) });
2473
+ }
1940
2474
  function SharesModal({
1941
2475
  auth: supplied,
1942
2476
  accounts: suppliedAccounts,
1943
2477
  sync,
1944
2478
  shares,
2479
+ invites,
1945
2480
  scope,
1946
2481
  repo = "default",
1947
2482
  ...props
@@ -1949,37 +2484,43 @@ function SharesModal({
1949
2484
  const live = useAuth();
1950
2485
  const liveAccounts = useAccounts();
1951
2486
  const auth = supplied ?? live;
1952
- return /* @__PURE__ */ jsx3(
2487
+ return /* @__PURE__ */ jsx4(
1953
2488
  Modal,
1954
2489
  {
1955
2490
  ...props,
1956
2491
  title: "Shares",
1957
2492
  description: "Manage incoming invitations and share access to selected data.",
1958
- header: /* @__PURE__ */ jsx3(
2493
+ header: /* @__PURE__ */ jsx4(
1959
2494
  AccountHeader,
1960
2495
  {
1961
2496
  account: (suppliedAccounts ?? liveAccounts).activeAccount,
1962
2497
  sync
1963
2498
  }
1964
2499
  ),
1965
- children: !auth.isReady ? /* @__PURE__ */ jsx3("p", { role: "status", children: "Checking session\u2026" }) : !auth.isSignedIn ? /* @__PURE__ */ jsxs(Fragment2, { children: [
1966
- /* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "Sign in to share data." }),
1967
- /* @__PURE__ */ jsx3(SignInButton, { auth })
1968
- ] }) : /* @__PURE__ */ jsx3(
2500
+ children: !auth.isReady ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Checking session\u2026" }) : !auth.isSignedIn ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
2501
+ /* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Sign in to share data." }),
2502
+ /* @__PURE__ */ jsx4(SignInButton, { auth })
2503
+ ] }) : /* @__PURE__ */ jsx4(
1969
2504
  SharesContent,
1970
2505
  {
1971
2506
  shares,
2507
+ invites,
2508
+ auth,
2509
+ accounts: suppliedAccounts ?? liveAccounts,
1972
2510
  scope,
1973
2511
  repo,
1974
2512
  canWrite: auth.canWrite
1975
2513
  },
1976
- auth.did ?? "account"
2514
+ (suppliedAccounts ?? liveAccounts).activeAccount?.id ?? auth.did
1977
2515
  )
1978
2516
  }
1979
2517
  );
1980
2518
  }
1981
2519
  function SharesContent({
1982
2520
  shares: supplied,
2521
+ invites,
2522
+ auth,
2523
+ accounts,
1983
2524
  scope,
1984
2525
  repo,
1985
2526
  canWrite
@@ -1994,29 +2535,25 @@ function SharesContent({
1994
2535
  const scopeValid = scope.length > 0 && scope.every(
1995
2536
  (item) => item.table.trim() && (item.recordIds === void 0 || item.recordIds.length > 0)
1996
2537
  );
1997
- return /* @__PURE__ */ jsxs(Tabs.Root, { defaultValue: "outgoing", className: "basic-shares", children: [
1998
- /* @__PURE__ */ jsxs(Tabs.List, { className: "basic-tabs", "aria-label": "Share direction", children: [
1999
- /* @__PURE__ */ jsx3(Tabs.Tab, { value: "outgoing", children: "Outgoing" }),
2000
- /* @__PURE__ */ jsx3(Tabs.Tab, { value: "incoming", children: "Incoming invitations" })
2538
+ return /* @__PURE__ */ jsxs2(Tabs.Root, { defaultValue: "outgoing", className: "basic-shares", children: [
2539
+ /* @__PURE__ */ jsxs2(Tabs.List, { className: "basic-tabs", "aria-label": "Share direction", children: [
2540
+ /* @__PURE__ */ jsx4(Tabs.Tab, { value: "outgoing", children: "Outgoing" }),
2541
+ /* @__PURE__ */ jsx4(Tabs.Tab, { value: "incoming", children: "Share Invites" })
2001
2542
  ] }),
2002
- /* @__PURE__ */ jsx3(Tabs.Panel, { value: "incoming", children: /* @__PURE__ */ jsxs("section", { "aria-label": "Incoming invitations", children: [
2003
- /* @__PURE__ */ jsx3("h3", { className: "basic-title", children: "Incoming invitations" }),
2004
- /* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "View, accept, or decline incoming invitations in Basic ID. Your app session cannot access the account-wide inbox." }),
2005
- /* @__PURE__ */ jsx3("a", { className: "basic-link", href: shares.manageUrl(), children: "Open incoming invitations in Basic ID \u2197" })
2006
- ] }) }),
2007
- /* @__PURE__ */ jsxs(Tabs.Panel, { value: "outgoing", children: [
2008
- /* @__PURE__ */ jsx3("p", { className: "basic-muted", children: "Revoking access stops future requests. It cannot retract data the recipient already downloaded." }),
2009
- /* @__PURE__ */ jsxs("div", { className: "basic-scope", children: [
2010
- /* @__PURE__ */ jsx3("strong", { children: "New invitation permissions" }),
2011
- scope.map((item, index) => /* @__PURE__ */ jsxs("span", { children: [
2543
+ /* @__PURE__ */ jsx4(Tabs.Panel, { value: "incoming", children: /* @__PURE__ */ jsx4(ShareInvites, { invites, auth, accounts }) }),
2544
+ /* @__PURE__ */ jsxs2(Tabs.Panel, { value: "outgoing", children: [
2545
+ /* @__PURE__ */ jsx4("p", { className: "basic-muted", children: "Revoking access stops future requests. It cannot retract data the recipient already downloaded." }),
2546
+ /* @__PURE__ */ jsxs2("div", { className: "basic-scope", children: [
2547
+ /* @__PURE__ */ jsx4("strong", { children: "New invitation permissions" }),
2548
+ scope.map((item, index) => /* @__PURE__ */ jsxs2("span", { children: [
2012
2549
  item.table,
2013
2550
  " \xB7",
2014
2551
  " ",
2015
2552
  item.recordIds ? `${item.recordIds.length} selected records` : "all records"
2016
2553
  ] }, index))
2017
2554
  ] }),
2018
- !canWrite && /* @__PURE__ */ jsx3("p", { className: "basic-error", children: "This session is read only. Sharing changes are disabled." }),
2019
- /* @__PURE__ */ jsxs(
2555
+ !canWrite && /* @__PURE__ */ jsx4("p", { className: "basic-error", children: "This session is read only. Sharing changes are disabled." }),
2556
+ /* @__PURE__ */ jsxs2(
2020
2557
  "form",
2021
2558
  {
2022
2559
  className: "basic-share-form",
@@ -2036,9 +2573,9 @@ function SharesContent({
2036
2573
  });
2037
2574
  },
2038
2575
  children: [
2039
- /* @__PURE__ */ jsxs("label", { className: "basic-field", children: [
2576
+ /* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
2040
2577
  "Recipient handle or DID",
2041
- /* @__PURE__ */ jsx3(
2578
+ /* @__PURE__ */ jsx4(
2042
2579
  "input",
2043
2580
  {
2044
2581
  className: "basic-input",
@@ -2050,9 +2587,9 @@ function SharesContent({
2050
2587
  }
2051
2588
  )
2052
2589
  ] }),
2053
- /* @__PURE__ */ jsxs("label", { className: "basic-field", children: [
2590
+ /* @__PURE__ */ jsxs2("label", { className: "basic-field", children: [
2054
2591
  "Permission",
2055
- /* @__PURE__ */ jsxs(
2592
+ /* @__PURE__ */ jsxs2(
2056
2593
  "select",
2057
2594
  {
2058
2595
  className: "basic-input",
@@ -2060,13 +2597,13 @@ function SharesContent({
2060
2597
  onChange: (event) => setRole(event.target.value),
2061
2598
  disabled: action.pending || !canWrite,
2062
2599
  children: [
2063
- /* @__PURE__ */ jsx3("option", { value: "viewer", children: "Can view" }),
2064
- /* @__PURE__ */ jsx3("option", { value: "editor", children: "Can edit" })
2600
+ /* @__PURE__ */ jsx4("option", { value: "viewer", children: "Can view" }),
2601
+ /* @__PURE__ */ jsx4("option", { value: "editor", children: "Can edit" })
2065
2602
  ]
2066
2603
  }
2067
2604
  )
2068
2605
  ] }),
2069
- /* @__PURE__ */ jsx3(
2606
+ /* @__PURE__ */ jsx4(
2070
2607
  BasicButton,
2071
2608
  {
2072
2609
  type: "submit",
@@ -2078,12 +2615,12 @@ function SharesContent({
2078
2615
  ]
2079
2616
  }
2080
2617
  ),
2081
- !scopeValid && /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: "Select at least one table or record to share." }),
2082
- action.error && /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: action.error }),
2083
- message && /* @__PURE__ */ jsx3("p", { role: "status", className: "basic-muted", children: message }),
2084
- /* @__PURE__ */ jsxs("div", { className: "basic-section-heading", children: [
2085
- /* @__PURE__ */ jsx3("h3", { className: "basic-title", children: "Outgoing shares \xB7 all permissions" }),
2086
- /* @__PURE__ */ jsx3(
2618
+ !scopeValid && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: "Select at least one table or record to share." }),
2619
+ action.error && /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: action.error }),
2620
+ message && /* @__PURE__ */ jsx4("p", { role: "status", className: "basic-muted", children: message }),
2621
+ /* @__PURE__ */ jsxs2("div", { className: "basic-section-heading", children: [
2622
+ /* @__PURE__ */ jsx4("h3", { className: "basic-title", children: "Outgoing shares \xB7 all permissions" }),
2623
+ /* @__PURE__ */ jsx4(
2087
2624
  BasicButton,
2088
2625
  {
2089
2626
  disabled: action.pending || shares.isLoading,
@@ -2092,10 +2629,15 @@ function SharesContent({
2092
2629
  }
2093
2630
  )
2094
2631
  ] }),
2095
- shares.isLoading ? /* @__PURE__ */ jsx3("p", { role: "status", children: "Loading shares\u2026" }) : shares.error ? /* @__PURE__ */ jsx3("p", { role: "alert", className: "basic-error", children: shares.error.message }) : !shares.data.length ? /* @__PURE__ */ jsx3("p", { className: "basic-empty", children: "No outgoing shares yet." }) : /* @__PURE__ */ jsx3("ul", { className: "basic-share-list", children: shares.data.map((share) => /* @__PURE__ */ jsxs("li", { children: [
2096
- /* @__PURE__ */ jsxs("div", { className: "basic-identity", children: [
2097
- /* @__PURE__ */ jsx3("strong", { children: share.display.shareName || share.recipientDid }),
2098
- /* @__PURE__ */ jsxs("small", { children: [
2632
+ shares.isLoading ? /* @__PURE__ */ jsx4("p", { role: "status", children: "Loading shares\u2026" }) : shares.error ? /* @__PURE__ */ jsx4("p", { role: "alert", className: "basic-error", children: shares.error.message }) : !shares.data.length ? /* @__PURE__ */ jsx4("p", { className: "basic-empty", children: "No outgoing shares yet." }) : /* @__PURE__ */ jsx4("ul", { className: "basic-share-list", children: shares.data.map((share) => /* @__PURE__ */ jsxs2("li", { children: [
2633
+ /* @__PURE__ */ jsx4(ShareRecipientAvatar, { recipient: { did: share.recipientDid } }),
2634
+ /* @__PURE__ */ jsxs2("div", { className: "basic-identity", children: [
2635
+ /* @__PURE__ */ jsx4("strong", { children: share.display.shareName || share.recipientDid }),
2636
+ share.display.shareName && /* @__PURE__ */ jsxs2("small", { children: [
2637
+ "To ",
2638
+ share.recipientDid
2639
+ ] }),
2640
+ /* @__PURE__ */ jsxs2("small", { children: [
2099
2641
  share.role === "viewer" ? "Can view" : "Can edit",
2100
2642
  " \xB7",
2101
2643
  " ",
@@ -2105,9 +2647,9 @@ function SharesContent({
2105
2647
  share.scope.map((item) => item.table).join(", ")
2106
2648
  ] })
2107
2649
  ] }),
2108
- share.state !== "ended" && (confirmation === share.id ? /* @__PURE__ */ jsxs("div", { className: "basic-actions", children: [
2109
- /* @__PURE__ */ jsx3("span", { children: "Remove access?" }),
2110
- /* @__PURE__ */ jsxs(
2650
+ share.state !== "ended" && (confirmation === share.id ? /* @__PURE__ */ jsxs2("div", { className: "basic-actions", children: [
2651
+ /* @__PURE__ */ jsx4("span", { children: "Remove access?" }),
2652
+ /* @__PURE__ */ jsxs2(
2111
2653
  BasicButton,
2112
2654
  {
2113
2655
  disabled: action.pending || !canWrite,
@@ -2126,7 +2668,7 @@ function SharesContent({
2126
2668
  ]
2127
2669
  }
2128
2670
  ),
2129
- /* @__PURE__ */ jsx3(
2671
+ /* @__PURE__ */ jsx4(
2130
2672
  BasicButton,
2131
2673
  {
2132
2674
  disabled: action.pending,
@@ -2134,7 +2676,7 @@ function SharesContent({
2134
2676
  children: "Keep access"
2135
2677
  }
2136
2678
  )
2137
- ] }) : /* @__PURE__ */ jsx3(
2679
+ ] }) : /* @__PURE__ */ jsx4(
2138
2680
  BasicButton,
2139
2681
  {
2140
2682
  disabled: action.pending || !canWrite,
@@ -2155,6 +2697,11 @@ export {
2155
2697
  BrowserKeyValueStorage,
2156
2698
  BrowserTokenStore,
2157
2699
  PersistenceStore,
2700
+ ShareInvites,
2701
+ ShareInvitesModal,
2702
+ ShareRecipientAvatar,
2703
+ ShareRecipientAvatars,
2704
+ ShareRecipientLabel,
2158
2705
  SharesModal,
2159
2706
  SignInButton,
2160
2707
  SignOutButton,
@@ -2183,6 +2730,8 @@ export {
2183
2730
  useQuery,
2184
2731
  useRepos,
2185
2732
  useSchemaStatus,
2733
+ useShareInvites,
2734
+ useShareRecipients,
2186
2735
  useStorageInfo,
2187
2736
  useSyncStatus
2188
2737
  };