astryx-dracula 0.2.0 → 0.3.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 +30 -18
- package/README.md +22 -11
- package/USAGE.md +29 -10
- package/astryx-dracula.js +19 -13
- package/astryx-dracula.variants.d.ts +15 -0
- package/package.json +59 -17
- package/shared/auth-chrome-config.ts +18 -0
- package/shared/auth-chrome.tsx +25 -0
- package/shared/auth-copy.ts +22 -0
- package/shared/chaptered-doc-config.ts +92 -0
- package/shared/chaptered-doc.tsx +332 -0
- package/shared/chart-hues.ts +27 -0
- package/shared/chart-labels.tsx +44 -0
- package/shared/chart-legend.tsx +100 -0
- package/shared/chart-panel-style.ts +13 -0
- package/shared/data-bar.tsx +160 -0
- package/shared/gallery-image.ts +20 -0
- package/shared/login-demo.ts +7 -0
- package/shared/metric-delta.tsx +36 -0
- package/shared/order-desk.tsx +273 -0
- package/shared/revenue-chart.tsx +174 -0
- package/shared/scene-castle.tsx +322 -0
- package/shared/scene-frame.tsx +88 -0
- package/shared/scene-hues.ts +49 -0
- package/shared/scene-tile.tsx +128 -0
- package/shared/settings-data.ts +125 -0
- package/shared/settings-rows.tsx +179 -0
- package/shared/sparkline.tsx +94 -0
- package/shared/sso-icons.tsx +30 -0
- package/templates/ai-chat-landing.tsx +67 -32
- package/templates/ai-chat.tsx +41 -20
- package/templates/blank.tsx +5 -2
- package/templates/centered-hero.tsx +15 -124
- package/templates/classic-gallery.tsx +21 -65
- package/templates/contact-form.tsx +62 -40
- package/templates/dashboard-portfolio.tsx +146 -227
- package/templates/dashboard.tsx +123 -121
- package/templates/detail-page.tsx +101 -95
- package/templates/documentation-design.template.mjs +1 -1
- package/templates/documentation-design.tsx +85 -96
- package/templates/documentation-technical.template.mjs +1 -1
- package/templates/documentation-technical.tsx +33 -21
- package/templates/documentation.template.mjs +1 -1
- package/templates/documentation.tsx +54 -74
- package/templates/editor.tsx +119 -89
- package/templates/file-explorer.tsx +133 -84
- package/templates/form-two-column.tsx +62 -124
- package/templates/gallery-hero.tsx +17 -171
- package/templates/ide.tsx +27 -21
- package/templates/incident-console.tsx +105 -69
- package/templates/kanban-board.tsx +100 -41
- package/templates/library.template.mjs +2 -2
- package/templates/library.tsx +38 -41
- package/templates/login-card.tsx +59 -86
- package/templates/login-split.tsx +88 -128
- package/templates/login-sso.tsx +107 -68
- package/templates/login.tsx +108 -52
- package/templates/messaging-shell.tsx +172 -143
- package/templates/mixed-gallery.tsx +31 -130
- package/templates/payment-form.tsx +369 -289
- package/templates/product-detail.tsx +40 -57
- package/templates/product-gallery.tsx +31 -40
- package/templates/product-tour.template.mjs +6 -0
- package/templates/product-tour.tsx +916 -0
- package/templates/settings-dialog.tsx +145 -286
- package/templates/settings-sidebar.tsx +179 -267
- package/templates/settings.tsx +42 -13
- package/templates/shell-nav.tsx +32 -23
- package/templates/shell-side-nav.tsx +30 -19
- package/templates/shell-top-nav.tsx +81 -43
- package/templates/side-gallery.tsx +39 -93
- package/templates/table-grouped.tsx +63 -33
- package/templates/table-page-chart.tsx +24 -297
- package/templates/table-page-heatmap-status.tsx +157 -91
- package/templates/table-page-shoe-store-heatmap.tsx +19 -288
- package/templates/table-page.tsx +24 -6
- package/templates/table.tsx +24 -7
- package/templates/tech-report.template.mjs +6 -0
- package/templates/tech-report.tsx +1486 -0
- package/templates/theme-showcase.template.mjs +1 -1
- package/templates/theme-showcase.tsx +313 -249
- package/theme.css +76 -14
- package/tokens.css +425 -30
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
// XLE (canonical structure, validated with `bunx astryx layout check`):
|
|
3
|
+
// L > (LP[p=0] > V[g=4] > Tx"Account settings"[t=label] + (UL > LI*8) + D + LI"Professional hosting tools") + (LC[p=6] > V[g=0] > (Tbar > B.ghost + Hd"Personal info"[level=1]) + Hd"Personal info"[level=1] + (V[g=0] > (H[j=between a=start] > (V[g=0] > Tx"Legal name"[weight=semibold] + Tx"Vlad Dracul"[t=supporting]) + Lk"Edit")*7) + (C.muted > V[g=4] > (H[g=3 a=start] > Ic + (V[g=1] > Tx"Why is info hidden?"[weight=semibold] + Tx[t=supporting]))*3))
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Settings Panels — account sections with a nav panel and divided rows. Frame: Layout nav panel (fill) | content column of section views. One (Frame/responsive/container: see XLE header above.)
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import {Fragment, useState, type CSSProperties} from 'react';
|
|
4
10
|
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
5
11
|
import {
|
|
6
12
|
VStack,
|
|
@@ -21,18 +27,12 @@ import {Card} from '@astryxdesign/core/Card';
|
|
|
21
27
|
import {Switch} from '@astryxdesign/core/Switch';
|
|
22
28
|
import {Divider} from '@astryxdesign/core/Divider';
|
|
23
29
|
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
24
|
-
import {
|
|
30
|
+
import {StatusDot} from '@astryxdesign/core/StatusDot';
|
|
25
31
|
import {Icon} from '@astryxdesign/core/Icon';
|
|
26
32
|
import {Center} from '@astryxdesign/core/Center';
|
|
27
33
|
import {
|
|
28
|
-
User,
|
|
29
34
|
Lock,
|
|
30
35
|
ShieldCheck,
|
|
31
|
-
Bell,
|
|
32
|
-
FileText,
|
|
33
|
-
CreditCard,
|
|
34
|
-
Globe,
|
|
35
|
-
Briefcase,
|
|
36
36
|
Wrench,
|
|
37
37
|
Monitor,
|
|
38
38
|
SquarePen,
|
|
@@ -40,6 +40,9 @@ import {
|
|
|
40
40
|
ArrowLeft,
|
|
41
41
|
ChevronRight,
|
|
42
42
|
} from 'lucide-react';
|
|
43
|
+
import {NAV_ITEMS, LOGIN_ROWS, SOCIAL_ROWS, DEVICE_ROWS, INFO_TILES, iconBox, actionNoWrap, sideNavHeading} from 'astryx-dracula/shared/settings-data';
|
|
44
|
+
import {InfoRowItem, ExpandableRow} from 'astryx-dracula/shared/settings-rows';
|
|
45
|
+
import type {InfoRow} from 'astryx-dracula/shared/settings-data';
|
|
43
46
|
|
|
44
47
|
// Anchor the page to the viewport height so the sidebar + content fill the
|
|
45
48
|
// screen. Layout height="fill" is min-height:100% which collapses when the
|
|
@@ -47,11 +50,6 @@ import {
|
|
|
47
50
|
const fillViewport: CSSProperties = {
|
|
48
51
|
minHeight: '100dvh',
|
|
49
52
|
};
|
|
50
|
-
const iconBox: CSSProperties = {
|
|
51
|
-
borderRadius: 'var(--radius-container)',
|
|
52
|
-
backgroundColor: 'var(--color-background-surface)',
|
|
53
|
-
flexShrink: 0,
|
|
54
|
-
};
|
|
55
53
|
const rowPadding: CSSProperties = {
|
|
56
54
|
paddingBlock: 'var(--spacing-4)',
|
|
57
55
|
};
|
|
@@ -59,25 +57,15 @@ const sideNavPadding: CSSProperties = {
|
|
|
59
57
|
paddingBlock: 'var(--spacing-4)',
|
|
60
58
|
paddingInline: 'var(--spacing-3)',
|
|
61
59
|
};
|
|
62
|
-
const sideNavHeading: CSSProperties = {
|
|
63
|
-
marginInline: 'var(--spacing-4)',
|
|
64
|
-
};
|
|
65
60
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
{label: 'Privacy', icon: ShieldCheck},
|
|
70
|
-
{label: 'Notifications', icon: Bell},
|
|
71
|
-
{label: 'Taxes', icon: FileText},
|
|
72
|
-
{label: 'Payments', icon: CreditCard},
|
|
73
|
-
{label: 'Languages & currency', icon: Globe},
|
|
74
|
-
{label: 'Travel for work', icon: Briefcase},
|
|
75
|
-
];
|
|
61
|
+
// Same-route hash: demo links stay focusable anchors without escaping the
|
|
62
|
+
// template through the hash router (bare "#" would drop back to the home page).
|
|
63
|
+
const SELF_HASH = '#/templates/settings-sidebar';
|
|
76
64
|
|
|
77
65
|
// Section title shown beside the mobile back button (matches each section's
|
|
78
66
|
// in-content heading, which is hidden on mobile to avoid a duplicate).
|
|
79
67
|
const SECTION_TITLES: Record<string, string> = {
|
|
80
|
-
'Personal information': 'Personal
|
|
68
|
+
'Personal information': 'Personal information',
|
|
81
69
|
'Login & security': 'Login & security',
|
|
82
70
|
Privacy: 'Privacy',
|
|
83
71
|
Notifications: 'Notifications',
|
|
@@ -88,124 +76,16 @@ const SECTION_TITLES: Record<string, string> = {
|
|
|
88
76
|
'Professional hosting tools': 'Hosting tools',
|
|
89
77
|
};
|
|
90
78
|
|
|
91
|
-
interface InfoRow {
|
|
92
|
-
label: string;
|
|
93
|
-
value: string;
|
|
94
|
-
action: string;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
const LOGIN_ROWS: InfoRow[] = [
|
|
98
|
-
{label: 'Password', value: 'Not created', action: 'Create'},
|
|
99
|
-
];
|
|
100
|
-
|
|
101
|
-
const SOCIAL_ROWS: InfoRow[] = [
|
|
102
|
-
{label: 'Google', value: 'Connected', action: 'Disconnect'},
|
|
103
|
-
];
|
|
104
|
-
|
|
105
79
|
const TAX_ROWS: InfoRow[] = [
|
|
106
|
-
{label: '
|
|
107
|
-
{label: '
|
|
80
|
+
{label: 'Tax scrolls', value: 'Not provided', action: 'Add'},
|
|
81
|
+
{label: 'Past scrolls', value: 'No scrolls yet', action: 'View'},
|
|
108
82
|
];
|
|
109
83
|
|
|
110
84
|
const PAYOUT_ROWS: InfoRow[] = [
|
|
111
|
-
{label: 'Payout
|
|
112
|
-
{label: 'Past
|
|
113
|
-
];
|
|
114
|
-
|
|
115
|
-
const DEVICE_ROWS: {
|
|
116
|
-
label: string;
|
|
117
|
-
badge?: string;
|
|
118
|
-
location: string;
|
|
119
|
-
action?: string;
|
|
120
|
-
}[] = [
|
|
121
|
-
{
|
|
122
|
-
label: 'OS X 10.15.7 · Chrome',
|
|
123
|
-
badge: 'CURRENT SESSION',
|
|
124
|
-
location: 'Brașov, Transylvania · March 30, 2026 at 19:31',
|
|
125
|
-
},
|
|
126
|
-
{label: 'Session', location: 'August 9, 2023 at 04:19', action: 'Log out'},
|
|
127
|
-
{
|
|
128
|
-
label: 'OS X 10.15.7 · unknown',
|
|
129
|
-
location: 'Whitby, England · April 14, 2023 at 17:47',
|
|
130
|
-
action: 'Log out',
|
|
131
|
-
},
|
|
85
|
+
{label: 'Payout crypt', value: 'Not set up', action: 'Add'},
|
|
86
|
+
{label: 'Past payouts', value: 'No tributes yet', action: 'View'},
|
|
132
87
|
];
|
|
133
88
|
|
|
134
|
-
function InfoRowItem({label, value, action}: InfoRow) {
|
|
135
|
-
return (
|
|
136
|
-
<>
|
|
137
|
-
<HStack hAlign="between" vAlign="start" style={rowPadding}>
|
|
138
|
-
<VStack gap={0}>
|
|
139
|
-
<Text type="body" weight="semibold" display="block">
|
|
140
|
-
{label}
|
|
141
|
-
</Text>
|
|
142
|
-
<Text type="supporting" color="secondary" display="block">
|
|
143
|
-
{value}
|
|
144
|
-
</Text>
|
|
145
|
-
</VStack>
|
|
146
|
-
{action && <Link href="#/templates/settings-sidebar">{action}</Link>}
|
|
147
|
-
</HStack>
|
|
148
|
-
<Divider />
|
|
149
|
-
</>
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
interface ExpandableRowProps {
|
|
154
|
-
label: string;
|
|
155
|
-
value: string;
|
|
156
|
-
children: React.ReactNode;
|
|
157
|
-
isExpanded: boolean;
|
|
158
|
-
onEdit: () => void;
|
|
159
|
-
onCancel: () => void;
|
|
160
|
-
onSave: () => void;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
function ExpandableRow({
|
|
164
|
-
label,
|
|
165
|
-
value,
|
|
166
|
-
children,
|
|
167
|
-
isExpanded,
|
|
168
|
-
onEdit,
|
|
169
|
-
onCancel,
|
|
170
|
-
onSave,
|
|
171
|
-
}: ExpandableRowProps) {
|
|
172
|
-
return (
|
|
173
|
-
<>
|
|
174
|
-
{isExpanded ? (
|
|
175
|
-
<VStack gap={4} style={rowPadding}>
|
|
176
|
-
<Text type="body" weight="semibold" display="block">
|
|
177
|
-
{label}
|
|
178
|
-
</Text>
|
|
179
|
-
{children}
|
|
180
|
-
<HStack gap={2}>
|
|
181
|
-
<Button label="Save" variant="primary" onClick={onSave} />
|
|
182
|
-
<Button label="Cancel" variant="ghost" onClick={onCancel} />
|
|
183
|
-
</HStack>
|
|
184
|
-
</VStack>
|
|
185
|
-
) : (
|
|
186
|
-
<HStack hAlign="between" vAlign="start" style={rowPadding}>
|
|
187
|
-
<VStack gap={0}>
|
|
188
|
-
<Text type="body" weight="semibold" display="block">
|
|
189
|
-
{label}
|
|
190
|
-
</Text>
|
|
191
|
-
<Text type="supporting" color="secondary" display="block">
|
|
192
|
-
{value}
|
|
193
|
-
</Text>
|
|
194
|
-
</VStack>
|
|
195
|
-
<Link
|
|
196
|
-
href="#/templates/settings-sidebar"
|
|
197
|
-
onClick={(e: React.MouseEvent) => {
|
|
198
|
-
e.preventDefault();
|
|
199
|
-
onEdit();
|
|
200
|
-
}}>
|
|
201
|
-
Edit
|
|
202
|
-
</Link>
|
|
203
|
-
</HStack>
|
|
204
|
-
)}
|
|
205
|
-
<Divider />
|
|
206
|
-
</>
|
|
207
|
-
);
|
|
208
|
-
}
|
|
209
89
|
|
|
210
90
|
const LANGUAGES = [
|
|
211
91
|
{label: 'English (Canada)', value: 'en-CA'},
|
|
@@ -272,9 +152,9 @@ export default function SettingsSidebar() {
|
|
|
272
152
|
|
|
273
153
|
const navList = (
|
|
274
154
|
<VStack gap={4} style={sideNavPadding}>
|
|
275
|
-
<
|
|
155
|
+
<Text type="label" style={sideNavHeading}>
|
|
276
156
|
Account settings
|
|
277
|
-
</
|
|
157
|
+
</Text>
|
|
278
158
|
<List density="spacious">
|
|
279
159
|
{NAV_ITEMS.map(item => (
|
|
280
160
|
<ListItem
|
|
@@ -296,7 +176,6 @@ export default function SettingsSidebar() {
|
|
|
296
176
|
<ListItem
|
|
297
177
|
label="Professional hosting tools"
|
|
298
178
|
startContent={<Icon icon={Wrench} />}
|
|
299
|
-
onClick={() => {}}
|
|
300
179
|
/>
|
|
301
180
|
</List>
|
|
302
181
|
</VStack>
|
|
@@ -308,7 +187,14 @@ export default function SettingsSidebar() {
|
|
|
308
187
|
<Layout
|
|
309
188
|
height="fill"
|
|
310
189
|
style={fillViewport}
|
|
311
|
-
|
|
190
|
+
// padding={0}, not padding={2}. This wraps the SAME navList element
|
|
191
|
+
// the desktop LayoutPanel renders with padding={0}, and sideNavPadding
|
|
192
|
+
// already supplies the list's 12px inline inset. The extra 8px here is
|
|
193
|
+
// what made the same nav list measure 20px on mobile against 12px on
|
|
194
|
+
// desktop -- and against 24px further down, so the two mobile states
|
|
195
|
+
// disagreed with each other too. The container owns no gutter; the
|
|
196
|
+
// list owns its own.
|
|
197
|
+
content={<LayoutContent padding={0}>{navList}</LayoutContent>}
|
|
312
198
|
/>
|
|
313
199
|
);
|
|
314
200
|
}
|
|
@@ -326,7 +212,7 @@ export default function SettingsSidebar() {
|
|
|
326
212
|
)
|
|
327
213
|
}
|
|
328
214
|
content={
|
|
329
|
-
<LayoutContent padding={
|
|
215
|
+
<LayoutContent padding={6}>
|
|
330
216
|
<VStack gap={0}>
|
|
331
217
|
{/* Mobile detail view: a back button sits beside the section title
|
|
332
218
|
(the per-section headings below are hidden on mobile). Toolbar's
|
|
@@ -334,7 +220,7 @@ export default function SettingsSidebar() {
|
|
|
334
220
|
flush with the content edge. */}
|
|
335
221
|
{isNarrow && (
|
|
336
222
|
<Toolbar
|
|
337
|
-
label={`Back to Account settings
|
|
223
|
+
label={`Back to Account settings: ${SECTION_TITLES[activeNav]}`}
|
|
338
224
|
gap={2}
|
|
339
225
|
startContent={
|
|
340
226
|
<>
|
|
@@ -346,14 +232,14 @@ export default function SettingsSidebar() {
|
|
|
346
232
|
icon={<Icon icon={ArrowLeft} size="sm" />}
|
|
347
233
|
onClick={() => setMobileView('nav')}
|
|
348
234
|
/>
|
|
349
|
-
<Heading level={
|
|
235
|
+
<Heading level={1}>{SECTION_TITLES[activeNav]}</Heading>
|
|
350
236
|
</>
|
|
351
237
|
}
|
|
352
238
|
/>
|
|
353
239
|
)}
|
|
354
240
|
{activeNav === 'Login & security' && (
|
|
355
241
|
<VStack gap={6}>
|
|
356
|
-
{!isNarrow && <Heading level={
|
|
242
|
+
{!isNarrow && <Heading level={1}>Login & security</Heading>}
|
|
357
243
|
|
|
358
244
|
<TabList value={activeTab} onChange={setActiveTab} hasDivider>
|
|
359
245
|
<Tab value="login" label="Login" />
|
|
@@ -363,38 +249,60 @@ export default function SettingsSidebar() {
|
|
|
363
249
|
{activeTab === 'login' && (
|
|
364
250
|
<VStack gap={8}>
|
|
365
251
|
<VStack gap={0}>
|
|
366
|
-
<Heading level={
|
|
252
|
+
<Heading level={2}>Login</Heading>
|
|
367
253
|
<Divider />
|
|
368
254
|
{LOGIN_ROWS.map(row => (
|
|
369
|
-
<InfoRowItem
|
|
255
|
+
<InfoRowItem
|
|
256
|
+
key={row.label}
|
|
257
|
+
{...row}
|
|
258
|
+
href={SELF_HASH}
|
|
259
|
+
style={rowPadding}
|
|
260
|
+
/>
|
|
370
261
|
))}
|
|
371
262
|
</VStack>
|
|
372
263
|
|
|
373
264
|
<VStack gap={0}>
|
|
374
|
-
<Heading level={
|
|
265
|
+
<Heading level={2}>Social accounts</Heading>
|
|
375
266
|
<Divider />
|
|
376
267
|
{SOCIAL_ROWS.map(row => (
|
|
377
|
-
<InfoRowItem
|
|
268
|
+
<InfoRowItem
|
|
269
|
+
key={row.label}
|
|
270
|
+
{...row}
|
|
271
|
+
href={SELF_HASH}
|
|
272
|
+
style={rowPadding}
|
|
273
|
+
/>
|
|
378
274
|
))}
|
|
379
275
|
</VStack>
|
|
380
276
|
|
|
381
277
|
<VStack gap={0}>
|
|
382
|
-
<Heading level={
|
|
278
|
+
<Heading level={2}>Device history</Heading>
|
|
383
279
|
<Divider />
|
|
384
|
-
{DEVICE_ROWS.map((device
|
|
280
|
+
{DEVICE_ROWS.map((device) => (
|
|
385
281
|
<HStack
|
|
386
|
-
key={
|
|
282
|
+
key={device.location}
|
|
387
283
|
gap={3}
|
|
388
284
|
vAlign="start"
|
|
389
285
|
style={rowPadding}>
|
|
390
286
|
<Icon icon={Monitor} />
|
|
391
287
|
<StackItem size="fill">
|
|
392
288
|
<VStack gap={0}>
|
|
393
|
-
|
|
289
|
+
{/* wrap: the label plus the session status
|
|
290
|
+
exceed the content width on a phone. */}
|
|
291
|
+
<HStack gap={2} vAlign="center" wrap="wrap">
|
|
394
292
|
<Text type="body" weight="semibold">
|
|
395
293
|
{device.label}
|
|
396
294
|
</Text>
|
|
397
|
-
{device.
|
|
295
|
+
{device.isCurrent && (
|
|
296
|
+
<HStack gap={1} vAlign="center">
|
|
297
|
+
<StatusDot
|
|
298
|
+
variant="success"
|
|
299
|
+
label="Current session"
|
|
300
|
+
/>
|
|
301
|
+
<Text type="supporting" color="secondary">
|
|
302
|
+
Current session
|
|
303
|
+
</Text>
|
|
304
|
+
</HStack>
|
|
305
|
+
)}
|
|
398
306
|
</HStack>
|
|
399
307
|
<Text
|
|
400
308
|
type="supporting"
|
|
@@ -406,7 +314,9 @@ export default function SettingsSidebar() {
|
|
|
406
314
|
</VStack>
|
|
407
315
|
</StackItem>
|
|
408
316
|
{device.action && (
|
|
409
|
-
<Link href=
|
|
317
|
+
<Link href={SELF_HASH} style={actionNoWrap}>
|
|
318
|
+
{device.action}
|
|
319
|
+
</Link>
|
|
410
320
|
)}
|
|
411
321
|
</HStack>
|
|
412
322
|
))}
|
|
@@ -414,7 +324,7 @@ export default function SettingsSidebar() {
|
|
|
414
324
|
</VStack>
|
|
415
325
|
|
|
416
326
|
<VStack gap={0}>
|
|
417
|
-
<Heading level={
|
|
327
|
+
<Heading level={2}>Account</Heading>
|
|
418
328
|
<Divider />
|
|
419
329
|
<HStack
|
|
420
330
|
hAlign="between"
|
|
@@ -431,7 +341,9 @@ export default function SettingsSidebar() {
|
|
|
431
341
|
This action cannot be undone
|
|
432
342
|
</Text>
|
|
433
343
|
</VStack>
|
|
434
|
-
<Link href=
|
|
344
|
+
<Link href={SELF_HASH} style={actionNoWrap}>
|
|
345
|
+
Deactivate
|
|
346
|
+
</Link>
|
|
435
347
|
</HStack>
|
|
436
348
|
<Divider />
|
|
437
349
|
</VStack>
|
|
@@ -441,12 +353,12 @@ export default function SettingsSidebar() {
|
|
|
441
353
|
{activeTab === 'shared' && (
|
|
442
354
|
<VStack gap={8}>
|
|
443
355
|
<VStack gap={2}>
|
|
444
|
-
<Heading level={
|
|
356
|
+
<Heading level={2}>Shared access</Heading>
|
|
445
357
|
<Divider />
|
|
446
358
|
<Text type="body" color="secondary">
|
|
447
359
|
Review each request carefully before approving access.
|
|
448
|
-
We'll email your
|
|
449
|
-
code that lets them
|
|
360
|
+
We'll email your kin or coven-mate a 4-digit
|
|
361
|
+
code that lets them enter your crypt from their
|
|
450
362
|
trusted device.
|
|
451
363
|
</Text>
|
|
452
364
|
</VStack>
|
|
@@ -457,7 +369,7 @@ export default function SettingsSidebar() {
|
|
|
457
369
|
<Icon icon={Lock} />
|
|
458
370
|
</Center>
|
|
459
371
|
<VStack gap={1}>
|
|
460
|
-
<Text type="body"
|
|
372
|
+
<Text type="body">
|
|
461
373
|
Adding devices from people you trust
|
|
462
374
|
</Text>
|
|
463
375
|
<Text type="body" color="secondary">
|
|
@@ -477,7 +389,7 @@ export default function SettingsSidebar() {
|
|
|
477
389
|
{activeNav === 'Languages & currency' && (
|
|
478
390
|
<VStack gap={6}>
|
|
479
391
|
{!isNarrow && (
|
|
480
|
-
<Heading level={
|
|
392
|
+
<Heading level={1}>Languages & currency</Heading>
|
|
481
393
|
)}
|
|
482
394
|
<VStack gap={0}>
|
|
483
395
|
<ExpandableRow
|
|
@@ -489,7 +401,9 @@ export default function SettingsSidebar() {
|
|
|
489
401
|
isExpanded={expandedRow === 'language'}
|
|
490
402
|
onEdit={() => setExpandedRow('language')}
|
|
491
403
|
onCancel={() => setExpandedRow(null)}
|
|
492
|
-
onSave={() => setExpandedRow(null)}
|
|
404
|
+
onSave={() => setExpandedRow(null)}
|
|
405
|
+
href={SELF_HASH}
|
|
406
|
+
style={rowPadding}>
|
|
493
407
|
<Selector
|
|
494
408
|
label="Language"
|
|
495
409
|
isLabelHidden
|
|
@@ -508,7 +422,9 @@ export default function SettingsSidebar() {
|
|
|
508
422
|
isExpanded={expandedRow === 'currency'}
|
|
509
423
|
onEdit={() => setExpandedRow('currency')}
|
|
510
424
|
onCancel={() => setExpandedRow(null)}
|
|
511
|
-
onSave={() => setExpandedRow(null)}
|
|
425
|
+
onSave={() => setExpandedRow(null)}
|
|
426
|
+
href={SELF_HASH}
|
|
427
|
+
style={rowPadding}>
|
|
512
428
|
<Selector
|
|
513
429
|
label="Currency"
|
|
514
430
|
isLabelHidden
|
|
@@ -527,7 +443,9 @@ export default function SettingsSidebar() {
|
|
|
527
443
|
isExpanded={expandedRow === 'timezone'}
|
|
528
444
|
onEdit={() => setExpandedRow('timezone')}
|
|
529
445
|
onCancel={() => setExpandedRow(null)}
|
|
530
|
-
onSave={() => setExpandedRow(null)}
|
|
446
|
+
onSave={() => setExpandedRow(null)}
|
|
447
|
+
href={SELF_HASH}
|
|
448
|
+
style={rowPadding}>
|
|
531
449
|
<Selector
|
|
532
450
|
label="Time zone"
|
|
533
451
|
isLabelHidden
|
|
@@ -543,7 +461,9 @@ export default function SettingsSidebar() {
|
|
|
543
461
|
|
|
544
462
|
{activeNav === 'Personal information' && (
|
|
545
463
|
<VStack gap={6}>
|
|
546
|
-
{!isNarrow &&
|
|
464
|
+
{!isNarrow && (
|
|
465
|
+
<Heading level={1}>Personal information</Heading>
|
|
466
|
+
)}
|
|
547
467
|
<VStack gap={0}>
|
|
548
468
|
<ExpandableRow
|
|
549
469
|
label="Legal name"
|
|
@@ -551,7 +471,9 @@ export default function SettingsSidebar() {
|
|
|
551
471
|
isExpanded={expandedRow === 'legalName'}
|
|
552
472
|
onEdit={() => setExpandedRow('legalName')}
|
|
553
473
|
onCancel={() => setExpandedRow(null)}
|
|
554
|
-
onSave={() => setExpandedRow(null)}
|
|
474
|
+
onSave={() => setExpandedRow(null)}
|
|
475
|
+
href={SELF_HASH}
|
|
476
|
+
style={rowPadding}>
|
|
555
477
|
<TextInput
|
|
556
478
|
label="Legal name"
|
|
557
479
|
isLabelHidden
|
|
@@ -565,7 +487,9 @@ export default function SettingsSidebar() {
|
|
|
565
487
|
isExpanded={expandedRow === 'preferredName'}
|
|
566
488
|
onEdit={() => setExpandedRow('preferredName')}
|
|
567
489
|
onCancel={() => setExpandedRow(null)}
|
|
568
|
-
onSave={() => setExpandedRow(null)}
|
|
490
|
+
onSave={() => setExpandedRow(null)}
|
|
491
|
+
href={SELF_HASH}
|
|
492
|
+
style={rowPadding}>
|
|
569
493
|
<TextInput
|
|
570
494
|
label="Preferred first name"
|
|
571
495
|
isLabelHidden
|
|
@@ -579,7 +503,9 @@ export default function SettingsSidebar() {
|
|
|
579
503
|
isExpanded={expandedRow === 'email'}
|
|
580
504
|
onEdit={() => setExpandedRow('email')}
|
|
581
505
|
onCancel={() => setExpandedRow(null)}
|
|
582
|
-
onSave={() => setExpandedRow(null)}
|
|
506
|
+
onSave={() => setExpandedRow(null)}
|
|
507
|
+
href={SELF_HASH}
|
|
508
|
+
style={rowPadding}>
|
|
583
509
|
<TextInput
|
|
584
510
|
label="Email address"
|
|
585
511
|
isLabelHidden
|
|
@@ -593,7 +519,9 @@ export default function SettingsSidebar() {
|
|
|
593
519
|
isExpanded={expandedRow === 'phone'}
|
|
594
520
|
onEdit={() => setExpandedRow('phone')}
|
|
595
521
|
onCancel={() => setExpandedRow(null)}
|
|
596
|
-
onSave={() => setExpandedRow(null)}
|
|
522
|
+
onSave={() => setExpandedRow(null)}
|
|
523
|
+
href={SELF_HASH}
|
|
524
|
+
style={rowPadding}>
|
|
597
525
|
<TextInput
|
|
598
526
|
label="Phone number"
|
|
599
527
|
isLabelHidden
|
|
@@ -605,6 +533,8 @@ export default function SettingsSidebar() {
|
|
|
605
533
|
label="Identity verification"
|
|
606
534
|
value="Verified"
|
|
607
535
|
action=""
|
|
536
|
+
href={SELF_HASH}
|
|
537
|
+
style={rowPadding}
|
|
608
538
|
/>
|
|
609
539
|
<ExpandableRow
|
|
610
540
|
label="Residential address"
|
|
@@ -612,7 +542,9 @@ export default function SettingsSidebar() {
|
|
|
612
542
|
isExpanded={expandedRow === 'address'}
|
|
613
543
|
onEdit={() => setExpandedRow('address')}
|
|
614
544
|
onCancel={() => setExpandedRow(null)}
|
|
615
|
-
onSave={() => setExpandedRow(null)}
|
|
545
|
+
onSave={() => setExpandedRow(null)}
|
|
546
|
+
href={SELF_HASH}
|
|
547
|
+
style={rowPadding}>
|
|
616
548
|
<TextInput
|
|
617
549
|
label="Residential address"
|
|
618
550
|
isLabelHidden
|
|
@@ -626,7 +558,9 @@ export default function SettingsSidebar() {
|
|
|
626
558
|
isExpanded={expandedRow === 'mailingAddress'}
|
|
627
559
|
onEdit={() => setExpandedRow('mailingAddress')}
|
|
628
560
|
onCancel={() => setExpandedRow(null)}
|
|
629
|
-
onSave={() => setExpandedRow(null)}
|
|
561
|
+
onSave={() => setExpandedRow(null)}
|
|
562
|
+
href={SELF_HASH}
|
|
563
|
+
style={rowPadding}>
|
|
630
564
|
<TextInput
|
|
631
565
|
label="Mailing address"
|
|
632
566
|
isLabelHidden
|
|
@@ -640,7 +574,9 @@ export default function SettingsSidebar() {
|
|
|
640
574
|
isExpanded={expandedRow === 'emergencyContact'}
|
|
641
575
|
onEdit={() => setExpandedRow('emergencyContact')}
|
|
642
576
|
onCancel={() => setExpandedRow(null)}
|
|
643
|
-
onSave={() => setExpandedRow(null)}
|
|
577
|
+
onSave={() => setExpandedRow(null)}
|
|
578
|
+
href={SELF_HASH}
|
|
579
|
+
style={rowPadding}>
|
|
644
580
|
<TextInput
|
|
645
581
|
label="Emergency contact"
|
|
646
582
|
isLabelHidden
|
|
@@ -652,61 +588,27 @@ export default function SettingsSidebar() {
|
|
|
652
588
|
|
|
653
589
|
<Card padding={4}>
|
|
654
590
|
<VStack gap={4}>
|
|
655
|
-
|
|
656
|
-
<
|
|
657
|
-
<
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
</Center>
|
|
677
|
-
<VStack gap={0}>
|
|
678
|
-
<Text type="body" weight="semibold" display="block">
|
|
679
|
-
Which details can be edited?
|
|
680
|
-
</Text>
|
|
681
|
-
<Text
|
|
682
|
-
type="supporting"
|
|
683
|
-
color="secondary"
|
|
684
|
-
display="block">
|
|
685
|
-
Contact info and personal details can be edited. If
|
|
686
|
-
this info was used to verify your identity,
|
|
687
|
-
you'll need to get verified again the next time
|
|
688
|
-
you book—or to continue hosting.
|
|
689
|
-
</Text>
|
|
690
|
-
</VStack>
|
|
691
|
-
</HStack>
|
|
692
|
-
<Divider />
|
|
693
|
-
<HStack gap={3} vAlign="start">
|
|
694
|
-
<Center width={48} height={48} style={iconBox}>
|
|
695
|
-
<Icon icon={Share2} />
|
|
696
|
-
</Center>
|
|
697
|
-
<VStack gap={0}>
|
|
698
|
-
<Text type="body" weight="semibold" display="block">
|
|
699
|
-
What info is shared with others?
|
|
700
|
-
</Text>
|
|
701
|
-
<Text
|
|
702
|
-
type="supporting"
|
|
703
|
-
color="secondary"
|
|
704
|
-
display="block">
|
|
705
|
-
We only release contact information after a
|
|
706
|
-
reservation is confirmed.
|
|
707
|
-
</Text>
|
|
708
|
-
</VStack>
|
|
709
|
-
</HStack>
|
|
591
|
+
{INFO_TILES.map((tile, i) => (
|
|
592
|
+
<Fragment key={tile.title}>
|
|
593
|
+
{i > 0 && <Divider />}
|
|
594
|
+
<HStack gap={3} vAlign="start">
|
|
595
|
+
<Center width={48} height={48} style={iconBox}>
|
|
596
|
+
<Icon icon={tile.icon} />
|
|
597
|
+
</Center>
|
|
598
|
+
<VStack gap={0}>
|
|
599
|
+
<Text type="body" weight="semibold" display="block">
|
|
600
|
+
{tile.title}
|
|
601
|
+
</Text>
|
|
602
|
+
<Text
|
|
603
|
+
type="body"
|
|
604
|
+
color="secondary"
|
|
605
|
+
display="block">
|
|
606
|
+
{tile.body}
|
|
607
|
+
</Text>
|
|
608
|
+
</VStack>
|
|
609
|
+
</HStack>
|
|
610
|
+
</Fragment>
|
|
611
|
+
))}
|
|
710
612
|
</VStack>
|
|
711
613
|
</Card>
|
|
712
614
|
</VStack>
|
|
@@ -714,11 +616,11 @@ export default function SettingsSidebar() {
|
|
|
714
616
|
|
|
715
617
|
{activeNav === 'Privacy' && (
|
|
716
618
|
<VStack gap={6}>
|
|
717
|
-
{!isNarrow && <Heading level={
|
|
619
|
+
{!isNarrow && <Heading level={1}>Privacy</Heading>}
|
|
718
620
|
|
|
719
621
|
<VStack gap={8}>
|
|
720
622
|
<VStack gap={0}>
|
|
721
|
-
<Heading level={
|
|
623
|
+
<Heading level={2}>Messages</Heading>
|
|
722
624
|
<VStack style={rowPadding}>
|
|
723
625
|
<Switch
|
|
724
626
|
label="Show people when I've read their messages."
|
|
@@ -732,17 +634,17 @@ export default function SettingsSidebar() {
|
|
|
732
634
|
<Text type="body" weight="semibold">
|
|
733
635
|
Blocked people
|
|
734
636
|
</Text>
|
|
735
|
-
<Link href=
|
|
637
|
+
<Link href={SELF_HASH}>View</Link>
|
|
736
638
|
</HStack>
|
|
737
639
|
<Divider />
|
|
738
640
|
</VStack>
|
|
739
641
|
|
|
740
642
|
<VStack gap={0}>
|
|
741
|
-
<Heading level={
|
|
643
|
+
<Heading level={2}>Listings</Heading>
|
|
742
644
|
<VStack style={rowPadding}>
|
|
743
645
|
<Switch
|
|
744
|
-
label="
|
|
745
|
-
description="Turning this on means
|
|
646
|
+
label="List my wares in the scrying mirrors"
|
|
647
|
+
description="Turning this on means scrying engines, like Google, will show your wares to seekers."
|
|
746
648
|
value={searchEngines}
|
|
747
649
|
onChange={setSearchEngines}
|
|
748
650
|
labelPosition="start"
|
|
@@ -753,16 +655,16 @@ export default function SettingsSidebar() {
|
|
|
753
655
|
</VStack>
|
|
754
656
|
|
|
755
657
|
<VStack gap={4}>
|
|
756
|
-
<Heading level={
|
|
658
|
+
<Heading level={2}>Reviews</Heading>
|
|
757
659
|
<Text type="body" color="secondary">
|
|
758
660
|
Choose what's shared when you write a review.{' '}
|
|
759
|
-
<Link href=
|
|
661
|
+
<Link href={SELF_HASH} type="body">
|
|
760
662
|
Learn more
|
|
761
663
|
</Link>
|
|
762
664
|
</Text>
|
|
763
665
|
<VStack gap={4}>
|
|
764
666
|
<Switch
|
|
765
|
-
label="Show my home
|
|
667
|
+
label="Show my home haunt and country"
|
|
766
668
|
description="Ex: City and country"
|
|
767
669
|
value={showCity}
|
|
768
670
|
onChange={setShowCity}
|
|
@@ -770,8 +672,8 @@ export default function SettingsSidebar() {
|
|
|
770
672
|
labelSpacing="spread"
|
|
771
673
|
/>
|
|
772
674
|
<Switch
|
|
773
|
-
label="Show my
|
|
774
|
-
description="Ex:
|
|
675
|
+
label="Show my journey type"
|
|
676
|
+
description="Ex: Rested with kin or familiars"
|
|
775
677
|
value={showTripType}
|
|
776
678
|
onChange={setShowTripType}
|
|
777
679
|
labelPosition="start"
|
|
@@ -786,8 +688,8 @@ export default function SettingsSidebar() {
|
|
|
786
688
|
labelSpacing="spread"
|
|
787
689
|
/>
|
|
788
690
|
<Switch
|
|
789
|
-
label="Show my booked
|
|
790
|
-
description="Ex:
|
|
691
|
+
label="Show my booked revels"
|
|
692
|
+
description="Ex: Midnight feasts and tasting rituals"
|
|
791
693
|
value={showServices}
|
|
792
694
|
onChange={setShowServices}
|
|
793
695
|
labelPosition="start"
|
|
@@ -798,11 +700,11 @@ export default function SettingsSidebar() {
|
|
|
798
700
|
</VStack>
|
|
799
701
|
|
|
800
702
|
<VStack gap={4}>
|
|
801
|
-
<Heading level={
|
|
703
|
+
<Heading level={2}>Data privacy</Heading>
|
|
802
704
|
<Card>
|
|
803
705
|
<HStack hAlign="between" vAlign="center">
|
|
804
706
|
<Text type="body">Request my personal data</Text>
|
|
805
|
-
<Link href=
|
|
707
|
+
<Link href={SELF_HASH}>Request</Link>
|
|
806
708
|
</HStack>
|
|
807
709
|
</Card>
|
|
808
710
|
<Switch
|
|
@@ -816,7 +718,7 @@ export default function SettingsSidebar() {
|
|
|
816
718
|
<Card>
|
|
817
719
|
<HStack hAlign="between" vAlign="center">
|
|
818
720
|
<Text type="body">Delete my account</Text>
|
|
819
|
-
<Link href=
|
|
721
|
+
<Link href={SELF_HASH}>Delete</Link>
|
|
820
722
|
</HStack>
|
|
821
723
|
</Card>
|
|
822
724
|
<Card variant="muted">
|
|
@@ -825,13 +727,13 @@ export default function SettingsSidebar() {
|
|
|
825
727
|
<Icon icon={ShieldCheck} />
|
|
826
728
|
</Center>
|
|
827
729
|
<VStack gap={1}>
|
|
828
|
-
<Text type="body"
|
|
730
|
+
<Text type="body">
|
|
829
731
|
Committed to privacy
|
|
830
732
|
</Text>
|
|
831
|
-
<Text type="
|
|
733
|
+
<Text type="body" color="secondary">
|
|
832
734
|
We're committed to keeping your data protected.
|
|
833
735
|
See details in our{' '}
|
|
834
|
-
<Link href=
|
|
736
|
+
<Link href={SELF_HASH} type="supporting">
|
|
835
737
|
Privacy Policy
|
|
836
738
|
</Link>
|
|
837
739
|
.
|
|
@@ -846,13 +748,13 @@ export default function SettingsSidebar() {
|
|
|
846
748
|
|
|
847
749
|
{activeNav === 'Notifications' && (
|
|
848
750
|
<VStack gap={6}>
|
|
849
|
-
{!isNarrow && <Heading level={
|
|
751
|
+
{!isNarrow && <Heading level={1}>Notifications</Heading>}
|
|
850
752
|
<VStack gap={0}>
|
|
851
|
-
<Heading level={
|
|
753
|
+
<Heading level={2}>Messages</Heading>
|
|
852
754
|
<VStack style={rowPadding}>
|
|
853
755
|
<Switch
|
|
854
756
|
label="Email notifications"
|
|
855
|
-
description="
|
|
757
|
+
description="Coven updates, journey reminders, and crypt activity."
|
|
856
758
|
value={emailNotif}
|
|
857
759
|
onChange={setEmailNotif}
|
|
858
760
|
labelPosition="start"
|
|
@@ -863,7 +765,7 @@ export default function SettingsSidebar() {
|
|
|
863
765
|
<VStack style={rowPadding}>
|
|
864
766
|
<Switch
|
|
865
767
|
label="Push notifications"
|
|
866
|
-
description="
|
|
768
|
+
description="Swift ravens for messages and booking requests."
|
|
867
769
|
value={pushNotif}
|
|
868
770
|
onChange={setPushNotif}
|
|
869
771
|
labelPosition="start"
|
|
@@ -877,12 +779,17 @@ export default function SettingsSidebar() {
|
|
|
877
779
|
|
|
878
780
|
{activeNav === 'Taxes' && (
|
|
879
781
|
<VStack gap={6}>
|
|
880
|
-
{!isNarrow && <Heading level={
|
|
782
|
+
{!isNarrow && <Heading level={1}>Taxes</Heading>}
|
|
881
783
|
<VStack gap={0}>
|
|
882
|
-
<Heading level={
|
|
784
|
+
<Heading level={2}>Tax scrolls</Heading>
|
|
883
785
|
<Divider />
|
|
884
786
|
{TAX_ROWS.map(row => (
|
|
885
|
-
<InfoRowItem
|
|
787
|
+
<InfoRowItem
|
|
788
|
+
key={row.label}
|
|
789
|
+
{...row}
|
|
790
|
+
href={SELF_HASH}
|
|
791
|
+
style={rowPadding}
|
|
792
|
+
/>
|
|
886
793
|
))}
|
|
887
794
|
</VStack>
|
|
888
795
|
</VStack>
|
|
@@ -890,12 +797,17 @@ export default function SettingsSidebar() {
|
|
|
890
797
|
|
|
891
798
|
{activeNav === 'Payments' && (
|
|
892
799
|
<VStack gap={6}>
|
|
893
|
-
{!isNarrow && <Heading level={
|
|
800
|
+
{!isNarrow && <Heading level={1}>Payments</Heading>}
|
|
894
801
|
<VStack gap={0}>
|
|
895
|
-
<Heading level={
|
|
802
|
+
<Heading level={2}>Payout crypt</Heading>
|
|
896
803
|
<Divider />
|
|
897
804
|
{PAYOUT_ROWS.map(row => (
|
|
898
|
-
<InfoRowItem
|
|
805
|
+
<InfoRowItem
|
|
806
|
+
key={row.label}
|
|
807
|
+
{...row}
|
|
808
|
+
href={SELF_HASH}
|
|
809
|
+
style={rowPadding}
|
|
810
|
+
/>
|
|
899
811
|
))}
|
|
900
812
|
</VStack>
|
|
901
813
|
</VStack>
|
|
@@ -903,13 +815,13 @@ export default function SettingsSidebar() {
|
|
|
903
815
|
|
|
904
816
|
{activeNav === 'Travel for work' && (
|
|
905
817
|
<VStack gap={6}>
|
|
906
|
-
{!isNarrow && <Heading level={
|
|
818
|
+
{!isNarrow && <Heading level={1}>Travel for work</Heading>}
|
|
907
819
|
<VStack gap={0}>
|
|
908
|
-
<Heading level={
|
|
820
|
+
<Heading level={2}>Work haunts</Heading>
|
|
909
821
|
<VStack style={rowPadding}>
|
|
910
822
|
<Switch
|
|
911
|
-
label="Show
|
|
912
|
-
description="Add a
|
|
823
|
+
label="Show night-errand options at checkout"
|
|
824
|
+
description="Add a coven address to expense night errands and unlock travel-ready wares."
|
|
913
825
|
value={workTrips}
|
|
914
826
|
onChange={setWorkTrips}
|
|
915
827
|
labelPosition="start"
|
|
@@ -924,7 +836,7 @@ export default function SettingsSidebar() {
|
|
|
924
836
|
{activeNav === 'Professional hosting tools' && (
|
|
925
837
|
<VStack gap={6}>
|
|
926
838
|
{!isNarrow && (
|
|
927
|
-
<Heading level={
|
|
839
|
+
<Heading level={1}>Professional hosting tools</Heading>
|
|
928
840
|
)}
|
|
929
841
|
<Card variant="muted">
|
|
930
842
|
<HStack gap={4} vAlign="start">
|
|
@@ -932,10 +844,10 @@ export default function SettingsSidebar() {
|
|
|
932
844
|
<Icon icon={Wrench} />
|
|
933
845
|
</Center>
|
|
934
846
|
<VStack gap={1}>
|
|
935
|
-
<Text type="body"
|
|
936
|
-
|
|
847
|
+
<Text type="body">
|
|
848
|
+
Hosting grimoire
|
|
937
849
|
</Text>
|
|
938
|
-
<Text type="
|
|
850
|
+
<Text type="body" color="secondary">
|
|
939
851
|
Manage multiple listings, route tasks to co-hosts, and
|
|
940
852
|
review consolidated payouts from one place.
|
|
941
853
|
</Text>
|