astryx-dracula 0.6.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BRAND.md +54 -3
- package/README.md +11 -4
- package/USAGE.md +1 -1
- package/astryx-dracula.d.ts +2 -2
- package/astryx-dracula.js +26 -4
- package/astryx-dracula.variants.d.ts +2 -2
- package/package.json +11 -11
- package/shared/auth-chrome-config.ts +0 -4
- package/shared/auth-chrome.tsx +2 -3
- package/shared/chaptered-doc-config.ts +3 -2
- package/shared/order-desk.tsx +52 -54
- package/shared/revenue-chart.tsx +1 -1
- package/shared/scene-castle.tsx +21 -13
- package/templates/ai-chat-landing.tsx +6 -9
- package/templates/ai-chat.tsx +5 -1
- package/templates/centered-hero.tsx +2 -2
- package/templates/classic-gallery.tsx +5 -0
- package/templates/contact-form.tsx +9 -0
- package/templates/dashboard-portfolio.tsx +17 -4
- package/templates/dashboard.tsx +5 -5
- package/templates/detail-page.tsx +20 -28
- package/templates/documentation-design.tsx +3 -0
- package/templates/documentation-technical.tsx +8 -5
- package/templates/documentation.tsx +13 -6
- package/templates/form-two-column.tsx +11 -2
- package/templates/form-wizard.template.mjs +15 -0
- package/templates/form-wizard.tsx +878 -0
- package/templates/gallery-hero.tsx +10 -4
- package/templates/ide.tsx +177 -96
- package/templates/incident-console.tsx +15 -5
- package/templates/kanban-board.tsx +46 -4
- package/templates/library.tsx +12 -3
- package/templates/login-split.tsx +3 -3
- package/templates/login-sso.tsx +9 -17
- package/templates/messaging-shell.tsx +109 -46
- package/templates/mixed-gallery.tsx +6 -0
- package/templates/payment-form.tsx +29 -28
- package/templates/product-detail.tsx +12 -3
- package/templates/product-gallery.tsx +8 -3
- package/templates/product-tour.tsx +11 -7
- package/templates/settings-dialog.tsx +5 -0
- package/templates/settings-sidebar.tsx +603 -584
- package/templates/settings.tsx +5 -2
- package/templates/shell-nav.tsx +23 -3
- package/templates/shell-side-nav.tsx +94 -81
- package/templates/shell-top-nav.tsx +98 -86
- package/templates/table-grouped.tsx +146 -132
- package/templates/{table-page-shoe-store-heatmap.template.mjs → table-page-shoe-store.template.mjs} +1 -1
- package/templates/{table-page-shoe-store-heatmap.tsx → table-page-shoe-store.tsx} +1 -1
- package/templates/table-page.tsx +8 -0
- package/templates/table-tree.template.mjs +16 -0
- package/templates/table-tree.tsx +707 -0
- package/templates/tech-report.tsx +8 -5
- package/templates/theme-showcase.tsx +18 -11
- package/templates/work-item-detail.template.mjs +8 -0
- package/templates/work-item-detail.tsx +1049 -0
- package/theme.css +38 -3
- package/theme.css.d.ts +2 -2
- package/tokens.css +41 -4
|
@@ -31,6 +31,7 @@ import { Tab, TabList } from "@astryxdesign/core/TabList";
|
|
|
31
31
|
import { Heading, Text } from "@astryxdesign/core/Text";
|
|
32
32
|
import { TextInput } from "@astryxdesign/core/TextInput";
|
|
33
33
|
import { Toolbar } from "@astryxdesign/core/Toolbar";
|
|
34
|
+
import { VisuallyHidden } from "@astryxdesign/core/VisuallyHidden";
|
|
34
35
|
import type { InfoRow } from "astryx-dracula/shared/settings-data";
|
|
35
36
|
import {
|
|
36
37
|
actionNoWrap,
|
|
@@ -50,10 +51,13 @@ import { ArrowLeft, ChevronRight, Lock, Monitor, ShieldCheck, Wrench } from "luc
|
|
|
50
51
|
import { type CSSProperties, useState } from "react";
|
|
51
52
|
|
|
52
53
|
// Anchor the page to the viewport height so the sidebar + content fill the
|
|
53
|
-
// screen. Layout height="fill" is
|
|
54
|
-
//
|
|
54
|
+
// screen. `Layout height="fill"` is height:100%, which collapses to auto
|
|
55
|
+
// against a content-sized host; 100dvh is definite and needs no ancestor.
|
|
56
|
+
// `height`, not `minHeight`: a min-height lets the Layout grow with its
|
|
57
|
+
// content and hands the scroll back to the document, which is the failure
|
|
58
|
+
// the fill is supposed to prevent.
|
|
55
59
|
const fillViewport: CSSProperties = {
|
|
56
|
-
|
|
60
|
+
height: "100dvh",
|
|
57
61
|
};
|
|
58
62
|
const rowPadding: CSSProperties = {
|
|
59
63
|
paddingBlock: "var(--spacing-4)",
|
|
@@ -157,642 +161,657 @@ export default function SettingsSidebar() {
|
|
|
157
161
|
// Mobile, nav view: show only the menu (full width, no sidebar slot).
|
|
158
162
|
if (isNarrow && mobileView === "nav") {
|
|
159
163
|
return (
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
164
|
+
<>
|
|
165
|
+
{/* This branch is the whole page on a phone and the nav list carries no
|
|
166
|
+
heading of its own, so the document would have none. */}
|
|
167
|
+
<VisuallyHidden>
|
|
168
|
+
<Heading level={1}>Settings</Heading>
|
|
169
|
+
</VisuallyHidden>
|
|
170
|
+
<Layout
|
|
171
|
+
height="fill"
|
|
172
|
+
style={fillViewport}
|
|
173
|
+
// padding={0}, not padding={2}. This wraps the SAME navList element
|
|
174
|
+
// the desktop LayoutPanel renders with padding={0}, and the navList's
|
|
175
|
+
// own paddingBlock/paddingInline props supply the 16px/12px inset.
|
|
176
|
+
// The extra 8px here is what made the same nav list measure 20px on
|
|
177
|
+
// mobile against 12px on desktop -- and against 24px further down,
|
|
178
|
+
// disagreed with each other too. The container owns no gutter; the
|
|
179
|
+
// list owns its own.
|
|
180
|
+
content={<LayoutContent padding={0}>{navList}</LayoutContent>}
|
|
181
|
+
/>
|
|
182
|
+
</>
|
|
172
183
|
);
|
|
173
184
|
}
|
|
174
185
|
|
|
175
186
|
return (
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
187
|
+
<>
|
|
188
|
+
{/* The nav list is the whole page at narrow width, and lists no heading. */}
|
|
189
|
+
{isNarrow && (
|
|
190
|
+
<VisuallyHidden>
|
|
191
|
+
<Heading level={1}>Settings</Heading>
|
|
192
|
+
</VisuallyHidden>
|
|
193
|
+
)}
|
|
194
|
+
<Layout
|
|
195
|
+
height="fill"
|
|
196
|
+
contentWidth={1200}
|
|
197
|
+
style={fillViewport}
|
|
198
|
+
start={
|
|
199
|
+
isNarrow ? undefined : (
|
|
200
|
+
<LayoutPanel hasDivider padding={0}>
|
|
201
|
+
{navList}
|
|
202
|
+
</LayoutPanel>
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
content={
|
|
206
|
+
<LayoutContent padding={6}>
|
|
207
|
+
<VStack gap={0}>
|
|
208
|
+
{/* Mobile detail view: a back button sits beside the section title
|
|
191
209
|
(the per-section headings below are hidden on mobile). Toolbar's
|
|
192
210
|
start slot edge-compensates the ghost button so its icon aligns
|
|
193
211
|
flush with the content edge. */}
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
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
|
-
|
|
212
|
+
{isNarrow && (
|
|
213
|
+
<Toolbar
|
|
214
|
+
label={`Back to Account settings: ${activeNav === HOSTING_TOOLS_TITLE ? "Hosting tools" : activeNav}`}
|
|
215
|
+
gap={2}
|
|
216
|
+
startContent={
|
|
217
|
+
<>
|
|
218
|
+
<Button
|
|
219
|
+
label="Back to Account settings"
|
|
220
|
+
variant="ghost"
|
|
221
|
+
size="sm"
|
|
222
|
+
isIconOnly
|
|
223
|
+
icon={<Icon icon={ArrowLeft} size="sm" />}
|
|
224
|
+
onClick={() => setMobileView("nav")}
|
|
225
|
+
/>
|
|
226
|
+
<Heading level={1}>
|
|
227
|
+
{activeNav === HOSTING_TOOLS_TITLE ? "Hosting tools" : activeNav}
|
|
228
|
+
</Heading>
|
|
229
|
+
</>
|
|
230
|
+
}
|
|
231
|
+
/>
|
|
232
|
+
)}
|
|
233
|
+
{activeNav === "Login & security" && (
|
|
234
|
+
<VStack gap={6}>
|
|
235
|
+
{!isNarrow && <Heading level={1}>Login & security</Heading>}
|
|
236
|
+
|
|
237
|
+
<TabList value={activeTab} onChange={setActiveTab} hasDivider>
|
|
238
|
+
<Tab value="login" label="Login" />
|
|
239
|
+
<Tab value="shared" label="Shared access" />
|
|
240
|
+
</TabList>
|
|
241
|
+
|
|
242
|
+
{activeTab === "login" && (
|
|
243
|
+
<VStack gap={8}>
|
|
244
|
+
<VStack gap={2}>
|
|
245
|
+
<Heading level={2}>Login</Heading>
|
|
246
|
+
{LOGIN_ROWS.map((row) => (
|
|
247
|
+
<InfoRowItem
|
|
248
|
+
key={row.label}
|
|
249
|
+
{...row}
|
|
250
|
+
hasDivider={false}
|
|
251
|
+
style={rowPadding}
|
|
252
|
+
/>
|
|
253
|
+
))}
|
|
254
|
+
</VStack>
|
|
255
|
+
|
|
256
|
+
<VStack gap={2}>
|
|
257
|
+
<Heading level={2}>Social accounts</Heading>
|
|
258
|
+
{SOCIAL_ROWS.map((row) => (
|
|
259
|
+
<InfoRowItem
|
|
260
|
+
key={row.label}
|
|
261
|
+
{...row}
|
|
262
|
+
hasDivider={false}
|
|
263
|
+
style={rowPadding}
|
|
264
|
+
/>
|
|
265
|
+
))}
|
|
266
|
+
</VStack>
|
|
267
|
+
|
|
268
|
+
<VStack gap={2}>
|
|
269
|
+
<Heading level={2}>Device history</Heading>
|
|
270
|
+
{DEVICE_ROWS.map((device) => (
|
|
271
|
+
<HStack key={device.location} gap={3} vAlign="start" style={rowPadding}>
|
|
272
|
+
<Icon icon={Monitor} />
|
|
273
|
+
<StackItem size="fill">
|
|
274
|
+
<VStack gap={1}>
|
|
275
|
+
<HStack gap={2} vAlign="center" wrap="wrap">
|
|
276
|
+
<Text type="body" weight="semibold">
|
|
277
|
+
{device.label}
|
|
278
|
+
</Text>
|
|
279
|
+
{device.isCurrent && (
|
|
280
|
+
<HStack gap={1} vAlign="center">
|
|
281
|
+
<StatusDot variant="success" label="Current session" />
|
|
282
|
+
<Text type="supporting" color="secondary">
|
|
283
|
+
Current session
|
|
284
|
+
</Text>
|
|
285
|
+
</HStack>
|
|
286
|
+
)}
|
|
287
|
+
</HStack>
|
|
288
|
+
<Text
|
|
289
|
+
type="supporting"
|
|
290
|
+
color="secondary"
|
|
291
|
+
display="block"
|
|
292
|
+
hasTabularNumbers
|
|
293
|
+
>
|
|
294
|
+
{device.location}
|
|
260
295
|
</Text>
|
|
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
|
-
|
|
296
|
+
</VStack>
|
|
297
|
+
</StackItem>
|
|
298
|
+
{device.action && (
|
|
299
|
+
/* No handler: the showcase has no backend, and an
|
|
300
|
+
empty onClick makes an unwired control look wired.
|
|
301
|
+
The shared rows take the same stance. */
|
|
302
|
+
<Button
|
|
303
|
+
label={device.action}
|
|
304
|
+
variant="secondary"
|
|
305
|
+
size="sm"
|
|
306
|
+
style={actionNoWrap}
|
|
307
|
+
/>
|
|
308
|
+
)}
|
|
309
|
+
</HStack>
|
|
310
|
+
))}
|
|
311
|
+
</VStack>
|
|
312
|
+
|
|
313
|
+
<VStack gap={2}>
|
|
314
|
+
<Heading level={2}>Account</Heading>
|
|
315
|
+
<HStack hAlign="between" vAlign="start" style={rowPadding}>
|
|
316
|
+
<VStack gap={1}>
|
|
317
|
+
<Text type="body" weight="semibold" display="block">
|
|
318
|
+
Deactivate your account
|
|
319
|
+
</Text>
|
|
320
|
+
<Text type="supporting" color="secondary" display="block">
|
|
321
|
+
This action cannot be undone
|
|
322
|
+
</Text>
|
|
323
|
+
</VStack>
|
|
324
|
+
<Button
|
|
325
|
+
label="Deactivate"
|
|
326
|
+
variant="secondary"
|
|
327
|
+
size="sm"
|
|
328
|
+
style={actionNoWrap}
|
|
329
|
+
/>
|
|
289
330
|
</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>
|
|
331
|
+
</VStack>
|
|
312
332
|
</VStack>
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
</
|
|
333
|
+
)}
|
|
334
|
+
|
|
335
|
+
{activeTab === "shared" && (
|
|
336
|
+
<VStack gap={8}>
|
|
337
|
+
<VStack gap={2}>
|
|
338
|
+
<Heading level={2}>Shared access</Heading>
|
|
339
|
+
<Text type="body" color="secondary">
|
|
340
|
+
Review each request carefully before approving access. We'll email
|
|
341
|
+
your kin or coven-mate a 4-digit code that lets them enter your crypt from
|
|
342
|
+
their trusted device.
|
|
343
|
+
</Text>
|
|
344
|
+
</VStack>
|
|
345
|
+
|
|
346
|
+
<Card variant="muted">
|
|
347
|
+
<HStack gap={4} vAlign="start">
|
|
348
|
+
<Center width={48} height={48} style={iconBox}>
|
|
349
|
+
<Icon icon={Lock} />
|
|
350
|
+
</Center>
|
|
351
|
+
<VStack gap={1}>
|
|
352
|
+
<Text type="body">Adding devices from people you trust</Text>
|
|
353
|
+
<Text type="body" color="secondary">
|
|
354
|
+
When you approve a request, you grant someone full access to your
|
|
355
|
+
account. They'll be able to change reservations and send messages
|
|
356
|
+
on your behalf.
|
|
357
|
+
</Text>
|
|
358
|
+
</VStack>
|
|
359
|
+
</HStack>
|
|
360
|
+
</Card>
|
|
325
361
|
</VStack>
|
|
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
|
-
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
|
|
362
|
+
)}
|
|
363
|
+
</VStack>
|
|
364
|
+
)}
|
|
365
|
+
|
|
366
|
+
{activeNav === "Languages & currency" && (
|
|
367
|
+
<VStack gap={6}>
|
|
368
|
+
{!isNarrow && <Heading level={1}>Languages & currency</Heading>}
|
|
369
|
+
<VStack gap={0}>
|
|
370
|
+
<ExpandableRow
|
|
371
|
+
label="Preferred language"
|
|
372
|
+
value={LANGUAGES.find((l) => l.value === language)?.label ?? language}
|
|
373
|
+
isExpanded={expandedRow === "language"}
|
|
374
|
+
onEdit={() => setExpandedRow("language")}
|
|
375
|
+
onCancel={() => setExpandedRow(null)}
|
|
376
|
+
onSave={() => setExpandedRow(null)}
|
|
377
|
+
hasDivider={false}
|
|
378
|
+
style={rowPadding}
|
|
379
|
+
>
|
|
380
|
+
<Selector
|
|
381
|
+
label="Language"
|
|
382
|
+
isLabelHidden
|
|
383
|
+
size="lg"
|
|
384
|
+
value={language}
|
|
385
|
+
onChange={setLanguage}
|
|
386
|
+
options={LANGUAGES}
|
|
387
|
+
/>
|
|
388
|
+
</ExpandableRow>
|
|
389
|
+
<ExpandableRow
|
|
390
|
+
label="Preferred currency"
|
|
391
|
+
value={CURRENCIES.find((c) => c.value === currency)?.label ?? currency}
|
|
392
|
+
isExpanded={expandedRow === "currency"}
|
|
393
|
+
onEdit={() => setExpandedRow("currency")}
|
|
394
|
+
onCancel={() => setExpandedRow(null)}
|
|
395
|
+
onSave={() => setExpandedRow(null)}
|
|
396
|
+
hasDivider={false}
|
|
397
|
+
style={rowPadding}
|
|
398
|
+
>
|
|
399
|
+
<Selector
|
|
400
|
+
label="Currency"
|
|
401
|
+
isLabelHidden
|
|
402
|
+
size="lg"
|
|
403
|
+
value={currency}
|
|
404
|
+
onChange={setCurrency}
|
|
405
|
+
options={CURRENCIES}
|
|
406
|
+
/>
|
|
407
|
+
</ExpandableRow>
|
|
408
|
+
<ExpandableRow
|
|
400
409
|
label="Time zone"
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
410
|
+
value={TIMEZONES.find((t) => t.value === timezone)?.label ?? timezone}
|
|
411
|
+
isExpanded={expandedRow === "timezone"}
|
|
412
|
+
onEdit={() => setExpandedRow("timezone")}
|
|
413
|
+
onCancel={() => setExpandedRow(null)}
|
|
414
|
+
onSave={() => setExpandedRow(null)}
|
|
415
|
+
hasDivider={false}
|
|
416
|
+
style={rowPadding}
|
|
417
|
+
>
|
|
418
|
+
<Selector
|
|
419
|
+
label="Time zone"
|
|
420
|
+
isLabelHidden
|
|
421
|
+
size="lg"
|
|
422
|
+
value={timezone}
|
|
423
|
+
onChange={setTimezone}
|
|
424
|
+
options={TIMEZONES}
|
|
425
|
+
/>
|
|
426
|
+
</ExpandableRow>
|
|
427
|
+
</VStack>
|
|
408
428
|
</VStack>
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
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
|
|
429
|
+
)}
|
|
430
|
+
|
|
431
|
+
{activeNav === "Personal information" && (
|
|
432
|
+
<VStack gap={6}>
|
|
433
|
+
{!isNarrow && <Heading level={1}>Personal information</Heading>}
|
|
434
|
+
<VStack gap={0}>
|
|
435
|
+
<ExpandableRow
|
|
427
436
|
label="Legal name"
|
|
428
|
-
isLabelHidden
|
|
429
437
|
value={legalName}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
438
|
+
isExpanded={expandedRow === "legalName"}
|
|
439
|
+
onEdit={() => setExpandedRow("legalName")}
|
|
440
|
+
onCancel={() => setExpandedRow(null)}
|
|
441
|
+
onSave={() => setExpandedRow(null)}
|
|
442
|
+
hasDivider={false}
|
|
443
|
+
style={rowPadding}
|
|
444
|
+
>
|
|
445
|
+
<TextInput
|
|
446
|
+
label="Legal name"
|
|
447
|
+
isLabelHidden
|
|
448
|
+
value={legalName}
|
|
449
|
+
onChange={setLegalName}
|
|
450
|
+
/>
|
|
451
|
+
</ExpandableRow>
|
|
452
|
+
<ExpandableRow
|
|
444
453
|
label="Preferred first name"
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
<
|
|
454
|
+
value={preferredName || "Not provided"}
|
|
455
|
+
isExpanded={expandedRow === "preferredName"}
|
|
456
|
+
onEdit={() => setExpandedRow("preferredName")}
|
|
457
|
+
onCancel={() => setExpandedRow(null)}
|
|
458
|
+
onSave={() => setExpandedRow(null)}
|
|
459
|
+
hasDivider={false}
|
|
460
|
+
style={rowPadding}
|
|
461
|
+
>
|
|
462
|
+
<TextInput
|
|
463
|
+
label="Preferred first name"
|
|
464
|
+
isLabelHidden
|
|
465
|
+
value={preferredName}
|
|
466
|
+
onChange={setPreferredName}
|
|
467
|
+
/>
|
|
468
|
+
</ExpandableRow>
|
|
469
|
+
<ExpandableRow
|
|
461
470
|
label="Email address"
|
|
462
|
-
isLabelHidden
|
|
463
471
|
value={email}
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
472
|
+
isExpanded={expandedRow === "email"}
|
|
473
|
+
onEdit={() => setExpandedRow("email")}
|
|
474
|
+
onCancel={() => setExpandedRow(null)}
|
|
475
|
+
onSave={() => setExpandedRow(null)}
|
|
476
|
+
hasDivider={false}
|
|
477
|
+
style={rowPadding}
|
|
478
|
+
>
|
|
479
|
+
<TextInput
|
|
480
|
+
label="Email address"
|
|
481
|
+
isLabelHidden
|
|
482
|
+
value={email}
|
|
483
|
+
onChange={setEmail}
|
|
484
|
+
/>
|
|
485
|
+
</ExpandableRow>
|
|
486
|
+
<ExpandableRow
|
|
478
487
|
label="Phone number"
|
|
479
|
-
isLabelHidden
|
|
480
488
|
value={phone}
|
|
481
|
-
|
|
489
|
+
isExpanded={expandedRow === "phone"}
|
|
490
|
+
onEdit={() => setExpandedRow("phone")}
|
|
491
|
+
onCancel={() => setExpandedRow(null)}
|
|
492
|
+
onSave={() => setExpandedRow(null)}
|
|
493
|
+
hasDivider={false}
|
|
494
|
+
style={rowPadding}
|
|
495
|
+
>
|
|
496
|
+
<TextInput
|
|
497
|
+
label="Phone number"
|
|
498
|
+
isLabelHidden
|
|
499
|
+
value={phone}
|
|
500
|
+
onChange={setPhone}
|
|
501
|
+
/>
|
|
502
|
+
</ExpandableRow>
|
|
503
|
+
<InfoRowItem
|
|
504
|
+
label="Identity verification"
|
|
505
|
+
value="Verified"
|
|
506
|
+
action=""
|
|
507
|
+
hasDivider={false}
|
|
508
|
+
style={rowPadding}
|
|
482
509
|
/>
|
|
483
|
-
|
|
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
|
|
510
|
+
<ExpandableRow
|
|
502
511
|
label="Residential address"
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
<
|
|
512
|
+
value={address || "Not provided"}
|
|
513
|
+
isExpanded={expandedRow === "address"}
|
|
514
|
+
onEdit={() => setExpandedRow("address")}
|
|
515
|
+
onCancel={() => setExpandedRow(null)}
|
|
516
|
+
onSave={() => setExpandedRow(null)}
|
|
517
|
+
hasDivider={false}
|
|
518
|
+
style={rowPadding}
|
|
519
|
+
>
|
|
520
|
+
<TextInput
|
|
521
|
+
label="Residential address"
|
|
522
|
+
isLabelHidden
|
|
523
|
+
value={address}
|
|
524
|
+
onChange={setAddress}
|
|
525
|
+
/>
|
|
526
|
+
</ExpandableRow>
|
|
527
|
+
<ExpandableRow
|
|
519
528
|
label="Mailing address"
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
<
|
|
529
|
+
value={mailingAddress || "Not provided"}
|
|
530
|
+
isExpanded={expandedRow === "mailingAddress"}
|
|
531
|
+
onEdit={() => setExpandedRow("mailingAddress")}
|
|
532
|
+
onCancel={() => setExpandedRow(null)}
|
|
533
|
+
onSave={() => setExpandedRow(null)}
|
|
534
|
+
hasDivider={false}
|
|
535
|
+
style={rowPadding}
|
|
536
|
+
>
|
|
537
|
+
<TextInput
|
|
538
|
+
label="Mailing address"
|
|
539
|
+
isLabelHidden
|
|
540
|
+
value={mailingAddress}
|
|
541
|
+
onChange={setMailingAddress}
|
|
542
|
+
/>
|
|
543
|
+
</ExpandableRow>
|
|
544
|
+
<ExpandableRow
|
|
536
545
|
label="Emergency contact"
|
|
537
|
-
isLabelHidden
|
|
538
546
|
value={emergencyContact}
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
547
|
+
isExpanded={expandedRow === "emergencyContact"}
|
|
548
|
+
onEdit={() => setExpandedRow("emergencyContact")}
|
|
549
|
+
onCancel={() => setExpandedRow(null)}
|
|
550
|
+
onSave={() => setExpandedRow(null)}
|
|
551
|
+
hasDivider={false}
|
|
552
|
+
style={rowPadding}
|
|
553
|
+
>
|
|
554
|
+
<TextInput
|
|
555
|
+
label="Emergency contact"
|
|
556
|
+
isLabelHidden
|
|
557
|
+
value={emergencyContact}
|
|
558
|
+
onChange={setEmergencyContact}
|
|
559
|
+
/>
|
|
560
|
+
</ExpandableRow>
|
|
561
|
+
</VStack>
|
|
562
|
+
|
|
563
|
+
<Card padding={4}>
|
|
564
|
+
<VStack gap={4}>
|
|
565
|
+
{INFO_TILES.map((tile) => (
|
|
566
|
+
<HStack key={tile.title} gap={3} vAlign="start">
|
|
567
|
+
<Center width={48} height={48} style={iconBox}>
|
|
568
|
+
<Icon icon={tile.icon} />
|
|
569
|
+
</Center>
|
|
570
|
+
<VStack gap={1}>
|
|
571
|
+
<Text type="body" weight="semibold" display="block">
|
|
572
|
+
{tile.title}
|
|
573
|
+
</Text>
|
|
574
|
+
<Text type="body" color="secondary" display="block">
|
|
575
|
+
{tile.body}
|
|
576
|
+
</Text>
|
|
577
|
+
</VStack>
|
|
578
|
+
</HStack>
|
|
579
|
+
))}
|
|
580
|
+
</VStack>
|
|
581
|
+
</Card>
|
|
542
582
|
</VStack>
|
|
583
|
+
)}
|
|
543
584
|
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
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
|
-
)}
|
|
585
|
+
{activeNav === "Privacy" && (
|
|
586
|
+
<VStack gap={6}>
|
|
587
|
+
{!isNarrow && <Heading level={1}>Privacy</Heading>}
|
|
565
588
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
589
|
+
<VStack gap={8}>
|
|
590
|
+
<VStack gap={2}>
|
|
591
|
+
<Heading level={2}>Messages</Heading>
|
|
592
|
+
<VStack style={rowPadding}>
|
|
593
|
+
<Switch
|
|
594
|
+
label="Show people when I've read their messages."
|
|
595
|
+
value={readReceipts}
|
|
596
|
+
onChange={setReadReceipts}
|
|
597
|
+
labelPosition="start"
|
|
598
|
+
labelSpacing="spread"
|
|
599
|
+
/>
|
|
600
|
+
</VStack>
|
|
601
|
+
<HStack hAlign="between" vAlign="center" style={rowPadding}>
|
|
602
|
+
<Text type="body" weight="semibold">
|
|
603
|
+
Blocked people
|
|
604
|
+
</Text>
|
|
605
|
+
<Link href={SELF_HASH}>View</Link>
|
|
606
|
+
</HStack>
|
|
607
|
+
</VStack>
|
|
569
608
|
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
609
|
+
<VStack gap={2}>
|
|
610
|
+
<Heading level={2}>Listings</Heading>
|
|
611
|
+
<VStack style={rowPadding}>
|
|
612
|
+
<Switch
|
|
613
|
+
label="List my wares in the scrying mirrors"
|
|
614
|
+
description="Turning this on means scrying engines, like Google, will show your wares to seekers."
|
|
615
|
+
value={searchEngines}
|
|
616
|
+
onChange={setSearchEngines}
|
|
617
|
+
labelPosition="start"
|
|
618
|
+
labelSpacing="spread"
|
|
619
|
+
/>
|
|
620
|
+
</VStack>
|
|
581
621
|
</VStack>
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
622
|
+
|
|
623
|
+
<VStack gap={4}>
|
|
624
|
+
<Heading level={2}>Reviews</Heading>
|
|
625
|
+
<Text type="body" color="secondary">
|
|
626
|
+
Choose what's shared when you write a review.{" "}
|
|
627
|
+
<Link href={SELF_HASH} type="body" hasUnderline>
|
|
628
|
+
Learn more
|
|
629
|
+
</Link>
|
|
585
630
|
</Text>
|
|
586
|
-
<
|
|
587
|
-
|
|
588
|
-
|
|
631
|
+
<VStack gap={4}>
|
|
632
|
+
<Switch
|
|
633
|
+
label="Show my home haunt and country"
|
|
634
|
+
description="Ex: City and country"
|
|
635
|
+
value={showCity}
|
|
636
|
+
onChange={setShowCity}
|
|
637
|
+
labelPosition="start"
|
|
638
|
+
labelSpacing="spread"
|
|
639
|
+
/>
|
|
640
|
+
<Switch
|
|
641
|
+
label="Show my journey type"
|
|
642
|
+
description="Ex: Rested with kin or familiars"
|
|
643
|
+
value={showTripType}
|
|
644
|
+
onChange={setShowTripType}
|
|
645
|
+
labelPosition="start"
|
|
646
|
+
labelSpacing="spread"
|
|
647
|
+
/>
|
|
648
|
+
<Switch
|
|
649
|
+
label="Show my length of stay"
|
|
650
|
+
description="Ex: A few nights, about a week, etc."
|
|
651
|
+
value={showStayLength}
|
|
652
|
+
onChange={setShowStayLength}
|
|
653
|
+
labelPosition="start"
|
|
654
|
+
labelSpacing="spread"
|
|
655
|
+
/>
|
|
656
|
+
<Switch
|
|
657
|
+
label="Show my booked revels"
|
|
658
|
+
description="Ex: Midnight feasts and tasting rituals"
|
|
659
|
+
value={showServices}
|
|
660
|
+
onChange={setShowServices}
|
|
661
|
+
labelPosition="start"
|
|
662
|
+
labelSpacing="spread"
|
|
663
|
+
/>
|
|
664
|
+
</VStack>
|
|
665
|
+
</VStack>
|
|
589
666
|
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
667
|
+
<VStack gap={4}>
|
|
668
|
+
<Heading level={2}>Data privacy</Heading>
|
|
669
|
+
<Card>
|
|
670
|
+
<HStack hAlign="between" vAlign="center">
|
|
671
|
+
<Text type="body">Request my personal data</Text>
|
|
672
|
+
<Button
|
|
673
|
+
label="Request"
|
|
674
|
+
variant="secondary"
|
|
675
|
+
size="sm"
|
|
676
|
+
style={actionNoWrap}
|
|
677
|
+
/>
|
|
678
|
+
</HStack>
|
|
679
|
+
</Card>
|
|
593
680
|
<Switch
|
|
594
|
-
label="
|
|
595
|
-
description="
|
|
596
|
-
value={
|
|
597
|
-
onChange={
|
|
681
|
+
label="Help improve AI-powered features"
|
|
682
|
+
description="When this is on, we use your data to develop and improve AI models."
|
|
683
|
+
value={aiFeatures}
|
|
684
|
+
onChange={setAiFeatures}
|
|
598
685
|
labelPosition="start"
|
|
599
686
|
labelSpacing="spread"
|
|
600
687
|
/>
|
|
688
|
+
<Card>
|
|
689
|
+
<HStack hAlign="between" vAlign="center">
|
|
690
|
+
<Text type="body">Delete my account</Text>
|
|
691
|
+
<Button
|
|
692
|
+
label="Delete"
|
|
693
|
+
variant="secondary"
|
|
694
|
+
size="sm"
|
|
695
|
+
style={actionNoWrap}
|
|
696
|
+
/>
|
|
697
|
+
</HStack>
|
|
698
|
+
</Card>
|
|
699
|
+
<Card variant="muted">
|
|
700
|
+
<HStack gap={4} vAlign="start">
|
|
701
|
+
<Center width={48} height={48} style={iconBox}>
|
|
702
|
+
<Icon icon={ShieldCheck} />
|
|
703
|
+
</Center>
|
|
704
|
+
<VStack gap={1}>
|
|
705
|
+
<Text type="body">Committed to privacy</Text>
|
|
706
|
+
<Text type="body" color="secondary">
|
|
707
|
+
We're committed to keeping your data protected. See details in
|
|
708
|
+
our{" "}
|
|
709
|
+
<Link href={SELF_HASH} type="supporting" hasUnderline>
|
|
710
|
+
Privacy Policy
|
|
711
|
+
</Link>
|
|
712
|
+
.
|
|
713
|
+
</Text>
|
|
714
|
+
</VStack>
|
|
715
|
+
</HStack>
|
|
716
|
+
</Card>
|
|
601
717
|
</VStack>
|
|
602
718
|
</VStack>
|
|
719
|
+
</VStack>
|
|
720
|
+
)}
|
|
603
721
|
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
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
|
-
/>
|
|
722
|
+
{activeNav === "Notifications" && (
|
|
723
|
+
<VStack gap={6}>
|
|
724
|
+
{!isNarrow && <Heading level={1}>Notifications</Heading>}
|
|
725
|
+
<VStack gap={2}>
|
|
726
|
+
<Heading level={2}>Messages</Heading>
|
|
727
|
+
<VStack gap={4} style={rowPadding}>
|
|
629
728
|
<Switch
|
|
630
|
-
label="
|
|
631
|
-
description="
|
|
632
|
-
value={
|
|
633
|
-
onChange={
|
|
729
|
+
label="Email notifications"
|
|
730
|
+
description="Coven updates, journey reminders, and crypt activity."
|
|
731
|
+
value={emailNotif}
|
|
732
|
+
onChange={setEmailNotif}
|
|
634
733
|
labelPosition="start"
|
|
635
734
|
labelSpacing="spread"
|
|
636
735
|
/>
|
|
637
736
|
<Switch
|
|
638
|
-
label="
|
|
639
|
-
description="
|
|
640
|
-
value={
|
|
641
|
-
onChange={
|
|
737
|
+
label="Push notifications"
|
|
738
|
+
description="Swift ravens for messages and booking requests."
|
|
739
|
+
value={pushNotif}
|
|
740
|
+
onChange={setPushNotif}
|
|
642
741
|
labelPosition="start"
|
|
643
742
|
labelSpacing="spread"
|
|
644
743
|
/>
|
|
645
744
|
</VStack>
|
|
646
745
|
</VStack>
|
|
746
|
+
</VStack>
|
|
747
|
+
)}
|
|
647
748
|
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
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>
|
|
749
|
+
{activeNav === "Taxes" && (
|
|
750
|
+
<VStack gap={6}>
|
|
751
|
+
{!isNarrow && <Heading level={1}>Taxes</Heading>}
|
|
752
|
+
<VStack gap={2}>
|
|
753
|
+
<Heading level={2}>Tax scrolls</Heading>
|
|
754
|
+
{TAX_ROWS.map((row) => (
|
|
755
|
+
<InfoRowItem key={row.label} {...row} hasDivider={false} style={rowPadding} />
|
|
756
|
+
))}
|
|
699
757
|
</VStack>
|
|
700
758
|
</VStack>
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
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
|
-
/>
|
|
759
|
+
)}
|
|
760
|
+
|
|
761
|
+
{activeNav === "Payments" && (
|
|
762
|
+
<VStack gap={6}>
|
|
763
|
+
{!isNarrow && <Heading level={1}>Payments</Heading>}
|
|
764
|
+
<VStack gap={2}>
|
|
765
|
+
<Heading level={2}>Payout crypt</Heading>
|
|
766
|
+
{PAYOUT_ROWS.map((row) => (
|
|
767
|
+
<InfoRowItem key={row.label} {...row} hasDivider={false} style={rowPadding} />
|
|
768
|
+
))}
|
|
726
769
|
</VStack>
|
|
727
770
|
</VStack>
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
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
|
-
/>
|
|
771
|
+
)}
|
|
772
|
+
|
|
773
|
+
{activeNav === "Travel for work" && (
|
|
774
|
+
<VStack gap={6}>
|
|
775
|
+
{!isNarrow && <Heading level={1}>Travel for work</Heading>}
|
|
776
|
+
<VStack gap={2}>
|
|
777
|
+
<Heading level={2}>Work haunts</Heading>
|
|
778
|
+
<VStack style={rowPadding}>
|
|
779
|
+
<Switch
|
|
780
|
+
label="Show night-errand options at checkout"
|
|
781
|
+
description="Add a coven address to expense night errands and unlock travel-ready wares."
|
|
782
|
+
value={workTrips}
|
|
783
|
+
onChange={setWorkTrips}
|
|
784
|
+
labelPosition="start"
|
|
785
|
+
labelSpacing="spread"
|
|
786
|
+
/>
|
|
787
|
+
</VStack>
|
|
769
788
|
</VStack>
|
|
770
789
|
</VStack>
|
|
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
|
-
|
|
790
|
+
)}
|
|
791
|
+
|
|
792
|
+
{activeNav === "Professional hosting tools" && (
|
|
793
|
+
<VStack gap={6}>
|
|
794
|
+
{!isNarrow && <Heading level={1}>Professional hosting tools</Heading>}
|
|
795
|
+
<Card variant="muted">
|
|
796
|
+
<HStack gap={4} vAlign="start">
|
|
797
|
+
<Center width={48} height={48} style={iconBox}>
|
|
798
|
+
<Icon icon={Wrench} />
|
|
799
|
+
</Center>
|
|
800
|
+
<VStack gap={1}>
|
|
801
|
+
<Text type="body">Hosting grimoire</Text>
|
|
802
|
+
<Text type="body" color="secondary">
|
|
803
|
+
Manage multiple listings, route tasks to co-hosts, and review consolidated
|
|
804
|
+
payouts from one place.
|
|
805
|
+
</Text>
|
|
806
|
+
</VStack>
|
|
807
|
+
</HStack>
|
|
808
|
+
</Card>
|
|
809
|
+
</VStack>
|
|
810
|
+
)}
|
|
811
|
+
</VStack>
|
|
812
|
+
</LayoutContent>
|
|
813
|
+
}
|
|
814
|
+
/>
|
|
815
|
+
</>
|
|
797
816
|
);
|
|
798
817
|
}
|