@streamoid/settings 0.6.0 → 0.6.2

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.d.mts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { SVGProps, ReactNode } from 'react';
3
+ import { WorkspaceUsage } from '@streamoid/ui';
3
4
 
4
5
  /**
5
6
  * Settings tab identifiers and URL mapping helpers.
@@ -141,6 +142,13 @@ interface SettingsWorkspaceCurrent {
141
142
  /** Optional reactive credit summary if the host tracks it. */
142
143
  availableCredits?: number | null;
143
144
  totalCredits?: number | null;
145
+ /**
146
+ * Storage & bandwidth against the plan allowance, as the HOST has already
147
+ * fetched and evaluated it (`evaluateWorkspaceUsage` from `@streamoid/ui`).
148
+ * This package never requests it. When present, the Billing tab renders a
149
+ * usage meter for each kind; absent or null renders none.
150
+ */
151
+ usage?: WorkspaceUsage | null;
144
152
  /** ISO country code for the workspace; drives plan currency selection. */
145
153
  country?: string;
146
154
  /**
@@ -512,6 +520,8 @@ interface MemberPermissionsPayload {
512
520
  serviceIds: string[];
513
521
  storeIds: string[];
514
522
  }
523
+ /** `SettingsWorkspaceCurrent.usage`; re-exported from `@streamoid/ui`. */
524
+ type WorkspaceUsageResponse = WorkspaceUsage;
515
525
  interface AvailableCreditsResponse {
516
526
  availableCredits: number;
517
527
  }
@@ -803,6 +813,18 @@ interface SettingsNavigationAdapter {
803
813
  getCheckoutReturnUrl?: (kind: "success" | "cancel") => string;
804
814
  /** Imperative navigate to another settings tab. */
805
815
  navigateToTab: (tab: SettingsTab) => void;
816
+ /**
817
+ * Go back to whatever the user was doing before they opened settings.
818
+ *
819
+ * Distinct from `close`: closing is "leave settings" and lands wherever the
820
+ * host decides settings' parent is; back is "the screen I came from", which
821
+ * only the history knows. Omit it and the shell calls
822
+ * `window.history.back()`, which is right in every host today — settings is
823
+ * a route, and the browser already knows where the user was. Supply it when
824
+ * your router keeps its own stack, or pass `onBack={null}` on
825
+ * `<SettingsContent>` to render no back control at all.
826
+ */
827
+ back?: () => void;
806
828
  /**
807
829
  * Leave settings entirely. Supplying this makes the shell render a close (×)
808
830
  * button and dismiss on Escape. Hosts that would rather pass a callback
@@ -928,8 +950,19 @@ interface SettingsContentProps {
928
950
  * no close affordance is rendered — that is the pre-0.3.8 behaviour.
929
951
  */
930
952
  onClose?: () => void;
953
+ /**
954
+ * Go back to the screen the user came from, rendered as a `← Back` control
955
+ * above the breadcrumb.
956
+ *
957
+ * Defaults to `adapters.navigation.back`, and to `window.history.back()`
958
+ * when neither is supplied — settings is a route in every host, so the
959
+ * browser already knows where the user was, and requiring a prop would mean
960
+ * the control appeared in whichever app remembered to pass one. Pass `null`
961
+ * to render no back control.
962
+ */
963
+ onBack?: (() => void) | null;
931
964
  }
932
- declare function SettingsContent({ adapters, activeTab, onClose, hiddenApps, }: SettingsContentProps): react.JSX.Element;
965
+ declare function SettingsContent({ adapters, activeTab, onClose, onBack, hiddenApps, }: SettingsContentProps): react.JSX.Element;
933
966
 
934
967
  interface WorkspaceData {
935
968
  id: string;
@@ -1361,4 +1394,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1361
1394
  */
1362
1395
  declare function useSettingsAdapters(): SettingsAdapters;
1363
1396
 
1364
- export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, OrganizationInviteModal, type OrganizationInviteModalProps, type OrganizationJoinRequest, type OrganizationMember, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, WorkspaceTab, countLabel, resolveSettingsTabFromPath, useSettingsAdapters, userLanguageLabel };
1397
+ export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, OrganizationInviteModal, type OrganizationInviteModalProps, type OrganizationJoinRequest, type OrganizationMember, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, WorkspaceTab, type WorkspaceUsageResponse, countLabel, resolveSettingsTabFromPath, useSettingsAdapters, userLanguageLabel };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { SVGProps, ReactNode } from 'react';
3
+ import { WorkspaceUsage } from '@streamoid/ui';
3
4
 
4
5
  /**
5
6
  * Settings tab identifiers and URL mapping helpers.
@@ -141,6 +142,13 @@ interface SettingsWorkspaceCurrent {
141
142
  /** Optional reactive credit summary if the host tracks it. */
142
143
  availableCredits?: number | null;
143
144
  totalCredits?: number | null;
145
+ /**
146
+ * Storage & bandwidth against the plan allowance, as the HOST has already
147
+ * fetched and evaluated it (`evaluateWorkspaceUsage` from `@streamoid/ui`).
148
+ * This package never requests it. When present, the Billing tab renders a
149
+ * usage meter for each kind; absent or null renders none.
150
+ */
151
+ usage?: WorkspaceUsage | null;
144
152
  /** ISO country code for the workspace; drives plan currency selection. */
145
153
  country?: string;
146
154
  /**
@@ -512,6 +520,8 @@ interface MemberPermissionsPayload {
512
520
  serviceIds: string[];
513
521
  storeIds: string[];
514
522
  }
523
+ /** `SettingsWorkspaceCurrent.usage`; re-exported from `@streamoid/ui`. */
524
+ type WorkspaceUsageResponse = WorkspaceUsage;
515
525
  interface AvailableCreditsResponse {
516
526
  availableCredits: number;
517
527
  }
@@ -803,6 +813,18 @@ interface SettingsNavigationAdapter {
803
813
  getCheckoutReturnUrl?: (kind: "success" | "cancel") => string;
804
814
  /** Imperative navigate to another settings tab. */
805
815
  navigateToTab: (tab: SettingsTab) => void;
816
+ /**
817
+ * Go back to whatever the user was doing before they opened settings.
818
+ *
819
+ * Distinct from `close`: closing is "leave settings" and lands wherever the
820
+ * host decides settings' parent is; back is "the screen I came from", which
821
+ * only the history knows. Omit it and the shell calls
822
+ * `window.history.back()`, which is right in every host today — settings is
823
+ * a route, and the browser already knows where the user was. Supply it when
824
+ * your router keeps its own stack, or pass `onBack={null}` on
825
+ * `<SettingsContent>` to render no back control at all.
826
+ */
827
+ back?: () => void;
806
828
  /**
807
829
  * Leave settings entirely. Supplying this makes the shell render a close (×)
808
830
  * button and dismiss on Escape. Hosts that would rather pass a callback
@@ -928,8 +950,19 @@ interface SettingsContentProps {
928
950
  * no close affordance is rendered — that is the pre-0.3.8 behaviour.
929
951
  */
930
952
  onClose?: () => void;
953
+ /**
954
+ * Go back to the screen the user came from, rendered as a `← Back` control
955
+ * above the breadcrumb.
956
+ *
957
+ * Defaults to `adapters.navigation.back`, and to `window.history.back()`
958
+ * when neither is supplied — settings is a route in every host, so the
959
+ * browser already knows where the user was, and requiring a prop would mean
960
+ * the control appeared in whichever app remembered to pass one. Pass `null`
961
+ * to render no back control.
962
+ */
963
+ onBack?: (() => void) | null;
931
964
  }
