@streamoid/settings 0.1.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.
@@ -0,0 +1,691 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { SVGProps, ReactNode } from 'react';
3
+
4
+ /**
5
+ * Settings tab identifiers and URL mapping helpers.
6
+ *
7
+ * The package is router-agnostic — consumers own their routing and pass the
8
+ * resolved tab into <SettingsContent activeTab={...} />. These helpers exist
9
+ * so consumers don't have to re-implement tab/URL conversion if they don't
10
+ * want to.
11
+ */
12
+ type SettingsTab = "profile" | "workspace" | "referral" | "team" | "billing" | "apikey";
13
+ /** Internal tab id → URL slug. */
14
+ declare const TAB_TO_URL: Record<SettingsTab, string>;
15
+ /** URL slug → internal tab id. */
16
+ declare const URL_TO_TAB: Record<string, SettingsTab>;
17
+ /** Human-readable label for each tab (used for breadcrumbs etc.). */
18
+ declare const TAB_LABELS: Record<SettingsTab, string>;
19
+ /**
20
+ * Resolve a `SettingsTab` from a URL pathname. Looks for the last segment that
21
+ * matches a known slug; falls back to `"profile"` (the default Account tab).
22
+ *
23
+ * Example: `/settings/billing` → `"billing"`.
24
+ */
25
+ declare function resolveSettingsTabFromPath(path: string): SettingsTab;
26
+
27
+ /**
28
+ * Adapter contracts for @streamoid/settings.
29
+ *
30
+ * The host application (cxo-dashboard, photogenix, etc.) implements one
31
+ * `SettingsAdapters` object and passes it into <SettingsContent>. Every
32
+ * sub-component in this package reads from `useSettingsAdapters()` instead of
33
+ * importing the host's auth/workspace/services/router/toast directly.
34
+ *
35
+ * Design notes:
36
+ * - State that the host already owns reactively (current user, current
37
+ * workspace) is *embedded* in the adapter object. The host re-creates the
38
+ * adapter object (or its inner objects) when its state changes; React's
39
+ * normal render-on-prop-change semantics flow that change into the package.
40
+ * - Lists that the package fetches on demand (workspace list, members,
41
+ * invoices, tokens) are exposed as async functions. The package owns the
42
+ * `loading`/`data` state internally and re-fetches after mutations.
43
+ * - Mutations don't return anything the package depends on; the convention is
44
+ * "fire the mutation, then refetch". Errors throw.
45
+ */
46
+
47
+ interface SettingsAuthUser {
48
+ id: string;
49
+ email: string;
50
+ name?: string;
51
+ imageUrl?: string;
52
+ role?: string;
53
+ company?: string;
54
+ createdAt?: number | string;
55
+ }
56
+ interface SettingsAuthAdapter {
57
+ user: SettingsAuthUser | null;
58
+ refreshProfile: () => Promise<void>;
59
+ updateProfile: (patch: {
60
+ name?: string;
61
+ imageUrl?: string | null;
62
+ }) => Promise<void>;
63
+ clearAuth: () => void;
64
+ logout: () => Promise<void>;
65
+ }
66
+ interface SettingsWorkspaceCurrent {
67
+ id: string;
68
+ name?: string;
69
+ imageUrl?: string;
70
+ role?: "admin" | "member" | string;
71
+ /** Optional reactive credit summary if the host tracks it. */
72
+ availableCredits?: number | null;
73
+ totalCredits?: number | null;
74
+ }
75
+ interface SettingsWorkspaceListItem {
76
+ _id: string;
77
+ name: string;
78
+ imageUrl?: string;
79
+ image?: string;
80
+ isCurrent?: boolean;
81
+ role?: string;
82
+ membersCount?: number;
83
+ /** Optional plan label (e.g. "Free", "Pro"). */
84
+ plan?: string;
85
+ /** Optional owner email shown in the workspace list. */
86
+ ownerEmail?: string;
87
+ }
88
+ interface SettingsWorkspaceAdapter {
89
+ current: SettingsWorkspaceCurrent | null;
90
+ list: () => Promise<SettingsWorkspaceListItem[]>;
91
+ /**
92
+ * Create a workspace and return the new workspace's id (so the caller can
93
+ * immediately switch to it). The host adapter is also free to perform the
94
+ * switch internally and return `void` — the caller checks for `id`.
95
+ *
96
+ * `imageFile` is provided when the user uploaded one in the workspace
97
+ * modal; the host adapter is expected to upload it to its own storage
98
+ * (CXO uses multipart form upload to `/workspace`).
99
+ */
100
+ create: (input: {
101
+ name: string;
102
+ imageFile?: File | null;
103
+ imageUrl?: string | null;
104
+ }) => Promise<{
105
+ id: string;
106
+ imageUrl?: string;
107
+ ownerEmail?: string;
108
+ } | void>;
109
+ update: (id: string, patch: {
110
+ name?: string;
111
+ imageFile?: File | null;
112
+ imageRemoved?: boolean;
113
+ imageUrl?: string | null;
114
+ }) => Promise<{
115
+ imageUrl?: string;
116
+ } | void>;
117
+ switch: (id: string) => Promise<void>;
118
+ leave: (id: string) => Promise<void>;
119
+ delete: (id: string) => Promise<void>;
120
+ /**
121
+ * Optional: returns the highest role in a workspace. Used by the workspace
122
+ * modal to decide whether the current user can delete the workspace
123
+ * (admin who is also the highest-role member).
124
+ *
125
+ * When omitted, the package falls back to comparing the caller's role on
126
+ * `current` against `"admin"` directly.
127
+ */
128
+ getHighestRole?: (workspaceId: string) => Promise<{
129
+ data?: {
130
+ role?: string;
131
+ } | null;
132
+ }>;
133
+ /**
134
+ * Optional: host-controlled refresh after the package mutates workspace
135
+ * state. If provided, the package will call this instead of (or in addition
136
+ * to) re-running `list()`. Lets the host re-sync its own context state.
137
+ */
138
+ refresh?: () => Promise<void>;
139
+ }
140
+ type TokenExpiry = "30d" | "60d" | "90d" | "1y" | "never";
141
+ interface ApiToken {
142
+ _id: string;
143
+ name: string;
144
+ tokenPrefix: string;
145
+ workspaceId: string;
146
+ expiresAt: string | null;
147
+ lastUsedAt: string | null;
148
+ status: "active" | "revoked";
149
+ createdAt: string;
150
+ }
151
+ interface CreatedToken extends ApiToken {
152
+ /** Raw token value — returned only once at creation. */
153
+ token: string;
154
+ }
155
+ interface WorkspaceMember {
156
+ _id: string;
157
+ role: "admin" | "member";
158
+ creditAccess: boolean;
159
+ inviteAccess: boolean;
160
+ user: {
161
+ _id: string;
162
+ email: string;
163
+ name: string;
164
+ createdAt?: string;
165
+ };
166
+ service: {
167
+ _id: string;
168
+ serviceGroupName?: string;
169
+ }[];
170
+ stores: {
171
+ _id: string;
172
+ name?: string;
173
+ }[];
174
+ createdAt?: string;
175
+ invitedBy?: string | {
176
+ email?: string;
177
+ name?: string;
178
+ };
179
+ addedBy?: string | {
180
+ email?: string;
181
+ name?: string;
182
+ };
183
+ }
184
+ interface WorkspaceInvite {
185
+ _id: string;
186
+ email: string | {
187
+ email?: string;
188
+ name?: string;
189
+ };
190
+ status: "active" | "rejected";
191
+ token?: string;
192
+ invitedBy?: string | {
193
+ email?: string;
194
+ name?: string;
195
+ };
196
+ addedBy?: string | {
197
+ email?: string;
198
+ name?: string;
199
+ };
200
+ updatedBy?: string | {
201
+ email?: string;
202
+ name?: string;
203
+ };
204
+ role?: "admin" | "member";
205
+ creditAccess?: boolean;
206
+ inviteAccess?: boolean;
207
+ service?: Array<{
208
+ _id?: string;
209
+ serviceGroupName?: string;
210
+ name?: string;
211
+ }>;
212
+ services?: Array<{
213
+ _id?: string;
214
+ serviceGroupName?: string;
215
+ name?: string;
216
+ }>;
217
+ serviceIds?: string[];
218
+ stores?: Array<{
219
+ _id?: string;
220
+ name?: string;
221
+ } | string>;
222
+ storeIds?: string[];
223
+ }
224
+ interface ServiceItem {
225
+ _id: string;
226
+ name: string;
227
+ serviceGroupName?: string;
228
+ pageUrl?: string;
229
+ }
230
+ interface StoreItem {
231
+ _id: string;
232
+ name: string;
233
+ }
234
+ /** Payload shared by `inviteMember` and `updateMemberRole`. */
235
+ interface MemberPermissionsPayload {
236
+ role: "admin" | "member";
237
+ creditAccess: boolean;
238
+ inviteAccess: boolean;
239
+ serviceIds: string[];
240
+ storeIds: string[];
241
+ }
242
+ interface AvailableCreditsResponse {
243
+ availableCredits: number;
244
+ }
245
+ interface SubscriptionPlan {
246
+ id: string;
247
+ name: string;
248
+ amount: number;
249
+ subscriptionEndDate?: string;
250
+ }
251
+ interface BillingSubscription {
252
+ createdAt: string;
253
+ downgradeScheduled: boolean;
254
+ stripeCustomerId: string;
255
+ plan: SubscriptionPlan;
256
+ }
257
+ interface SubscriptionResponse {
258
+ data: BillingSubscription | null;
259
+ }
260
+ interface PriceMetadata {
261
+ name: string;
262
+ credits: string;
263
+ [key: string]: string;
264
+ }
265
+ interface Price {
266
+ id: string;
267
+ unit_amount: number;
268
+ metadata: PriceMetadata;
269
+ }
270
+ interface BillingProduct {
271
+ id: string;
272
+ name: string;
273
+ prices: Price[];
274
+ }
275
+ interface ProductsResponse {
276
+ data: BillingProduct[];
277
+ }
278
+ interface UsageHistoryItem {
279
+ _id: string;
280
+ type: "deduct" | "return" | "add";
281
+ createdAt: string;
282
+ amount: number;
283
+ triggeredByUserId?: string;
284
+ meta?: {
285
+ info?: string;
286
+ stripeInvoiceId?: string;
287
+ };
288
+ service?: {
289
+ serviceGroupName: string;
290
+ };
291
+ refBlockId?: string;
292
+ expiresAt?: string;
293
+ amountPaid?: number;
294
+ /** Stripe transaction id when present. Some usage rows (e.g. internal returns) are emitted without one. */
295
+ transactionId?: string;
296
+ }
297
+ interface UsageHistoryResponse {
298
+ data: UsageHistoryItem[];
299
+ }
300
+ interface InvoicePdfResponse {
301
+ data: {
302
+ invoiceData: {
303
+ invoice_pdf: string;
304
+ id?: string;
305
+ };
306
+ receiptPdfUrl: string;
307
+ data_of_issue: string;
308
+ };
309
+ }
310
+ interface CustomCreditInfo {
311
+ price: number;
312
+ credits: number;
313
+ currency?: string;
314
+ billingCycle?: string;
315
+ requestCustomerCardDetails?: boolean;
316
+ downgradeData?: {
317
+ price: number;
318
+ };
319
+ }
320
+ interface CustomCreditResponse {
321
+ data: CustomCreditInfo;
322
+ }
323
+ /**
324
+ * Payload for upgrading / downgrading a subscription. The adapter
325
+ * implementation injects `workspaceId`, `userId`, and `triggeredByUserId`
326
+ * before hitting the backend — those fields are intentionally absent here.
327
+ */
328
+ interface UpdateSubscriptionPayload {
329
+ priceId: string;
330
+ productId: string;
331
+ quantity: number;
332
+ customerEmail: string;
333
+ customMetadata?: Record<string, string>;
334
+ successUrl: string;
335
+ cancelUrl: string;
336
+ action: "upgrade" | "downgrade";
337
+ }
338
+ interface UpdateSubscriptionResponse {
339
+ data: {
340
+ checkoutUrl?: string;
341
+ };
342
+ }
343
+ /** Analytics event sent after billing-related actions (CXO-only). */
344
+ interface BillingEventPayload {
345
+ eventName: string;
346
+ description: string;
347
+ plan?: string;
348
+ metadata?: {
349
+ action: string;
350
+ additionalInfo?: string;
351
+ };
352
+ }
353
+ /**
354
+ * Payload for `buyCredits` / topup flows. The adapter implementation injects
355
+ * `workspaceId` and `triggeredByUserId` — the package doesn't need to know
356
+ * who's logged in or which workspace is active.
357
+ */
358
+ interface BuyCreditsPayload {
359
+ serviceName: string;
360
+ credits: number;
361
+ unitAmount: number;
362
+ itemCount: number;
363
+ currency: string;
364
+ successUrl: string;
365
+ cancelUrl: string;
366
+ metadata?: Record<string, string>;
367
+ }
368
+ interface BuyCreditsResponse {
369
+ checkoutUrl?: string;
370
+ url?: string;
371
+ sessionId?: string;
372
+ availableCredits?: number;
373
+ credits?: number;
374
+ }
375
+ /**
376
+ * The API adapter is split into three concern areas (billing / teams /
377
+ * tokens) but kept flat to match the original spec. Methods are grouped with
378
+ * comments below.
379
+ *
380
+ * **Convention**: methods do not take a `workspaceId` — the host adapter
381
+ * implementation closes over the active workspace and passes it to the
382
+ * underlying API. Methods return *clean* values (no `{status, data}`
383
+ * envelope); the host adapter unwraps the envelope and throws on non-zero
384
+ * status codes if applicable.
385
+ *
386
+ * Methods marked optional (`?:`) are CXO-specific and may be absent in other
387
+ * hosts (e.g. Photogenix). Components hide the corresponding affordance when
388
+ * the method is undefined.
389
+ */
390
+ interface SettingsApiAdapter {
391
+ /** Plan/products catalog. Mirrors CXO's `/subscriptions/products`. */
392
+ fetchPlans: () => Promise<ProductsResponse>;
393
+ /**
394
+ * Current active subscription. Returns `{ data: null }` when the workspace
395
+ * has no plan yet (free tier).
396
+ */
397
+ fetchCurrentPlan: () => Promise<SubscriptionResponse>;
398
+ /** Available credit balance for the active workspace. */
399
+ fetchAvailableCredits: () => Promise<AvailableCreditsResponse>;
400
+ /** Invoice history (CXO: `getUsageHistory(_, "add")`). */
401
+ fetchInvoices: () => Promise<UsageHistoryResponse>;
402
+ /** Get a downloadable invoice PDF / receipt URL. */
403
+ downloadInvoice: (orderId: string) => Promise<InvoicePdfResponse>;
404
+ /** Create a topup (buy-credits) checkout session. Returns the Stripe URL. */
405
+ buyCredits: (input: BuyCreditsPayload) => Promise<BuyCreditsResponse | {
406
+ data: BuyCreditsResponse;
407
+ }>;
408
+ /** Per-credit usage / deduction logs (CXO: `getUsageHistory(_, "deduct,return")`). */
409
+ fetchUsageLogs?: () => Promise<UsageHistoryResponse>;
410
+ /** Upgrade or downgrade a subscription. Returns checkout URL when applicable. */
411
+ updateSubscription?: (payload: UpdateSubscriptionPayload) => Promise<UpdateSubscriptionResponse>;
412
+ /** CXO-only: undo a pending plan downgrade before it takes effect. */
413
+ revertDowngrade?: () => Promise<{
414
+ data: unknown;
415
+ }>;
416
+ /** CXO-only analytics callback fired after every plan/credit mutation. */
417
+ sendBillingEvent?: (event: BillingEventPayload) => Promise<unknown>;
418
+ /** CXO-only: provision billing for a freshly-created workspace. */
419
+ createWorkspaceOnBilling?: (input: {
420
+ serviceNames: string[];
421
+ }) => Promise<unknown>;
422
+ /** CXO-only: returns custom (non-plan) credit info, e.g. one-off grants. */
423
+ getCustomCreditInfo?: () => Promise<CustomCreditResponse | null>;
424
+ fetchMembers: () => Promise<WorkspaceMember[]>;
425
+ fetchPendingInvites: () => Promise<WorkspaceInvite[]>;
426
+ /** Send an invitation to `email` with the given permissions. */
427
+ inviteMember: (input: {
428
+ email: string;
429
+ } & MemberPermissionsPayload) => Promise<void>;
430
+ /**
431
+ * Canonical name for role updates. CXO's underlying service is named
432
+ * `changeUserRole(workspaceId, payload)`; the adapter wraps that. Both
433
+ * `updateMemberRole` and (optional) `changeUserRole` aliases work.
434
+ */
435
+ updateMemberRole: (input: {
436
+ userId: string;
437
+ } & MemberPermissionsPayload) => Promise<void>;
438
+ /**
439
+ * Remove members and/or pending invitations in a single call. CXO's
440
+ * underlying API supports batched removes; pass `userIds` for active members
441
+ * and `invitationIds` for invites. Hosts that don't support batching can
442
+ * implement this by calling their per-id endpoints in parallel.
443
+ */
444
+ removeMember: (input: {
445
+ userIds?: string[];
446
+ invitationIds?: string[];
447
+ }) => Promise<void>;
448
+ /**
449
+ * Cancel a pending invitation. CXO uses an invite token (preferred); fall
450
+ * back to invitationId if no token is available.
451
+ */
452
+ cancelInvite: (input: {
453
+ token?: string;
454
+ invitationId?: string;
455
+ }) => Promise<void>;
456
+ resendInvite: (invitationId: string) => Promise<void>;
457
+ /** CXO-only: promote one or more members to admin in a single call. */
458
+ promoteAsAdmin?: (userIds: string[]) => Promise<void>;
459
+ /** CXO-only: fetch granular per-user details (services, scopes, etc.). */
460
+ getUserDetail?: (userId: string) => Promise<WorkspaceMember | null>;
461
+ /**
462
+ * CXO-only: fetch the service catalog (apps the workspace can grant access
463
+ * to). When omitted, the package treats the workspace as having no
464
+ * service-level restrictions and falls back to the role-only permission
465
+ * model.
466
+ */
467
+ getServices?: () => Promise<ServiceItem[]>;
468
+ /** CXO-only: fetch the catalogix store list for the permissions picker. */
469
+ getStores?: () => Promise<StoreItem[]>;
470
+ /**
471
+ * CXO-only: returns the highest role the current user holds in the
472
+ * workspace; gates write affordances inside the Team tab. Mirrors
473
+ * `SettingsWorkspaceAdapter.getHighestRole` but workspace-scoped — both can
474
+ * point at the same backend endpoint.
475
+ */
476
+ getHighestRole?: () => Promise<{
477
+ role: "admin" | "member";
478
+ }>;
479
+ fetchTokens: (params?: {
480
+ showRevoked?: boolean;
481
+ }) => Promise<ApiToken[]>;
482
+ createToken: (input: {
483
+ name: string;
484
+ expiry: TokenExpiry;
485
+ }) => Promise<CreatedToken>;
486
+ revokeToken: (input: {
487
+ tokenId: string;
488
+ permanent?: boolean;
489
+ }) => Promise<void>;
490
+ fetchReferrals?: () => Promise<unknown[]>;
491
+ }
492
+ interface SettingsNavigationAdapter {
493
+ /** Imperative navigate to another settings tab. */
494
+ navigateToTab: (tab: SettingsTab) => void;
495
+ /** External-link navigate (e.g. for "What's new" or referral promo links). */
496
+ openExternal: (url: string) => void;
497
+ }
498
+ interface SettingsToastAdapter {
499
+ success: (message: string) => void;
500
+ error: (message: string) => void;
501
+ info?: (message: string) => void;
502
+ }
503
+ interface SettingsImageUploadAdapter {
504
+ /** Upload an image file and return its public URL. */
505
+ upload: (file: File) => Promise<string>;
506
+ }
507
+ interface SettingsAdapters {
508
+ auth: SettingsAuthAdapter;
509
+ workspace: SettingsWorkspaceAdapter;
510
+ api: SettingsApiAdapter;
511
+ navigation: SettingsNavigationAdapter;
512
+ toast: SettingsToastAdapter;
513
+ imageUpload: SettingsImageUploadAdapter;
514
+ }
515
+
516
+ type WorkspaceInfo = SettingsWorkspaceListItem & {
517
+ initials?: string;
518
+ plan?: string;
519
+ ownerEmail?: string;
520
+ };
521
+ declare function ProfileTab(): react_jsx_runtime.JSX.Element;
522
+ declare function WorkspaceTab({ workspaces, loading, onCreateClick: _onCreateClick, onEditClick, onSwitchClick, onLeaveClick, }: {
523
+ workspaces: WorkspaceInfo[];
524
+ loading: boolean;
525
+ onCreateClick: () => void;
526
+ onEditClick: (ws: WorkspaceInfo) => void;
527
+ onSwitchClick: (ws: WorkspaceInfo) => void;
528
+ onLeaveClick: (ws: WorkspaceInfo) => void;
529
+ }): react_jsx_runtime.JSX.Element;
530
+ declare function ReferralTab(): react_jsx_runtime.JSX.Element;
531
+ interface SettingsContentProps {
532
+ adapters: SettingsAdapters;
533
+ /** Currently active tab. The host owns routing and resolves this from the URL. */
534
+ activeTab?: SettingsTab;
535
+ }
536
+ declare function SettingsContent({ adapters, activeTab }: SettingsContentProps): react_jsx_runtime.JSX.Element;
537
+
538
+ type IconProps = Omit<SVGProps<SVGSVGElement>, 'color' | 'strokeWidth' | 'width' | 'height'> & {
539
+ color?: string;
540
+ strokeWidth?: number | string;
541
+ size?: number | string;
542
+ };
543
+ declare const SiconKey: ({ color, strokeWidth, size, ...props }: IconProps) => react_jsx_runtime.JSX.Element;
544
+
545
+ declare function BillingContent({ embedded }?: {
546
+ embedded?: boolean;
547
+ }): react_jsx_runtime.JSX.Element;
548
+
549
+ declare function TeamsContent({ embedded, onInviteOpen, onInviteOpenChange, }?: {
550
+ embedded?: boolean;
551
+ onInviteOpen?: boolean;
552
+ onInviteOpenChange?: (open: boolean) => void;
553
+ }): react_jsx_runtime.JSX.Element;
554
+
555
+ declare function TokensContent({ embedded, showRevokedOverride, onShowRevokedChange: _onShowRevokedChange, createOpenOverride, onCreateOpenChange, }?: {
556
+ embedded?: boolean;
557
+ showRevokedOverride?: boolean;
558
+ onShowRevokedChange?: (v: boolean) => void;
559
+ createOpenOverride?: boolean;
560
+ onCreateOpenChange?: (v: boolean) => void;
561
+ }): react_jsx_runtime.JSX.Element;
562
+
563
+ interface ProfileAvatarProps {
564
+ name: string;
565
+ profileImage?: string;
566
+ size?: number;
567
+ initialsClassName?: string;
568
+ borderRadius?: string;
569
+ }
570
+ /**
571
+ * Renders a profile/workspace avatar using ScDp.
572
+ * Automatically shows image or initials fallback.
573
+ */
574
+ declare function ProfileAvatar({ name, profileImage, size, initialsClassName, borderRadius, }: ProfileAvatarProps): react_jsx_runtime.JSX.Element;
575
+
576
+ interface WorkspaceData {
577
+ id: string;
578
+ name: string;
579
+ initials: string;
580
+ role: string;
581
+ plan: string;
582
+ ownerEmail: string;
583
+ isCurrent: boolean;
584
+ imageUrl?: string;
585
+ imageName?: string;
586
+ }
587
+ interface WorkspaceModalProps {
588
+ open: boolean;
589
+ mode: "create" | "update";
590
+ workspace?: WorkspaceData | null;
591
+ onClose: () => void;
592
+ onCreate?: (name: string, imageFile: File | null) => void | boolean | Promise<void | boolean>;
593
+ onUpdate?: (name: string, imageFile: File | null, imageRemoved: boolean) => void | boolean | Promise<void | boolean>;
594
+ onLeave?: () => void | boolean | Promise<void | boolean>;
595
+ onDelete?: () => void | boolean | Promise<void | boolean>;
596
+ }
597
+ declare function WorkspaceModal({ open, mode, workspace, onClose, onCreate, onUpdate, onLeave, onDelete, }: WorkspaceModalProps): react_jsx_runtime.JSX.Element | null;
598
+
599
+ interface ConfirmLeaveModalProps {
600
+ open: boolean;
601
+ workspaceName: string;
602
+ /** When true, shows the "sole admin" variant that blocks leaving */
603
+ isSoleAdmin?: boolean;
604
+ onClose: () => void;
605
+ onConfirm: () => void | Promise<void>;
606
+ /** Called when user clicks "Go to Teams" in the sole admin variant */
607
+ onGoToTeams?: () => void;
608
+ }
609
+ declare function ConfirmLeaveModal({ open, workspaceName, isSoleAdmin, onClose, onConfirm, onGoToTeams, }: ConfirmLeaveModalProps): react_jsx_runtime.JSX.Element | null;
610
+
611
+ interface ConfirmDeleteModalProps {
612
+ open: boolean;
613
+ workspaceName: string;
614
+ onClose: () => void;
615
+ onConfirm: () => void | Promise<void>;
616
+ }
617
+ declare function ConfirmDeleteModal({ open, workspaceName, onClose, onConfirm, }: ConfirmDeleteModalProps): react_jsx_runtime.JSX.Element | null;
618
+
619
+ interface BuyCreditsModalProps {
620
+ onClose: () => void;
621
+ onBuy: (credits: number, price: number) => void;
622
+ }
623
+ declare function BuyCreditsModal({ onClose, onBuy }: BuyCreditsModalProps): react_jsx_runtime.JSX.Element;
624
+
625
+ interface UserPermissions {
626
+ artifax: boolean;
627
+ photogenix: boolean;
628
+ catalogix: boolean;
629
+ canUseCredits: boolean;
630
+ canInviteUser: boolean;
631
+ role: "admin" | "member";
632
+ catalogixStores: string[];
633
+ }
634
+ interface TeamMember {
635
+ id: string;
636
+ kind: "member" | "invite";
637
+ /** Unified user id (for change-role and remove-users userIds). */
638
+ userId?: string;
639
+ /** Invitation id (for remove-users invitationIds). */
640
+ invitationId?: string;
641
+ /** Invitation token (for invite-cancel flow, if needed). */
642
+ inviteToken?: string;
643
+ name?: string;
644
+ userEmail: string;
645
+ invitedBy: string;
646
+ signedOn?: string;
647
+ permissions: UserPermissions;
648
+ }
649
+ declare const DEFAULT_PERMISSIONS: UserPermissions;
650
+
651
+ type ModalMode = "invite" | "update";
652
+ interface StoreOption {
653
+ _id: string;
654
+ name?: string;
655
+ }
656
+ interface InviteUpdateModalProps {
657
+ open: boolean;
658
+ mode: ModalMode;
659
+ userEmail?: string;
660
+ stores?: StoreOption[];
661
+ allowSubmitWithoutChanges?: boolean;
662
+ initialPermissions?: UserPermissions;
663
+ onClose: () => void;
664
+ onSave?: (permissions: UserPermissions) => void;
665
+ onRemove?: () => void;
666
+ /** Controls whether the Remove user button is enabled. Defaults to true. */
667
+ canRemove?: boolean;
668
+ /** Called only in invite mode; receives (permissions, email) */
669
+ onInvite?: (permissions: UserPermissions, email: string) => void;
670
+ }
671
+ declare function InviteUpdateModal({ open, mode, userEmail, stores, allowSubmitWithoutChanges, initialPermissions, onClose, onSave, onRemove, canRemove, onInvite, }: InviteUpdateModalProps): react_jsx_runtime.JSX.Element | null;
672
+
673
+ interface ExportDateModalProps {
674
+ title: string;
675
+ onClose: () => void;
676
+ onExport: (startDate: Date, endDate: Date) => void;
677
+ }
678
+ declare function ExportDateModal({ title, onClose, onExport, }: ExportDateModalProps): react_jsx_runtime.JSX.Element;
679
+
680
+ declare function SettingsAdaptersProvider({ adapters, children, }: {
681
+ adapters: SettingsAdapters;
682
+ children: ReactNode;
683
+ }): react_jsx_runtime.JSX.Element;
684
+ /**
685
+ * Read the host-provided adapters from anywhere inside <SettingsContent>.
686
+ * Throws at runtime if used outside the provider — which only happens if a
687
+ * sub-component is rendered directly without the shell.
688
+ */
689
+ declare function useSettingsAdapters(): SettingsAdapters;
690
+
691
+ export { type ApiToken, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, type MemberPermissionsPayload, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsTab, type SettingsToastAdapter, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_LABELS, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserPermissions, type WorkspaceData, type WorkspaceInvite, type WorkspaceMember, WorkspaceModal, WorkspaceTab, resolveSettingsTabFromPath, useSettingsAdapters };