@withpotter/components 0.13.0-next.124 → 0.13.0-next.59
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/billing/overview-tab.js +3 -4
- package/dist/billing/overview-tab.js.map +1 -1
- package/dist/billing/plans-tab.js +12 -6
- package/dist/billing/plans-tab.js.map +1 -1
- package/dist/charts/index.d.ts +1 -1
- package/dist/charts/index.js +1 -3
- package/dist/charts/index.js.map +1 -1
- package/dist/dashboard/activity-feed.d.ts +0 -2
- package/dist/dashboard/activity-feed.js +1 -4
- package/dist/dashboard/activity-feed.js.map +1 -1
- package/dist/dashboard/home/ask-controls.js +0 -1
- package/dist/dashboard/home/ask-controls.js.map +1 -1
- package/dist/dashboard/home/ask-mode-chip.js +4 -4
- package/dist/dashboard/home/ask-mode-chip.js.map +1 -1
- package/dist/dashboard/home/home-ask.js +3 -3
- package/dist/dashboard/home/home-ask.js.map +1 -1
- package/dist/dashboard/home/home-quick-actions.js +1 -9
- package/dist/dashboard/home/home-quick-actions.js.map +1 -1
- package/dist/dashboard/home/widgets/activity-widget.js +43 -56
- package/dist/dashboard/home/widgets/activity-widget.js.map +1 -1
- package/dist/dashboard/home/widgets/home-widgets.js +2 -3
- package/dist/dashboard/home/widgets/home-widgets.js.map +1 -1
- package/dist/dashboard/home/widgets/money-widgets.js +4 -9
- package/dist/dashboard/home/widgets/money-widgets.js.map +1 -1
- package/dist/dashboard/home/widgets/registry.d.ts +3 -6
- package/dist/dashboard/home/widgets/registry.js +2 -12
- package/dist/dashboard/home/widgets/registry.js.map +1 -1
- package/dist/dashboard/home/widgets/team-widget.js +3 -15
- package/dist/dashboard/home/widgets/team-widget.js.map +1 -1
- package/dist/dashboard/home/widgets/types.d.ts +1 -13
- package/dist/dashboard/home/widgets/types.js.map +1 -1
- package/dist/dashboard/home/widgets/use-home-layout.js +4 -9
- package/dist/dashboard/home/widgets/use-home-layout.js.map +1 -1
- package/dist/dashboard/home/widgets/website-widget.js +1 -9
- package/dist/dashboard/home/widgets/website-widget.js.map +1 -1
- package/dist/dashboard/page-transition.d.ts +0 -11
- package/dist/dashboard/page-transition.js +2 -9
- package/dist/dashboard/page-transition.js.map +1 -1
- package/dist/features/gift-card-artwork.js +1 -1
- package/dist/features/gift-card-artwork.js.map +1 -1
- package/dist/features/gift-cards/gift-cards-feature.js +518 -656
- package/dist/features/gift-cards/gift-cards-feature.js.map +1 -1
- package/dist/features/product-form.js +1 -1
- package/dist/features/product-form.js.map +1 -1
- package/dist/mobile/screens/billing-flows.js +6 -7
- package/dist/mobile/screens/billing-flows.js.map +1 -1
- package/dist/mobile/screens/billing.js +2 -2
- package/dist/mobile/screens/billing.js.map +1 -1
- package/dist/notifications-dropdown.js +1 -11
- package/dist/notifications-dropdown.js.map +1 -1
- package/dist/shell/notification-kinds.d.ts +2 -11
- package/dist/shell/notification-kinds.js +1 -16
- package/dist/shell/notification-kinds.js.map +1 -1
- package/dist/shell/notification-row.d.ts +2 -6
- package/dist/shell/notification-row.js +33 -59
- package/dist/shell/notification-row.js.map +1 -1
- package/dist/shell/product-switcher.js +0 -3
- package/dist/shell/product-switcher.js.map +1 -1
- package/dist/shell/settings-modal-context.d.ts +0 -2
- package/dist/shell/settings-modal-context.js +2 -4
- package/dist/shell/settings-modal-context.js.map +1 -1
- package/dist/shell/settings-panels.js +9 -29
- package/dist/shell/settings-panels.js.map +1 -1
- package/dist/shell/settings-rows.d.ts +2 -7
- package/dist/shell/settings-rows.js +36 -93
- package/dist/shell/settings-rows.js.map +1 -1
- package/dist/shell/shell.css +0 -192
- package/dist/shell/sidebar-footer.js +2 -6
- package/dist/shell/sidebar-footer.js.map +1 -1
- package/dist/shell/unified-settings-modal.d.ts +2 -3
- package/dist/shell/unified-settings-modal.js +74 -151
- package/dist/shell/unified-settings-modal.js.map +1 -1
- package/dist/sidebar/config.js +3 -19
- package/dist/sidebar/config.js.map +1 -1
- package/dist/sidebar/more-group.js +1 -1
- package/dist/sidebar/more-group.js.map +1 -1
- package/dist/sidebar/nav-renderers.js +0 -2
- package/dist/sidebar/nav-renderers.js.map +1 -1
- package/dist/sidebar/nav-section.js +3 -5
- package/dist/sidebar/nav-section.js.map +1 -1
- package/dist/sidebar/setup-progress.d.ts +1 -3
- package/dist/sidebar/setup-progress.js +2 -2
- package/dist/sidebar/setup-progress.js.map +1 -1
- package/dist/sidebar/spine-groups.js +1 -7
- package/dist/sidebar/spine-groups.js.map +1 -1
- package/dist/sidebar.js +5 -5
- package/dist/sidebar.js.map +1 -1
- package/dist/templates/template-live-thumb.js +5 -16
- package/dist/templates/template-live-thumb.js.map +1 -1
- package/package.json +5 -5
- package/dist/dashboard/activity-paid.d.ts +0 -10
- package/dist/dashboard/activity-paid.js +0 -7
- package/dist/dashboard/activity-paid.js.map +0 -1
- package/dist/dashboard/home/host-quick-actions.d.ts +0 -19
- package/dist/dashboard/home/host-quick-actions.js +0 -12
- package/dist/dashboard/home/host-quick-actions.js.map +0 -1
- package/dist/dashboard/home/widgets/host-widgets.d.ts +0 -6
- package/dist/dashboard/home/widgets/host-widgets.js +0 -16
- package/dist/dashboard/home/widgets/host-widgets.js.map +0 -1
- package/dist/dashboard/home/widgets/member-label.d.ts +0 -11
- package/dist/dashboard/home/widgets/member-label.js +0 -10
- package/dist/dashboard/home/widgets/member-label.js.map +0 -1
- package/dist/dashboard/home/widgets/middle-ellipsis.d.ts +0 -5
- package/dist/dashboard/home/widgets/middle-ellipsis.js +0 -11
- package/dist/dashboard/home/widgets/middle-ellipsis.js.map +0 -1
- package/dist/dashboard/home/widgets/revenue-series.d.ts +0 -12
- package/dist/dashboard/home/widgets/revenue-series.js +0 -26
- package/dist/dashboard/home/widgets/revenue-series.js.map +0 -1
- package/dist/dashboard/page-transition-key.d.ts +0 -7
- package/dist/dashboard/page-transition-key.js +0 -11
- package/dist/dashboard/page-transition-key.js.map +0 -1
- package/dist/features/gift-cards/gift-card-logic.d.ts +0 -41
- package/dist/features/gift-cards/gift-card-logic.js +0 -65
- package/dist/features/gift-cards/gift-card-logic.js.map +0 -1
- package/dist/features/gift-cards/hint.d.ts +0 -9
- package/dist/features/gift-cards/hint.js +0 -25
- package/dist/features/gift-cards/hint.js.map +0 -1
- package/dist/shell/notification-actions.d.ts +0 -12
- package/dist/shell/notification-actions.js +0 -18
- package/dist/shell/notification-actions.js.map +0 -1
- package/dist/shell/settings-groups.d.ts +0 -23
- package/dist/shell/settings-groups.js +0 -22
- package/dist/shell/settings-groups.js.map +0 -1
- package/dist/shell/settings-host.d.ts +0 -39
- package/dist/shell/settings-host.js +0 -37
- package/dist/shell/settings-host.js.map +0 -1
- package/dist/shell/sidebar-cards.d.ts +0 -32
- package/dist/shell/sidebar-cards.js +0 -37
- package/dist/shell/sidebar-cards.js.map +0 -1
- package/dist/templates/template-tile-source.d.ts +0 -24
- package/dist/templates/template-tile-source.js +0 -18
- package/dist/templates/template-tile-source.js.map +0 -1
package/dist/shell/shell.css
CHANGED
|
@@ -2797,195 +2797,3 @@
|
|
|
2797
2797
|
background-image: none;
|
|
2798
2798
|
}
|
|
2799
2799
|
}
|
|
2800
|
-
|
|
2801
|
-
/* The plan on the business you are in, only where the host names one. */
|
|
2802
|
-
.pv-psw-plan {
|
|
2803
|
-
flex: none;
|
|
2804
|
-
margin-left: auto;
|
|
2805
|
-
padding: 1px 8px;
|
|
2806
|
-
border-radius: 999px;
|
|
2807
|
-
border: 1px solid color-mix(in srgb, var(--accent-primary) 45%, transparent);
|
|
2808
|
-
background: color-mix(in srgb, var(--accent-primary) 22%, transparent);
|
|
2809
|
-
color: var(--text-primary);
|
|
2810
|
-
font-size: 11px;
|
|
2811
|
-
font-weight: 500;
|
|
2812
|
-
line-height: 16px;
|
|
2813
|
-
white-space: nowrap;
|
|
2814
|
-
}
|
|
2815
|
-
|
|
2816
|
-
/* Two cards stacked at the foot, opening on hover or focus. Numbers are
|
|
2817
|
-
Lovable's: 56px cards, 8px apart, a 0.2s ease-out. */
|
|
2818
|
-
.pv-shell .side-stack {
|
|
2819
|
-
position: relative;
|
|
2820
|
-
margin: 0 -8px;
|
|
2821
|
-
padding: 8px;
|
|
2822
|
-
}
|
|
2823
|
-
.pv-shell .side-stack-in {
|
|
2824
|
-
position: relative;
|
|
2825
|
-
height: 56px;
|
|
2826
|
-
transition: height 0.2s cubic-bezier(0, 0, 0.2, 1);
|
|
2827
|
-
}
|
|
2828
|
-
.pv-shell .side-stack-in:has(.side-stack-back) {
|
|
2829
|
-
height: 64px;
|
|
2830
|
-
}
|
|
2831
|
-
.pv-shell .side-stack:hover .side-stack-in:has(.side-stack-back),
|
|
2832
|
-
.pv-shell .side-stack:focus-within .side-stack-in:has(.side-stack-back) {
|
|
2833
|
-
height: 120px;
|
|
2834
|
-
}
|
|
2835
|
-
.pv-shell .side-stack .side-stack-card {
|
|
2836
|
-
position: absolute;
|
|
2837
|
-
inset-inline: 0;
|
|
2838
|
-
bottom: 0;
|
|
2839
|
-
height: 56px;
|
|
2840
|
-
margin: 0;
|
|
2841
|
-
display: flex;
|
|
2842
|
-
flex-direction: row;
|
|
2843
|
-
align-items: center;
|
|
2844
|
-
justify-content: space-between;
|
|
2845
|
-
gap: 10px;
|
|
2846
|
-
padding: 0 12px 0 14px;
|
|
2847
|
-
border-radius: 12px;
|
|
2848
|
-
border: 1px solid var(--border-default);
|
|
2849
|
-
background: var(--bg-elevated, var(--bg-muted));
|
|
2850
|
-
transform-origin: bottom;
|
|
2851
|
-
transition: transform 0.2s cubic-bezier(0, 0, 0.2, 1), background 0.12s;
|
|
2852
|
-
}
|
|
2853
|
-
.pv-shell .side-stack .side-stack-front {
|
|
2854
|
-
z-index: 2;
|
|
2855
|
-
text-align: left;
|
|
2856
|
-
}
|
|
2857
|
-
.pv-shell .side-stack-in:has(.side-stack-back) .side-stack-front {
|
|
2858
|
-
transform: translateY(-8px);
|
|
2859
|
-
}
|
|
2860
|
-
.pv-shell .side-stack .side-stack-back {
|
|
2861
|
-
z-index: 1;
|
|
2862
|
-
flex-direction: column;
|
|
2863
|
-
align-items: stretch;
|
|
2864
|
-
justify-content: center;
|
|
2865
|
-
gap: 7px;
|
|
2866
|
-
transform: translateY(-1px) scale(0.95);
|
|
2867
|
-
}
|
|
2868
|
-
.pv-shell .side-stack:hover .side-stack-front,
|
|
2869
|
-
.pv-shell .side-stack:focus-within .side-stack-front {
|
|
2870
|
-
transform: translateY(-64px);
|
|
2871
|
-
}
|
|
2872
|
-
.pv-shell .side-stack:hover .side-stack-back,
|
|
2873
|
-
.pv-shell .side-stack:focus-within .side-stack-back {
|
|
2874
|
-
transform: none;
|
|
2875
|
-
}
|
|
2876
|
-
.pv-shell .side-stack-text {
|
|
2877
|
-
display: flex;
|
|
2878
|
-
flex-direction: column;
|
|
2879
|
-
min-width: 0;
|
|
2880
|
-
}
|
|
2881
|
-
.pv-shell .side-stack-text b {
|
|
2882
|
-
font-size: 13px;
|
|
2883
|
-
font-weight: 500;
|
|
2884
|
-
line-height: 18px;
|
|
2885
|
-
color: var(--text-primary);
|
|
2886
|
-
}
|
|
2887
|
-
.pv-shell .side-stack-text span {
|
|
2888
|
-
font-size: 12px;
|
|
2889
|
-
line-height: 16px;
|
|
2890
|
-
color: var(--text-tertiary);
|
|
2891
|
-
}
|
|
2892
|
-
.pv-shell .side-stack-glyph {
|
|
2893
|
-
display: grid;
|
|
2894
|
-
place-items: center;
|
|
2895
|
-
flex: none;
|
|
2896
|
-
width: 32px;
|
|
2897
|
-
height: 32px;
|
|
2898
|
-
border-radius: 50%;
|
|
2899
|
-
background: color-mix(in srgb, var(--accent-primary) 18%, transparent);
|
|
2900
|
-
color: var(--accent-primary);
|
|
2901
|
-
}
|
|
2902
|
-
@media (prefers-reduced-motion: reduce) {
|
|
2903
|
-
.pv-shell .side-stack-in,
|
|
2904
|
-
.pv-shell .side-stack .side-stack-card {
|
|
2905
|
-
transition: none;
|
|
2906
|
-
}
|
|
2907
|
-
}
|
|
2908
|
-
|
|
2909
|
-
/* ===================== Settings window (the modal) =====================
|
|
2910
|
-
* One named variant: the window's own palette, so its rail, rows and panels draw the same values everywhere
|
|
2911
|
-
* (the prototype's warm frame). Light takes the prototype's values; dark falls back to the theme tokens so the window
|
|
2912
|
-
* still follows the theme. Panels inside the window read the same variables, with their own fallbacks outside it.
|
|
2913
|
-
*
|
|
2914
|
-
* "Dark" means the window itself is dark. On a desktop dashboard the root carries `.dark` for the sidebar while the
|
|
2915
|
-
* content card, and every dialog that opens over it, is light: the root then also says `data-shell-light` (see
|
|
2916
|
-
* lib/theme-context.tsx). So the dark fallback is for `.dark` WITHOUT that flag, or the light window would draw in
|
|
2917
|
-
* the theme's tokens (grey card, teal headings) instead of its own. */
|
|
2918
|
-
.st-modal,
|
|
2919
|
-
.st-panel {
|
|
2920
|
-
--st-rail: #f6f6f3;
|
|
2921
|
-
--st-rail-line: #ecece8;
|
|
2922
|
-
--st-rail-rule: #e6e6e2;
|
|
2923
|
-
--st-ink-2: #4a4a52;
|
|
2924
|
-
--st-ink-3: #6b6b72;
|
|
2925
|
-
--st-ink-4: #8b8b93;
|
|
2926
|
-
--st-row-hover: rgba(0, 0, 0, 0.045);
|
|
2927
|
-
--st-row-on-ring: 0 0 0 1px rgba(0, 0, 29, 0.06), 0 1px 3px rgba(0, 0, 0, 0.06);
|
|
2928
|
-
--st-search-ring: 0 0 0 1px rgba(0, 0, 29, 0.07);
|
|
2929
|
-
--st-card: #f6f6f3;
|
|
2930
|
-
--st-card-ring: 0 0 0 1px rgba(0, 0, 29, 0.05);
|
|
2931
|
-
--st-pick: #f3faf6;
|
|
2932
|
-
--st-pick-ring: 0 0 0 1px rgba(63, 156, 122, 0.45);
|
|
2933
|
-
--st-pick-dot: #3f9c7a;
|
|
2934
|
-
--st-chip: #f1f1ee;
|
|
2935
|
-
--st-rule: #eeeeea;
|
|
2936
|
-
--st-ink-1: #141416;
|
|
2937
|
-
--st-btn: #ffffff;
|
|
2938
|
-
--st-btn-hover: #f6f6f4;
|
|
2939
|
-
--st-btn-ring: 0 0 0 1px rgba(0, 0, 29, 0.1), 0 1px 2px rgba(0, 0, 0, 0.05);
|
|
2940
|
-
--st-lime: #bbda4c;
|
|
2941
|
-
--st-lime-hover: #c7e25f;
|
|
2942
|
-
--st-lime-ink: #2b3806;
|
|
2943
|
-
--st-frame: #ffffff;
|
|
2944
|
-
--st-frame-ring: 0 0 0 1px rgba(0, 0, 29, 0.1);
|
|
2945
|
-
--st-th: #fafaf8;
|
|
2946
|
-
--st-seg: #ececea;
|
|
2947
|
-
--st-seg-on-ring: 0 1px 2px rgba(0, 0, 0, 0.12), 0 0 0 1px rgba(0, 0, 29, 0.05);
|
|
2948
|
-
--st-icon: #3c6462;
|
|
2949
|
-
}
|
|
2950
|
-
.dark:not([data-shell-light]) .st-modal,
|
|
2951
|
-
.dark:not([data-shell-light]) .st-panel {
|
|
2952
|
-
--st-rail: var(--bg-muted);
|
|
2953
|
-
--st-rail-line: var(--border-subtle);
|
|
2954
|
-
--st-rail-rule: var(--border-subtle);
|
|
2955
|
-
--st-ink-2: var(--text-secondary);
|
|
2956
|
-
--st-ink-3: var(--text-tertiary);
|
|
2957
|
-
--st-ink-4: var(--text-tertiary);
|
|
2958
|
-
--st-row-hover: var(--interactive-hover);
|
|
2959
|
-
--st-row-on-ring: 0 0 0 1px var(--border-subtle);
|
|
2960
|
-
--st-search-ring: 0 0 0 1px var(--border-subtle);
|
|
2961
|
-
--st-card: var(--bg-muted);
|
|
2962
|
-
--st-card-ring: 0 0 0 1px var(--border-subtle);
|
|
2963
|
-
--st-pick: color-mix(in srgb, var(--pv-accent, #3f9c7a) 10%, var(--bg-base));
|
|
2964
|
-
--st-pick-ring: 0 0 0 1px color-mix(in srgb, #3f9c7a 55%, transparent);
|
|
2965
|
-
--st-pick-dot: #3f9c7a;
|
|
2966
|
-
--st-chip: var(--bg-muted);
|
|
2967
|
-
--st-rule: var(--border-subtle);
|
|
2968
|
-
--st-ink-1: var(--text-primary);
|
|
2969
|
-
--st-btn: var(--bg-muted);
|
|
2970
|
-
--st-btn-hover: var(--interactive-hover);
|
|
2971
|
-
--st-btn-ring: var(--shadow-button);
|
|
2972
|
-
--st-lime: var(--brand-500, #bbda4c);
|
|
2973
|
-
--st-lime-hover: var(--brand-600, #c7e25f);
|
|
2974
|
-
--st-lime-ink: #ffffff;
|
|
2975
|
-
--st-frame: var(--bg-base);
|
|
2976
|
-
--st-frame-ring: 0 0 0 1px var(--border-subtle);
|
|
2977
|
-
--st-th: var(--bg-muted);
|
|
2978
|
-
--st-seg: var(--bg-muted);
|
|
2979
|
-
--st-seg-on-ring: var(--shadow-sm);
|
|
2980
|
-
--st-icon: var(--text-secondary);
|
|
2981
|
-
}
|
|
2982
|
-
|
|
2983
|
-
/* The muted text every panel draws its hints and captions in (`--text-tertiary`) is the theme's own value, and on the desktop
|
|
2984
|
-
* dashboard the theme's is a teal. The window's muted ink is the prototype's grey. Only when the window is light: in the dark
|
|
2985
|
-
* fallback `--st-ink-3` is itself `--text-tertiary`, and pointing one at the other would loop. */
|
|
2986
|
-
html:not(.dark) .st-modal,
|
|
2987
|
-
html:not(.dark) .st-panel,
|
|
2988
|
-
html[data-shell-light] .st-modal,
|
|
2989
|
-
html[data-shell-light] .st-panel {
|
|
2990
|
-
--text-tertiary: var(--st-ink-3);
|
|
2991
|
-
}
|
|
@@ -2,13 +2,11 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { usePathname } from "@withpotter/lib/use-pathname";
|
|
4
4
|
import { useAuth } from "@withpotter/lib/auth-context";
|
|
5
|
-
import { usePermissions } from "@withpotter/lib/use-permissions";
|
|
6
5
|
import { NotificationsDropdown } from "../notifications-dropdown";
|
|
7
6
|
import { SetupProgress } from "../sidebar/setup-progress";
|
|
8
7
|
import { FootResourcesMenu } from "./foot-resources-menu";
|
|
9
8
|
import { FootThemeMenu } from "./foot-theme-menu";
|
|
10
9
|
import { PlanUpgradeLink } from "./plan-upgrade-link";
|
|
11
|
-
import { SidebarCardStack, useSidebarCards } from "./sidebar-cards";
|
|
12
10
|
function SidebarFooter({
|
|
13
11
|
collapsed = false
|
|
14
12
|
}) {
|
|
@@ -16,12 +14,10 @@ function SidebarFooter({
|
|
|
16
14
|
const { tenant } = useAuth();
|
|
17
15
|
const onSettings = pathname?.startsWith("/dashboard/settings") ?? false;
|
|
18
16
|
const iconBtn = "side-foot-link !w-7 !justify-center !gap-0 !px-0";
|
|
19
|
-
const { isOwner } = usePermissions();
|
|
20
|
-
const stacked = Boolean(useSidebarCards()?.upgrade) && isOwner && !collapsed && !onSettings;
|
|
21
17
|
return /* @__PURE__ */ jsxs("div", { className: "side-foot-wrap", children: [
|
|
22
|
-
|
|
18
|
+
!collapsed && !onSettings && /* @__PURE__ */ jsx(SetupProgress, {}),
|
|
23
19
|
/* @__PURE__ */ jsxs("div", { className: "side-foot", children: [
|
|
24
|
-
|
|
20
|
+
/* @__PURE__ */ jsx(PlanUpgradeLink, { collapsed }),
|
|
25
21
|
/* @__PURE__ */ jsx("div", { className: "side-foot-switch", children: /* @__PURE__ */ jsxs("div", { className: "side-foot-icons", children: [
|
|
26
22
|
/* @__PURE__ */ jsx(FootResourcesMenu, { className: "side-foot-link !w-auto" }),
|
|
27
23
|
/* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/shell/sidebar-footer.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname } from '@withpotter/lib/use-pathname';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { usePermissions } from '@withpotter/lib/use-permissions';\nimport { NotificationsDropdown } from '../notifications-dropdown';\nimport { SetupProgress } from '../sidebar/setup-progress';\nimport { FootResourcesMenu } from './foot-resources-menu';\nimport { FootThemeMenu } from './foot-theme-menu';\nimport { PlanUpgradeLink } from './plan-upgrade-link';\nimport { SidebarCardStack, useSidebarCards } from './sidebar-cards';\n\n/**\n * The foot of the sidebar: who's in this business, and the things that are\n * about YOU rather than about the page.\n *\n * One exception, and it leads: Take payment. It belongs to no page, which is\n * precisely why it cannot live on one — see `take-payment-button.tsx`.\n *\n * THREE THINGS LEFT OR MOVED, against Lovable, the reference for this rail:\n * workspace at the top, nav, then the foot. Lovable's bottom row is an avatar\n * on the left and an inbox on the right, and ours is not any more — the\n * account went into the switcher on 2026-09-03, so the last line is two\n * switches rather than an identity.\n *\n * Invite/Team → BACK, and it is one row now rather than a face stack you\n * could not act on. It went to the workspace switcher on the\n * argument that adding someone to a business is a workspace\n * act; scope turned\n * out to be the wrong axis to sort that menu on.\n * Help → BACK, on John's call 2026-08-23. It was moved to the home\n * on the argument that a rail row for a twice-a-year\n * destination is rail spent on the rare case. What that\n * missed is WHEN it is wanted: a merchant looking for help is\n * stuck on some screen deep in the app, and \"go back to the\n * home first\" is the one instruction a stuck person will not\n * follow. A rail row costs 30px on every screen and is on the\n * screen where the trouble actually is. The two escapes that\n * used to sit inside the ask intro — \"Report a bug\" and\n * \"Message the team\" — are gone with it; this is where a\n * person goes when something is wrong, and three doors to the\n * same room is worse than one that is always visible.\n * Notifications→ BACK. It was built against a live API and mounted nowhere,\n * so the whole read model had no face: notifications were\n * being written and nobody could see one. It now shares the\n * bottom line with the theme flip, the account having gone to\n * the switcher.\n *\n * TWO WORKSPACE-SCOPE ROWS SIT HERE — Workspace settings and Team, moved back\n * out of the switcher on John's call, 2026-09-03, and they are the LAST block\n * before the account line rather than the first; the rows argue their own\n * order where they are written. That is a deliberate hole in\n * the \"footer is person scope\" line above, and the line is the thing that was\n * wrong: a rail sorted by scope makes a merchant work out which scope a\n * destination belongs to before they can find it, which is the same complaint\n * the nav has. They are rows because they are destinations, and a destination\n * you visit weekly should not be behind a control whose job is switching\n * business. Both are gated — `canManageSettings` and, inside the row itself,\n * `canManageTeam` — so someone working a shift sees neither.\n *\n * Pinned with margin-top:auto and nothing stretched to meet it: the gap above\n * is the nav's breathing room, not a hole that wants filling.\n */\nexport function SidebarFooter({\n collapsed = false,\n}: {\n collapsed?: boolean;\n /** Still passed by the sidebar until the navigation PR drops the footer's\n * old edit toggle; the footer no longer draws one. */\n editing?: boolean;\n onToggleEdit?: () => void;\n}) {\n const pathname = usePathname();\n const { tenant } = useAuth();\n const onSettings = pathname?.startsWith('/dashboard/settings') ?? false;\n /* The same shape as Support (`side-foot-link`: 28px, 10px corners, the same\n hover and open fill), square so it holds only the icon. */\n const iconBtn = 'side-foot-link !w-7 !justify-center !gap-0 !px-0';\n /* A host that supplies plan cards gets the stack in place of the setup bar and\n the Upgrade row; every other host keeps both exactly as they were. */\n const { isOwner } = usePermissions();\n const stacked = Boolean(useSidebarCards()?.upgrade) && isOwner && !collapsed && !onSettings;\n\n return (\n <div className=\"side-foot-wrap\">\n {/* How far through setting up, ABOVE the foot's divider. Not on the\n collapsed rail or inside settings, where there is no room or no need. */}\n {stacked ? <SidebarCardStack /> : !collapsed && !onSettings && <SetupProgress />}\n <div className=\"side-foot\">\n {/* NO CARDS IN THE RAIL. John, 2026-09-03: *\"this credits card and refer\n a business thingy, let's remove it from the sidebar footer... the\n refer a business can be on the homepage and the credits maybe.\"*\n\n Right, and the deck's own note had the reason without following it:\n the argument for Lovable's stacked pair is that a sidebar can carry\n two standing offers without spending two rows on them ALL DAY. It\n still spends them on every screen — a merchant reading an order has a\n credit meter and a referral pitch in the corner of their eye. The\n home is where a business looks up rather than down, and it already\n has a board built for exactly this: widgets a merchant can size,\n move, or throw away, which is the one thing a rail card can never\n offer.\n\n The deck's mechanic is not lost. `AnimatedHeight` came out of the\n create-business modal for it and stayed in `ui/`. */}\n\n {/* Search is at the head of the rail now (see `sidebar.tsx`). */}\n\n {/* NO HELP ROW. John, 2026-09-03: *\"let's remove the help and support\n from the sidebar footer and let's see how the footer looks like\"*.\n\n WHAT LEFT WITH IT, because this row was carrying more than its\n label by the end of that day: Give feedback had been merged INTO the\n help page an hour before (two rows for one errand), and\n `/dashboard/help` is the only door in the app to support cases — it\n is where \"Start a case\" and \"Your cases\" live. So removing one row\n took out the app's only desktop route to help, to feedback, and to a\n case a merchant had already opened.\n\n The consolation written here was wrong and worth recording: it said\n search covered part of it by answering from `HELP_TOPICS` inline. It\n does not. `sidebar-ask` and `use-command-search` between them search\n orders, customers, invoices, products and support cases, and no help\n topic — so the removal left zero doors, not a partial one. That is\n the shape of this whole class of bug: a row is deleted and the thing\n that was supposed to absorb it never did.\n\n IT NOW LIVES IN THE SWITCHER, which is where the note that used to\n be here said it should go — `switcher-account-group`, two rows under\n the person: Help & support, and Send feedback. The foot stays lean\n and the doors exist. */}\n\n {/* NO ASK FIELD IN THIS RAIL, at either end of it. John, 2026-08-25,\n twice in ten minutes: first *\"remove the ask anything on the side\n bar side put it on the footer sidebar\"*, then — with it sitting in\n the footer — *\"the ask anything search bar remove it form the\n sidebar\"*. Read together, the objection is not the slot, it is a\n text field in the rail at all: the sidebar is where you go\n somewhere, and a box you type sentences into is a surface you work\n in.\n\n So the app's doors to Box are the home's own bar, `/dashboard/\n ask`, and `PotterLauncher` on mobile. Desktop has none on the\n screens in between; that is the trade this makes, and the mount is\n one revert away in `components/shell/sidebar-ask.tsx` if it should\n come back somewhere that is not a rail. */}\n {/* THE LAST LINE: the help menu, the notifications bell and the theme\n flip, at the left. The account is in the workspace menu at the top\n now (John, 2026-10-11). The bell is the one the note above says came\n BACK: it had been left out of this line, so notifications were\n written and still nobody could see one. */}\n {/* Upgrade, only when the admin switches it on (Pricing › Display). */}\n {!stacked && <PlanUpgradeLink collapsed={collapsed} />}\n <div className=\"side-foot-switch\">\n <div className=\"side-foot-icons\">\n <FootResourcesMenu className=\"side-foot-link !w-auto\" />\n <span\n aria-hidden=\"true\"\n className=\"mx-1 h-4 w-px shrink-0 bg-[var(--border-subtle)]\"\n />\n <NotificationsDropdown\n tenantSlug={tenant?.slug}\n className={iconBtn}\n />\n <FootThemeMenu className={iconBtn} />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAuFiB,cAmEP,YAnEO;AArFjB,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,sBAAsB;AAC/B,SAAS,6BAA6B;AACtC,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAChC,SAAS,kBAAkB,uBAAuB;AAqD3C,SAAS,cAAc;AAAA,EAC5B,YAAY;AACd,GAMG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,OAAO,IAAI,QAAQ;AAC3B,QAAM,aAAa,UAAU,WAAW,qBAAqB,KAAK;AAGlE,QAAM,UAAU;AAGhB,QAAM,EAAE,QAAQ,IAAI,eAAe;AACnC,QAAM,UAAU,QAAQ,gBAAgB,GAAG,OAAO,KAAK,WAAW,CAAC,aAAa,CAAC;AAEjF,SACE,qBAAC,SAAI,WAAU,kBAGZ;AAAA,cAAU,oBAAC,oBAAiB,IAAK,CAAC,aAAa,CAAC,cAAc,oBAAC,iBAAc;AAAA,IAC9E,qBAAC,SAAI,WAAU,aAgEZ;AAAA,OAAC,WAAW,oBAAC,mBAAgB,WAAsB;AAAA,MACpD,oBAAC,SAAI,WAAU,oBACb,+BAAC,SAAI,WAAU,mBACb;AAAA,4BAAC,qBAAkB,WAAU,0BAAyB;AAAA,QACtD;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA;AAAA,QACZ;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,YAAY,QAAQ;AAAA,YACpB,WAAW;AAAA;AAAA,QACb;AAAA,QACA,oBAAC,iBAAc,WAAW,SAAS;AAAA,SACrC,GACF;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../src/shell/sidebar-footer.tsx"],"sourcesContent":["'use client';\n\nimport { usePathname } from '@withpotter/lib/use-pathname';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { NotificationsDropdown } from '../notifications-dropdown';\nimport { SetupProgress } from '../sidebar/setup-progress';\nimport { FootResourcesMenu } from './foot-resources-menu';\nimport { FootThemeMenu } from './foot-theme-menu';\nimport { PlanUpgradeLink } from './plan-upgrade-link';\n\n/**\n * The foot of the sidebar: who's in this business, and the things that are\n * about YOU rather than about the page.\n *\n * One exception, and it leads: Take payment. It belongs to no page, which is\n * precisely why it cannot live on one — see `take-payment-button.tsx`.\n *\n * THREE THINGS LEFT OR MOVED, against Lovable, the reference for this rail:\n * workspace at the top, nav, then the foot. Lovable's bottom row is an avatar\n * on the left and an inbox on the right, and ours is not any more — the\n * account went into the switcher on 2026-09-03, so the last line is two\n * switches rather than an identity.\n *\n * Invite/Team → BACK, and it is one row now rather than a face stack you\n * could not act on. It went to the workspace switcher on the\n * argument that adding someone to a business is a workspace\n * act; scope turned\n * out to be the wrong axis to sort that menu on.\n * Help → BACK, on John's call 2026-08-23. It was moved to the home\n * on the argument that a rail row for a twice-a-year\n * destination is rail spent on the rare case. What that\n * missed is WHEN it is wanted: a merchant looking for help is\n * stuck on some screen deep in the app, and \"go back to the\n * home first\" is the one instruction a stuck person will not\n * follow. A rail row costs 30px on every screen and is on the\n * screen where the trouble actually is. The two escapes that\n * used to sit inside the ask intro — \"Report a bug\" and\n * \"Message the team\" — are gone with it; this is where a\n * person goes when something is wrong, and three doors to the\n * same room is worse than one that is always visible.\n * Notifications→ BACK. It was built against a live API and mounted nowhere,\n * so the whole read model had no face: notifications were\n * being written and nobody could see one. It now shares the\n * bottom line with the theme flip, the account having gone to\n * the switcher.\n *\n * TWO WORKSPACE-SCOPE ROWS SIT HERE — Workspace settings and Team, moved back\n * out of the switcher on John's call, 2026-09-03, and they are the LAST block\n * before the account line rather than the first; the rows argue their own\n * order where they are written. That is a deliberate hole in\n * the \"footer is person scope\" line above, and the line is the thing that was\n * wrong: a rail sorted by scope makes a merchant work out which scope a\n * destination belongs to before they can find it, which is the same complaint\n * the nav has. They are rows because they are destinations, and a destination\n * you visit weekly should not be behind a control whose job is switching\n * business. Both are gated — `canManageSettings` and, inside the row itself,\n * `canManageTeam` — so someone working a shift sees neither.\n *\n * Pinned with margin-top:auto and nothing stretched to meet it: the gap above\n * is the nav's breathing room, not a hole that wants filling.\n */\nexport function SidebarFooter({\n collapsed = false,\n}: {\n collapsed?: boolean;\n /** Still passed by the sidebar until the navigation PR drops the footer's\n * old edit toggle; the footer no longer draws one. */\n editing?: boolean;\n onToggleEdit?: () => void;\n}) {\n const pathname = usePathname();\n const { tenant } = useAuth();\n const onSettings = pathname?.startsWith('/dashboard/settings') ?? false;\n /* The same shape as Support (`side-foot-link`: 28px, 10px corners, the same\n hover and open fill), square so it holds only the icon. */\n const iconBtn = 'side-foot-link !w-7 !justify-center !gap-0 !px-0';\n\n return (\n <div className=\"side-foot-wrap\">\n {/* How far through setting up, ABOVE the foot's divider. Not on the\n collapsed rail or inside settings, where there is no room or no need. */}\n {!collapsed && !onSettings && <SetupProgress />}\n <div className=\"side-foot\">\n {/* NO CARDS IN THE RAIL. John, 2026-09-03: *\"this credits card and refer\n a business thingy, let's remove it from the sidebar footer... the\n refer a business can be on the homepage and the credits maybe.\"*\n\n Right, and the deck's own note had the reason without following it:\n the argument for Lovable's stacked pair is that a sidebar can carry\n two standing offers without spending two rows on them ALL DAY. It\n still spends them on every screen — a merchant reading an order has a\n credit meter and a referral pitch in the corner of their eye. The\n home is where a business looks up rather than down, and it already\n has a board built for exactly this: widgets a merchant can size,\n move, or throw away, which is the one thing a rail card can never\n offer.\n\n The deck's mechanic is not lost. `AnimatedHeight` came out of the\n create-business modal for it and stayed in `ui/`. */}\n\n {/* Search is at the head of the rail now (see `sidebar.tsx`). */}\n\n {/* NO HELP ROW. John, 2026-09-03: *\"let's remove the help and support\n from the sidebar footer and let's see how the footer looks like\"*.\n\n WHAT LEFT WITH IT, because this row was carrying more than its\n label by the end of that day: Give feedback had been merged INTO the\n help page an hour before (two rows for one errand), and\n `/dashboard/help` is the only door in the app to support cases — it\n is where \"Start a case\" and \"Your cases\" live. So removing one row\n took out the app's only desktop route to help, to feedback, and to a\n case a merchant had already opened.\n\n The consolation written here was wrong and worth recording: it said\n search covered part of it by answering from `HELP_TOPICS` inline. It\n does not. `sidebar-ask` and `use-command-search` between them search\n orders, customers, invoices, products and support cases, and no help\n topic — so the removal left zero doors, not a partial one. That is\n the shape of this whole class of bug: a row is deleted and the thing\n that was supposed to absorb it never did.\n\n IT NOW LIVES IN THE SWITCHER, which is where the note that used to\n be here said it should go — `switcher-account-group`, two rows under\n the person: Help & support, and Send feedback. The foot stays lean\n and the doors exist. */}\n\n {/* NO ASK FIELD IN THIS RAIL, at either end of it. John, 2026-08-25,\n twice in ten minutes: first *\"remove the ask anything on the side\n bar side put it on the footer sidebar\"*, then — with it sitting in\n the footer — *\"the ask anything search bar remove it form the\n sidebar\"*. Read together, the objection is not the slot, it is a\n text field in the rail at all: the sidebar is where you go\n somewhere, and a box you type sentences into is a surface you work\n in.\n\n So the app's doors to Box are the home's own bar, `/dashboard/\n ask`, and `PotterLauncher` on mobile. Desktop has none on the\n screens in between; that is the trade this makes, and the mount is\n one revert away in `components/shell/sidebar-ask.tsx` if it should\n come back somewhere that is not a rail. */}\n {/* THE LAST LINE: the help menu, the notifications bell and the theme\n flip, at the left. The account is in the workspace menu at the top\n now (John, 2026-10-11). The bell is the one the note above says came\n BACK: it had been left out of this line, so notifications were\n written and still nobody could see one. */}\n {/* Upgrade, only when the admin switches it on (Pricing › Display). */}\n <PlanUpgradeLink collapsed={collapsed} />\n <div className=\"side-foot-switch\">\n <div className=\"side-foot-icons\">\n <FootResourcesMenu className=\"side-foot-link !w-auto\" />\n <span\n aria-hidden=\"true\"\n className=\"mx-1 h-4 w-px shrink-0 bg-[var(--border-subtle)]\"\n />\n <NotificationsDropdown\n tenantSlug={tenant?.slug}\n className={iconBtn}\n />\n <FootThemeMenu className={iconBtn} />\n </div>\n </div>\n </div>\n </div>\n );\n}\n"],"mappings":";AAiFoC,cAmE1B,YAnE0B;AA/EpC,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,6BAA6B;AACtC,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB;AAClC,SAAS,qBAAqB;AAC9B,SAAS,uBAAuB;AAqDzB,SAAS,cAAc;AAAA,EAC5B,YAAY;AACd,GAMG;AACD,QAAM,WAAW,YAAY;AAC7B,QAAM,EAAE,OAAO,IAAI,QAAQ;AAC3B,QAAM,aAAa,UAAU,WAAW,qBAAqB,KAAK;AAGlE,QAAM,UAAU;AAEhB,SACE,qBAAC,SAAI,WAAU,kBAGZ;AAAA,KAAC,aAAa,CAAC,cAAc,oBAAC,iBAAc;AAAA,IAC7C,qBAAC,SAAI,WAAU,aAgEb;AAAA,0BAAC,mBAAgB,WAAsB;AAAA,MACvC,oBAAC,SAAI,WAAU,oBACb,+BAAC,SAAI,WAAU,mBACb;AAAA,4BAAC,qBAAkB,WAAU,0BAAyB;AAAA,QACtD;AAAA,UAAC;AAAA;AAAA,YACC,eAAY;AAAA,YACZ,WAAU;AAAA;AAAA,QACZ;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,YAAY,QAAQ;AAAA,YACpB,WAAW;AAAA;AAAA,QACb;AAAA,QACA,oBAAC,iBAAc,WAAW,SAAS;AAAA,SACrC,GACF;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Settings, yours and the business's, in one window.
|
|
3
3
|
*
|
|
4
|
-
* It is the account modal's shell (a rail on the left, the page on the right)
|
|
5
|
-
*
|
|
6
|
-
* then the rows in two groups, Business and You. A search matches row names and the
|
|
4
|
+
* It is the account modal's shell (a rail on the left, the page on the right)
|
|
5
|
+
* with every row in one list. A search at the top matches row names and the
|
|
7
6
|
* sections inside them, so "passkeys" or "time zone" finds its row. Rows the
|
|
8
7
|
* member may not open are not drawn. Get help leaves the window, so it carries
|
|
9
8
|
* an arrow.
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import {
|
|
3
|
+
import { useMemo, useState } from "react";
|
|
4
4
|
import Link from "next/link";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { BusinessMark } from "@withpotter/ui-kit/business-mark";
|
|
8
|
-
import { Dialog, DialogClose, DialogContent, DialogTitle } from "@withpotter/ui-kit/dialog";
|
|
5
|
+
import { ArrowLeft, ArrowUpRight, Search } from "lucide-react";
|
|
6
|
+
import { Dialog, DialogContent, DialogTitle } from "@withpotter/ui-kit/dialog";
|
|
9
7
|
import { Input } from "@withpotter/ui-kit/input";
|
|
10
8
|
import { TextMorph } from "@withpotter/ui-kit/text-morph";
|
|
11
9
|
import {
|
|
@@ -15,12 +13,8 @@ import {
|
|
|
15
13
|
import {
|
|
16
14
|
SettingsDrillProvider
|
|
17
15
|
} from "@withpotter/pages-core/dashboard/settings/_components/settings-drill";
|
|
18
|
-
import { useAuth } from "@withpotter/lib/auth-context";
|
|
19
16
|
import { usePermissions } from "@withpotter/lib/use-permissions";
|
|
20
17
|
import { SettingsPanel } from "./settings-panels";
|
|
21
|
-
import { groupRows } from "./settings-groups";
|
|
22
|
-
import { useSidebarCards } from "./sidebar-cards";
|
|
23
|
-
import { hostRowForHref, useSettingsHostRows } from "./settings-host";
|
|
24
18
|
import {
|
|
25
19
|
HELP_HREF,
|
|
26
20
|
HELP_ICON,
|
|
@@ -28,9 +22,7 @@ import {
|
|
|
28
22
|
matchRows,
|
|
29
23
|
rowForHref
|
|
30
24
|
} from "./settings-rows";
|
|
31
|
-
const ROW_CLASS = "
|
|
32
|
-
const ROW_IDLE = "text-[var(--st-ink-2)] hover:bg-[var(--st-row-hover)] hover:text-[var(--text-primary)]";
|
|
33
|
-
const ROW_ON = "bg-[var(--bg-base)] text-[var(--text-primary)] shadow-[var(--st-row-on-ring)]";
|
|
25
|
+
const ROW_CLASS = "flex w-full items-center gap-3 rounded-lg px-3 py-3 text-left text-sm font-medium transition-colors";
|
|
34
26
|
function UnifiedSettingsModal({
|
|
35
27
|
open,
|
|
36
28
|
href,
|
|
@@ -47,20 +39,13 @@ function UnifiedSettingsModal({
|
|
|
47
39
|
setQuery("");
|
|
48
40
|
setView(null);
|
|
49
41
|
}
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
const own = SETTINGS_ROWS.filter(
|
|
42
|
+
const rows = useMemo(
|
|
43
|
+
() => SETTINGS_ROWS.filter(
|
|
53
44
|
(r) => !r.permission || loading || r.permission.some((p) => can(p))
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
const into = at === -1 ? list.length : at + 1;
|
|
58
|
-
return [...list.slice(0, into), extra, ...list.slice(into)];
|
|
59
|
-
}, own);
|
|
60
|
-
}, [can, loading, host]);
|
|
45
|
+
),
|
|
46
|
+
[can, loading]
|
|
47
|
+
);
|
|
61
48
|
const shown = matchRows(rows, query);
|
|
62
|
-
const railRows = shown.filter((r) => r.id !== "legal");
|
|
63
|
-
const legalRow = shown.find((r) => r.id === "legal");
|
|
64
49
|
const drill = useMemo(
|
|
65
50
|
() => ({
|
|
66
51
|
view,
|
|
@@ -73,29 +58,15 @@ function UnifiedSettingsModal({
|
|
|
73
58
|
}),
|
|
74
59
|
[view]
|
|
75
60
|
);
|
|
76
|
-
const wanted = picked ??
|
|
61
|
+
const wanted = picked ?? rowForHref(href);
|
|
77
62
|
const current = rows.find((r) => r.id === wanted) ?? rows[0];
|
|
78
63
|
const HelpIcon = HELP_ICON;
|
|
79
64
|
const [statusSlot, setStatusSlot] = useState(null);
|
|
80
|
-
const { tenant } = useAuth();
|
|
81
|
-
const planLabel = useSidebarCards()?.planLabel;
|
|
82
|
-
const name = tenant?.businessName?.trim() ?? "";
|
|
83
|
-
const [scope, animate] = useAnimate();
|
|
84
|
-
const reduced = useReducedMotion();
|
|
85
|
-
const shownKey = `${current?.id ?? ""}:${view?.key ?? ""}`;
|
|
86
|
-
const lastKey = useRef(shownKey);
|
|
87
|
-
useEffect(() => {
|
|
88
|
-
if (lastKey.current === shownKey) return;
|
|
89
|
-
lastKey.current = shownKey;
|
|
90
|
-
if (reduced || !scope.current) return;
|
|
91
|
-
void animate(scope.current, { opacity: [0, 1], y: [8, 0] }, { duration: 0.22, ease: [0.22, 1, 0.36, 1] });
|
|
92
|
-
}, [shownKey, reduced, animate, scope]);
|
|
93
65
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: (next) => !next && onClose(), children: /* @__PURE__ */ jsxs(
|
|
94
66
|
DialogContent,
|
|
95
67
|
{
|
|
96
68
|
"aria-label": "Settings",
|
|
97
|
-
|
|
98
|
-
className: "st-modal flex h-[min(640px,calc(100dvh-2.5rem))] w-[calc(100%-2.5rem)] max-w-[920px] gap-0 overflow-hidden rounded-2xl border-0 p-0 text-[13.5px] shadow-[0_24px_60px_-20px_rgba(18,18,34,0.45),0_0_0_1px_rgba(0,0,0,0.04)]",
|
|
69
|
+
className: "flex h-[min(78vh,640px)] max-w-[860px] gap-0 overflow-hidden p-0",
|
|
99
70
|
children: [
|
|
100
71
|
/* @__PURE__ */ jsxs(
|
|
101
72
|
"nav",
|
|
@@ -112,155 +83,107 @@ function UnifiedSettingsModal({
|
|
|
112
83
|
const next = e.key === "ArrowDown" ? (at + 1) % rowsEls.length : (at - 1 + rowsEls.length) % rowsEls.length;
|
|
113
84
|
rowsEls[next].focus();
|
|
114
85
|
},
|
|
115
|
-
className: "flex w-[
|
|
86
|
+
className: "flex w-[224px] shrink-0 flex-col gap-1 overflow-y-auto border-r border-[var(--border-subtle)] bg-[var(--bg-muted)] p-3",
|
|
116
87
|
children: [
|
|
117
|
-
|
|
118
|
-
/* @__PURE__ */ jsx(
|
|
119
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
120
|
-
/* @__PURE__ */ jsx("p", { className: "max-w-[150px] truncate text-[14px] font-semibold leading-[18px] text-[var(--text-primary)]", children: name }),
|
|
121
|
-
planLabel && /* @__PURE__ */ jsx("p", { className: "truncate text-[12px] leading-4 text-[var(--st-ink-3)]", children: planLabel })
|
|
122
|
-
] })
|
|
123
|
-
] }),
|
|
124
|
-
/* @__PURE__ */ jsxs("div", { className: "mb-1.5 flex h-8 shrink-0 items-center gap-2 rounded-[10px] bg-[var(--bg-base)] px-2.5 text-[var(--st-ink-3)] shadow-[var(--st-search-ring)] focus-within:text-[var(--text-primary)]", children: [
|
|
125
|
-
/* @__PURE__ */ jsx(Search, { className: "size-[15px] shrink-0", strokeWidth: 1.8 }),
|
|
88
|
+
/* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center gap-2 rounded-lg border border-[var(--border-subtle)] bg-[var(--bg-base)] px-3 text-[var(--text-tertiary)] focus-within:text-[var(--text-primary)]", children: [
|
|
89
|
+
/* @__PURE__ */ jsx(Search, { className: "size-4 shrink-0" }),
|
|
126
90
|
/* @__PURE__ */ jsx(
|
|
127
91
|
Input,
|
|
128
92
|
{
|
|
129
93
|
variant: "bare",
|
|
130
94
|
value: query,
|
|
131
95
|
onChange: (e) => setQuery(e.target.value),
|
|
132
|
-
placeholder: "Search
|
|
96
|
+
placeholder: "Search",
|
|
133
97
|
"aria-label": "Search settings",
|
|
134
98
|
className: "min-w-0 flex-1"
|
|
135
99
|
}
|
|
136
100
|
)
|
|
137
101
|
] }),
|
|
138
|
-
/* @__PURE__ */
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
] }),
|
|
144
|
-
groupRows(railRows).map((group) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
145
|
-
/* @__PURE__ */ jsx("p", { className: "px-2 pb-1.5 pt-3.5 text-[12px] font-medium leading-5 text-[var(--st-ink-4)]", children: group.label }),
|
|
146
|
-
group.rows.map((r) => {
|
|
147
|
-
const selected = r.id === current?.id;
|
|
148
|
-
const Icon = r.icon;
|
|
149
|
-
if (r.href) {
|
|
150
|
-
return /* @__PURE__ */ jsxs(
|
|
151
|
-
Link,
|
|
152
|
-
{
|
|
153
|
-
"data-row": true,
|
|
154
|
-
href: r.href,
|
|
155
|
-
onClick: onClose,
|
|
156
|
-
className: `${ROW_CLASS} ${ROW_IDLE}`,
|
|
157
|
-
children: [
|
|
158
|
-
/* @__PURE__ */ jsx(Icon, { className: "size-4 shrink-0", strokeWidth: 1.75 }),
|
|
159
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: r.name }),
|
|
160
|
-
/* @__PURE__ */ jsx(ArrowUpRight, { className: "ml-auto size-[13px] shrink-0 opacity-[.55]" })
|
|
161
|
-
]
|
|
162
|
-
},
|
|
163
|
-
r.id
|
|
164
|
-
);
|
|
165
|
-
}
|
|
166
|
-
return /* @__PURE__ */ jsxs(
|
|
167
|
-
"button",
|
|
168
|
-
{
|
|
169
|
-
"data-row": true,
|
|
170
|
-
type: "button",
|
|
171
|
-
"aria-current": selected ? "page" : void 0,
|
|
172
|
-
onClick: () => {
|
|
173
|
-
setPicked(r.id);
|
|
174
|
-
setView(null);
|
|
175
|
-
},
|
|
176
|
-
className: `${ROW_CLASS} ${selected ? ROW_ON : ROW_IDLE}`,
|
|
177
|
-
children: [
|
|
178
|
-
/* @__PURE__ */ jsx(Icon, { className: "size-4 shrink-0", strokeWidth: 1.75 }),
|
|
179
|
-
/* @__PURE__ */ jsx("span", { className: "truncate", children: r.name })
|
|
180
|
-
]
|
|
181
|
-
},
|
|
182
|
-
r.id
|
|
183
|
-
);
|
|
184
|
-
})
|
|
185
|
-
] }, group.key))
|
|
102
|
+
/* @__PURE__ */ jsx("p", { className: "px-3 pb-1 pt-1 text-xs font-medium text-[var(--text-tertiary)]", children: "Settings" }),
|
|
103
|
+
shown.length === 0 && /* @__PURE__ */ jsxs("p", { className: "px-3 py-2 text-sm text-[var(--text-tertiary)]", children: [
|
|
104
|
+
"Nothing matches \u201C",
|
|
105
|
+
query,
|
|
106
|
+
"\u201D."
|
|
186
107
|
] }),
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
108
|
+
shown.map((r) => {
|
|
109
|
+
const selected = r.id === current?.id;
|
|
110
|
+
const Icon = r.icon;
|
|
111
|
+
if (r.href) {
|
|
112
|
+
return /* @__PURE__ */ jsxs(
|
|
113
|
+
Link,
|
|
114
|
+
{
|
|
115
|
+
"data-row": true,
|
|
116
|
+
href: r.href,
|
|
117
|
+
onClick: onClose,
|
|
118
|
+
className: `${ROW_CLASS} text-[var(--text-secondary)] hover:bg-[var(--interactive-hover)] hover:text-[var(--text-primary)]`,
|
|
119
|
+
children: [
|
|
120
|
+
/* @__PURE__ */ jsx(Icon, { className: "size-[18px] shrink-0" }),
|
|
121
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: r.name })
|
|
122
|
+
]
|
|
123
|
+
},
|
|
124
|
+
r.id
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return /* @__PURE__ */ jsxs(
|
|
202
128
|
"button",
|
|
203
129
|
{
|
|
204
|
-
type: "button",
|
|
205
130
|
"data-row": true,
|
|
206
|
-
|
|
131
|
+
type: "button",
|
|
132
|
+
"aria-current": selected ? "page" : void 0,
|
|
207
133
|
onClick: () => {
|
|
208
|
-
setPicked(
|
|
134
|
+
setPicked(r.id);
|
|
209
135
|
setView(null);
|
|
210
136
|
},
|
|
211
|
-
className:
|
|
212
|
-
children:
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
137
|
+
className: `${ROW_CLASS} ${selected ? "bg-[var(--bg-base)] text-[var(--text-primary)] shadow-sm" : "text-[var(--text-secondary)] hover:bg-[var(--interactive-hover)] hover:text-[var(--text-primary)]"}`,
|
|
138
|
+
children: [
|
|
139
|
+
/* @__PURE__ */ jsx(Icon, { className: "size-[18px] shrink-0" }),
|
|
140
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: r.name })
|
|
141
|
+
]
|
|
142
|
+
},
|
|
143
|
+
r.id
|
|
144
|
+
);
|
|
145
|
+
}),
|
|
146
|
+
/* @__PURE__ */ jsx("div", { className: "mt-auto border-t border-[var(--border-subtle)] pt-2", children: /* @__PURE__ */ jsxs(
|
|
147
|
+
Link,
|
|
148
|
+
{
|
|
149
|
+
href: HELP_HREF,
|
|
150
|
+
onClick: onClose,
|
|
151
|
+
className: `${ROW_CLASS} text-[var(--text-secondary)] hover:bg-[var(--interactive-hover)] hover:text-[var(--text-primary)]`,
|
|
152
|
+
children: [
|
|
153
|
+
/* @__PURE__ */ jsx(HelpIcon, { className: "size-[18px] shrink-0" }),
|
|
154
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1", children: "Get help" }),
|
|
155
|
+
/* @__PURE__ */ jsx(ArrowUpRight, { className: "size-4 shrink-0 text-[var(--text-tertiary)]" })
|
|
156
|
+
]
|
|
157
|
+
}
|
|
158
|
+
) })
|
|
216
159
|
]
|
|
217
160
|
}
|
|
218
161
|
),
|
|
219
162
|
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-1 flex-col", children: [
|
|
220
|
-
/* @__PURE__ */ jsxs("div", { className: "flex
|
|
221
|
-
/* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
|
|
222
|
-
view && /* @__PURE__ */
|
|
163
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3 border-b border-[var(--border-subtle)] px-4 py-3", children: [
|
|
164
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
165
|
+
view && /* @__PURE__ */ jsx(
|
|
223
166
|
"button",
|
|
224
167
|
{
|
|
225
168
|
type: "button",
|
|
226
169
|
onClick: drill.back,
|
|
227
170
|
"aria-label": `Back to ${current?.name ?? "Settings"}`,
|
|
228
|
-
className: "-
|
|
229
|
-
children:
|
|
230
|
-
/* @__PURE__ */ jsx(ChevronLeft, { className: "size-[15px]", strokeWidth: 2 }),
|
|
231
|
-
current?.name ?? "Settings"
|
|
232
|
-
]
|
|
171
|
+
className: "grid size-7 shrink-0 place-items-center rounded-lg text-[var(--text-secondary)] transition-colors hover:bg-[var(--interactive-hover)] hover:text-[var(--text-primary)]",
|
|
172
|
+
children: /* @__PURE__ */ jsx(ArrowLeft, { className: "size-4" })
|
|
233
173
|
}
|
|
234
174
|
),
|
|
235
175
|
/* @__PURE__ */ jsx(
|
|
236
176
|
DialogTitle,
|
|
237
177
|
{
|
|
238
178
|
"aria-label": view?.title ?? current?.name ?? "Settings",
|
|
239
|
-
className: "truncate text-
|
|
179
|
+
className: "truncate text-md font-semibold text-[var(--text-primary)]",
|
|
240
180
|
children: /* @__PURE__ */ jsx(TextMorph, { as: "span", children: view?.title ?? current?.name ?? "Settings" })
|
|
241
181
|
}
|
|
242
|
-
),
|
|
243
|
-
!view && current?.subtitle && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-[13px] leading-[18px] text-[var(--st-ink-3)]", children: current.subtitle })
|
|
244
|
-
] }),
|
|
245
|
-
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2.5", children: [
|
|
246
|
-
/* @__PURE__ */ jsx("div", { ref: setStatusSlot, className: "flex items-center" }),
|
|
247
|
-
/* @__PURE__ */ jsx(
|
|
248
|
-
DialogClose,
|
|
249
|
-
{
|
|
250
|
-
"aria-label": "Close",
|
|
251
|
-
className: "grid size-8 place-items-center rounded-[9px] text-[var(--st-ink-2)] transition-colors hover:bg-[var(--st-row-hover)] hover:text-[var(--text-primary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--focus-ring)]",
|
|
252
|
-
children: /* @__PURE__ */ jsx(X, { className: "size-[18px]", strokeWidth: 2 })
|
|
253
|
-
}
|
|
254
182
|
)
|
|
255
|
-
] })
|
|
183
|
+
] }),
|
|
184
|
+
/* @__PURE__ */ jsx("div", { className: "mr-7 flex items-center gap-2", children: /* @__PURE__ */ jsx("div", { ref: setStatusSlot, className: "flex items-center" }) })
|
|
256
185
|
] }),
|
|
257
|
-
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-
|
|
258
|
-
SettingsPanel,
|
|
259
|
-
{
|
|
260
|
-
id: current.id
|
|
261
|
-
},
|
|
262
|
-
current.id
|
|
263
|
-
) }) }) }) }) })
|
|
186
|
+
/* @__PURE__ */ jsx("div", { className: "min-h-0 flex-1 overflow-y-auto px-1 py-4 outline-none", children: current && /* @__PURE__ */ jsx(SettingsDrillProvider, { value: drill, children: /* @__PURE__ */ jsx(SettingsSurface, { variant: "plain", children: /* @__PURE__ */ jsx(SettingsStatusSlot, { element: statusSlot, children: /* @__PURE__ */ jsx(SettingsPanel, { id: current.id }, current.id) }) }) }) })
|
|
264
187
|
] })
|
|
265
188
|
]
|
|
266
189
|
}
|