932
- declare function SettingsContent({ adapters, activeTab, onClose, hiddenApps, }: SettingsContentProps): react.JSX.Element;
965
+ declare function SettingsContent({ adapters, activeTab, onClose, onBack, hiddenApps, }: SettingsContentProps): react.JSX.Element;
933
966
 
934
967
  interface WorkspaceData {
935
968
  id: string;
@@ -1361,4 +1394,4 @@ declare function SettingsAdaptersProvider({ adapters, children, }: {
1361
1394
  */
1362
1395
  declare function useSettingsAdapters(): SettingsAdapters;
1363
1396
 
1364
- export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, OrganizationInviteModal, type OrganizationInviteModalProps, type OrganizationJoinRequest, type OrganizationMember, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, WorkspaceTab, countLabel, resolveSettingsTabFromPath, useSettingsAdapters, userLanguageLabel };
1397
+ export { APP_KEYS, type ApiToken, type AppKey, type AvailableCreditsResponse, BillingContent, type BillingEventPayload, type BillingProduct, type BillingSubscription, BuyCreditsModal, type BuyCreditsPayload, type BuyCreditsResponse, ConfirmDeleteModal, ConfirmLeaveModal, type CreatedToken, type CustomCreditInfo, type CustomCreditResponse, DEFAULT_PERMISSIONS, DEFAULT_USER_LANGUAGE, ExportDateModal, InviteUpdateModal, type InvoicePdfResponse, MemberListFrame, type MemberListFrameProps, type MemberListTab, MemberListToolbar, type MemberListToolbarProps, type MemberPermissionsPayload, OrganizationContent, type OrganizationData, type OrganizationInvite, OrganizationInviteModal, type OrganizationInviteModalProps, type OrganizationJoinRequest, type OrganizationMember, OrganizationModal, type OrganizationView, type OrganizationWorkspaceItem, type Price, type PriceMetadata, type ProductsResponse, ProfileAvatar, ProfileTab, ReferralTab, SCOPE_LABELS, ScopeHeader, type ScopeHeaderProps, type ServiceItem, type SettingsAdapters, SettingsAdaptersProvider, type SettingsApiAdapter, type SettingsAuthAdapter, type SettingsAuthUser, SettingsContent, type SettingsContentProps, type SettingsImageUploadAdapter, type SettingsNavigationAdapter, type SettingsOrganizationAdapter, type SettingsOrganizationCurrent, type SettingsOrganizationListItem, type SettingsScope, type SettingsTab, type SettingsToastAdapter, SettingsTooltip, type SettingsTooltipPlacement, type SettingsTooltipProps, type SettingsWorkspaceAdapter, type SettingsWorkspaceCurrent, type SettingsWorkspaceListItem, SiconKey, type StoreItem, type SubscriptionPlan, type SubscriptionResponse, TAB_DESCRIPTIONS, TAB_LABELS, TAB_SCOPE, TAB_TO_URL, type TeamMember, TeamsContent, type TokenExpiry, TokensContent, URL_TO_TAB, USER_LANGUAGES, type UpdateSubscriptionPayload, type UpdateSubscriptionResponse, type UsageHistoryItem, type UsageHistoryResponse, type UserLanguage, type UserPermissions, type WorkspaceData, WorkspaceGeneralTab, type WorkspaceGeneralTabProps, type WorkspaceInvite, WorkspaceListTab, type WorkspaceMember, WorkspaceModal, WorkspaceTab, type WorkspaceUsageResponse, countLabel, resolveSettingsTabFromPath, useSettingsAdapters, userLanguageLabel };
package/dist/index.js CHANGED
@@ -1511,7 +1511,11 @@ var TAB_LABELS = {
1511
1511
  organizationWorkspaces: "Workspaces",
1512
1512
  organizationDomains: "Domains & requests",
1513
1513
  referral: "Referral",
1514
- billing: "Billing",
1514
+ /* "Billing & usage", not "Billing". The tab has held usage history as well
1515
+ as the plan and invoices since the credits work, and hosts had started
1516
+ saying "Billing & usage" in their own rails while this said "Billing" —
1517
+ so the nav item and the thing it opened disagreed by a word. */
1518
+ billing: "Billing & usage",
1515
1519
  apikey: "API Keys"
1516
1520
  };
1517
1521
  var TAB_DESCRIPTIONS = {
@@ -9171,6 +9175,7 @@ function BillingContent({
9171
9175
  fetchBillingOverview();
9172
9176
  fetchUserMap();
9173
9177
  }, [fetchBillingOverview, fetchUserMap]);
9178
+ const usage = workspace.current?.usage ?? null;
9174
9179
  (0, import_react14.useEffect)(() => {
9175
9180
  void logBillingEvent("billing_page_viewed", "Billing page viewed", {
9176
9181
  action: "view"
@@ -9478,6 +9483,28 @@ function BillingContent({
9478
9483
  ]
9479
9484
  }
9480
9485
  ),
9486
+ usage ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
9487
+ "div",
9488
+ {
9489
+ className: "grid shrink-0 w-full",
9490
+ style: {
9491
+ gap: "var(--spacing-6xl)",
9492
+ gridTemplateColumns: "repeat(auto-fit, minmax(18rem, 1fr))"
9493
+ },
9494
+ children: [
9495
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_ui9.ScUsageMeterCard, { kind: "storage", plan: usage.plan, status: usage.storage }),
9496
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
9497
+ import_ui9.ScUsageMeterCard,
9498
+ {
9499
+ kind: "bandwidth",
9500
+ plan: usage.plan,
9501
+ status: usage.bandwidth,
9502
+ footnote: `This billing month \xB7 resets ${new Date(usage.period.to).toLocaleDateString(void 0, { day: "numeric", month: "short" })}`
9503
+ }
9504
+ )
9505
+ ]
9506
+ }
9507
+ ) : null,
9481
9508
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("div", { className: "flex items-center justify-between shrink-0 w-full", children: [
9482
9509
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(BillingTabBar, { activeTab, onTabChange: setActiveTab }),
9483
9510
  /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(
@@ -10968,194 +10995,202 @@ function ProfileTab() {
10968
10995
  }
10969
10996
  auth.clearAuth();
10970
10997
  };
10971
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10998
+ return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10972
10999
  "div",
10973
11000
  {
10974
11001
  className: "flex flex-col items-start flex-1 min-w-0",
10975
11002
  style: { gap: "var(--spacing-3xl)" },
10976
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10977
- "div",
10978
- {
10979
- className: "flex items-start w-full",
10980
- style: {
10981
- backgroundColor: "var(--alias-surface-base)",
10982
- borderRadius: "var(--radius-3xl)",
10983
- border: "1px solid var(--alias-border-subtle)",
10984
- padding: "var(--spacing-6xl)",
10985
- gap: "var(--spacing-6xl)"
10986
- },
10987
- children: [
10988
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
10989
- "div",
10990
- {
10991
- className: "flex flex-col items-center shrink-0",
10992
- style: { gap: "var(--spacing-md)", width: 120 },
10993
- children: [
10994
- profileImage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
10995
- "img",
10996
- {
10997
- src: profileImage,
10998
- alt: "Profile",
10999
- style: {
11000
- width: 100,
11001
- height: 100,
11002
- borderRadius: "var(--radius-full)",
11003
- objectFit: "cover",
11004
- flexShrink: 0
11005
- }
11006
- }
11007
- ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11008
- "div",
11009
- {
11010
- "aria-label": "Profile",
11011
- className: "flex items-center justify-center",
11012
- style: {
11013
- width: 100,
11014
- height: 100,
11015
- borderRadius: "var(--radius-full)",
11016
- backgroundColor: "var(--alias-surface-raised)",
11017
- border: "1px solid var(--alias-border-subtle)",
11018
- flexShrink: 0
11019
- },
11020
- children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11021
- "span",
11022
- {
11023
- style: {
11024
- color: "var(--alias-text---icons-primary)",
11025
- fontFamily: "var(--font-family-font-family-display)",
11026
- fontSize: 34,
11027
- fontWeight: 600,
11028
- lineHeight: "34px"
11029
- },
11030
- children: profileInitial
11003
+ children: [
11004
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11005
+ "div",
11006
+ {
11007
+ className: "flex items-start w-full",
11008
+ style: {
11009
+ backgroundColor: "var(--alias-surface-base)",
11010
+ borderRadius: "var(--radius-3xl)",
11011
+ border: "1px solid var(--alias-border-subtle)",
11012
+ padding: "var(--spacing-6xl)",
11013
+ gap: "var(--spacing-6xl)"
11014
+ },
11015
+ children: [
11016
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11017
+ "div",
11018
+ {
11019
+ className: "flex flex-col items-center shrink-0",
11020
+ style: { gap: "var(--spacing-md)", width: 120 },
11021
+ children: [
11022
+ profileImage ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11023
+ "img",
11024
+ {
11025
+ src: profileImage,
11026
+ alt: "Profile",
11027
+ style: {
11028
+ width: 100,
11029
+ height: 100,
11030
+ borderRadius: "var(--radius-full)",
11031
+ objectFit: "cover",
11032
+ flexShrink: 0
11031
11033
  }
11032
- )
11033
- }
11034
- ),
11035
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11036
- "input",
11037
- {
11038
- ref: fileInputRef,
11039
- type: "file",
11040
- accept: "image/*",
11041
- style: { display: "none" },
11042
- onChange: handleImageChange
11043
- }
11044
- ),
11045
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-center", style: { gap: 10 }, children: [
11046
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11047
- import_ui13.ScButton,
11034
+ }
11035
+ ) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11036
+ "div",
11048
11037
  {
11049
- icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons12.SiconUpload, { className: "w-5 h-5", color: PRIMARY_COLOR3 }),
11050
- styleVariant: "icon-only",
11051
- variant: "tertiary",
11052
- size: "md",
11053
- state: disableAllActions ? "disabled" : "default",
11054
- onClick: handleUploadClick
11038
+ "aria-label": "Profile",
11039
+ className: "flex items-center justify-center",
11040
+ style: {
11041
+ width: 100,
11042
+ height: 100,
11043
+ borderRadius: "var(--radius-full)",
11044
+ backgroundColor: "var(--alias-surface-raised)",
11045
+ border: "1px solid var(--alias-border-subtle)",
11046
+ flexShrink: 0
11047
+ },
11048
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11049
+ "span",
11050
+ {
11051
+ style: {
11052
+ color: "var(--alias-text---icons-primary)",
11053
+ fontFamily: "var(--font-family-font-family-display)",
11054
+ fontSize: 34,
11055
+ fontWeight: 600,
11056
+ lineHeight: "34px"
11057
+ },
11058
+ children: profileInitial
11059
+ }
11060
+ )
11055
11061
  }
11056
11062
  ),
11057
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_ui11.ScVDivider, {}),
11058
11063
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11059
- import_ui13.ScButton,
11064
+ "input",
11060
11065
  {
11061
- icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11062
- import_icons12.SiconDelete,
11063
- {
11064
- className: "w-5 h-5",
11065
- color: "var(--primitives-error-500)"
11066
- }
11067
- ),
11068
- styleVariant: "icon-only",
11069
- variant: "tertiary",
11070
- size: "md",
11071
- state: disableAllActions || !profileImage ? "disabled" : "default",
11072
- onClick: handleDeleteImage
11066
+ ref: fileInputRef,
11067
+ type: "file",
11068
+ accept: "image/*",
11069
+ style: { display: "none" },
11070
+ onChange: handleImageChange
11071
+ }
11072
+ ),
11073
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11074
+ "div",
11075
+ {
11076
+ className: "flex flex-col items-stretch w-full",
11077
+ style: { gap: "var(--spacing-md)" },
11078
+ children: [
11079
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11080
+ import_ui13.ScButton,
11081
+ {
11082
+ text: "Upload photo",
11083
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons12.SiconUpload, { className: "w-5 h-5", color: PRIMARY_COLOR3 }),
11084
+ styleVariant: "icon-left",
11085
+ variant: "outline",
11086
+ size: "md",
11087
+ state: disableAllActions ? "disabled" : "default",
11088
+ onClick: handleUploadClick
11089
+ }
11090
+ ),
11091
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11092
+ import_ui13.ScButton,
11093
+ {
11094
+ text: "Remove photo",
11095
+ icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11096
+ import_icons12.SiconDelete,
11097
+ {
11098
+ className: "w-5 h-5",
11099
+ color: PRIMARY_COLOR3
11100
+ }
11101
+ ),
11102
+ styleVariant: "icon-left",
11103
+ variant: "outline",
11104
+ size: "md",
11105
+ state: disableAllActions || !profileImage ? "disabled" : "default",
11106
+ onClick: handleDeleteImage
11107
+ }
11108
+ )
11109
+ ]
11073
11110
  }
11074
11111
  )
11075
- ] })
11076
- ]
11077
- }
11078
- ),
11079
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11080
- "div",
11081
- {
11082
- className: "shrink-0",
11083
- style: {
11084
- width: 0,
11085
- alignSelf: "stretch",
11086
- borderLeft: "0.5px solid var(--alias-border-divider)"
11112
+ ]
11087
11113
  }
