astryx-dracula 0.5.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/BRAND.md +3 -3
- package/README.md +7 -4
- package/USAGE.md +49 -49
- package/astryx-dracula.d.ts +2 -2
- package/astryx-dracula.js +25 -9
- package/astryx-dracula.variants.d.ts +2 -2
- package/astryx.integration.mjs +1 -1
- package/icons.mjs +21 -17
- package/icons.tsx +69 -62
- package/package.json +125 -120
- package/shared/auth-chrome-config.ts +6 -6
- package/shared/auth-chrome.tsx +143 -144
- package/shared/auth-copy.ts +14 -14
- package/shared/chaptered-doc-config.ts +48 -51
- package/shared/chaptered-doc.tsx +267 -289
- package/shared/chart-hues.ts +25 -10
- package/shared/chart-labels.tsx +31 -30
- package/shared/chart-legend.tsx +55 -56
- package/shared/chart-panel-style.ts +3 -3
- package/shared/data-bar.tsx +97 -102
- package/shared/format-money.ts +1 -1
- package/shared/gallery-image.ts +6 -6
- package/shared/login-demo.ts +1 -1
- package/shared/metric-card.tsx +101 -105
- package/shared/metric-delta.tsx +28 -27
- package/shared/order-desk.tsx +205 -216
- package/shared/revenue-chart.tsx +145 -165
- package/shared/scene-castle.tsx +206 -291
- package/shared/scene-frame.tsx +33 -32
- package/shared/scene-hues.ts +17 -17
- package/shared/scene-tile.tsx +88 -92
- package/shared/settings-data.ts +119 -125
- package/shared/settings-rows.tsx +122 -159
- package/shared/sparkline.tsx +75 -88
- package/shared/sso-icons.tsx +10 -22
- package/shared/stars.tsx +16 -25
- package/templates/ai-chat-landing.template.mjs +5 -4
- package/templates/ai-chat-landing.tsx +473 -460
- package/templates/ai-chat.template.mjs +5 -4
- package/templates/ai-chat.tsx +543 -612
- package/templates/blank.template.mjs +5 -4
- package/templates/blank.tsx +18 -14
- package/templates/centered-hero.template.mjs +5 -4
- package/templates/centered-hero.tsx +55 -68
- package/templates/classic-gallery.template.mjs +5 -4
- package/templates/classic-gallery.tsx +97 -104
- package/templates/contact-form.template.mjs +5 -4
- package/templates/contact-form.tsx +247 -282
- package/templates/dashboard-portfolio.template.mjs +5 -4
- package/templates/dashboard-portfolio.tsx +717 -548
- package/templates/dashboard.template.mjs +5 -4
- package/templates/dashboard.tsx +596 -567
- package/templates/detail-page.template.mjs +5 -4
- package/templates/detail-page.tsx +546 -603
- package/templates/documentation-design.template.mjs +5 -4
- package/templates/documentation-design.tsx +231 -243
- package/templates/documentation-technical.template.mjs +5 -4
- package/templates/documentation-technical.tsx +236 -239
- package/templates/documentation.template.mjs +5 -4
- package/templates/documentation.tsx +267 -279
- package/templates/editor.template.mjs +5 -4
- package/templates/editor.tsx +844 -877
- package/templates/file-explorer.template.mjs +5 -4
- package/templates/file-explorer.tsx +566 -590
- package/templates/form-two-column.template.mjs +5 -4
- package/templates/form-two-column.tsx +195 -210
- package/templates/gallery-hero.template.mjs +5 -4
- package/templates/gallery-hero.tsx +93 -114
- package/templates/ide.template.mjs +5 -4
- package/templates/ide.tsx +407 -453
- package/templates/incident-console.template.mjs +5 -4
- package/templates/incident-console.tsx +593 -575
- package/templates/kanban-board.template.mjs +5 -4
- package/templates/kanban-board.tsx +665 -683
- package/templates/library.template.mjs +5 -4
- package/templates/library.tsx +409 -430
- package/templates/login-card.template.mjs +5 -4
- package/templates/login-card.tsx +63 -72
- package/templates/login-split.template.mjs +5 -4
- package/templates/login-split.tsx +192 -193
- package/templates/login-sso.template.mjs +5 -4
- package/templates/login-sso.tsx +257 -258
- package/templates/login.template.mjs +5 -4
- package/templates/login.tsx +53 -49
- package/templates/messaging-shell.template.mjs +5 -4
- package/templates/messaging-shell.tsx +556 -574
- package/templates/mixed-gallery.template.mjs +5 -4
- package/templates/mixed-gallery.tsx +60 -58
- package/templates/payment-form.template.mjs +5 -4
- package/templates/payment-form.tsx +882 -991
- package/templates/product-detail.template.mjs +5 -4
- package/templates/product-detail.tsx +261 -272
- package/templates/product-gallery.template.mjs +5 -4
- package/templates/product-gallery.tsx +126 -137
- package/templates/product-tour.template.mjs +5 -4
- package/templates/product-tour.tsx +741 -773
- package/templates/settings-dialog.template.mjs +5 -4
- package/templates/settings-dialog.tsx +688 -717
- package/templates/settings-sidebar.template.mjs +5 -4
- package/templates/settings-sidebar.tsx +762 -807
- package/templates/settings.template.mjs +5 -4
- package/templates/settings.tsx +289 -304
- package/templates/shell-nav.template.mjs +5 -4
- package/templates/shell-nav.tsx +212 -219
- package/templates/shell-side-nav.template.mjs +5 -4
- package/templates/shell-side-nav.tsx +135 -157
- package/templates/shell-top-nav.template.mjs +5 -4
- package/templates/shell-top-nav.tsx +182 -203
- package/templates/side-gallery.template.mjs +5 -4
- package/templates/side-gallery.tsx +85 -90
- package/templates/table-grouped.template.mjs +5 -4
- package/templates/table-grouped.tsx +1000 -1053
- package/templates/table-page-chart.template.mjs +5 -4
- package/templates/table-page-chart.tsx +400 -398
- package/templates/table-page-heatmap-status.template.mjs +5 -4
- package/templates/table-page-heatmap-status.tsx +483 -512
- package/templates/table-page-shoe-store-heatmap.template.mjs +5 -4
- package/templates/table-page-shoe-store-heatmap.tsx +748 -746
- package/templates/table-page.template.mjs +5 -4
- package/templates/table-page.tsx +396 -405
- package/templates/table.template.mjs +5 -4
- package/templates/table.tsx +92 -93
- package/templates/tech-report.template.mjs +5 -4
- package/templates/tech-report.tsx +1316 -1304
- package/templates/theme-showcase.template.mjs +5 -4
- package/templates/theme-showcase.tsx +871 -951
- package/theme.css +35 -77
- package/theme.css.d.ts +9 -0
- package/tokens.css +373 -380
|
@@ -1,843 +1,798 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
-
// XLE (canonical structure
|
|
3
|
-
//
|
|
2
|
+
// XLE (canonical structure of the tree below; the CLI had no XLE validator
|
|
3
|
+
// after `astryx layout` was removed in 0.7.0, so this is a reading aid and a
|
|
4
|
+
// human drift check — update it with the file, never alone):
|
|
5
|
+
// L[h=fill] > (LP[divider p=0] > V[g=4 paddingBlock=4 paddingInline=3] > Tx"Account settings"[t=label] + (UL[density=spacious edge=flush] > LI*8) + D + (UL[density=spacious edge=flush] > LI"Professional hosting tools")) + (LC[p=6] > V[g=0] > (Tbar[g=2] > B.ghost"Back to Account settings" + Hd"Personal information"[level=1]) + Hd"Personal information"[level=1] + (V[g=0] > (H[j=between a=start] > (V[g=1] > Tx"Legal name"[weight=semibold] + Tx"Vlad Dracul"[t=body]) + B.secondary"Edit")*7 + (H[j=between a=start] > (V[g=1] > Tx"Identity verification"[weight=semibold] + Tx"Verified"[t=body]))) + (C[p=4] > V[g=4] > (H[g=3 a=start] > Ctr[w=48 h=48] > Ic + (V[g=1] > Tx"Why isn't my info shown here?"[weight=semibold] + Tx[t=body]))*3)) ;; L[h=fill] > LC[p=0] > V[g=4 paddingBlock=4 paddingInline=3] > Tx"Account settings"[t=label] + (UL[density=spacious edge=flush] > LI*8) + D + (UL[density=spacious edge=flush] > LI"Professional hosting tools")
|
|
4
6
|
|
|
5
7
|
/**
|
|
6
8
|
* Settings Panels — account sections with a nav panel and spaced rows. Frame: Layout nav panel (fill) | content column of section views. One (Frame/responsive/container: see XLE header above.)
|
|
7
9
|
*/
|
|
8
10
|
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
+
import { Button } from "@astryxdesign/core/Button";
|
|
12
|
+
import { Card } from "@astryxdesign/core/Card";
|
|
13
|
+
import { Center } from "@astryxdesign/core/Center";
|
|
14
|
+
import { Divider } from "@astryxdesign/core/Divider";
|
|
15
|
+
import { useMediaQuery } from "@astryxdesign/core/hooks";
|
|
16
|
+
import { Icon } from "@astryxdesign/core/Icon";
|
|
11
17
|
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
} from
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import {
|
|
24
|
-
import {
|
|
25
|
-
import {
|
|
26
|
-
import {
|
|
27
|
-
import {
|
|
28
|
-
import {
|
|
29
|
-
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
30
|
-
import {StatusDot} from '@astryxdesign/core/StatusDot';
|
|
31
|
-
import {Icon} from '@astryxdesign/core/Icon';
|
|
32
|
-
import {Center} from '@astryxdesign/core/Center';
|
|
18
|
+
HStack,
|
|
19
|
+
Layout,
|
|
20
|
+
LayoutContent,
|
|
21
|
+
LayoutPanel,
|
|
22
|
+
StackItem,
|
|
23
|
+
VStack,
|
|
24
|
+
} from "@astryxdesign/core/Layout";
|
|
25
|
+
import { Link } from "@astryxdesign/core/Link";
|
|
26
|
+
import { List, ListItem } from "@astryxdesign/core/List";
|
|
27
|
+
import { Selector } from "@astryxdesign/core/Selector";
|
|
28
|
+
import { StatusDot } from "@astryxdesign/core/StatusDot";
|
|
29
|
+
import { Switch } from "@astryxdesign/core/Switch";
|
|
30
|
+
import { Tab, TabList } from "@astryxdesign/core/TabList";
|
|
31
|
+
import { Heading, Text } from "@astryxdesign/core/Text";
|
|
32
|
+
import { TextInput } from "@astryxdesign/core/TextInput";
|
|
33
|
+
import { Toolbar } from "@astryxdesign/core/Toolbar";
|
|
34
|
+
import type { InfoRow } from "astryx-dracula/shared/settings-data";
|
|
33
35
|
import {
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
36
|
+
actionNoWrap,
|
|
37
|
+
CURRENCIES,
|
|
38
|
+
DEVICE_ROWS,
|
|
39
|
+
INFO_TILES,
|
|
40
|
+
iconBox,
|
|
41
|
+
LANGUAGES,
|
|
42
|
+
LOGIN_ROWS,
|
|
43
|
+
NAV_ITEMS,
|
|
44
|
+
SOCIAL_ROWS,
|
|
45
|
+
sideNavHeading,
|
|
46
|
+
TIMEZONES,
|
|
47
|
+
} from "astryx-dracula/shared/settings-data";
|
|
48
|
+
import { ExpandableRow, InfoRowItem } from "astryx-dracula/shared/settings-rows";
|
|
49
|
+
import { ArrowLeft, ChevronRight, Lock, Monitor, ShieldCheck, Wrench } from "lucide-react";
|
|
50
|
+
import { type CSSProperties, useState } from "react";
|
|
44
51
|
|
|
45
52
|
// Anchor the page to the viewport height so the sidebar + content fill the
|
|
46
53
|
// screen. Layout height="fill" is min-height:100% which collapses when the
|
|
47
54
|
// host container is content-sized; Layout has no viewport-height prop.
|
|
48
55
|
const fillViewport: CSSProperties = {
|
|
49
|
-
|
|
56
|
+
minHeight: "100dvh",
|
|
50
57
|
};
|
|
51
58
|
const rowPadding: CSSProperties = {
|
|
52
|
-
|
|
59
|
+
paddingBlock: "var(--spacing-4)",
|
|
53
60
|
};
|
|
54
61
|
|
|
55
62
|
// Same-route hash: demo links stay focusable anchors without escaping the
|
|
56
63
|
// template through the hash router (bare "#" would drop back to the home page).
|
|
57
|
-
const SELF_HASH =
|
|
64
|
+
const SELF_HASH = "#/templates/settings-sidebar";
|
|
58
65
|
|
|
59
66
|
// Title beside the mobile back button: the section's own heading, except the
|
|
60
67
|
// long "Professional hosting tools" which shortens to "Hosting tools".
|
|
61
|
-
const HOSTING_TOOLS_TITLE =
|
|
68
|
+
const HOSTING_TOOLS_TITLE = "Professional hosting tools";
|
|
62
69
|
|
|
63
70
|
// Both record sections pair a setup row ("Add") with a history row that
|
|
64
71
|
// navigates to past records — one factory, not two copied arrays.
|
|
65
72
|
function recordRows(
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
currentLabel: string,
|
|
74
|
+
currentValue: string,
|
|
75
|
+
pastLabel: string,
|
|
76
|
+
pastValue: string,
|
|
70
77
|
): InfoRow[] {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
return [
|
|
79
|
+
{ label: currentLabel, value: currentValue, action: "Add" },
|
|
80
|
+
{
|
|
81
|
+
label: pastLabel,
|
|
82
|
+
value: pastValue,
|
|
83
|
+
action: "View",
|
|
84
|
+
actionKind: "destination",
|
|
85
|
+
href: SELF_HASH,
|
|
86
|
+
},
|
|
87
|
+
];
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
const TAX_ROWS = recordRows(
|
|
84
|
-
'Tax scrolls',
|
|
85
|
-
'Not provided',
|
|
86
|
-
'Past scrolls',
|
|
87
|
-
'No scrolls yet',
|
|
88
|
-
);
|
|
90
|
+
const TAX_ROWS = recordRows("Tax scrolls", "Not provided", "Past scrolls", "No scrolls yet");
|
|
89
91
|
|
|
90
|
-
const PAYOUT_ROWS = recordRows(
|
|
91
|
-
'Payout crypt',
|
|
92
|
-
'Not set up',
|
|
93
|
-
'Past payouts',
|
|
94
|
-
'No tributes yet',
|
|
95
|
-
);
|
|
92
|
+
const PAYOUT_ROWS = recordRows("Payout crypt", "Not set up", "Past payouts", "No tributes yet");
|
|
96
93
|
|
|
97
94
|
export default function SettingsSidebar() {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
}
|
|
195
|
-
content={
|
|
196
|
-
<LayoutContent padding={6}>
|
|
197
|
-
<VStack gap={0}>
|
|
198
|
-
{/* Mobile detail view: a back button sits beside the section title
|
|
95
|
+
const isNarrow = useMediaQuery("(max-width: 768px)");
|
|
96
|
+
// Mobile is a master→detail drill-down: 'nav' shows the menu, 'detail' shows
|
|
97
|
+
// the selected section with a back button. Desktop shows both side-by-side.
|
|
98
|
+
const [mobileView, setMobileView] = useState<"nav" | "detail">("nav");
|
|
99
|
+
const [activeNav, setActiveNav] = useState("Personal information");
|
|
100
|
+
const [activeTab, setActiveTab] = useState("login");
|
|
101
|
+
const [readReceipts, setReadReceipts] = useState(true);
|
|
102
|
+
const [searchEngines, setSearchEngines] = useState(true);
|
|
103
|
+
const [showCity, setShowCity] = useState(true);
|
|
104
|
+
const [showTripType, setShowTripType] = useState(true);
|
|
105
|
+
const [showStayLength, setShowStayLength] = useState(true);
|
|
106
|
+
const [showServices, setShowServices] = useState(true);
|
|
107
|
+
const [aiFeatures, setAiFeatures] = useState(true);
|
|
108
|
+
const [emailNotif, setEmailNotif] = useState(true);
|
|
109
|
+
const [pushNotif, setPushNotif] = useState(true);
|
|
110
|
+
const [workTrips, setWorkTrips] = useState(false);
|
|
111
|
+
|
|
112
|
+
const [expandedRow, setExpandedRow] = useState<string | null>(null);
|
|
113
|
+
const [language, setLanguage] = useState("en-CA");
|
|
114
|
+
const [currency, setCurrency] = useState("CAD");
|
|
115
|
+
const [timezone, setTimezone] = useState("ET");
|
|
116
|
+
|
|
117
|
+
const [legalName, setLegalName] = useState("Vlad Dracul");
|
|
118
|
+
const [preferredName, setPreferredName] = useState("");
|
|
119
|
+
const [email, setEmail] = useState("v***d@castle-dracula.ro");
|
|
120
|
+
const [phone, setPhone] = useState("+1 ***-***-0123");
|
|
121
|
+
const [address, setAddress] = useState("");
|
|
122
|
+
const [mailingAddress, setMailingAddress] = useState("");
|
|
123
|
+
const [emergencyContact, setEmergencyContact] = useState("Provided");
|
|
124
|
+
|
|
125
|
+
// Selecting a nav item also drills into the detail view on mobile.
|
|
126
|
+
const selectNav = (label: string) => {
|
|
127
|
+
setActiveNav(label);
|
|
128
|
+
setMobileView("detail");
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const navList = (
|
|
132
|
+
<VStack gap={4} paddingBlock={4} paddingInline={3}>
|
|
133
|
+
<Text type="label" style={sideNavHeading}>
|
|
134
|
+
Account settings
|
|
135
|
+
</Text>
|
|
136
|
+
<List density="spacious" edge="flush">
|
|
137
|
+
{NAV_ITEMS.map((item) => (
|
|
138
|
+
<ListItem
|
|
139
|
+
key={item.label}
|
|
140
|
+
label={item.label}
|
|
141
|
+
startContent={<Icon icon={item.icon} />}
|
|
142
|
+
endContent={
|
|
143
|
+
isNarrow ? <Icon icon={ChevronRight} size="sm" color="secondary" /> : undefined
|
|
144
|
+
}
|
|
145
|
+
isSelected={!isNarrow && activeNav === item.label}
|
|
146
|
+
onClick={() => selectNav(item.label)}
|
|
147
|
+
/>
|
|
148
|
+
))}
|
|
149
|
+
</List>
|
|
150
|
+
<Divider />
|
|
151
|
+
<List density="spacious" edge="flush">
|
|
152
|
+
<ListItem label="Professional hosting tools" startContent={<Icon icon={Wrench} />} />
|
|
153
|
+
</List>
|
|
154
|
+
</VStack>
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
// Mobile, nav view: show only the menu (full width, no sidebar slot).
|
|
158
|
+
if (isNarrow && mobileView === "nav") {
|
|
159
|
+
return (
|
|
160
|
+
<Layout
|
|
161
|
+
height="fill"
|
|
162
|
+
style={fillViewport}
|
|
163
|
+
// padding={0}, not padding={2}. This wraps the SAME navList element
|
|
164
|
+
// the desktop LayoutPanel renders with padding={0}, and the navList's
|
|
165
|
+
// own paddingBlock/paddingInline props supply the 16px/12px inset.
|
|
166
|
+
// The extra 8px here is what made the same nav list measure 20px on
|
|
167
|
+
// mobile against 12px on desktop -- and against 24px further down,
|
|
168
|
+
// disagreed with each other too. The container owns no gutter; the
|
|
169
|
+
// list owns its own.
|
|
170
|
+
content={<LayoutContent padding={0}>{navList}</LayoutContent>}
|
|
171
|
+
/>
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return (
|
|
176
|
+
<Layout
|
|
177
|
+
height="fill"
|
|
178
|
+
contentWidth={1200}
|
|
179
|
+
style={fillViewport}
|
|
180
|
+
start={
|
|
181
|
+
isNarrow ? undefined : (
|
|
182
|
+
<LayoutPanel hasDivider padding={0}>
|
|
183
|
+
{navList}
|
|
184
|
+
</LayoutPanel>
|
|
185
|
+
)
|
|
186
|
+
}
|
|
187
|
+
content={
|
|
188
|
+
<LayoutContent padding={6}>
|
|
189
|
+
<VStack gap={0}>
|
|
190
|
+
{/* Mobile detail view: a back button sits beside the section title
|
|
199
191
|
(the per-section headings below are hidden on mobile). Toolbar's
|
|
200
192
|
start slot edge-compensates the ghost button so its icon aligns
|
|
201
193
|
flush with the content edge. */}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
onChange={setWorkTrips}
|
|
807
|
-
labelPosition="start"
|
|
808
|
-
labelSpacing="spread"
|
|
809
|
-
/>
|
|
810
|
-
</VStack>
|
|
811
|
-
</VStack>
|
|
812
|
-
</VStack>
|
|
813
|
-
)}
|
|
814
|
-
|
|
815
|
-
{activeNav === 'Professional hosting tools' && (
|
|
816
|
-
<VStack gap={6}>
|
|
817
|
-
{!isNarrow && (
|
|
818
|
-
<Heading level={1}>Professional hosting tools</Heading>
|
|
819
|
-
)}
|
|
820
|
-
<Card variant="muted">
|
|
821
|
-
<HStack gap={4} vAlign="start">
|
|
822
|
-
<Center width={48} height={48} style={iconBox}>
|
|
823
|
-
<Icon icon={Wrench} />
|
|
824
|
-
</Center>
|
|
825
|
-
<VStack gap={1}>
|
|
826
|
-
<Text type="body">
|
|
827
|
-
Hosting grimoire
|
|
828
|
-
</Text>
|
|
829
|
-
<Text type="body" color="secondary">
|
|
830
|
-
Manage multiple listings, route tasks to co-hosts, and
|
|
831
|
-
review consolidated payouts from one place.
|
|
832
|
-
</Text>
|
|
833
|
-
</VStack>
|
|
834
|
-
</HStack>
|
|
835
|
-
</Card>
|
|
836
|
-
</VStack>
|
|
837
|
-
)}
|
|
838
|
-
</VStack>
|
|
839
|
-
</LayoutContent>
|
|
840
|
-
}
|
|
841
|
-
/>
|
|
842
|
-
);
|
|
194
|
+
{isNarrow && (
|
|
195
|
+
<Toolbar
|
|
196
|
+
label={`Back to Account settings: ${activeNav === HOSTING_TOOLS_TITLE ? "Hosting tools" : activeNav}`}
|
|
197
|
+
gap={2}
|
|
198
|
+
startContent={
|
|
199
|
+
<>
|
|
200
|
+
<Button
|
|
201
|
+
label="Back to Account settings"
|
|
202
|
+
variant="ghost"
|
|
203
|
+
size="sm"
|
|
204
|
+
isIconOnly
|
|
205
|
+
icon={<Icon icon={ArrowLeft} size="sm" />}
|
|
206
|
+
onClick={() => setMobileView("nav")}
|
|
207
|
+
/>
|
|
208
|
+
<Heading level={1}>
|
|
209
|
+
{activeNav === HOSTING_TOOLS_TITLE ? "Hosting tools" : activeNav}
|
|
210
|
+
</Heading>
|
|
211
|
+
</>
|
|
212
|
+
}
|
|
213
|
+
/>
|
|
214
|
+
)}
|
|
215
|
+
{activeNav === "Login & security" && (
|
|
216
|
+
<VStack gap={6}>
|
|
217
|
+
{!isNarrow && <Heading level={1}>Login & security</Heading>}
|
|
218
|
+
|
|
219
|
+
<TabList value={activeTab} onChange={setActiveTab} hasDivider>
|
|
220
|
+
<Tab value="login" label="Login" />
|
|
221
|
+
<Tab value="shared" label="Shared access" />
|
|
222
|
+
</TabList>
|
|
223
|
+
|
|
224
|
+
{activeTab === "login" && (
|
|
225
|
+
<VStack gap={8}>
|
|
226
|
+
<VStack gap={2}>
|
|
227
|
+
<Heading level={2}>Login</Heading>
|
|
228
|
+
{LOGIN_ROWS.map((row) => (
|
|
229
|
+
<InfoRowItem
|
|
230
|
+
key={row.label}
|
|
231
|
+
{...row}
|
|
232
|
+
hasDivider={false}
|
|
233
|
+
style={rowPadding}
|
|
234
|
+
/>
|
|
235
|
+
))}
|
|
236
|
+
</VStack>
|
|
237
|
+
|
|
238
|
+
<VStack gap={2}>
|
|
239
|
+
<Heading level={2}>Social accounts</Heading>
|
|
240
|
+
{SOCIAL_ROWS.map((row) => (
|
|
241
|
+
<InfoRowItem
|
|
242
|
+
key={row.label}
|
|
243
|
+
{...row}
|
|
244
|
+
hasDivider={false}
|
|
245
|
+
style={rowPadding}
|
|
246
|
+
/>
|
|
247
|
+
))}
|
|
248
|
+
</VStack>
|
|
249
|
+
|
|
250
|
+
<VStack gap={2}>
|
|
251
|
+
<Heading level={2}>Device history</Heading>
|
|
252
|
+
{DEVICE_ROWS.map((device) => (
|
|
253
|
+
<HStack key={device.location} gap={3} vAlign="start" style={rowPadding}>
|
|
254
|
+
<Icon icon={Monitor} />
|
|
255
|
+
<StackItem size="fill">
|
|
256
|
+
<VStack gap={1}>
|
|
257
|
+
<HStack gap={2} vAlign="center" wrap="wrap">
|
|
258
|
+
<Text type="body" weight="semibold">
|
|
259
|
+
{device.label}
|
|
260
|
+
</Text>
|
|
261
|
+
{device.isCurrent && (
|
|
262
|
+
<HStack gap={1} vAlign="center">
|
|
263
|
+
<StatusDot variant="success" label="Current session" />
|
|
264
|
+
<Text type="supporting" color="secondary">
|
|
265
|
+
Current session
|
|
266
|
+
</Text>
|
|
267
|
+
</HStack>
|
|
268
|
+
)}
|
|
269
|
+
</HStack>
|
|
270
|
+
<Text
|
|
271
|
+
type="supporting"
|
|
272
|
+
color="secondary"
|
|
273
|
+
display="block"
|
|
274
|
+
hasTabularNumbers
|
|
275
|
+
>
|
|
276
|
+
{device.location}
|
|
277
|
+
</Text>
|
|
278
|
+
</VStack>
|
|
279
|
+
</StackItem>
|
|
280
|
+
{device.action && (
|
|
281
|
+
<Button
|
|
282
|
+
label={device.action}
|
|
283
|
+
variant="secondary"
|
|
284
|
+
size="sm"
|
|
285
|
+
onClick={() => {}}
|
|
286
|
+
style={actionNoWrap}
|
|
287
|
+
/>
|
|
288
|
+
)}
|
|
289
|
+
</HStack>
|
|
290
|
+
))}
|
|
291
|
+
</VStack>
|
|
292
|
+
|
|
293
|
+
<VStack gap={2}>
|
|
294
|
+
<Heading level={2}>Account</Heading>
|
|
295
|
+
<HStack hAlign="between" vAlign="start" style={rowPadding}>
|
|
296
|
+
<VStack gap={1}>
|
|
297
|
+
<Text type="body" weight="semibold" display="block">
|
|
298
|
+
Deactivate your account
|
|
299
|
+
</Text>
|
|
300
|
+
<Text type="supporting" color="secondary" display="block">
|
|
301
|
+
This action cannot be undone
|
|
302
|
+
</Text>
|
|
303
|
+
</VStack>
|
|
304
|
+
<Button
|
|
305
|
+
label="Deactivate"
|
|
306
|
+
variant="secondary"
|
|
307
|
+
size="sm"
|
|
308
|
+
onClick={() => {}}
|
|
309
|
+
style={actionNoWrap}
|
|
310
|
+
/>
|
|
311
|
+
</HStack>
|
|
312
|
+
</VStack>
|
|
313
|
+
</VStack>
|
|
314
|
+
)}
|
|
315
|
+
|
|
316
|
+
{activeTab === "shared" && (
|
|
317
|
+
<VStack gap={8}>
|
|
318
|
+
<VStack gap={2}>
|
|
319
|
+
<Heading level={2}>Shared access</Heading>
|
|
320
|
+
<Text type="body" color="secondary">
|
|
321
|
+
Review each request carefully before approving access. We'll email your
|
|
322
|
+
kin or coven-mate a 4-digit code that lets them enter your crypt from their
|
|
323
|
+
trusted device.
|
|
324
|
+
</Text>
|
|
325
|
+
</VStack>
|
|
326
|
+
|
|
327
|
+
<Card variant="muted">
|
|
328
|
+
<HStack gap={4} vAlign="start">
|
|
329
|
+
<Center width={48} height={48} style={iconBox}>
|
|
330
|
+
<Icon icon={Lock} />
|
|
331
|
+
</Center>
|
|
332
|
+
<VStack gap={1}>
|
|
333
|
+
<Text type="body">Adding devices from people you trust</Text>
|
|
334
|
+
<Text type="body" color="secondary">
|
|
335
|
+
When you approve a request, you grant someone full access to your
|
|
336
|
+
account. They'll be able to change reservations and send messages
|
|
337
|
+
on your behalf.
|
|
338
|
+
</Text>
|
|
339
|
+
</VStack>
|
|
340
|
+
</HStack>
|
|
341
|
+
</Card>
|
|
342
|
+
</VStack>
|
|
343
|
+
)}
|
|
344
|
+
</VStack>
|
|
345
|
+
)}
|
|
346
|
+
|
|
347
|
+
{activeNav === "Languages & currency" && (
|
|
348
|
+
<VStack gap={6}>
|
|
349
|
+
{!isNarrow && <Heading level={1}>Languages & currency</Heading>}
|
|
350
|
+
<VStack gap={0}>
|
|
351
|
+
<ExpandableRow
|
|
352
|
+
label="Preferred language"
|
|
353
|
+
value={LANGUAGES.find((l) => l.value === language)?.label ?? language}
|
|
354
|
+
isExpanded={expandedRow === "language"}
|
|
355
|
+
onEdit={() => setExpandedRow("language")}
|
|
356
|
+
onCancel={() => setExpandedRow(null)}
|
|
357
|
+
onSave={() => setExpandedRow(null)}
|
|
358
|
+
hasDivider={false}
|
|
359
|
+
style={rowPadding}
|
|
360
|
+
>
|
|
361
|
+
<Selector
|
|
362
|
+
label="Language"
|
|
363
|
+
isLabelHidden
|
|
364
|
+
size="lg"
|
|
365
|
+
value={language}
|
|
366
|
+
onChange={setLanguage}
|
|
367
|
+
options={LANGUAGES}
|
|
368
|
+
/>
|
|
369
|
+
</ExpandableRow>
|
|
370
|
+
<ExpandableRow
|
|
371
|
+
label="Preferred currency"
|
|
372
|
+
value={CURRENCIES.find((c) => c.value === currency)?.label ?? currency}
|
|
373
|
+
isExpanded={expandedRow === "currency"}
|
|
374
|
+
onEdit={() => setExpandedRow("currency")}
|
|
375
|
+
onCancel={() => setExpandedRow(null)}
|
|
376
|
+
onSave={() => setExpandedRow(null)}
|
|
377
|
+
hasDivider={false}
|
|
378
|
+
style={rowPadding}
|
|
379
|
+
>
|
|
380
|
+
<Selector
|
|
381
|
+
label="Currency"
|
|
382
|
+
isLabelHidden
|
|
383
|
+
size="lg"
|
|
384
|
+
value={currency}
|
|
385
|
+
onChange={setCurrency}
|
|
386
|
+
options={CURRENCIES}
|
|
387
|
+
/>
|
|
388
|
+
</ExpandableRow>
|
|
389
|
+
<ExpandableRow
|
|
390
|
+
label="Time zone"
|
|
391
|
+
value={TIMEZONES.find((t) => t.value === timezone)?.label ?? timezone}
|
|
392
|
+
isExpanded={expandedRow === "timezone"}
|
|
393
|
+
onEdit={() => setExpandedRow("timezone")}
|
|
394
|
+
onCancel={() => setExpandedRow(null)}
|
|
395
|
+
onSave={() => setExpandedRow(null)}
|
|
396
|
+
hasDivider={false}
|
|
397
|
+
style={rowPadding}
|
|
398
|
+
>
|
|
399
|
+
<Selector
|
|
400
|
+
label="Time zone"
|
|
401
|
+
isLabelHidden
|
|
402
|
+
size="lg"
|
|
403
|
+
value={timezone}
|
|
404
|
+
onChange={setTimezone}
|
|
405
|
+
options={TIMEZONES}
|
|
406
|
+
/>
|
|
407
|
+
</ExpandableRow>
|
|
408
|
+
</VStack>
|
|
409
|
+
</VStack>
|
|
410
|
+
)}
|
|
411
|
+
|
|
412
|
+
{activeNav === "Personal information" && (
|
|
413
|
+
<VStack gap={6}>
|
|
414
|
+
{!isNarrow && <Heading level={1}>Personal information</Heading>}
|
|
415
|
+
<VStack gap={0}>
|
|
416
|
+
<ExpandableRow
|
|
417
|
+
label="Legal name"
|
|
418
|
+
value={legalName}
|
|
419
|
+
isExpanded={expandedRow === "legalName"}
|
|
420
|
+
onEdit={() => setExpandedRow("legalName")}
|
|
421
|
+
onCancel={() => setExpandedRow(null)}
|
|
422
|
+
onSave={() => setExpandedRow(null)}
|
|
423
|
+
hasDivider={false}
|
|
424
|
+
style={rowPadding}
|
|
425
|
+
>
|
|
426
|
+
<TextInput
|
|
427
|
+
label="Legal name"
|
|
428
|
+
isLabelHidden
|
|
429
|
+
value={legalName}
|
|
430
|
+
onChange={setLegalName}
|
|
431
|
+
/>
|
|
432
|
+
</ExpandableRow>
|
|
433
|
+
<ExpandableRow
|
|
434
|
+
label="Preferred first name"
|
|
435
|
+
value={preferredName || "Not provided"}
|
|
436
|
+
isExpanded={expandedRow === "preferredName"}
|
|
437
|
+
onEdit={() => setExpandedRow("preferredName")}
|
|
438
|
+
onCancel={() => setExpandedRow(null)}
|
|
439
|
+
onSave={() => setExpandedRow(null)}
|
|
440
|
+
hasDivider={false}
|
|
441
|
+
style={rowPadding}
|
|
442
|
+
>
|
|
443
|
+
<TextInput
|
|
444
|
+
label="Preferred first name"
|
|
445
|
+
isLabelHidden
|
|
446
|
+
value={preferredName}
|
|
447
|
+
onChange={setPreferredName}
|
|
448
|
+
/>
|
|
449
|
+
</ExpandableRow>
|
|
450
|
+
<ExpandableRow
|
|
451
|
+
label="Email address"
|
|
452
|
+
value={email}
|
|
453
|
+
isExpanded={expandedRow === "email"}
|
|
454
|
+
onEdit={() => setExpandedRow("email")}
|
|
455
|
+
onCancel={() => setExpandedRow(null)}
|
|
456
|
+
onSave={() => setExpandedRow(null)}
|
|
457
|
+
hasDivider={false}
|
|
458
|
+
style={rowPadding}
|
|
459
|
+
>
|
|
460
|
+
<TextInput
|
|
461
|
+
label="Email address"
|
|
462
|
+
isLabelHidden
|
|
463
|
+
value={email}
|
|
464
|
+
onChange={setEmail}
|
|
465
|
+
/>
|
|
466
|
+
</ExpandableRow>
|
|
467
|
+
<ExpandableRow
|
|
468
|
+
label="Phone number"
|
|
469
|
+
value={phone}
|
|
470
|
+
isExpanded={expandedRow === "phone"}
|
|
471
|
+
onEdit={() => setExpandedRow("phone")}
|
|
472
|
+
onCancel={() => setExpandedRow(null)}
|
|
473
|
+
onSave={() => setExpandedRow(null)}
|
|
474
|
+
hasDivider={false}
|
|
475
|
+
style={rowPadding}
|
|
476
|
+
>
|
|
477
|
+
<TextInput
|
|
478
|
+
label="Phone number"
|
|
479
|
+
isLabelHidden
|
|
480
|
+
value={phone}
|
|
481
|
+
onChange={setPhone}
|
|
482
|
+
/>
|
|
483
|
+
</ExpandableRow>
|
|
484
|
+
<InfoRowItem
|
|
485
|
+
label="Identity verification"
|
|
486
|
+
value="Verified"
|
|
487
|
+
action=""
|
|
488
|
+
hasDivider={false}
|
|
489
|
+
style={rowPadding}
|
|
490
|
+
/>
|
|
491
|
+
<ExpandableRow
|
|
492
|
+
label="Residential address"
|
|
493
|
+
value={address || "Not provided"}
|
|
494
|
+
isExpanded={expandedRow === "address"}
|
|
495
|
+
onEdit={() => setExpandedRow("address")}
|
|
496
|
+
onCancel={() => setExpandedRow(null)}
|
|
497
|
+
onSave={() => setExpandedRow(null)}
|
|
498
|
+
hasDivider={false}
|
|
499
|
+
style={rowPadding}
|
|
500
|
+
>
|
|
501
|
+
<TextInput
|
|
502
|
+
label="Residential address"
|
|
503
|
+
isLabelHidden
|
|
504
|
+
value={address}
|
|
505
|
+
onChange={setAddress}
|
|
506
|
+
/>
|
|
507
|
+
</ExpandableRow>
|
|
508
|
+
<ExpandableRow
|
|
509
|
+
label="Mailing address"
|
|
510
|
+
value={mailingAddress || "Not provided"}
|
|
511
|
+
isExpanded={expandedRow === "mailingAddress"}
|
|
512
|
+
onEdit={() => setExpandedRow("mailingAddress")}
|
|
513
|
+
onCancel={() => setExpandedRow(null)}
|
|
514
|
+
onSave={() => setExpandedRow(null)}
|
|
515
|
+
hasDivider={false}
|
|
516
|
+
style={rowPadding}
|
|
517
|
+
>
|
|
518
|
+
<TextInput
|
|
519
|
+
label="Mailing address"
|
|
520
|
+
isLabelHidden
|
|
521
|
+
value={mailingAddress}
|
|
522
|
+
onChange={setMailingAddress}
|
|
523
|
+
/>
|
|
524
|
+
</ExpandableRow>
|
|
525
|
+
<ExpandableRow
|
|
526
|
+
label="Emergency contact"
|
|
527
|
+
value={emergencyContact}
|
|
528
|
+
isExpanded={expandedRow === "emergencyContact"}
|
|
529
|
+
onEdit={() => setExpandedRow("emergencyContact")}
|
|
530
|
+
onCancel={() => setExpandedRow(null)}
|
|
531
|
+
onSave={() => setExpandedRow(null)}
|
|
532
|
+
hasDivider={false}
|
|
533
|
+
style={rowPadding}
|
|
534
|
+
>
|
|
535
|
+
<TextInput
|
|
536
|
+
label="Emergency contact"
|
|
537
|
+
isLabelHidden
|
|
538
|
+
value={emergencyContact}
|
|
539
|
+
onChange={setEmergencyContact}
|
|
540
|
+
/>
|
|
541
|
+
</ExpandableRow>
|
|
542
|
+
</VStack>
|
|
543
|
+
|
|
544
|
+
<Card padding={4}>
|
|
545
|
+
<VStack gap={4}>
|
|
546
|
+
{INFO_TILES.map((tile) => (
|
|
547
|
+
<HStack key={tile.title} gap={3} vAlign="start">
|
|
548
|
+
<Center width={48} height={48} style={iconBox}>
|
|
549
|
+
<Icon icon={tile.icon} />
|
|
550
|
+
</Center>
|
|
551
|
+
<VStack gap={1}>
|
|
552
|
+
<Text type="body" weight="semibold" display="block">
|
|
553
|
+
{tile.title}
|
|
554
|
+
</Text>
|
|
555
|
+
<Text type="body" color="secondary" display="block">
|
|
556
|
+
{tile.body}
|
|
557
|
+
</Text>
|
|
558
|
+
</VStack>
|
|
559
|
+
</HStack>
|
|
560
|
+
))}
|
|
561
|
+
</VStack>
|
|
562
|
+
</Card>
|
|
563
|
+
</VStack>
|
|
564
|
+
)}
|
|
565
|
+
|
|
566
|
+
{activeNav === "Privacy" && (
|
|
567
|
+
<VStack gap={6}>
|
|
568
|
+
{!isNarrow && <Heading level={1}>Privacy</Heading>}
|
|
569
|
+
|
|
570
|
+
<VStack gap={8}>
|
|
571
|
+
<VStack gap={2}>
|
|
572
|
+
<Heading level={2}>Messages</Heading>
|
|
573
|
+
<VStack style={rowPadding}>
|
|
574
|
+
<Switch
|
|
575
|
+
label="Show people when I've read their messages."
|
|
576
|
+
value={readReceipts}
|
|
577
|
+
onChange={setReadReceipts}
|
|
578
|
+
labelPosition="start"
|
|
579
|
+
labelSpacing="spread"
|
|
580
|
+
/>
|
|
581
|
+
</VStack>
|
|
582
|
+
<HStack hAlign="between" vAlign="center" style={rowPadding}>
|
|
583
|
+
<Text type="body" weight="semibold">
|
|
584
|
+
Blocked people
|
|
585
|
+
</Text>
|
|
586
|
+
<Link href={SELF_HASH}>View</Link>
|
|
587
|
+
</HStack>
|
|
588
|
+
</VStack>
|
|
589
|
+
|
|
590
|
+
<VStack gap={2}>
|
|
591
|
+
<Heading level={2}>Listings</Heading>
|
|
592
|
+
<VStack style={rowPadding}>
|
|
593
|
+
<Switch
|
|
594
|
+
label="List my wares in the scrying mirrors"
|
|
595
|
+
description="Turning this on means scrying engines, like Google, will show your wares to seekers."
|
|
596
|
+
value={searchEngines}
|
|
597
|
+
onChange={setSearchEngines}
|
|
598
|
+
labelPosition="start"
|
|
599
|
+
labelSpacing="spread"
|
|
600
|
+
/>
|
|
601
|
+
</VStack>
|
|
602
|
+
</VStack>
|
|
603
|
+
|
|
604
|
+
<VStack gap={4}>
|
|
605
|
+
<Heading level={2}>Reviews</Heading>
|
|
606
|
+
<Text type="body" color="secondary">
|
|
607
|
+
Choose what's shared when you write a review.{" "}
|
|
608
|
+
<Link href={SELF_HASH} type="body" hasUnderline>
|
|
609
|
+
Learn more
|
|
610
|
+
</Link>
|
|
611
|
+
</Text>
|
|
612
|
+
<VStack gap={4}>
|
|
613
|
+
<Switch
|
|
614
|
+
label="Show my home haunt and country"
|
|
615
|
+
description="Ex: City and country"
|
|
616
|
+
value={showCity}
|
|
617
|
+
onChange={setShowCity}
|
|
618
|
+
labelPosition="start"
|
|
619
|
+
labelSpacing="spread"
|
|
620
|
+
/>
|
|
621
|
+
<Switch
|
|
622
|
+
label="Show my journey type"
|
|
623
|
+
description="Ex: Rested with kin or familiars"
|
|
624
|
+
value={showTripType}
|
|
625
|
+
onChange={setShowTripType}
|
|
626
|
+
labelPosition="start"
|
|
627
|
+
labelSpacing="spread"
|
|
628
|
+
/>
|
|
629
|
+
<Switch
|
|
630
|
+
label="Show my length of stay"
|
|
631
|
+
description="Ex: A few nights, about a week, etc."
|
|
632
|
+
value={showStayLength}
|
|
633
|
+
onChange={setShowStayLength}
|
|
634
|
+
labelPosition="start"
|
|
635
|
+
labelSpacing="spread"
|
|
636
|
+
/>
|
|
637
|
+
<Switch
|
|
638
|
+
label="Show my booked revels"
|
|
639
|
+
description="Ex: Midnight feasts and tasting rituals"
|
|
640
|
+
value={showServices}
|
|
641
|
+
onChange={setShowServices}
|
|
642
|
+
labelPosition="start"
|
|
643
|
+
labelSpacing="spread"
|
|
644
|
+
/>
|
|
645
|
+
</VStack>
|
|
646
|
+
</VStack>
|
|
647
|
+
|
|
648
|
+
<VStack gap={4}>
|
|
649
|
+
<Heading level={2}>Data privacy</Heading>
|
|
650
|
+
<Card>
|
|
651
|
+
<HStack hAlign="between" vAlign="center">
|
|
652
|
+
<Text type="body">Request my personal data</Text>
|
|
653
|
+
<Button
|
|
654
|
+
label="Request"
|
|
655
|
+
variant="secondary"
|
|
656
|
+
size="sm"
|
|
657
|
+
onClick={() => {}}
|
|
658
|
+
style={actionNoWrap}
|
|
659
|
+
/>
|
|
660
|
+
</HStack>
|
|
661
|
+
</Card>
|
|
662
|
+
<Switch
|
|
663
|
+
label="Help improve AI-powered features"
|
|
664
|
+
description="When this is on, we use your data to develop and improve AI models."
|
|
665
|
+
value={aiFeatures}
|
|
666
|
+
onChange={setAiFeatures}
|
|
667
|
+
labelPosition="start"
|
|
668
|
+
labelSpacing="spread"
|
|
669
|
+
/>
|
|
670
|
+
<Card>
|
|
671
|
+
<HStack hAlign="between" vAlign="center">
|
|
672
|
+
<Text type="body">Delete my account</Text>
|
|
673
|
+
<Button
|
|
674
|
+
label="Delete"
|
|
675
|
+
variant="secondary"
|
|
676
|
+
size="sm"
|
|
677
|
+
onClick={() => {}}
|
|
678
|
+
style={actionNoWrap}
|
|
679
|
+
/>
|
|
680
|
+
</HStack>
|
|
681
|
+
</Card>
|
|
682
|
+
<Card variant="muted">
|
|
683
|
+
<HStack gap={4} vAlign="start">
|
|
684
|
+
<Center width={48} height={48} style={iconBox}>
|
|
685
|
+
<Icon icon={ShieldCheck} />
|
|
686
|
+
</Center>
|
|
687
|
+
<VStack gap={1}>
|
|
688
|
+
<Text type="body">Committed to privacy</Text>
|
|
689
|
+
<Text type="body" color="secondary">
|
|
690
|
+
We're committed to keeping your data protected. See details in our{" "}
|
|
691
|
+
<Link href={SELF_HASH} type="supporting" hasUnderline>
|
|
692
|
+
Privacy Policy
|
|
693
|
+
</Link>
|
|
694
|
+
.
|
|
695
|
+
</Text>
|
|
696
|
+
</VStack>
|
|
697
|
+
</HStack>
|
|
698
|
+
</Card>
|
|
699
|
+
</VStack>
|
|
700
|
+
</VStack>
|
|
701
|
+
</VStack>
|
|
702
|
+
)}
|
|
703
|
+
|
|
704
|
+
{activeNav === "Notifications" && (
|
|
705
|
+
<VStack gap={6}>
|
|
706
|
+
{!isNarrow && <Heading level={1}>Notifications</Heading>}
|
|
707
|
+
<VStack gap={2}>
|
|
708
|
+
<Heading level={2}>Messages</Heading>
|
|
709
|
+
<VStack gap={4} style={rowPadding}>
|
|
710
|
+
<Switch
|
|
711
|
+
label="Email notifications"
|
|
712
|
+
description="Coven updates, journey reminders, and crypt activity."
|
|
713
|
+
value={emailNotif}
|
|
714
|
+
onChange={setEmailNotif}
|
|
715
|
+
labelPosition="start"
|
|
716
|
+
labelSpacing="spread"
|
|
717
|
+
/>
|
|
718
|
+
<Switch
|
|
719
|
+
label="Push notifications"
|
|
720
|
+
description="Swift ravens for messages and booking requests."
|
|
721
|
+
value={pushNotif}
|
|
722
|
+
onChange={setPushNotif}
|
|
723
|
+
labelPosition="start"
|
|
724
|
+
labelSpacing="spread"
|
|
725
|
+
/>
|
|
726
|
+
</VStack>
|
|
727
|
+
</VStack>
|
|
728
|
+
</VStack>
|
|
729
|
+
)}
|
|
730
|
+
|
|
731
|
+
{activeNav === "Taxes" && (
|
|
732
|
+
<VStack gap={6}>
|
|
733
|
+
{!isNarrow && <Heading level={1}>Taxes</Heading>}
|
|
734
|
+
<VStack gap={2}>
|
|
735
|
+
<Heading level={2}>Tax scrolls</Heading>
|
|
736
|
+
{TAX_ROWS.map((row) => (
|
|
737
|
+
<InfoRowItem key={row.label} {...row} hasDivider={false} style={rowPadding} />
|
|
738
|
+
))}
|
|
739
|
+
</VStack>
|
|
740
|
+
</VStack>
|
|
741
|
+
)}
|
|
742
|
+
|
|
743
|
+
{activeNav === "Payments" && (
|
|
744
|
+
<VStack gap={6}>
|
|
745
|
+
{!isNarrow && <Heading level={1}>Payments</Heading>}
|
|
746
|
+
<VStack gap={2}>
|
|
747
|
+
<Heading level={2}>Payout crypt</Heading>
|
|
748
|
+
{PAYOUT_ROWS.map((row) => (
|
|
749
|
+
<InfoRowItem key={row.label} {...row} hasDivider={false} style={rowPadding} />
|
|
750
|
+
))}
|
|
751
|
+
</VStack>
|
|
752
|
+
</VStack>
|
|
753
|
+
)}
|
|
754
|
+
|
|
755
|
+
{activeNav === "Travel for work" && (
|
|
756
|
+
<VStack gap={6}>
|
|
757
|
+
{!isNarrow && <Heading level={1}>Travel for work</Heading>}
|
|
758
|
+
<VStack gap={2}>
|
|
759
|
+
<Heading level={2}>Work haunts</Heading>
|
|
760
|
+
<VStack style={rowPadding}>
|
|
761
|
+
<Switch
|
|
762
|
+
label="Show night-errand options at checkout"
|
|
763
|
+
description="Add a coven address to expense night errands and unlock travel-ready wares."
|
|
764
|
+
value={workTrips}
|
|
765
|
+
onChange={setWorkTrips}
|
|
766
|
+
labelPosition="start"
|
|
767
|
+
labelSpacing="spread"
|
|
768
|
+
/>
|
|
769
|
+
</VStack>
|
|
770
|
+
</VStack>
|
|
771
|
+
</VStack>
|
|
772
|
+
)}
|
|
773
|
+
|
|
774
|
+
{activeNav === "Professional hosting tools" && (
|
|
775
|
+
<VStack gap={6}>
|
|
776
|
+
{!isNarrow && <Heading level={1}>Professional hosting tools</Heading>}
|
|
777
|
+
<Card variant="muted">
|
|
778
|
+
<HStack gap={4} vAlign="start">
|
|
779
|
+
<Center width={48} height={48} style={iconBox}>
|
|
780
|
+
<Icon icon={Wrench} />
|
|
781
|
+
</Center>
|
|
782
|
+
<VStack gap={1}>
|
|
783
|
+
<Text type="body">Hosting grimoire</Text>
|
|
784
|
+
<Text type="body" color="secondary">
|
|
785
|
+
Manage multiple listings, route tasks to co-hosts, and review consolidated
|
|
786
|
+
payouts from one place.
|
|
787
|
+
</Text>
|
|
788
|
+
</VStack>
|
|
789
|
+
</HStack>
|
|
790
|
+
</Card>
|
|
791
|
+
</VStack>
|
|
792
|
+
)}
|
|
793
|
+
</VStack>
|
|
794
|
+
</LayoutContent>
|
|
795
|
+
}
|
|
796
|
+
/>
|
|
797
|
+
);
|
|
843
798
|
}
|