astryx-dracula 0.1.3 → 0.2.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 +1 -1
- package/README.md +2 -0
- package/USAGE.md +13 -0
- package/astryx-dracula.js +4 -4
- package/astryx.integration.mjs +3 -0
- package/package.json +4 -2
- package/templates/ai-chat-landing.template.mjs +6 -0
- package/templates/ai-chat-landing.tsx +476 -0
- package/templates/ai-chat.template.mjs +6 -0
- package/templates/ai-chat.tsx +762 -0
- package/templates/blank.template.mjs +6 -0
- package/templates/blank.tsx +16 -0
- package/templates/centered-hero.template.mjs +6 -0
- package/templates/centered-hero.tsx +188 -0
- package/templates/classic-gallery.template.mjs +6 -0
- package/templates/classic-gallery.tsx +181 -0
- package/templates/contact-form.template.mjs +6 -0
- package/templates/contact-form.tsx +292 -0
- package/templates/dashboard-portfolio.template.mjs +6 -0
- package/templates/dashboard-portfolio.tsx +800 -0
- package/templates/dashboard.template.mjs +6 -0
- package/templates/dashboard.tsx +774 -0
- package/templates/detail-page.template.mjs +6 -0
- package/templates/detail-page.tsx +695 -0
- package/templates/documentation-design.template.mjs +6 -0
- package/templates/documentation-design.tsx +751 -0
- package/templates/documentation-technical.template.mjs +6 -0
- package/templates/documentation-technical.tsx +292 -0
- package/templates/documentation.template.mjs +6 -0
- package/templates/documentation.tsx +347 -0
- package/templates/editor.template.mjs +6 -0
- package/templates/editor.tsx +959 -0
- package/templates/file-explorer.template.mjs +6 -0
- package/templates/file-explorer.tsx +577 -0
- package/templates/form-two-column.template.mjs +6 -0
- package/templates/form-two-column.tsx +314 -0
- package/templates/gallery-hero.template.mjs +6 -0
- package/templates/gallery-hero.tsx +287 -0
- package/templates/ide.template.mjs +6 -0
- package/templates/ide.tsx +533 -0
- package/templates/incident-console.template.mjs +6 -0
- package/templates/incident-console.tsx +584 -0
- package/templates/kanban-board.template.mjs +6 -0
- package/templates/kanban-board.tsx +746 -0
- package/templates/library.template.mjs +6 -0
- package/templates/library.tsx +489 -0
- package/templates/login-card.template.mjs +6 -0
- package/templates/login-card.tsx +200 -0
- package/templates/login-split.template.mjs +6 -0
- package/templates/login-split.tsx +318 -0
- package/templates/login-sso.template.mjs +6 -0
- package/templates/login-sso.tsx +277 -0
- package/templates/login.template.mjs +6 -0
- package/templates/login.tsx +98 -0
- package/templates/messaging-shell.template.mjs +6 -0
- package/templates/messaging-shell.tsx +675 -0
- package/templates/mixed-gallery.template.mjs +6 -0
- package/templates/mixed-gallery.tsx +190 -0
- package/templates/payment-form.template.mjs +6 -0
- package/templates/payment-form.tsx +990 -0
- package/templates/product-detail.template.mjs +6 -0
- package/templates/product-detail.tsx +366 -0
- package/templates/product-gallery.template.mjs +6 -0
- package/templates/product-gallery.tsx +173 -0
- package/templates/settings-dialog.template.mjs +6 -0
- package/templates/settings-dialog.tsx +920 -0
- package/templates/settings-sidebar.template.mjs +6 -0
- package/templates/settings-sidebar.tsx +952 -0
- package/templates/settings.template.mjs +6 -0
- package/templates/settings.tsx +235 -0
- package/templates/shell-nav.template.mjs +6 -0
- package/templates/shell-nav.tsx +306 -0
- package/templates/shell-side-nav.template.mjs +6 -0
- package/templates/shell-side-nav.tsx +238 -0
- package/templates/shell-top-nav.template.mjs +6 -0
- package/templates/shell-top-nav.tsx +243 -0
- package/templates/side-gallery.template.mjs +6 -0
- package/templates/side-gallery.tsx +179 -0
- package/templates/table-grouped.template.mjs +6 -0
- package/templates/table-grouped.tsx +1174 -0
- package/templates/table-page-chart.template.mjs +6 -0
- package/templates/table-page-chart.tsx +693 -0
- package/templates/table-page-heatmap-status.template.mjs +6 -0
- package/templates/table-page-heatmap-status.tsx +547 -0
- package/templates/table-page-shoe-store-heatmap.template.mjs +6 -0
- package/templates/table-page-shoe-store-heatmap.tsx +1038 -0
- package/templates/table-page.template.mjs +6 -0
- package/templates/table-page.tsx +445 -0
- package/templates/table.template.mjs +6 -0
- package/templates/table.tsx +84 -0
- package/templates/theme-showcase.template.mjs +6 -0
- package/templates/theme-showcase.tsx +1282 -0
- package/theme.css +4 -4
- package/tokens.css +4 -4
|
@@ -0,0 +1,952 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import {useState, type CSSProperties} from 'react';
|
|
4
|
+
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
5
|
+
import {
|
|
6
|
+
VStack,
|
|
7
|
+
HStack,
|
|
8
|
+
StackItem,
|
|
9
|
+
Layout,
|
|
10
|
+
LayoutContent,
|
|
11
|
+
LayoutPanel,
|
|
12
|
+
} from '@astryxdesign/core/Layout';
|
|
13
|
+
import {List, ListItem} from '@astryxdesign/core/List';
|
|
14
|
+
import {Toolbar} from '@astryxdesign/core/Toolbar';
|
|
15
|
+
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
16
|
+
import {Link} from '@astryxdesign/core/Link';
|
|
17
|
+
import {Button} from '@astryxdesign/core/Button';
|
|
18
|
+
import {Selector} from '@astryxdesign/core/Selector';
|
|
19
|
+
import {TextInput} from '@astryxdesign/core/TextInput';
|
|
20
|
+
import {Card} from '@astryxdesign/core/Card';
|
|
21
|
+
import {Switch} from '@astryxdesign/core/Switch';
|
|
22
|
+
import {Divider} from '@astryxdesign/core/Divider';
|
|
23
|
+
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
24
|
+
import {Badge} from '@astryxdesign/core/Badge';
|
|
25
|
+
import {Icon} from '@astryxdesign/core/Icon';
|
|
26
|
+
import {Center} from '@astryxdesign/core/Center';
|
|
27
|
+
import {
|
|
28
|
+
User,
|
|
29
|
+
Lock,
|
|
30
|
+
ShieldCheck,
|
|
31
|
+
Bell,
|
|
32
|
+
FileText,
|
|
33
|
+
CreditCard,
|
|
34
|
+
Globe,
|
|
35
|
+
Briefcase,
|
|
36
|
+
Wrench,
|
|
37
|
+
Monitor,
|
|
38
|
+
SquarePen,
|
|
39
|
+
Share2,
|
|
40
|
+
ArrowLeft,
|
|
41
|
+
ChevronRight,
|
|
42
|
+
} from 'lucide-react';
|
|
43
|
+
|
|
44
|
+
// Anchor the page to the viewport height so the sidebar + content fill the
|
|
45
|
+
// screen. Layout height="fill" is min-height:100% which collapses when the
|
|
46
|
+
// host container is content-sized; Layout has no viewport-height prop.
|
|
47
|
+
const fillViewport: CSSProperties = {
|
|
48
|
+
minHeight: '100dvh',
|
|
49
|
+
};
|
|
50
|
+
const iconBox: CSSProperties = {
|
|
51
|
+
borderRadius: 'var(--radius-container)',
|
|
52
|
+
backgroundColor: 'var(--color-background-surface)',
|
|
53
|
+
flexShrink: 0,
|
|
54
|
+
};
|
|
55
|
+
const rowPadding: CSSProperties = {
|
|
56
|
+
paddingBlock: 'var(--spacing-4)',
|
|
57
|
+
};
|
|
58
|
+
const sideNavPadding: CSSProperties = {
|
|
59
|
+
paddingBlock: 'var(--spacing-4)',
|
|
60
|
+
paddingInline: 'var(--spacing-3)',
|
|
61
|
+
};
|
|
62
|
+
const sideNavHeading: CSSProperties = {
|
|
63
|
+
marginInline: 'var(--spacing-4)',
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const NAV_ITEMS = [
|
|
67
|
+
{label: 'Personal information', icon: User},
|
|
68
|
+
{label: 'Login & security', icon: Lock},
|
|
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
|
+
];
|
|
76
|
+
|
|
77
|
+
// Section title shown beside the mobile back button (matches each section's
|
|
78
|
+
// in-content heading, which is hidden on mobile to avoid a duplicate).
|
|
79
|
+
const SECTION_TITLES: Record<string, string> = {
|
|
80
|
+
'Personal information': 'Personal info',
|
|
81
|
+
'Login & security': 'Login & security',
|
|
82
|
+
Privacy: 'Privacy',
|
|
83
|
+
Notifications: 'Notifications',
|
|
84
|
+
Taxes: 'Taxes',
|
|
85
|
+
Payments: 'Payments',
|
|
86
|
+
'Languages & currency': 'Languages & currency',
|
|
87
|
+
'Travel for work': 'Travel for work',
|
|
88
|
+
'Professional hosting tools': 'Hosting tools',
|
|
89
|
+
};
|
|
90
|
+
|
|
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
|
+
const TAX_ROWS: InfoRow[] = [
|
|
106
|
+
{label: 'Taxpayer information', value: 'Not provided', action: 'Add'},
|
|
107
|
+
{label: 'Tax documents', value: 'No documents yet', action: 'View'},
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
const PAYOUT_ROWS: InfoRow[] = [
|
|
111
|
+
{label: 'Payout method', value: 'Not set up', action: 'Add'},
|
|
112
|
+
{label: 'Past payments', value: 'No payments yet', action: 'View'},
|
|
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
|
+
},
|
|
132
|
+
];
|
|
133
|
+
|
|
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
|
+
|
|
210
|
+
const LANGUAGES = [
|
|
211
|
+
{label: 'English (Canada)', value: 'en-CA'},
|
|
212
|
+
{label: 'English (US)', value: 'en-US'},
|
|
213
|
+
{label: 'French', value: 'fr'},
|
|
214
|
+
{label: 'Spanish', value: 'es'},
|
|
215
|
+
{label: 'German', value: 'de'},
|
|
216
|
+
{label: 'Japanese', value: 'ja'},
|
|
217
|
+
];
|
|
218
|
+
|
|
219
|
+
const CURRENCIES = [
|
|
220
|
+
{label: 'Canadian dollar (CAD)', value: 'CAD'},
|
|
221
|
+
{label: 'US dollar (USD)', value: 'USD'},
|
|
222
|
+
{label: 'Euro (EUR)', value: 'EUR'},
|
|
223
|
+
{label: 'British pound (GBP)', value: 'GBP'},
|
|
224
|
+
{label: 'Japanese yen (JPY)', value: 'JPY'},
|
|
225
|
+
];
|
|
226
|
+
|
|
227
|
+
const TIMEZONES = [
|
|
228
|
+
{label: '(GMT-05:00) Eastern Time (US & Canada)', value: 'ET'},
|
|
229
|
+
{label: '(GMT-06:00) Central Time (US & Canada)', value: 'CT'},
|
|
230
|
+
{label: '(GMT-07:00) Mountain Time (US & Canada)', value: 'MT'},
|
|
231
|
+
{label: '(GMT-08:00) Pacific Time (US & Canada)', value: 'PT'},
|
|
232
|
+
{label: '(GMT+00:00) UTC', value: 'UTC'},
|
|
233
|
+
{label: '(GMT+01:00) London', value: 'GMT+1'},
|
|
234
|
+
];
|
|
235
|
+
|
|
236
|
+
export default function SettingsSidebar() {
|
|
237
|
+
const isNarrow = useMediaQuery('(max-width: 768px)');
|
|
238
|
+
// Mobile is a master→detail drill-down: 'nav' shows the menu, 'detail' shows
|
|
239
|
+
// the selected section with a back button. Desktop shows both side-by-side.
|
|
240
|
+
const [mobileView, setMobileView] = useState<'nav' | 'detail'>('nav');
|
|
241
|
+
const [activeNav, setActiveNav] = useState('Personal information');
|
|
242
|
+
const [activeTab, setActiveTab] = useState('login');
|
|
243
|
+
const [readReceipts, setReadReceipts] = useState(true);
|
|
244
|
+
const [searchEngines, setSearchEngines] = useState(true);
|
|
245
|
+
const [showCity, setShowCity] = useState(true);
|
|
246
|
+
const [showTripType, setShowTripType] = useState(true);
|
|
247
|
+
const [showStayLength, setShowStayLength] = useState(true);
|
|
248
|
+
const [showServices, setShowServices] = useState(true);
|
|
249
|
+
const [aiFeatures, setAiFeatures] = useState(true);
|
|
250
|
+
const [emailNotif, setEmailNotif] = useState(true);
|
|
251
|
+
const [pushNotif, setPushNotif] = useState(true);
|
|
252
|
+
const [workTrips, setWorkTrips] = useState(false);
|
|
253
|
+
|
|
254
|
+
const [expandedRow, setExpandedRow] = useState<string | null>(null);
|
|
255
|
+
const [language, setLanguage] = useState('en-CA');
|
|
256
|
+
const [currency, setCurrency] = useState('CAD');
|
|
257
|
+
const [timezone, setTimezone] = useState('ET');
|
|
258
|
+
|
|
259
|
+
const [legalName, setLegalName] = useState('Vlad Dracul');
|
|
260
|
+
const [preferredName, setPreferredName] = useState('');
|
|
261
|
+
const [email, setEmail] = useState('v***d@castle-dracula.ro');
|
|
262
|
+
const [phone, setPhone] = useState('+1 ***-***-0123');
|
|
263
|
+
const [address, setAddress] = useState('');
|
|
264
|
+
const [mailingAddress, setMailingAddress] = useState('');
|
|
265
|
+
const [emergencyContact, setEmergencyContact] = useState('Provided');
|
|
266
|
+
|
|
267
|
+
// Selecting a nav item also drills into the detail view on mobile.
|
|
268
|
+
const selectNav = (label: string) => {
|
|
269
|
+
setActiveNav(label);
|
|
270
|
+
setMobileView('detail');
|
|
271
|
+
};
|
|
272
|
+
|
|
273
|
+
const navList = (
|
|
274
|
+
<VStack gap={4} style={sideNavPadding}>
|
|
275
|
+
<Heading level={2} style={sideNavHeading}>
|
|
276
|
+
Account settings
|
|
277
|
+
</Heading>
|
|
278
|
+
<List density="spacious">
|
|
279
|
+
{NAV_ITEMS.map(item => (
|
|
280
|
+
<ListItem
|
|
281
|
+
key={item.label}
|
|
282
|
+
label={item.label}
|
|
283
|
+
startContent={<Icon icon={item.icon} />}
|
|
284
|
+
endContent={
|
|
285
|
+
isNarrow ? (
|
|
286
|
+
<Icon icon={ChevronRight} size="sm" color="secondary" />
|
|
287
|
+
) : undefined
|
|
288
|
+
}
|
|
289
|
+
isSelected={!isNarrow && activeNav === item.label}
|
|
290
|
+
onClick={() => selectNav(item.label)}
|
|
291
|
+
/>
|
|
292
|
+
))}
|
|
293
|
+
</List>
|
|
294
|
+
<Divider />
|
|
295
|
+
<List density="spacious">
|
|
296
|
+
<ListItem
|
|
297
|
+
label="Professional hosting tools"
|
|
298
|
+
startContent={<Icon icon={Wrench} />}
|
|
299
|
+
onClick={() => {}}
|
|
300
|
+
/>
|
|
301
|
+
</List>
|
|
302
|
+
</VStack>
|
|
303
|
+
);
|
|
304
|
+
|
|
305
|
+
// Mobile, nav view: show only the menu (full width, no sidebar slot).
|
|
306
|
+
if (isNarrow && mobileView === 'nav') {
|
|
307
|
+
return (
|
|
308
|
+
<Layout
|
|
309
|
+
height="fill"
|
|
310
|
+
style={fillViewport}
|
|
311
|
+
content={<LayoutContent padding={2}>{navList}</LayoutContent>}
|
|
312
|
+
/>
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return (
|
|
317
|
+
<Layout
|
|
318
|
+
height="fill"
|
|
319
|
+
contentWidth={1200}
|
|
320
|
+
style={fillViewport}
|
|
321
|
+
start={
|
|
322
|
+
isNarrow ? undefined : (
|
|
323
|
+
<LayoutPanel hasDivider padding={0}>
|
|
324
|
+
{navList}
|
|
325
|
+
</LayoutPanel>
|
|
326
|
+
)
|
|
327
|
+
}
|
|
328
|
+
content={
|
|
329
|
+
<LayoutContent padding={4}>
|
|
330
|
+
<VStack gap={0}>
|
|
331
|
+
{/* Mobile detail view: a back button sits beside the section title
|
|
332
|
+
(the per-section headings below are hidden on mobile). Toolbar's
|
|
333
|
+
start slot edge-compensates the ghost button so its icon aligns
|
|
334
|
+
flush with the content edge. */}
|
|
335
|
+
{isNarrow && (
|
|
336
|
+
<Toolbar
|
|
337
|
+
label={`Back to Account settings — ${SECTION_TITLES[activeNav]}`}
|
|
338
|
+
gap={2}
|
|
339
|
+
startContent={
|
|
340
|
+
<>
|
|
341
|
+
<Button
|
|
342
|
+
label="Back to Account settings"
|
|
343
|
+
variant="ghost"
|
|
344
|
+
size="sm"
|
|
345
|
+
isIconOnly
|
|
346
|
+
icon={<Icon icon={ArrowLeft} size="sm" />}
|
|
347
|
+
onClick={() => setMobileView('nav')}
|
|
348
|
+
/>
|
|
349
|
+
<Heading level={2}>{SECTION_TITLES[activeNav]}</Heading>
|
|
350
|
+
</>
|
|
351
|
+
}
|
|
352
|
+
/>
|
|
353
|
+
)}
|
|
354
|
+
{activeNav === 'Login & security' && (
|
|
355
|
+
<VStack gap={6}>
|
|
356
|
+
{!isNarrow && <Heading level={2}>Login & security</Heading>}
|
|
357
|
+
|
|
358
|
+
<TabList value={activeTab} onChange={setActiveTab} hasDivider>
|
|
359
|
+
<Tab value="login" label="Login" />
|
|
360
|
+
<Tab value="shared" label="Shared access" />
|
|
361
|
+
</TabList>
|
|
362
|
+
|
|
363
|
+
{activeTab === 'login' && (
|
|
364
|
+
<VStack gap={8}>
|
|
365
|
+
<VStack gap={0}>
|
|
366
|
+
<Heading level={3}>Login</Heading>
|
|
367
|
+
<Divider />
|
|
368
|
+
{LOGIN_ROWS.map(row => (
|
|
369
|
+
<InfoRowItem key={row.label} {...row} />
|
|
370
|
+
))}
|
|
371
|
+
</VStack>
|
|
372
|
+
|
|
373
|
+
<VStack gap={0}>
|
|
374
|
+
<Heading level={3}>Social accounts</Heading>
|
|
375
|
+
<Divider />
|
|
376
|
+
{SOCIAL_ROWS.map(row => (
|
|
377
|
+
<InfoRowItem key={row.label} {...row} />
|
|
378
|
+
))}
|
|
379
|
+
</VStack>
|
|
380
|
+
|
|
381
|
+
<VStack gap={0}>
|
|
382
|
+
<Heading level={3}>Device history</Heading>
|
|
383
|
+
<Divider />
|
|
384
|
+
{DEVICE_ROWS.map((device, i) => (
|
|
385
|
+
<HStack
|
|
386
|
+
key={i}
|
|
387
|
+
gap={3}
|
|
388
|
+
vAlign="start"
|
|
389
|
+
style={rowPadding}>
|
|
390
|
+
<Icon icon={Monitor} />
|
|
391
|
+
<StackItem size="fill">
|
|
392
|
+
<VStack gap={0}>
|
|
393
|
+
<HStack gap={2} vAlign="center">
|
|
394
|
+
<Text type="body" weight="semibold">
|
|
395
|
+
{device.label}
|
|
396
|
+
</Text>
|
|
397
|
+
{device.badge && <Badge label={device.badge} />}
|
|
398
|
+
</HStack>
|
|
399
|
+
<Text
|
|
400
|
+
type="supporting"
|
|
401
|
+
color="secondary"
|
|
402
|
+
display="block"
|
|
403
|
+
hasTabularNumbers>
|
|
404
|
+
{device.location}
|
|
405
|
+
</Text>
|
|
406
|
+
</VStack>
|
|
407
|
+
</StackItem>
|
|
408
|
+
{device.action && (
|
|
409
|
+
<Link href="#/templates/settings-sidebar">{device.action}</Link>
|
|
410
|
+
)}
|
|
411
|
+
</HStack>
|
|
412
|
+
))}
|
|
413
|
+
<Divider />
|
|
414
|
+
</VStack>
|
|
415
|
+
|
|
416
|
+
<VStack gap={0}>
|
|
417
|
+
<Heading level={3}>Account</Heading>
|
|
418
|
+
<Divider />
|
|
419
|
+
<HStack
|
|
420
|
+
hAlign="between"
|
|
421
|
+
vAlign="start"
|
|
422
|
+
style={rowPadding}>
|
|
423
|
+
<VStack gap={0}>
|
|
424
|
+
<Text type="body" weight="semibold" display="block">
|
|
425
|
+
Deactivate your account
|
|
426
|
+
</Text>
|
|
427
|
+
<Text
|
|
428
|
+
type="supporting"
|
|
429
|
+
color="secondary"
|
|
430
|
+
display="block">
|
|
431
|
+
This action cannot be undone
|
|
432
|
+
</Text>
|
|
433
|
+
</VStack>
|
|
434
|
+
<Link href="#/templates/settings-sidebar">Deactivate</Link>
|
|
435
|
+
</HStack>
|
|
436
|
+
<Divider />
|
|
437
|
+
</VStack>
|
|
438
|
+
</VStack>
|
|
439
|
+
)}
|
|
440
|
+
|
|
441
|
+
{activeTab === 'shared' && (
|
|
442
|
+
<VStack gap={8}>
|
|
443
|
+
<VStack gap={2}>
|
|
444
|
+
<Heading level={3}>Shared access</Heading>
|
|
445
|
+
<Divider />
|
|
446
|
+
<Text type="body" color="secondary">
|
|
447
|
+
Review each request carefully before approving access.
|
|
448
|
+
We'll email your employee or co-worker a 4-digit
|
|
449
|
+
code that lets them log into your account with their
|
|
450
|
+
trusted device.
|
|
451
|
+
</Text>
|
|
452
|
+
</VStack>
|
|
453
|
+
|
|
454
|
+
<Card variant="muted">
|
|
455
|
+
<HStack gap={4} vAlign="start">
|
|
456
|
+
<Center width={48} height={48} style={iconBox}>
|
|
457
|
+
<Icon icon={Lock} />
|
|
458
|
+
</Center>
|
|
459
|
+
<VStack gap={1}>
|
|
460
|
+
<Text type="body" weight="bold">
|
|
461
|
+
Adding devices from people you trust
|
|
462
|
+
</Text>
|
|
463
|
+
<Text type="body" color="secondary">
|
|
464
|
+
When you approve a request, you grant someone full
|
|
465
|
+
access to your account. They'll be able to
|
|
466
|
+
change reservations and send messages on your
|
|
467
|
+
behalf.
|
|
468
|
+
</Text>
|
|
469
|
+
</VStack>
|
|
470
|
+
</HStack>
|
|
471
|
+
</Card>
|
|
472
|
+
</VStack>
|
|
473
|
+
)}
|
|
474
|
+
</VStack>
|
|
475
|
+
)}
|
|
476
|
+
|
|
477
|
+
{activeNav === 'Languages & currency' && (
|
|
478
|
+
<VStack gap={6}>
|
|
479
|
+
{!isNarrow && (
|
|
480
|
+
<Heading level={2}>Languages & currency</Heading>
|
|
481
|
+
)}
|
|
482
|
+
<VStack gap={0}>
|
|
483
|
+
<ExpandableRow
|
|
484
|
+
label="Preferred language"
|
|
485
|
+
value={
|
|
486
|
+
LANGUAGES.find(l => l.value === language)?.label ??
|
|
487
|
+
language
|
|
488
|
+
}
|
|
489
|
+
isExpanded={expandedRow === 'language'}
|
|
490
|
+
onEdit={() => setExpandedRow('language')}
|
|
491
|
+
onCancel={() => setExpandedRow(null)}
|
|
492
|
+
onSave={() => setExpandedRow(null)}>
|
|
493
|
+
<Selector
|
|
494
|
+
label="Language"
|
|
495
|
+
isLabelHidden
|
|
496
|
+
size="lg"
|
|
497
|
+
value={language}
|
|
498
|
+
onChange={setLanguage}
|
|
499
|
+
options={LANGUAGES}
|
|
500
|
+
/>
|
|
501
|
+
</ExpandableRow>
|
|
502
|
+
<ExpandableRow
|
|
503
|
+
label="Preferred currency"
|
|
504
|
+
value={
|
|
505
|
+
CURRENCIES.find(c => c.value === currency)?.label ??
|
|
506
|
+
currency
|
|
507
|
+
}
|
|
508
|
+
isExpanded={expandedRow === 'currency'}
|
|
509
|
+
onEdit={() => setExpandedRow('currency')}
|
|
510
|
+
onCancel={() => setExpandedRow(null)}
|
|
511
|
+
onSave={() => setExpandedRow(null)}>
|
|
512
|
+
<Selector
|
|
513
|
+
label="Currency"
|
|
514
|
+
isLabelHidden
|
|
515
|
+
size="lg"
|
|
516
|
+
value={currency}
|
|
517
|
+
onChange={setCurrency}
|
|
518
|
+
options={CURRENCIES}
|
|
519
|
+
/>
|
|
520
|
+
</ExpandableRow>
|
|
521
|
+
<ExpandableRow
|
|
522
|
+
label="Time zone"
|
|
523
|
+
value={
|
|
524
|
+
TIMEZONES.find(t => t.value === timezone)?.label ??
|
|
525
|
+
timezone
|
|
526
|
+
}
|
|
527
|
+
isExpanded={expandedRow === 'timezone'}
|
|
528
|
+
onEdit={() => setExpandedRow('timezone')}
|
|
529
|
+
onCancel={() => setExpandedRow(null)}
|
|
530
|
+
onSave={() => setExpandedRow(null)}>
|
|
531
|
+
<Selector
|
|
532
|
+
label="Time zone"
|
|
533
|
+
isLabelHidden
|
|
534
|
+
size="lg"
|
|
535
|
+
value={timezone}
|
|
536
|
+
onChange={setTimezone}
|
|
537
|
+
options={TIMEZONES}
|
|
538
|
+
/>
|
|
539
|
+
</ExpandableRow>
|
|
540
|
+
</VStack>
|
|
541
|
+
</VStack>
|
|
542
|
+
)}
|
|
543
|
+
|
|
544
|
+
{activeNav === 'Personal information' && (
|
|
545
|
+
<VStack gap={6}>
|
|
546
|
+
{!isNarrow && <Heading level={2}>Personal info</Heading>}
|
|
547
|
+
<VStack gap={0}>
|
|
548
|
+
<ExpandableRow
|
|
549
|
+
label="Legal name"
|
|
550
|
+
value={legalName}
|
|
551
|
+
isExpanded={expandedRow === 'legalName'}
|
|
552
|
+
onEdit={() => setExpandedRow('legalName')}
|
|
553
|
+
onCancel={() => setExpandedRow(null)}
|
|
554
|
+
onSave={() => setExpandedRow(null)}>
|
|
555
|
+
<TextInput
|
|
556
|
+
label="Legal name"
|
|
557
|
+
isLabelHidden
|
|
558
|
+
value={legalName}
|
|
559
|
+
onChange={setLegalName}
|
|
560
|
+
/>
|
|
561
|
+
</ExpandableRow>
|
|
562
|
+
<ExpandableRow
|
|
563
|
+
label="Preferred first name"
|
|
564
|
+
value={preferredName || 'Not provided'}
|
|
565
|
+
isExpanded={expandedRow === 'preferredName'}
|
|
566
|
+
onEdit={() => setExpandedRow('preferredName')}
|
|
567
|
+
onCancel={() => setExpandedRow(null)}
|
|
568
|
+
onSave={() => setExpandedRow(null)}>
|
|
569
|
+
<TextInput
|
|
570
|
+
label="Preferred first name"
|
|
571
|
+
isLabelHidden
|
|
572
|
+
value={preferredName}
|
|
573
|
+
onChange={setPreferredName}
|
|
574
|
+
/>
|
|
575
|
+
</ExpandableRow>
|
|
576
|
+
<ExpandableRow
|
|
577
|
+
label="Email address"
|
|
578
|
+
value={email}
|
|
579
|
+
isExpanded={expandedRow === 'email'}
|
|
580
|
+
onEdit={() => setExpandedRow('email')}
|
|
581
|
+
onCancel={() => setExpandedRow(null)}
|
|
582
|
+
onSave={() => setExpandedRow(null)}>
|
|
583
|
+
<TextInput
|
|
584
|
+
label="Email address"
|
|
585
|
+
isLabelHidden
|
|
586
|
+
value={email}
|
|
587
|
+
onChange={setEmail}
|
|
588
|
+
/>
|
|
589
|
+
</ExpandableRow>
|
|
590
|
+
<ExpandableRow
|
|
591
|
+
label="Phone number"
|
|
592
|
+
value={phone}
|
|
593
|
+
isExpanded={expandedRow === 'phone'}
|
|
594
|
+
onEdit={() => setExpandedRow('phone')}
|
|
595
|
+
onCancel={() => setExpandedRow(null)}
|
|
596
|
+
onSave={() => setExpandedRow(null)}>
|
|
597
|
+
<TextInput
|
|
598
|
+
label="Phone number"
|
|
599
|
+
isLabelHidden
|
|
600
|
+
value={phone}
|
|
601
|
+
onChange={setPhone}
|
|
602
|
+
/>
|
|
603
|
+
</ExpandableRow>
|
|
604
|
+
<InfoRowItem
|
|
605
|
+
label="Identity verification"
|
|
606
|
+
value="Verified"
|
|
607
|
+
action=""
|
|
608
|
+
/>
|
|
609
|
+
<ExpandableRow
|
|
610
|
+
label="Residential address"
|
|
611
|
+
value={address || 'Not provided'}
|
|
612
|
+
isExpanded={expandedRow === 'address'}
|
|
613
|
+
onEdit={() => setExpandedRow('address')}
|
|
614
|
+
onCancel={() => setExpandedRow(null)}
|
|
615
|
+
onSave={() => setExpandedRow(null)}>
|
|
616
|
+
<TextInput
|
|
617
|
+
label="Residential address"
|
|
618
|
+
isLabelHidden
|
|
619
|
+
value={address}
|
|
620
|
+
onChange={setAddress}
|
|
621
|
+
/>
|
|
622
|
+
</ExpandableRow>
|
|
623
|
+
<ExpandableRow
|
|
624
|
+
label="Mailing address"
|
|
625
|
+
value={mailingAddress || 'Not provided'}
|
|
626
|
+
isExpanded={expandedRow === 'mailingAddress'}
|
|
627
|
+
onEdit={() => setExpandedRow('mailingAddress')}
|
|
628
|
+
onCancel={() => setExpandedRow(null)}
|
|
629
|
+
onSave={() => setExpandedRow(null)}>
|
|
630
|
+
<TextInput
|
|
631
|
+
label="Mailing address"
|
|
632
|
+
isLabelHidden
|
|
633
|
+
value={mailingAddress}
|
|
634
|
+
onChange={setMailingAddress}
|
|
635
|
+
/>
|
|
636
|
+
</ExpandableRow>
|
|
637
|
+
<ExpandableRow
|
|
638
|
+
label="Emergency contact"
|
|
639
|
+
value={emergencyContact}
|
|
640
|
+
isExpanded={expandedRow === 'emergencyContact'}
|
|
641
|
+
onEdit={() => setExpandedRow('emergencyContact')}
|
|
642
|
+
onCancel={() => setExpandedRow(null)}
|
|
643
|
+
onSave={() => setExpandedRow(null)}>
|
|
644
|
+
<TextInput
|
|
645
|
+
label="Emergency contact"
|
|
646
|
+
isLabelHidden
|
|
647
|
+
value={emergencyContact}
|
|
648
|
+
onChange={setEmergencyContact}
|
|
649
|
+
/>
|
|
650
|
+
</ExpandableRow>
|
|
651
|
+
</VStack>
|
|
652
|
+
|
|
653
|
+
<Card padding={4}>
|
|
654
|
+
<VStack gap={4}>
|
|
655
|
+
<HStack gap={3} vAlign="start">
|
|
656
|
+
<Center width={48} height={48} style={iconBox}>
|
|
657
|
+
<Icon icon={Lock} />
|
|
658
|
+
</Center>
|
|
659
|
+
<VStack gap={0}>
|
|
660
|
+
<Text type="body" weight="semibold" display="block">
|
|
661
|
+
Why isn't my info shown here?
|
|
662
|
+
</Text>
|
|
663
|
+
<Text
|
|
664
|
+
type="supporting"
|
|
665
|
+
color="secondary"
|
|
666
|
+
display="block">
|
|
667
|
+
We're hiding some account details to protect your
|
|
668
|
+
identity.
|
|
669
|
+
</Text>
|
|
670
|
+
</VStack>
|
|
671
|
+
</HStack>
|
|
672
|
+
<Divider />
|
|
673
|
+
<HStack gap={3} vAlign="start">
|
|
674
|
+
<Center width={48} height={48} style={iconBox}>
|
|
675
|
+
<Icon icon={SquarePen} />
|
|
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>
|
|
710
|
+
</VStack>
|
|
711
|
+
</Card>
|
|
712
|
+
</VStack>
|
|
713
|
+
)}
|
|
714
|
+
|
|
715
|
+
{activeNav === 'Privacy' && (
|
|
716
|
+
<VStack gap={6}>
|
|
717
|
+
{!isNarrow && <Heading level={2}>Privacy</Heading>}
|
|
718
|
+
|
|
719
|
+
<VStack gap={8}>
|
|
720
|
+
<VStack gap={0}>
|
|
721
|
+
<Heading level={3}>Messages</Heading>
|
|
722
|
+
<VStack style={rowPadding}>
|
|
723
|
+
<Switch
|
|
724
|
+
label="Show people when I've read their messages."
|
|
725
|
+
value={readReceipts}
|
|
726
|
+
onChange={setReadReceipts}
|
|
727
|
+
labelPosition="start"
|
|
728
|
+
labelSpacing="spread"
|
|
729
|
+
/>
|
|
730
|
+
</VStack>
|
|
731
|
+
<HStack hAlign="between" vAlign="center" style={rowPadding}>
|
|
732
|
+
<Text type="body" weight="semibold">
|
|
733
|
+
Blocked people
|
|
734
|
+
</Text>
|
|
735
|
+
<Link href="#/templates/settings-sidebar">View</Link>
|
|
736
|
+
</HStack>
|
|
737
|
+
<Divider />
|
|
738
|
+
</VStack>
|
|
739
|
+
|
|
740
|
+
<VStack gap={0}>
|
|
741
|
+
<Heading level={3}>Listings</Heading>
|
|
742
|
+
<VStack style={rowPadding}>
|
|
743
|
+
<Switch
|
|
744
|
+
label="Include my listing(s) in search engines"
|
|
745
|
+
description="Turning this on means search engines, like Google, will display your listing page(s) in search results."
|
|
746
|
+
value={searchEngines}
|
|
747
|
+
onChange={setSearchEngines}
|
|
748
|
+
labelPosition="start"
|
|
749
|
+
labelSpacing="spread"
|
|
750
|
+
/>
|
|
751
|
+
</VStack>
|
|
752
|
+
<Divider />
|
|
753
|
+
</VStack>
|
|
754
|
+
|
|
755
|
+
<VStack gap={4}>
|
|
756
|
+
<Heading level={3}>Reviews</Heading>
|
|
757
|
+
<Text type="body" color="secondary">
|
|
758
|
+
Choose what's shared when you write a review.{' '}
|
|
759
|
+
<Link href="#/templates/settings-sidebar" type="supporting">
|
|
760
|
+
Learn more
|
|
761
|
+
</Link>
|
|
762
|
+
</Text>
|
|
763
|
+
<VStack gap={4}>
|
|
764
|
+
<Switch
|
|
765
|
+
label="Show my home city and country"
|
|
766
|
+
description="Ex: City and country"
|
|
767
|
+
value={showCity}
|
|
768
|
+
onChange={setShowCity}
|
|
769
|
+
labelPosition="start"
|
|
770
|
+
labelSpacing="spread"
|
|
771
|
+
/>
|
|
772
|
+
<Switch
|
|
773
|
+
label="Show my trip type"
|
|
774
|
+
description="Ex: Stayed with kids or pets"
|
|
775
|
+
value={showTripType}
|
|
776
|
+
onChange={setShowTripType}
|
|
777
|
+
labelPosition="start"
|
|
778
|
+
labelSpacing="spread"
|
|
779
|
+
/>
|
|
780
|
+
<Switch
|
|
781
|
+
label="Show my length of stay"
|
|
782
|
+
description="Ex: A few nights, about a week, etc."
|
|
783
|
+
value={showStayLength}
|
|
784
|
+
onChange={setShowStayLength}
|
|
785
|
+
labelPosition="start"
|
|
786
|
+
labelSpacing="spread"
|
|
787
|
+
/>
|
|
788
|
+
<Switch
|
|
789
|
+
label="Show my booked services"
|
|
790
|
+
description="Ex: Gourmet brunch or tasting menu"
|
|
791
|
+
value={showServices}
|
|
792
|
+
onChange={setShowServices}
|
|
793
|
+
labelPosition="start"
|
|
794
|
+
labelSpacing="spread"
|
|
795
|
+
/>
|
|
796
|
+
</VStack>
|
|
797
|
+
<Divider />
|
|
798
|
+
</VStack>
|
|
799
|
+
|
|
800
|
+
<VStack gap={4}>
|
|
801
|
+
<Heading level={3}>Data privacy</Heading>
|
|
802
|
+
<Card>
|
|
803
|
+
<HStack hAlign="between" vAlign="center">
|
|
804
|
+
<Text type="body">Request my personal data</Text>
|
|
805
|
+
<Link href="#/templates/settings-sidebar">Request</Link>
|
|
806
|
+
</HStack>
|
|
807
|
+
</Card>
|
|
808
|
+
<Switch
|
|
809
|
+
label="Help improve AI-powered features"
|
|
810
|
+
description="When this is on, we use your data to develop and improve AI models."
|
|
811
|
+
value={aiFeatures}
|
|
812
|
+
onChange={setAiFeatures}
|
|
813
|
+
labelPosition="start"
|
|
814
|
+
labelSpacing="spread"
|
|
815
|
+
/>
|
|
816
|
+
<Card>
|
|
817
|
+
<HStack hAlign="between" vAlign="center">
|
|
818
|
+
<Text type="body">Delete my account</Text>
|
|
819
|
+
<Link href="#/templates/settings-sidebar">Delete</Link>
|
|
820
|
+
</HStack>
|
|
821
|
+
</Card>
|
|
822
|
+
<Card variant="muted">
|
|
823
|
+
<HStack gap={4} vAlign="start">
|
|
824
|
+
<Center width={48} height={48} style={iconBox}>
|
|
825
|
+
<Icon icon={ShieldCheck} />
|
|
826
|
+
</Center>
|
|
827
|
+
<VStack gap={1}>
|
|
828
|
+
<Text type="body" weight="bold">
|
|
829
|
+
Committed to privacy
|
|
830
|
+
</Text>
|
|
831
|
+
<Text type="supporting" color="secondary">
|
|
832
|
+
We're committed to keeping your data protected.
|
|
833
|
+
See details in our{' '}
|
|
834
|
+
<Link href="#/templates/settings-sidebar" type="supporting">
|
|
835
|
+
Privacy Policy
|
|
836
|
+
</Link>
|
|
837
|
+
.
|
|
838
|
+
</Text>
|
|
839
|
+
</VStack>
|
|
840
|
+
</HStack>
|
|
841
|
+
</Card>
|
|
842
|
+
</VStack>
|
|
843
|
+
</VStack>
|
|
844
|
+
</VStack>
|
|
845
|
+
)}
|
|
846
|
+
|
|
847
|
+
{activeNav === 'Notifications' && (
|
|
848
|
+
<VStack gap={6}>
|
|
849
|
+
{!isNarrow && <Heading level={2}>Notifications</Heading>}
|
|
850
|
+
<VStack gap={0}>
|
|
851
|
+
<Heading level={3}>Messages</Heading>
|
|
852
|
+
<VStack style={rowPadding}>
|
|
853
|
+
<Switch
|
|
854
|
+
label="Email notifications"
|
|
855
|
+
description="Listing updates, trip reminders, and account activity."
|
|
856
|
+
value={emailNotif}
|
|
857
|
+
onChange={setEmailNotif}
|
|
858
|
+
labelPosition="start"
|
|
859
|
+
labelSpacing="spread"
|
|
860
|
+
/>
|
|
861
|
+
</VStack>
|
|
862
|
+
<Divider />
|
|
863
|
+
<VStack style={rowPadding}>
|
|
864
|
+
<Switch
|
|
865
|
+
label="Push notifications"
|
|
866
|
+
description="Instant alerts for messages and reservation requests."
|
|
867
|
+
value={pushNotif}
|
|
868
|
+
onChange={setPushNotif}
|
|
869
|
+
labelPosition="start"
|
|
870
|
+
labelSpacing="spread"
|
|
871
|
+
/>
|
|
872
|
+
</VStack>
|
|
873
|
+
<Divider />
|
|
874
|
+
</VStack>
|
|
875
|
+
</VStack>
|
|
876
|
+
)}
|
|
877
|
+
|
|
878
|
+
{activeNav === 'Taxes' && (
|
|
879
|
+
<VStack gap={6}>
|
|
880
|
+
{!isNarrow && <Heading level={2}>Taxes</Heading>}
|
|
881
|
+
<VStack gap={0}>
|
|
882
|
+
<Heading level={3}>Tax documents</Heading>
|
|
883
|
+
<Divider />
|
|
884
|
+
{TAX_ROWS.map(row => (
|
|
885
|
+
<InfoRowItem key={row.label} {...row} />
|
|
886
|
+
))}
|
|
887
|
+
</VStack>
|
|
888
|
+
</VStack>
|
|
889
|
+
)}
|
|
890
|
+
|
|
891
|
+
{activeNav === 'Payments' && (
|
|
892
|
+
<VStack gap={6}>
|
|
893
|
+
{!isNarrow && <Heading level={2}>Payments</Heading>}
|
|
894
|
+
<VStack gap={0}>
|
|
895
|
+
<Heading level={3}>Payouts</Heading>
|
|
896
|
+
<Divider />
|
|
897
|
+
{PAYOUT_ROWS.map(row => (
|
|
898
|
+
<InfoRowItem key={row.label} {...row} />
|
|
899
|
+
))}
|
|
900
|
+
</VStack>
|
|
901
|
+
</VStack>
|
|
902
|
+
)}
|
|
903
|
+
|
|
904
|
+
{activeNav === 'Travel for work' && (
|
|
905
|
+
<VStack gap={6}>
|
|
906
|
+
{!isNarrow && <Heading level={2}>Travel for work</Heading>}
|
|
907
|
+
<VStack gap={0}>
|
|
908
|
+
<Heading level={3}>Work trips</Heading>
|
|
909
|
+
<VStack style={rowPadding}>
|
|
910
|
+
<Switch
|
|
911
|
+
label="Show work-trip options at checkout"
|
|
912
|
+
description="Add a work email to expense trips and unlock business-ready listings."
|
|
913
|
+
value={workTrips}
|
|
914
|
+
onChange={setWorkTrips}
|
|
915
|
+
labelPosition="start"
|
|
916
|
+
labelSpacing="spread"
|
|
917
|
+
/>
|
|
918
|
+
</VStack>
|
|
919
|
+
<Divider />
|
|
920
|
+
</VStack>
|
|
921
|
+
</VStack>
|
|
922
|
+
)}
|
|
923
|
+
|
|
924
|
+
{activeNav === 'Professional hosting tools' && (
|
|
925
|
+
<VStack gap={6}>
|
|
926
|
+
{!isNarrow && (
|
|
927
|
+
<Heading level={2}>Professional hosting tools</Heading>
|
|
928
|
+
)}
|
|
929
|
+
<Card variant="muted">
|
|
930
|
+
<HStack gap={4} vAlign="start">
|
|
931
|
+
<Center width={48} height={48} style={iconBox}>
|
|
932
|
+
<Icon icon={Wrench} />
|
|
933
|
+
</Center>
|
|
934
|
+
<VStack gap={1}>
|
|
935
|
+
<Text type="body" weight="bold">
|
|
936
|
+
Tools for professional hosts
|
|
937
|
+
</Text>
|
|
938
|
+
<Text type="supporting" color="secondary">
|
|
939
|
+
Manage multiple listings, route tasks to co-hosts, and
|
|
940
|
+
review consolidated payouts from one place.
|
|
941
|
+
</Text>
|
|
942
|
+
</VStack>
|
|
943
|
+
</HStack>
|
|
944
|
+
</Card>
|
|
945
|
+
</VStack>
|
|
946
|
+
)}
|
|
947
|
+
</VStack>
|
|
948
|
+
</LayoutContent>
|
|
949
|
+
}
|
|
950
|
+
/>
|
|
951
|
+
);
|
|
952
|
+
}
|