11088
- }
11089
- ),
11090
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11091
- "div",
11092
- {
11093
- className: "flex flex-col flex-1 min-w-0",
11094
- style: { gap: "var(--spacing-3xl)" },
11095
- children: [
11096
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11097
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", style: { overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11114
+ ),
11115
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11116
+ "div",
11117
+ {
11118
+ className: "shrink-0",
11119
+ style: {
11120
+ width: 0,
11121
+ alignSelf: "stretch",
11122
+ borderLeft: "0.5px solid var(--alias-border-divider)"
11123
+ }
11124
+ }
11125
+ ),
11126
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11127
+ "div",
11128
+ {
11129
+ className: "flex flex-col flex-1 min-w-0",
11130
+ style: { gap: "var(--spacing-3xl)" },
11131
+ children: [
11132
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11133
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", style: { overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11134
+ import_ui12.ScTextField,
11135
+ {
11136
+ label: "Full Name",
11137
+ labelGroup: "label",
11138
+ state: "filled",
11139
+ placeholderFilled: "Enter your name",
11140
+ tfGroup: "none",
11141
+ className: "sc-text-field-full-width",
11142
+ style: { width: "100%" },
11143
+ value: fullName,
11144
+ onChange: (e) => setFullName(e.target.value)
11145
+ }
11146
+ ) }),
11147
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11148
+ SpecializationDropdown,
11149
+ {
11150
+ value: selectedSpec,
11151
+ onChange: setSelectedSpec,
11152
+ disabled: disableAllActions
11153
+ }
11154
+ ) })
11155
+ ] }),
11156
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11157
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11158
+ LanguageDropdown,
11159
+ {
11160
+ value: selectedLanguage,
11161
+ onChange: setSelectedLanguage,
11162
+ disabled: disableAllActions
11163
+ }
11164
+ ) }),
11165
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0" })
11166
+ ] }),
11167
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-full", style: { overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11098
11168
  import_ui12.ScTextField,
11099
11169
  {
11100
- label: "Full Name",
11170
+ label: "Email ID",
11101
11171
  labelGroup: "label",
11102
- state: "filled",
11103
- placeholderFilled: "Enter your name",
11104
- tfGroup: "none",
11172
+ state: "default",
11173
+ value: user?.email ?? "",
11174
+ placeholderFilled: user?.email ?? "chris@kepler.com",
11175
+ tfGroup: "icon-right",
11176
+ tfRightIcon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11177
+ import_icons12.SiconLock,
11178
+ {
11179
+ className: "w-6 h-6",
11180
+ color: "var(--alias-text---icons-primary)"
11181
+ }
11182
+ ),
11105
11183
  className: "sc-text-field-full-width",
11106
11184
  style: { width: "100%" },
11107
- value: fullName,
11108
- onChange: (e) => setFullName(e.target.value)
11185
+ readOnly: true
11109
11186
  }
11110
11187
  ) }),
11111
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11112
- SpecializationDropdown,
11113
- {
11114
- value: selectedSpec,
11115
- onChange: setSelectedSpec,
11116
- disabled: disableAllActions
11117
- }
11118
- ) })
11119
- ] }),
11120
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11121
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11122
- LanguageDropdown,
11188
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11189
+ "div",
11123
11190
  {
11124
- value: selectedLanguage,
11125
- onChange: setSelectedLanguage,
11126
- disabled: disableAllActions
11127
- }
11128
- ) }),
11129
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex-1 min-w-0" })
11130
- ] }),
11131
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "w-full", style: { overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11132
- import_ui12.ScTextField,
11133
- {
11134
- label: "Email ID",
11135
- labelGroup: "label",
11136
- state: "default",
11137
- value: user?.email ?? "",
11138
- placeholderFilled: user?.email ?? "chris@kepler.com",
11139
- tfGroup: "icon-right",
11140
- tfRightIcon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11141
- import_icons12.SiconLock,
11142
- {
11143
- className: "w-6 h-6",
11144
- color: "var(--alias-text---icons-primary)"
11145
- }
11146
- ),
11147
- className: "sc-text-field-full-width",
11148
- style: { width: "100%" },
11149
- readOnly: true
11150
- }
11151
- ) }),
11152
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11153
- "div",
11154
- {
11155
- className: "flex items-center w-full",
11156
- style: { gap: "var(--spacing-3xl)", justifyContent: "flex-end", paddingTop: "var(--spacing-md)" },
11157
- children: [
11158
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11191
+ className: "flex items-center w-full",
11192
+ style: { justifyContent: "flex-end", paddingTop: "var(--spacing-md)" },
11193
+ children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11159
11194
  import_ui13.ScButton,
11160
11195
  {
11161
11196
  text: saving ? "Saving..." : "Save changes",
@@ -11164,25 +11199,69 @@ function ProfileTab() {
11164
11199
  state: saving || !dirty ? "disabled" : "default",
11165
11200
  onClick: handleSave
11166
11201
  }
11167
- ),
11168
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11169
- import_ui13.ScButton,
11170
- {
11171
- text: "Logout",
11172
- variant: "error",
11173
- size: "md",
11174
- onClick: handleLogout
11175
- }
11176
11202
  )
11177
- ]
11178
- }
11179
- )
11180
- ]
11181
- }
11182
- )
11183
- ]
11184
- }
11185
- )
11203
+ }
11204
+ )
11205
+ ]
11206
+ }
11207
+ )
11208
+ ]
11209
+ }
11210
+ ),
11211
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11212
+ "div",
11213
+ {
11214
+ className: "flex items-center w-full",
11215
+ style: {
11216
+ backgroundColor: "var(--alias-surface-base)",
11217
+ borderRadius: "var(--radius-3xl)",
11218
+ border: "1px solid var(--alias-border-subtle)",
11219
+ padding: "var(--spacing-6xl)",
11220
+ gap: "var(--spacing-3xl)"
11221
+ },
11222
+ children: [
11223
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col min-w-0 flex-1", style: { gap: "var(--spacing-xs)" }, children: [
11224
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11225
+ "span",
11226
+ {
11227
+ style: {
11228
+ fontFamily: "var(--font-family-font-family-body)",
11229
+ fontSize: "var(--font-size-font-size-md)",
11230
+ fontWeight: 600,
11231
+ lineHeight: "var(--line-height-line-height-md)",
11232
+ color: "var(--alias-text---icons-primary)"
11233
+ },
11234
+ children: "Session"
11235
+ }
11236
+ ),
11237
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11238
+ "span",
11239
+ {
11240
+ className: "truncate",
11241
+ style: {
11242
+ fontFamily: "var(--font-family-font-family-body)",
11243
+ fontSize: "var(--font-size-font-size-sm)",
11244
+ lineHeight: "var(--line-height-line-height-sm)",
11245
+ color: "var(--alias-text---icons-muted)"
11246
+ },
11247
+ title: user?.email ?? void 0,
11248
+ children: user?.email ? `Signed in as ${user.email}` : "Signed in"
11249
+ }
11250
+ )
11251
+ ] }),
11252
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
11253
+ import_ui13.ScButton,
11254
+ {
11255
+ text: "Log out",
11256
+ variant: "outline",
11257
+ size: "md",
11258
+ onClick: handleLogout
11259
+ }
11260
+ )
11261
+ ]
11262
+ }
11263
+ )
11264
+ ]
11186
11265
  }
11187
11266
  );
11188
11267
  }
@@ -11401,6 +11480,7 @@ function SettingsContent({
11401
11480
  adapters,
11402
11481
  activeTab = "profile",
11403
11482
  onClose,
11483
+ onBack,
11404
11484
  hiddenApps
11405
11485
  }) {
11406
11486
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(SettingsAdaptersProvider, { adapters, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
@@ -11408,6 +11488,7 @@ function SettingsContent({
11408
11488
  {
11409
11489
  activeTab,
11410
11490
  onClose: onClose ?? adapters.navigation.close,
11491
+ onBack: onBack === null ? null : onBack ?? adapters.navigation.back,
11411
11492
  hiddenApps
11412
11493
  }
11413
11494
  ) });
@@ -11415,6 +11496,7 @@ function SettingsContent({
11415
11496
  function SettingsContentInner({
11416
11497
  activeTab,
11417
11498
  onClose,
11499
+ onBack,
11418
11500
  hiddenApps
11419
11501
  }) {
11420
11502
  const {
@@ -11785,6 +11867,33 @@ function SettingsContentInner({
11785
11867
  width: "100%"
11786
11868
  },
11787
11869
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex flex-col w-full flex-1 min-h-0", style: { gap: 20, paddingTop: 16 }, children: [
11870
+ onBack !== null && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { className: "flex items-center shrink-0", style: { paddingLeft: 20 }, children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11871
+ "button",
11872
+ {
11873
+ type: "button",
11874
+ "aria-label": "Back to previous screen",
11875
+ className: "flex items-center cursor-pointer",
11876
+ style: {
11877
+ gap: "var(--spacing-sm)",
11878
+ padding: "var(--spacing-xs) var(--spacing-md)",
11879
+ marginLeft: "calc(var(--spacing-md) * -1)",
11880
+ border: "1px solid transparent",
11881
+ borderRadius: "var(--radius-xl)",
11882
+ background: "transparent",
11883
+ height: 32,
11884
+ color: "var(--alias-text---icons-muted)",
11885
+ fontFamily: "var(--font-family-font-family-body)",
11886
+ fontSize: "var(--font-size-font-size-sm)",
11887
+ fontWeight: 500,
11888
+ lineHeight: "var(--line-height-line-height-sm)"
11889
+ },
11890
+ onClick: () => onBack ? onBack() : window.history.back(),
11891
+ children: [
11892
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons12.SiconLeft, { className: "w-4 h-4 shrink-0", color: "var(--alias-text---icons-muted)" }),
11893
+ "Back"
11894
+ ]
11895
+ }
11896
+ ) }),
11788
11897
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
11789
11898
  "div",
11790
11899
  {
package/dist/index.mjs CHANGED
@@ -7,7 +7,6 @@ import {
7
7
  } from "react";
8
8
  import {
9
9
  ScSidebarMenu,
10
- ScVDivider,
11
10
  ScHDivider,
12
11
  ScMenuOptions
13
12
  } from "@streamoid/ui";
@@ -1476,7 +1475,11 @@ var TAB_LABELS = {
1476
1475
  organizationWorkspaces: "Workspaces",
1477
1476
  organizationDomains: "Domains & requests",
1478
1477
  referral: "Referral",
1479
- billing: "Billing",
1478
+ /* "Billing & usage", not "Billing". The tab has held usage history as well
1479
+ as the plan and invoices since the credits work, and hosts had started
1480
+ saying "Billing & usage" in their own rails while this said "Billing" —
1481
+ so the nav item and the thing it opened disagreed by a word. */
1482
+ billing: "Billing & usage",
1480
1483
  apikey: "API Keys"
1481
1484
  };
1482
1485
  var TAB_DESCRIPTIONS = {
@@ -6953,7 +6956,8 @@ import {
6953
6956
  ScBillingHistoryTableList,
6954
6957
  ScHeader,
6955
6958
  ScPlanCard,
6956
- ScPlanComparison
6959
+ ScPlanComparison,
6960
+ ScUsageMeterCard
6957
6961
  } from "@streamoid/ui";
6958
6962
  import {
6959
6963
  SiconDownload,
@@ -9174,6 +9178,7 @@ function BillingContent({
9174
9178
  fetchBillingOverview();
9175
9179
  fetchUserMap();
9176
9180
  }, [fetchBillingOverview, fetchUserMap]);
9181
+ const usage = workspace.current?.usage ?? null;
9177
9182
  useEffect10(() => {
9178
9183
  void logBillingEvent("billing_page_viewed", "Billing page viewed", {
9179
9184
  action: "view"
@@ -9481,6 +9486,28 @@ function BillingContent({
9481
9486
  ]
9482
9487
  }
9483
9488
  ),
9489
+ usage ? /* @__PURE__ */ jsxs16(
9490
+ "div",
9491
+ {
9492
+ className: "grid shrink-0 w-full",
9493
+ style: {
9494
+ gap: "var(--spacing-6xl)",
9495
+ gridTemplateColumns: "repeat(auto-fit, minmax(18rem, 1fr))"
9496
+ },
9497
+ children: [
9498
+ /* @__PURE__ */ jsx18(ScUsageMeterCard, { kind: "storage", plan: usage.plan, status: usage.storage }),
9499
+ /* @__PURE__ */ jsx18(
9500
+ ScUsageMeterCard,
9501
+ {
9502
+ kind: "bandwidth",
9503
+ plan: usage.plan,
9504
+ status: usage.bandwidth,
9505
+ footnote: `This billing month \xB7 resets ${new Date(usage.period.to).toLocaleDateString(void 0, { day: "numeric", month: "short" })}`
9506
+ }
9507
+ )
9508
+ ]
9509
+ }
9510
+ ) : null,
9484
9511
  /* @__PURE__ */ jsxs16("div", { className: "flex items-center justify-between shrink-0 w-full", children: [
9485
9512
  /* @__PURE__ */ jsx18(BillingTabBar, { activeTab, onTabChange: setActiveTab }),
9486
9513
  /* @__PURE__ */ jsxs16(
@@ -10977,194 +11004,202 @@ function ProfileTab() {
10977
11004
  }
10978
11005
  auth.clearAuth();
10979
11006
  };
10980
- return /* @__PURE__ */ jsx20(
11007
+ return /* @__PURE__ */ jsxs18(
10981
11008
  "div",
10982
11009
  {
10983
11010
  className: "flex flex-col items-start flex-1 min-w-0",
10984
11011
  style: { gap: "var(--spacing-3xl)" },
10985
- children: /* @__PURE__ */ jsxs18(
10986
- "div",
10987
- {
10988
- className: "flex items-start w-full",
10989
- style: {
10990
- backgroundColor: "var(--alias-surface-base)",
10991
- borderRadius: "var(--radius-3xl)",
10992
- border: "1px solid var(--alias-border-subtle)",
10993
- padding: "var(--spacing-6xl)",
10994
- gap: "var(--spacing-6xl)"
10995
- },
10996
- children: [
10997
- /* @__PURE__ */ jsxs18(
10998
- "div",
10999
- {
11000
- className: "flex flex-col items-center shrink-0",
11001
- style: { gap: "var(--spacing-md)", width: 120 },
11002
- children: [
11003
- profileImage ? /* @__PURE__ */ jsx20(
11004
- "img",
11005
- {
11006
- src: profileImage,
11007
- alt: "Profile",
11008
- style: {
11009
- width: 100,
11010
- height: 100,
11011
- borderRadius: "var(--radius-full)",
11012
- objectFit: "cover",
11013
- flexShrink: 0
11014
- }
11015
- }
11016
- ) : /* @__PURE__ */ jsx20(
11017
- "div",
11018
- {
11019
- "aria-label": "Profile",
11020
- className: "flex items-center justify-center",
11021
- style: {
11022
- width: 100,
11023
- height: 100,
11024
- borderRadius: "var(--radius-full)",
11025
- backgroundColor: "var(--alias-surface-raised)",
11026
- border: "1px solid var(--alias-border-subtle)",
11027
- flexShrink: 0
11028
- },
11029
- children: /* @__PURE__ */ jsx20(
11030
- "span",
11031
- {
11032
- style: {
11033
- color: "var(--alias-text---icons-primary)",
11034
- fontFamily: "var(--font-family-font-family-display)",
11035
- fontSize: 34,
11036
- fontWeight: 600,
11037
- lineHeight: "34px"
11038
- },
11039
- children: profileInitial
11012
+ children: [
11013
+ /* @__PURE__ */ jsxs18(
11014
+ "div",
11015
+ {
11016
+ className: "flex items-start w-full",
11017
+ style: {
11018
+ backgroundColor: "var(--alias-surface-base)",
11019
+ borderRadius: "var(--radius-3xl)",
11020
+ border: "1px solid var(--alias-border-subtle)",
11021
+ padding: "var(--spacing-6xl)",
11022
+ gap: "var(--spacing-6xl)"
11023
+ },
11024
+ children: [
11025
+ /* @__PURE__ */ jsxs18(
11026
+ "div",
11027
+ {
11028
+ className: "flex flex-col items-center shrink-0",
11029
+ style: { gap: "var(--spacing-md)", width: 120 },
11030
+ children: [
11031
+ profileImage ? /* @__PURE__ */ jsx20(
11032
+ "img",
11033
+ {
11034
+ src: profileImage,
11035
+ alt: "Profile",
11036
+ style: {
11037
+ width: 100,
11038
+ height: 100,
11039
+ borderRadius: "var(--radius-full)",
11040
+ objectFit: "cover",
11041
+ flexShrink: 0
11040
11042
  }
11041
- )
11042
- }
11043
- ),
11044
- /* @__PURE__ */ jsx20(
11045
- "input",
11046
- {
11047
- ref: fileInputRef,
11048
- type: "file",
11049
- accept: "image/*",
11050
- style: { display: "none" },
11051
- onChange: handleImageChange
11052
- }
11053
- ),
11054
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-center", style: { gap: 10 }, children: [
11055
- /* @__PURE__ */ jsx20(
11056
- ScButton7,
11043
+ }
11044
+ ) : /* @__PURE__ */ jsx20(
11045
+ "div",
11057
11046
  {
11058
- icon: /* @__PURE__ */ jsx20(SiconUpload2, { className: "w-5 h-5", color: PRIMARY_COLOR3 }),
11059
- styleVariant: "icon-only",
11060
- variant: "tertiary",
11061
- size: "md",
11062
- state: disableAllActions ? "disabled" : "default",
11063
- onClick: handleUploadClick
11047
+ "aria-label": "Profile",
11048
+ className: "flex items-center justify-center",
11049
+ style: {
11050
+ width: 100,
11051
+ height: 100,
11052
+ borderRadius: "var(--radius-full)",
11053
+ backgroundColor: "var(--alias-surface-raised)",
11054
+ border: "1px solid var(--alias-border-subtle)",
11055
+ flexShrink: 0
11056
+ },
11057
+ children: /* @__PURE__ */ jsx20(
11058
+ "span",
11059
+ {
11060
+ style: {
11061
+ color: "var(--alias-text---icons-primary)",
11062
+ fontFamily: "var(--font-family-font-family-display)",
11063
+ fontSize: 34,
11064
+ fontWeight: 600,
11065
+ lineHeight: "34px"
11066
+ },
11067
+ children: profileInitial
11068
+ }
11069
+ )
11064
11070
  }
11065
11071
  ),
11066
- /* @__PURE__ */ jsx20(ScVDivider, {}),
11067
11072
  /* @__PURE__ */ jsx20(
11068
- ScButton7,
11073
+ "input",
11069
11074
  {
11070
- icon: /* @__PURE__ */ jsx20(
11071
- SiconDelete,
11072
- {
11073
- className: "w-5 h-5",
11074
- color: "var(--primitives-error-500)"
11075
- }
11076
- ),
11077
- styleVariant: "icon-only",
11078
- variant: "tertiary",
11079
- size: "md",
11080
- state: disableAllActions || !profileImage ? "disabled" : "default",
11081
- onClick: handleDeleteImage
11075
+ ref: fileInputRef,
11076
+ type: "file",
11077
+ accept: "image/*",
11078
+ style: { display: "none" },
11079
+ onChange: handleImageChange
11080
+ }
11081
+ ),
11082
+ /* @__PURE__ */ jsxs18(
11083
+ "div",
11084
+ {
11085
+ className: "flex flex-col items-stretch w-full",
11086
+ style: { gap: "var(--spacing-md)" },
11087
+ children: [
11088
+ /* @__PURE__ */ jsx20(
11089
+ ScButton7,
11090
+ {
11091
+ text: "Upload photo",
11092
+ icon: /* @__PURE__ */ jsx20(SiconUpload2, { className: "w-5 h-5", color: PRIMARY_COLOR3 }),
11093
+ styleVariant: "icon-left",
11094
+ variant: "outline",
11095
+ size: "md",
11096
+ state: disableAllActions ? "disabled" : "default",
11097
+ onClick: handleUploadClick
11098
+ }
11099
+ ),
11100
+ /* @__PURE__ */ jsx20(
11101
+ ScButton7,
11102
+ {
11103
+ text: "Remove photo",
11104
+ icon: /* @__PURE__ */ jsx20(
11105
+ SiconDelete,
11106
+ {
11107
+ className: "w-5 h-5",
11108
+ color: PRIMARY_COLOR3
11109
+ }
11110
+ ),
11111
+ styleVariant: "icon-left",
11112
+ variant: "outline",
11113
+ size: "md",
11114
+ state: disableAllActions || !profileImage ? "disabled" : "default",
11115
+ onClick: handleDeleteImage
11116
+ }
11117
+ )
11118
+ ]
11082
11119
  }
11083
11120
  )
11084
- ] })
11085
- ]
11086
- }
11087
- ),
11088
- /* @__PURE__ */ jsx20(
11089
- "div",
11090
- {
11091
- className: "shrink-0",
11092
- style: {
11093
- width: 0,
11094
- alignSelf: "stretch",
11095
- borderLeft: "0.5px solid var(--alias-border-divider)"
11121
+ ]
11096
11122
  }
11097
- }
11098
- ),
11099
- /* @__PURE__ */ jsxs18(
11100
- "div",
11101
- {
11102
- className: "flex flex-col flex-1 min-w-0",
11103
- style: { gap: "var(--spacing-3xl)" },
11104
- children: [
11105
- /* @__PURE__ */ jsxs18("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11106
- /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx20(
11123
+ ),
11124
+ /* @__PURE__ */ jsx20(
11125
+ "div",
11126
+ {
11127
+ className: "shrink-0",
11128
+ style: {
11129
+ width: 0,
11130
+ alignSelf: "stretch",
11131
+ borderLeft: "0.5px solid var(--alias-border-divider)"
11132
+ }
11133
+ }
11134
+ ),
11135
+ /* @__PURE__ */ jsxs18(
11136
+ "div",
11137
+ {
11138
+ className: "flex flex-col flex-1 min-w-0",
11139
+ style: { gap: "var(--spacing-3xl)" },
11140
+ children: [
11141
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11142
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx20(
11143
+ ScTextField,
11144
+ {
11145
+ label: "Full Name",
11146
+ labelGroup: "label",
11147
+ state: "filled",
11148
+ placeholderFilled: "Enter your name",
11149
+ tfGroup: "none",
11150
+ className: "sc-text-field-full-width",
11151
+ style: { width: "100%" },
11152
+ value: fullName,
11153
+ onChange: (e) => setFullName(e.target.value)
11154
+ }
11155
+ ) }),
11156
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20(
11157
+ SpecializationDropdown,
11158
+ {
11159
+ value: selectedSpec,
11160
+ onChange: setSelectedSpec,
11161
+ disabled: disableAllActions
11162
+ }
11163
+ ) })
11164
+ ] }),
11165
+ /* @__PURE__ */ jsxs18("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11166
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20(
11167
+ LanguageDropdown,
11168
+ {
11169
+ value: selectedLanguage,
11170
+ onChange: setSelectedLanguage,
11171
+ disabled: disableAllActions
11172
+ }
11173
+ ) }),
11174
+ /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0" })
11175
+ ] }),
11176
+ /* @__PURE__ */ jsx20("div", { className: "w-full", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx20(
11107
11177
  ScTextField,
11108
11178
  {
11109
- label: "Full Name",
11179
+ label: "Email ID",
11110
11180
  labelGroup: "label",
11111
- state: "filled",
11112
- placeholderFilled: "Enter your name",
11113
- tfGroup: "none",
11181
+ state: "default",
11182
+ value: user?.email ?? "",
11183
+ placeholderFilled: user?.email ?? "chris@kepler.com",
11184
+ tfGroup: "icon-right",
11185
+ tfRightIcon: /* @__PURE__ */ jsx20(
11186
+ SiconLock,
11187
+ {
11188
+ className: "w-6 h-6",
11189
+ color: "var(--alias-text---icons-primary)"
11190
+ }
11191
+ ),
11114
11192
  className: "sc-text-field-full-width",
11115
11193
  style: { width: "100%" },
11116
- value: fullName,
11117
- onChange: (e) => setFullName(e.target.value)
11194
+ readOnly: true
11118
11195
  }
11119
11196
  ) }),
11120
- /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20(
11121
- SpecializationDropdown,
11122
- {
11123
- value: selectedSpec,
11124
- onChange: setSelectedSpec,
11125
- disabled: disableAllActions
11126
- }
11127
- ) })
11128
- ] }),
11129
- /* @__PURE__ */ jsxs18("div", { className: "flex items-start w-full", style: { gap: "var(--spacing-3xl)" }, children: [
11130
- /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0", children: /* @__PURE__ */ jsx20(
11131
- LanguageDropdown,
11197
+ /* @__PURE__ */ jsx20(
11198
+ "div",
11132
11199
  {
11133
- value: selectedLanguage,
11134
- onChange: setSelectedLanguage,
11135
- disabled: disableAllActions
11136
- }
11137
- ) }),
11138
- /* @__PURE__ */ jsx20("div", { className: "flex-1 min-w-0" })
11139
- ] }),
11140
- /* @__PURE__ */ jsx20("div", { className: "w-full", style: { overflow: "hidden" }, children: /* @__PURE__ */ jsx20(
11141
- ScTextField,
11142
- {
11143
- label: "Email ID",
11144
- labelGroup: "label",
11145
- state: "default",
11146
- value: user?.email ?? "",
11147
- placeholderFilled: user?.email ?? "chris@kepler.com",
11148
- tfGroup: "icon-right",
11149
- tfRightIcon: /* @__PURE__ */ jsx20(
11150
- SiconLock,
11151
- {
11152
- className: "w-6 h-6",
11153
- color: "var(--alias-text---icons-primary)"
11154
- }
11155
- ),
11156
- className: "sc-text-field-full-width",
11157
- style: { width: "100%" },
11158
- readOnly: true
11159
- }
11160
- ) }),
11161
- /* @__PURE__ */ jsxs18(
11162
- "div",
11163
- {
11164
- className: "flex items-center w-full",
11165
- style: { gap: "var(--spacing-3xl)", justifyContent: "flex-end", paddingTop: "var(--spacing-md)" },
11166
- children: [
11167
- /* @__PURE__ */ jsx20(
11200
+ className: "flex items-center w-full",
11201
+ style: { justifyContent: "flex-end", paddingTop: "var(--spacing-md)" },
11202
+ children: /* @__PURE__ */ jsx20(
11168
11203
  ScButton7,
11169
11204
  {
11170
11205
  text: saving ? "Saving..." : "Save changes",
@@ -11173,25 +11208,69 @@ function ProfileTab() {
11173
11208
  state: saving || !dirty ? "disabled" : "default",
11174
11209
  onClick: handleSave
11175
11210
  }
11176
- ),
11177
- /* @__PURE__ */ jsx20(
11178
- ScButton7,
11179
- {
11180
- text: "Logout",
11181
- variant: "error",
11182
- size: "md",
11183
- onClick: handleLogout
11184
- }
11185
11211
  )
11186
- ]
11187
- }
11188
- )
11189
- ]
11190
- }
11191
- )
11192
- ]
11193
- }
11194
- )
11212
+ }
11213
+ )
11214
+ ]
11215
+ }
11216
+ )
11217
+ ]
11218
+ }
11219
+ ),
11220
+ /* @__PURE__ */ jsxs18(
11221
+ "div",
11222
+ {
11223
+ className: "flex items-center w-full",
11224
+ style: {
11225
+ backgroundColor: "var(--alias-surface-base)",
11226
+ borderRadius: "var(--radius-3xl)",
11227
+ border: "1px solid var(--alias-border-subtle)",
11228
+ padding: "var(--spacing-6xl)",
11229
+ gap: "var(--spacing-3xl)"
11230
+ },
11231
+ children: [
11232
+ /* @__PURE__ */ jsxs18("div", { className: "flex flex-col min-w-0 flex-1", style: { gap: "var(--spacing-xs)" }, children: [
11233
+ /* @__PURE__ */ jsx20(
11234
+ "span",
11235
+ {
11236
+ style: {
11237
+ fontFamily: "var(--font-family-font-family-body)",
11238
+ fontSize: "var(--font-size-font-size-md)",
11239
+ fontWeight: 600,
11240
+ lineHeight: "var(--line-height-line-height-md)",
11241
+ color: "var(--alias-text---icons-primary)"
11242
+ },
11243
+ children: "Session"
11244
+ }
11245
+ ),
11246
+ /* @__PURE__ */ jsx20(
11247
+ "span",
11248
+ {
11249
+ className: "truncate",
11250
+ style: {
11251
+ fontFamily: "var(--font-family-font-family-body)",
11252
+ fontSize: "var(--font-size-font-size-sm)",
11253
+ lineHeight: "var(--line-height-line-height-sm)",
11254
+ color: "var(--alias-text---icons-muted)"
11255
+ },
11256
+ title: user?.email ?? void 0,
11257
+ children: user?.email ? `Signed in as ${user.email}` : "Signed in"
11258
+ }
11259
+ )
11260
+ ] }),
11261
+ /* @__PURE__ */ jsx20(
11262
+ ScButton7,
11263
+ {
11264
+ text: "Log out",
11265
+ variant: "outline",
11266
+ size: "md",
11267
+ onClick: handleLogout
11268
+ }
11269
+ )
11270
+ ]
11271
+ }
11272
+ )
11273
+ ]
11195
11274
  }
11196
11275
  );
11197
11276
  }
@@ -11410,6 +11489,7 @@ function SettingsContent({
11410
11489
  adapters,
11411
11490
  activeTab = "profile",
11412
11491
  onClose,
11492
+ onBack,
11413
11493
  hiddenApps
11414
11494
  }) {
11415
11495
  return /* @__PURE__ */ jsx20(SettingsAdaptersProvider, { adapters, children: /* @__PURE__ */ jsx20(
@@ -11417,6 +11497,7 @@ function SettingsContent({
11417
11497
  {
11418
11498
  activeTab,
11419
11499
  onClose: onClose ?? adapters.navigation.close,
11500
+ onBack: onBack === null ? null : onBack ?? adapters.navigation.back,
11420
11501
  hiddenApps
11421
11502
  }
11422
11503
  ) });
@@ -11424,6 +11505,7 @@ function SettingsContent({
11424
11505
  function SettingsContentInner({
11425
11506
  activeTab,
11426
11507
  onClose,
11508
+ onBack,
11427
11509
  hiddenApps
11428
11510
  }) {
11429
11511
  const {
@@ -11794,6 +11876,33 @@ function SettingsContentInner({
11794
11876
  width: "100%"
11795
11877
  },
11796
11878
  children: /* @__PURE__ */ jsxs18("div", { className: "flex flex-col w-full flex-1 min-h-0", style: { gap: 20, paddingTop: 16 }, children: [
11879
+ onBack !== null && /* @__PURE__ */ jsx20("div", { className: "flex items-center shrink-0", style: { paddingLeft: 20 }, children: /* @__PURE__ */ jsxs18(
11880
+ "button",
11881
+ {
11882
+ type: "button",
11883
+ "aria-label": "Back to previous screen",
11884
+ className: "flex items-center cursor-pointer",
11885
+ style: {
11886
+ gap: "var(--spacing-sm)",
11887
+ padding: "var(--spacing-xs) var(--spacing-md)",
11888
+ marginLeft: "calc(var(--spacing-md) * -1)",
11889
+ border: "1px solid transparent",
11890
+ borderRadius: "var(--radius-xl)",
11891
+ background: "transparent",
11892
+ height: 32,
11893
+ color: "var(--alias-text---icons-muted)",
11894
+ fontFamily: "var(--font-family-font-family-body)",
11895
+ fontSize: "var(--font-size-font-size-sm)",
11896
+ fontWeight: 500,
11897
+ lineHeight: "var(--line-height-line-height-sm)"
11898
+ },
11899
+ onClick: () => onBack ? onBack() : window.history.back(),
11900
+ children: [
11901
+ /* @__PURE__ */ jsx20(SiconLeft3, { className: "w-4 h-4 shrink-0", color: "var(--alias-text---icons-muted)" }),
11902
+ "Back"
11903
+ ]
11904
+ }
11905
+ ) }),
11797
11906
  /* @__PURE__ */ jsxs18(
11798
11907
  "div",
11799
11908
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@streamoid/settings",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.mjs",
6
6
  "types": "./dist/index.d.ts",