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,920 @@
|
|
|
1
|
+
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
|
+
|
|
3
|
+
import React, {useState, type CSSProperties} from 'react';
|
|
4
|
+
import {
|
|
5
|
+
VStack,
|
|
6
|
+
HStack,
|
|
7
|
+
StackItem,
|
|
8
|
+
Layout,
|
|
9
|
+
LayoutPanel,
|
|
10
|
+
LayoutContent,
|
|
11
|
+
} from '@astryxdesign/core/Layout';
|
|
12
|
+
import {Text, Heading} from '@astryxdesign/core/Text';
|
|
13
|
+
import {Button} from '@astryxdesign/core/Button';
|
|
14
|
+
import {Dialog, DialogHeader} from '@astryxdesign/core/Dialog';
|
|
15
|
+
import {List, ListItem} from '@astryxdesign/core/List';
|
|
16
|
+
import {Divider} from '@astryxdesign/core/Divider';
|
|
17
|
+
import {Selector} from '@astryxdesign/core/Selector';
|
|
18
|
+
import {TextInput} from '@astryxdesign/core/TextInput';
|
|
19
|
+
import {Card} from '@astryxdesign/core/Card';
|
|
20
|
+
import {Switch} from '@astryxdesign/core/Switch';
|
|
21
|
+
import {Link} from '@astryxdesign/core/Link';
|
|
22
|
+
import {TabList, Tab} from '@astryxdesign/core/TabList';
|
|
23
|
+
import {Badge} from '@astryxdesign/core/Badge';
|
|
24
|
+
import {Icon} from '@astryxdesign/core/Icon';
|
|
25
|
+
import {Center} from '@astryxdesign/core/Center';
|
|
26
|
+
import {useMediaQuery} from '@astryxdesign/core/hooks';
|
|
27
|
+
import {
|
|
28
|
+
User,
|
|
29
|
+
Lock,
|
|
30
|
+
Globe,
|
|
31
|
+
ShieldCheck,
|
|
32
|
+
Monitor,
|
|
33
|
+
Bell,
|
|
34
|
+
FileText,
|
|
35
|
+
CreditCard,
|
|
36
|
+
Briefcase,
|
|
37
|
+
SquarePen,
|
|
38
|
+
Share2,
|
|
39
|
+
} from 'lucide-react';
|
|
40
|
+
|
|
41
|
+
const iconBox: CSSProperties = {
|
|
42
|
+
borderRadius: 'var(--radius-container)',
|
|
43
|
+
backgroundColor: 'var(--color-background-surface)',
|
|
44
|
+
flexShrink: 0,
|
|
45
|
+
};
|
|
46
|
+
// Sticky dialog header bar — no Astryx prop for sticky/background/z-index.
|
|
47
|
+
// Inline + block padding comes from the parent LayoutContent `padding`.
|
|
48
|
+
const headerSticky: CSSProperties = {
|
|
49
|
+
position: 'sticky',
|
|
50
|
+
top: 0,
|
|
51
|
+
backgroundColor: 'var(--color-background-surface)',
|
|
52
|
+
zIndex: 1,
|
|
53
|
+
};
|
|
54
|
+
// No `maxWidth` prop on VStack — width only. Inline padding comes from
|
|
55
|
+
// the parent LayoutContent `padding`.
|
|
56
|
+
const contentMaxWidth: CSSProperties = {
|
|
57
|
+
maxWidth: 680,
|
|
58
|
+
};
|
|
59
|
+
// Aligns the sidebar heading with list-item label text. No heading margin prop.
|
|
60
|
+
const sideNavHeading: CSSProperties = {
|
|
61
|
+
marginInline: 'var(--spacing-4)',
|
|
62
|
+
};
|
|
63
|
+
const dialogHeight: CSSProperties = {
|
|
64
|
+
height: '85vh',
|
|
65
|
+
};
|
|
66
|
+
// Keeps row actions ("Log out", "Deactivate") on one line: without this the
|
|
67
|
+
// action column wraps mid-phrase at tablet widths while the info column still
|
|
68
|
+
// has room to wrap instead.
|
|
69
|
+
const actionNoWrap: CSSProperties = {
|
|
70
|
+
flexShrink: 0,
|
|
71
|
+
whiteSpace: 'nowrap',
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const NAV_ITEMS = [
|
|
75
|
+
{label: 'Personal information', icon: User},
|
|
76
|
+
{label: 'Login & security', icon: Lock},
|
|
77
|
+
{label: 'Privacy', icon: ShieldCheck},
|
|
78
|
+
{label: 'Notifications', icon: Bell},
|
|
79
|
+
{label: 'Taxes', icon: FileText},
|
|
80
|
+
{label: 'Payments', icon: CreditCard},
|
|
81
|
+
{label: 'Languages & currency', icon: Globe},
|
|
82
|
+
{label: 'Travel for work', icon: Briefcase},
|
|
83
|
+
];
|
|
84
|
+
|
|
85
|
+
const LOGIN_ROWS = [
|
|
86
|
+
{label: 'Password', value: 'Not created', action: 'Create'},
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
const SOCIAL_ROWS = [
|
|
90
|
+
{label: 'Google', value: 'Connected', action: 'Disconnect'},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const DEVICE_ROWS: {
|
|
94
|
+
label: string;
|
|
95
|
+
badge?: string;
|
|
96
|
+
location: string;
|
|
97
|
+
action?: string;
|
|
98
|
+
}[] = [
|
|
99
|
+
{
|
|
100
|
+
label: 'OS X 10.15.7 · Chrome',
|
|
101
|
+
badge: 'CURRENT SESSION',
|
|
102
|
+
location: 'Brașov, Transylvania · March 30, 2026 at 19:31',
|
|
103
|
+
},
|
|
104
|
+
{label: 'Session', location: 'August 9, 2023 at 04:19', action: 'Log out'},
|
|
105
|
+
{
|
|
106
|
+
label: 'OS X 10.15.7 · unknown',
|
|
107
|
+
location: 'Whitby, England · April 14, 2023 at 17:47',
|
|
108
|
+
action: 'Log out',
|
|
109
|
+
},
|
|
110
|
+
];
|
|
111
|
+
|
|
112
|
+
const LANGUAGES = [
|
|
113
|
+
{label: 'English (Canada)', value: 'en-CA'},
|
|
114
|
+
{label: 'English (US)', value: 'en-US'},
|
|
115
|
+
{label: 'French', value: 'fr'},
|
|
116
|
+
{label: 'Spanish', value: 'es'},
|
|
117
|
+
{label: 'German', value: 'de'},
|
|
118
|
+
{label: 'Japanese', value: 'ja'},
|
|
119
|
+
];
|
|
120
|
+
|
|
121
|
+
const CURRENCIES = [
|
|
122
|
+
{label: 'Canadian dollar (CAD)', value: 'CAD'},
|
|
123
|
+
{label: 'US dollar (USD)', value: 'USD'},
|
|
124
|
+
{label: 'Euro (EUR)', value: 'EUR'},
|
|
125
|
+
{label: 'British pound (GBP)', value: 'GBP'},
|
|
126
|
+
{label: 'Japanese yen (JPY)', value: 'JPY'},
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
const TIMEZONES = [
|
|
130
|
+
{label: '(GMT-05:00) Eastern Time (US & Canada)', value: 'ET'},
|
|
131
|
+
{label: '(GMT-06:00) Central Time (US & Canada)', value: 'CT'},
|
|
132
|
+
{label: '(GMT-07:00) Mountain Time (US & Canada)', value: 'MT'},
|
|
133
|
+
{label: '(GMT-08:00) Pacific Time (US & Canada)', value: 'PT'},
|
|
134
|
+
{label: '(GMT+00:00) UTC', value: 'UTC'},
|
|
135
|
+
{label: '(GMT+01:00) London', value: 'GMT+1'},
|
|
136
|
+
];
|
|
137
|
+
|
|
138
|
+
interface ExpandableRowProps {
|
|
139
|
+
label: string;
|
|
140
|
+
value: string;
|
|
141
|
+
children: React.ReactNode;
|
|
142
|
+
isExpanded: boolean;
|
|
143
|
+
onEdit: () => void;
|
|
144
|
+
onCancel: () => void;
|
|
145
|
+
onSave: () => void;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function ExpandableRow({
|
|
149
|
+
label,
|
|
150
|
+
value,
|
|
151
|
+
children,
|
|
152
|
+
isExpanded,
|
|
153
|
+
onEdit,
|
|
154
|
+
onCancel,
|
|
155
|
+
onSave,
|
|
156
|
+
}: ExpandableRowProps) {
|
|
157
|
+
return (
|
|
158
|
+
<>
|
|
159
|
+
{isExpanded ? (
|
|
160
|
+
<VStack gap={4}>
|
|
161
|
+
<Text type="body" weight="semibold" display="block">
|
|
162
|
+
{label}
|
|
163
|
+
</Text>
|
|
164
|
+
{children}
|
|
165
|
+
<HStack gap={2}>
|
|
166
|
+
<Button label="Save" variant="primary" onClick={onSave} />
|
|
167
|
+
<Button label="Cancel" variant="ghost" onClick={onCancel} />
|
|
168
|
+
</HStack>
|
|
169
|
+
</VStack>
|
|
170
|
+
) : (
|
|
171
|
+
<HStack hAlign="between" vAlign="start">
|
|
172
|
+
<VStack gap={0}>
|
|
173
|
+
<Text type="body" weight="semibold" display="block">
|
|
174
|
+
{label}
|
|
175
|
+
</Text>
|
|
176
|
+
<Text type="supporting" color="secondary" display="block">
|
|
177
|
+
{value}
|
|
178
|
+
</Text>
|
|
179
|
+
</VStack>
|
|
180
|
+
<Link
|
|
181
|
+
href="#/templates/settings-dialog"
|
|
182
|
+
onClick={(e: React.MouseEvent) => {
|
|
183
|
+
e.preventDefault();
|
|
184
|
+
onEdit();
|
|
185
|
+
}}>
|
|
186
|
+
Edit
|
|
187
|
+
</Link>
|
|
188
|
+
</HStack>
|
|
189
|
+
)}
|
|
190
|
+
<Divider />
|
|
191
|
+
</>
|
|
192
|
+
);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function InfoRowItem({
|
|
196
|
+
label,
|
|
197
|
+
value,
|
|
198
|
+
action,
|
|
199
|
+
}: {
|
|
200
|
+
label: string;
|
|
201
|
+
value: string;
|
|
202
|
+
action: string;
|
|
203
|
+
}) {
|
|
204
|
+
return (
|
|
205
|
+
<>
|
|
206
|
+
<HStack hAlign="between" vAlign="start">
|
|
207
|
+
<VStack gap={0}>
|
|
208
|
+
<Text type="body" weight="semibold" display="block">
|
|
209
|
+
{label}
|
|
210
|
+
</Text>
|
|
211
|
+
<Text type="supporting" color="secondary" display="block">
|
|
212
|
+
{value}
|
|
213
|
+
</Text>
|
|
214
|
+
</VStack>
|
|
215
|
+
{action && <Link>{action}</Link>}
|
|
216
|
+
</HStack>
|
|
217
|
+
<Divider />
|
|
218
|
+
</>
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export default function SettingsDialog() {
|
|
223
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
224
|
+
const [activeNav, setActiveNav] = useState('Login & security');
|
|
225
|
+
const [expandedRow, setExpandedRow] = useState<string | null>(null);
|
|
226
|
+
|
|
227
|
+
const [language, setLanguage] = useState('en-CA');
|
|
228
|
+
const [currency, setCurrency] = useState('CAD');
|
|
229
|
+
const [timezone, setTimezone] = useState('ET');
|
|
230
|
+
const [activeTab, setActiveTab] = useState('login');
|
|
231
|
+
|
|
232
|
+
const [legalName, setLegalName] = useState('Vlad Dracul');
|
|
233
|
+
const [preferredName, setPreferredName] = useState('');
|
|
234
|
+
const [email, setEmail] = useState('v***d@castle-dracula.ro');
|
|
235
|
+
const [phone, setPhone] = useState('+1 ***-***-0123');
|
|
236
|
+
const [address, setAddress] = useState('');
|
|
237
|
+
const [mailingAddress, setMailingAddress] = useState('');
|
|
238
|
+
const [emergencyContact, setEmergencyContact] = useState('Provided');
|
|
239
|
+
const [readReceipts, setReadReceipts] = useState(true);
|
|
240
|
+
const [searchEngines, setSearchEngines] = useState(true);
|
|
241
|
+
const [showCity, setShowCity] = useState(true);
|
|
242
|
+
const [showTripType, setShowTripType] = useState(true);
|
|
243
|
+
const [showStayLength, setShowStayLength] = useState(true);
|
|
244
|
+
const [showServices, setShowServices] = useState(true);
|
|
245
|
+
const [aiFeatures, setAiFeatures] = useState(true);
|
|
246
|
+
const [emailNotif, setEmailNotif] = useState(true);
|
|
247
|
+
const [pushNotif, setPushNotif] = useState(false);
|
|
248
|
+
const [workTravel, setWorkTravel] = useState(false);
|
|
249
|
+
|
|
250
|
+
// Below ~640px the 280px section sidebar crushes the content column to
|
|
251
|
+
// ~110px. The sidebar hides and a section picker renders above the content.
|
|
252
|
+
const isCompact = useMediaQuery('(max-width: 640px)');
|
|
253
|
+
|
|
254
|
+
const handleEdit = (row: string) => setExpandedRow(row);
|
|
255
|
+
const handleCancel = () => setExpandedRow(null);
|
|
256
|
+
const handleSave = () => setExpandedRow(null);
|
|
257
|
+
|
|
258
|
+
return (
|
|
259
|
+
<>
|
|
260
|
+
<Layout
|
|
261
|
+
content={
|
|
262
|
+
<LayoutContent padding={0}>
|
|
263
|
+
<Center height="80vh">
|
|
264
|
+
<Button
|
|
265
|
+
label="Open settings"
|
|
266
|
+
variant="primary"
|
|
267
|
+
onClick={() => setIsOpen(true)}
|
|
268
|
+
/>
|
|
269
|
+
</Center>
|
|
270
|
+
</LayoutContent>
|
|
271
|
+
}
|
|
272
|
+
/>
|
|
273
|
+
|
|
274
|
+
<Dialog
|
|
275
|
+
isOpen={isOpen}
|
|
276
|
+
onOpenChange={open => setIsOpen(open)}
|
|
277
|
+
width={isCompact ? 'calc(100vw - 32px)' : 900}
|
|
278
|
+
maxHeight="85vh"
|
|
279
|
+
padding={0}
|
|
280
|
+
purpose="form"
|
|
281
|
+
style={dialogHeight}>
|
|
282
|
+
<Layout
|
|
283
|
+
height="fill"
|
|
284
|
+
start={
|
|
285
|
+
isCompact ? undefined : (
|
|
286
|
+
<LayoutPanel width={280} hasDivider role="navigation" padding={3}>
|
|
287
|
+
<VStack gap={4}>
|
|
288
|
+
<Heading level={2} style={sideNavHeading}>
|
|
289
|
+
Account settings
|
|
290
|
+
</Heading>
|
|
291
|
+
<List density="spacious">
|
|
292
|
+
{NAV_ITEMS.map(item => (
|
|
293
|
+
<ListItem
|
|
294
|
+
key={item.label}
|
|
295
|
+
label={item.label}
|
|
296
|
+
startContent={<Icon icon={item.icon} />}
|
|
297
|
+
isSelected={activeNav === item.label}
|
|
298
|
+
onClick={() => {
|
|
299
|
+
setActiveNav(item.label);
|
|
300
|
+
setExpandedRow(null);
|
|
301
|
+
}}
|
|
302
|
+
/>
|
|
303
|
+
))}
|
|
304
|
+
</List>
|
|
305
|
+
</VStack>
|
|
306
|
+
</LayoutPanel>
|
|
307
|
+
)
|
|
308
|
+
}
|
|
309
|
+
content={
|
|
310
|
+
<LayoutContent isScrollable padding={6}>
|
|
311
|
+
<VStack gap={6}>
|
|
312
|
+
<VStack style={headerSticky}>
|
|
313
|
+
<DialogHeader
|
|
314
|
+
title={
|
|
315
|
+
activeNav === 'Personal information'
|
|
316
|
+
? 'Personal info'
|
|
317
|
+
: activeNav
|
|
318
|
+
}
|
|
319
|
+
onOpenChange={open => setIsOpen(open)}
|
|
320
|
+
hasDivider={false}
|
|
321
|
+
/>
|
|
322
|
+
</VStack>
|
|
323
|
+
{isCompact && (
|
|
324
|
+
<Selector
|
|
325
|
+
label="Settings section"
|
|
326
|
+
value={activeNav}
|
|
327
|
+
onChange={value => {
|
|
328
|
+
setActiveNav(value);
|
|
329
|
+
setExpandedRow(null);
|
|
330
|
+
}}
|
|
331
|
+
options={NAV_ITEMS.map(item => ({
|
|
332
|
+
label: item.label,
|
|
333
|
+
value: item.label,
|
|
334
|
+
}))}
|
|
335
|
+
width="100%"
|
|
336
|
+
/>
|
|
337
|
+
)}
|
|
338
|
+
<VStack gap={0} style={contentMaxWidth}>
|
|
339
|
+
{activeNav === 'Personal information' && (
|
|
340
|
+
<VStack gap={6}>
|
|
341
|
+
<VStack gap={4}>
|
|
342
|
+
<ExpandableRow
|
|
343
|
+
label="Legal name"
|
|
344
|
+
value={legalName}
|
|
345
|
+
isExpanded={expandedRow === 'legalName'}
|
|
346
|
+
onEdit={() => handleEdit('legalName')}
|
|
347
|
+
onCancel={handleCancel}
|
|
348
|
+
onSave={handleSave}>
|
|
349
|
+
<TextInput
|
|
350
|
+
label="Legal name"
|
|
351
|
+
isLabelHidden
|
|
352
|
+
value={legalName}
|
|
353
|
+
onChange={setLegalName}
|
|
354
|
+
/>
|
|
355
|
+
</ExpandableRow>
|
|
356
|
+
<ExpandableRow
|
|
357
|
+
label="Preferred first name"
|
|
358
|
+
value={preferredName || 'Not provided'}
|
|
359
|
+
isExpanded={expandedRow === 'preferredName'}
|
|
360
|
+
onEdit={() => handleEdit('preferredName')}
|
|
361
|
+
onCancel={handleCancel}
|
|
362
|
+
onSave={handleSave}>
|
|
363
|
+
<TextInput
|
|
364
|
+
label="Preferred first name"
|
|
365
|
+
isLabelHidden
|
|
366
|
+
value={preferredName}
|
|
367
|
+
onChange={setPreferredName}
|
|
368
|
+
/>
|
|
369
|
+
</ExpandableRow>
|
|
370
|
+
<ExpandableRow
|
|
371
|
+
label="Email address"
|
|
372
|
+
value={email}
|
|
373
|
+
isExpanded={expandedRow === 'email'}
|
|
374
|
+
onEdit={() => handleEdit('email')}
|
|
375
|
+
onCancel={handleCancel}
|
|
376
|
+
onSave={handleSave}>
|
|
377
|
+
<TextInput
|
|
378
|
+
label="Email address"
|
|
379
|
+
isLabelHidden
|
|
380
|
+
value={email}
|
|
381
|
+
onChange={setEmail}
|
|
382
|
+
/>
|
|
383
|
+
</ExpandableRow>
|
|
384
|
+
<ExpandableRow
|
|
385
|
+
label="Phone number"
|
|
386
|
+
value={phone}
|
|
387
|
+
isExpanded={expandedRow === 'phone'}
|
|
388
|
+
onEdit={() => handleEdit('phone')}
|
|
389
|
+
onCancel={handleCancel}
|
|
390
|
+
onSave={handleSave}>
|
|
391
|
+
<TextInput
|
|
392
|
+
label="Phone number"
|
|
393
|
+
isLabelHidden
|
|
394
|
+
value={phone}
|
|
395
|
+
onChange={setPhone}
|
|
396
|
+
/>
|
|
397
|
+
</ExpandableRow>
|
|
398
|
+
<InfoRowItem
|
|
399
|
+
label="Identity verification"
|
|
400
|
+
value="Verified"
|
|
401
|
+
action=""
|
|
402
|
+
/>
|
|
403
|
+
<ExpandableRow
|
|
404
|
+
label="Residential address"
|
|
405
|
+
value={address || 'Not provided'}
|
|
406
|
+
isExpanded={expandedRow === 'address'}
|
|
407
|
+
onEdit={() => handleEdit('address')}
|
|
408
|
+
onCancel={handleCancel}
|
|
409
|
+
onSave={handleSave}>
|
|
410
|
+
<TextInput
|
|
411
|
+
label="Residential address"
|
|
412
|
+
isLabelHidden
|
|
413
|
+
value={address}
|
|
414
|
+
onChange={setAddress}
|
|
415
|
+
/>
|
|
416
|
+
</ExpandableRow>
|
|
417
|
+
<ExpandableRow
|
|
418
|
+
label="Mailing address"
|
|
419
|
+
value={mailingAddress || 'Not provided'}
|
|
420
|
+
isExpanded={expandedRow === 'mailingAddress'}
|
|
421
|
+
onEdit={() => handleEdit('mailingAddress')}
|
|
422
|
+
onCancel={handleCancel}
|
|
423
|
+
onSave={handleSave}>
|
|
424
|
+
<TextInput
|
|
425
|
+
label="Mailing address"
|
|
426
|
+
isLabelHidden
|
|
427
|
+
value={mailingAddress}
|
|
428
|
+
onChange={setMailingAddress}
|
|
429
|
+
/>
|
|
430
|
+
</ExpandableRow>
|
|
431
|
+
<ExpandableRow
|
|
432
|
+
label="Emergency contact"
|
|
433
|
+
value={emergencyContact}
|
|
434
|
+
isExpanded={expandedRow === 'emergencyContact'}
|
|
435
|
+
onEdit={() => handleEdit('emergencyContact')}
|
|
436
|
+
onCancel={handleCancel}
|
|
437
|
+
onSave={handleSave}>
|
|
438
|
+
<TextInput
|
|
439
|
+
label="Emergency contact"
|
|
440
|
+
isLabelHidden
|
|
441
|
+
value={emergencyContact}
|
|
442
|
+
onChange={setEmergencyContact}
|
|
443
|
+
/>
|
|
444
|
+
</ExpandableRow>
|
|
445
|
+
</VStack>
|
|
446
|
+
|
|
447
|
+
<Card padding={4}>
|
|
448
|
+
<VStack gap={4}>
|
|
449
|
+
<HStack gap={3} vAlign="start">
|
|
450
|
+
<Center width={48} height={48} style={iconBox}>
|
|
451
|
+
<Icon icon={Lock} />
|
|
452
|
+
</Center>
|
|
453
|
+
<VStack gap={0}>
|
|
454
|
+
<Text
|
|
455
|
+
type="body"
|
|
456
|
+
weight="semibold"
|
|
457
|
+
display="block">
|
|
458
|
+
Why isn't my info shown here?
|
|
459
|
+
</Text>
|
|
460
|
+
<Text
|
|
461
|
+
type="supporting"
|
|
462
|
+
color="secondary"
|
|
463
|
+
display="block">
|
|
464
|
+
We're hiding some account details to
|
|
465
|
+
protect your identity.
|
|
466
|
+
</Text>
|
|
467
|
+
</VStack>
|
|
468
|
+
</HStack>
|
|
469
|
+
<Divider />
|
|
470
|
+
<HStack gap={3} vAlign="start">
|
|
471
|
+
<Center width={48} height={48} style={iconBox}>
|
|
472
|
+
<Icon icon={SquarePen} />
|
|
473
|
+
</Center>
|
|
474
|
+
<VStack gap={0}>
|
|
475
|
+
<Text
|
|
476
|
+
type="body"
|
|
477
|
+
weight="semibold"
|
|
478
|
+
display="block">
|
|
479
|
+
Which details can be edited?
|
|
480
|
+
</Text>
|
|
481
|
+
<Text
|
|
482
|
+
type="supporting"
|
|
483
|
+
color="secondary"
|
|
484
|
+
display="block">
|
|
485
|
+
Contact info and personal details can be edited.
|
|
486
|
+
If this info was used to verify your identity,
|
|
487
|
+
you'll need to get verified again the next
|
|
488
|
+
time you book—or to continue hosting.
|
|
489
|
+
</Text>
|
|
490
|
+
</VStack>
|
|
491
|
+
</HStack>
|
|
492
|
+
<Divider />
|
|
493
|
+
<HStack gap={3} vAlign="start">
|
|
494
|
+
<Center width={48} height={48} style={iconBox}>
|
|
495
|
+
<Icon icon={Share2} />
|
|
496
|
+
</Center>
|
|
497
|
+
<VStack gap={0}>
|
|
498
|
+
<Text
|
|
499
|
+
type="body"
|
|
500
|
+
weight="semibold"
|
|
501
|
+
display="block">
|
|
502
|
+
What info is shared with others?
|
|
503
|
+
</Text>
|
|
504
|
+
<Text
|
|
505
|
+
type="supporting"
|
|
506
|
+
color="secondary"
|
|
507
|
+
display="block">
|
|
508
|
+
We only release contact information after a
|
|
509
|
+
reservation is confirmed.
|
|
510
|
+
</Text>
|
|
511
|
+
</VStack>
|
|
512
|
+
</HStack>
|
|
513
|
+
</VStack>
|
|
514
|
+
</Card>
|
|
515
|
+
</VStack>
|
|
516
|
+
)}
|
|
517
|
+
|
|
518
|
+
{activeNav === 'Login & security' && (
|
|
519
|
+
<VStack gap={6}>
|
|
520
|
+
<TabList
|
|
521
|
+
value={activeTab}
|
|
522
|
+
onChange={setActiveTab}
|
|
523
|
+
hasDivider>
|
|
524
|
+
<Tab value="login" label="Login" />
|
|
525
|
+
<Tab value="shared" label="Shared access" />
|
|
526
|
+
</TabList>
|
|
527
|
+
|
|
528
|
+
{activeTab === 'login' && (
|
|
529
|
+
<VStack gap={8}>
|
|
530
|
+
<VStack gap={4}>
|
|
531
|
+
<Heading level={3}>Login</Heading>
|
|
532
|
+
<Divider />
|
|
533
|
+
{LOGIN_ROWS.map(row => (
|
|
534
|
+
<InfoRowItem key={row.label} {...row} />
|
|
535
|
+
))}
|
|
536
|
+
</VStack>
|
|
537
|
+
|
|
538
|
+
<VStack gap={4}>
|
|
539
|
+
<Heading level={3}>Social accounts</Heading>
|
|
540
|
+
<Divider />
|
|
541
|
+
{SOCIAL_ROWS.map(row => (
|
|
542
|
+
<InfoRowItem key={row.label} {...row} />
|
|
543
|
+
))}
|
|
544
|
+
</VStack>
|
|
545
|
+
|
|
546
|
+
<VStack gap={4}>
|
|
547
|
+
<Heading level={3}>Device history</Heading>
|
|
548
|
+
<Divider />
|
|
549
|
+
{DEVICE_ROWS.map((device, i) => (
|
|
550
|
+
<React.Fragment key={i}>
|
|
551
|
+
<HStack gap={3} vAlign="start">
|
|
552
|
+
<Icon icon={Monitor} />
|
|
553
|
+
<StackItem size="fill">
|
|
554
|
+
<VStack gap={0}>
|
|
555
|
+
<HStack gap={2} vAlign="center">
|
|
556
|
+
<Text type="body" weight="semibold">
|
|
557
|
+
{device.label}
|
|
558
|
+
</Text>
|
|
559
|
+
{device.badge && (
|
|
560
|
+
<Badge label={device.badge} />
|
|
561
|
+
)}
|
|
562
|
+
</HStack>
|
|
563
|
+
<Text
|
|
564
|
+
type="supporting"
|
|
565
|
+
color="secondary"
|
|
566
|
+
display="block"
|
|
567
|
+
hasTabularNumbers>
|
|
568
|
+
{device.location}
|
|
569
|
+
</Text>
|
|
570
|
+
</VStack>
|
|
571
|
+
</StackItem>
|
|
572
|
+
{device.action && (
|
|
573
|
+
<Link style={actionNoWrap}>
|
|
574
|
+
{device.action}
|
|
575
|
+
</Link>
|
|
576
|
+
)}
|
|
577
|
+
</HStack>
|
|
578
|
+
<Divider />
|
|
579
|
+
</React.Fragment>
|
|
580
|
+
))}
|
|
581
|
+
</VStack>
|
|
582
|
+
|
|
583
|
+
<VStack gap={4}>
|
|
584
|
+
<Heading level={3}>Account</Heading>
|
|
585
|
+
<Divider />
|
|
586
|
+
<HStack hAlign="between" vAlign="start">
|
|
587
|
+
<VStack gap={0}>
|
|
588
|
+
<Text
|
|
589
|
+
type="body"
|
|
590
|
+
weight="semibold"
|
|
591
|
+
display="block">
|
|
592
|
+
Deactivate your account
|
|
593
|
+
</Text>
|
|
594
|
+
<Text
|
|
595
|
+
type="supporting"
|
|
596
|
+
color="secondary"
|
|
597
|
+
display="block">
|
|
598
|
+
This action cannot be undone
|
|
599
|
+
</Text>
|
|
600
|
+
</VStack>
|
|
601
|
+
<Link>Deactivate</Link>
|
|
602
|
+
</HStack>
|
|
603
|
+
<Divider />
|
|
604
|
+
</VStack>
|
|
605
|
+
</VStack>
|
|
606
|
+
)}
|
|
607
|
+
|
|
608
|
+
{activeTab === 'shared' && (
|
|
609
|
+
<VStack gap={8}>
|
|
610
|
+
<VStack gap={2}>
|
|
611
|
+
<Heading level={3}>Shared access</Heading>
|
|
612
|
+
<Divider />
|
|
613
|
+
<Text type="body" color="secondary">
|
|
614
|
+
Review each request carefully before approving
|
|
615
|
+
access. We'll email your employee or
|
|
616
|
+
co-worker a 4-digit code that lets them log into
|
|
617
|
+
your account with their trusted device.
|
|
618
|
+
</Text>
|
|
619
|
+
</VStack>
|
|
620
|
+
|
|
621
|
+
<Card variant="muted">
|
|
622
|
+
<HStack gap={4} vAlign="start">
|
|
623
|
+
<Center width={48} height={48} style={iconBox}>
|
|
624
|
+
<Icon icon={Lock} />
|
|
625
|
+
</Center>
|
|
626
|
+
<VStack gap={1}>
|
|
627
|
+
<Text type="body" weight="bold">
|
|
628
|
+
Adding devices from people you trust
|
|
629
|
+
</Text>
|
|
630
|
+
<Text type="body" color="secondary">
|
|
631
|
+
When you approve a request, you grant someone
|
|
632
|
+
full access to your account. They'll be
|
|
633
|
+
able to change reservations and send messages
|
|
634
|
+
on your behalf.
|
|
635
|
+
</Text>
|
|
636
|
+
</VStack>
|
|
637
|
+
</HStack>
|
|
638
|
+
</Card>
|
|
639
|
+
</VStack>
|
|
640
|
+
)}
|
|
641
|
+
</VStack>
|
|
642
|
+
)}
|
|
643
|
+
|
|
644
|
+
{activeNav === 'Languages & currency' && (
|
|
645
|
+
<VStack gap={6}>
|
|
646
|
+
<VStack gap={4}>
|
|
647
|
+
<ExpandableRow
|
|
648
|
+
label="Preferred language"
|
|
649
|
+
value={
|
|
650
|
+
LANGUAGES.find(l => l.value === language)?.label ??
|
|
651
|
+
language
|
|
652
|
+
}
|
|
653
|
+
isExpanded={expandedRow === 'language'}
|
|
654
|
+
onEdit={() => handleEdit('language')}
|
|
655
|
+
onCancel={handleCancel}
|
|
656
|
+
onSave={handleSave}>
|
|
657
|
+
<Selector
|
|
658
|
+
label="Language"
|
|
659
|
+
isLabelHidden
|
|
660
|
+
size="lg"
|
|
661
|
+
value={language}
|
|
662
|
+
onChange={setLanguage}
|
|
663
|
+
options={LANGUAGES}
|
|
664
|
+
/>
|
|
665
|
+
</ExpandableRow>
|
|
666
|
+
<ExpandableRow
|
|
667
|
+
label="Preferred currency"
|
|
668
|
+
value={
|
|
669
|
+
CURRENCIES.find(c => c.value === currency)?.label ??
|
|
670
|
+
currency
|
|
671
|
+
}
|
|
672
|
+
isExpanded={expandedRow === 'currency'}
|
|
673
|
+
onEdit={() => handleEdit('currency')}
|
|
674
|
+
onCancel={handleCancel}
|
|
675
|
+
onSave={handleSave}>
|
|
676
|
+
<Selector
|
|
677
|
+
label="Currency"
|
|
678
|
+
isLabelHidden
|
|
679
|
+
size="lg"
|
|
680
|
+
value={currency}
|
|
681
|
+
onChange={setCurrency}
|
|
682
|
+
options={CURRENCIES}
|
|
683
|
+
/>
|
|
684
|
+
</ExpandableRow>
|
|
685
|
+
<ExpandableRow
|
|
686
|
+
label="Time zone"
|
|
687
|
+
value={
|
|
688
|
+
TIMEZONES.find(t => t.value === timezone)?.label ??
|
|
689
|
+
timezone
|
|
690
|
+
}
|
|
691
|
+
isExpanded={expandedRow === 'timezone'}
|
|
692
|
+
onEdit={() => handleEdit('timezone')}
|
|
693
|
+
onCancel={handleCancel}
|
|
694
|
+
onSave={handleSave}>
|
|
695
|
+
<Selector
|
|
696
|
+
label="Time zone"
|
|
697
|
+
isLabelHidden
|
|
698
|
+
size="lg"
|
|
699
|
+
value={timezone}
|
|
700
|
+
onChange={setTimezone}
|
|
701
|
+
options={TIMEZONES}
|
|
702
|
+
/>
|
|
703
|
+
</ExpandableRow>
|
|
704
|
+
</VStack>
|
|
705
|
+
</VStack>
|
|
706
|
+
)}
|
|
707
|
+
|
|
708
|
+
{activeNav === 'Notifications' && (
|
|
709
|
+
<VStack gap={6}>
|
|
710
|
+
<VStack gap={4}>
|
|
711
|
+
<Heading level={3}>Notifications</Heading>
|
|
712
|
+
<Switch
|
|
713
|
+
label="Email notifications"
|
|
714
|
+
description="Booking updates, reminders, and policy changes."
|
|
715
|
+
value={emailNotif}
|
|
716
|
+
onChange={setEmailNotif}
|
|
717
|
+
labelPosition="start"
|
|
718
|
+
labelSpacing="spread"
|
|
719
|
+
/>
|
|
720
|
+
<Divider />
|
|
721
|
+
<Switch
|
|
722
|
+
label="Push notifications"
|
|
723
|
+
description="Time-sensitive alerts on this device."
|
|
724
|
+
value={pushNotif}
|
|
725
|
+
onChange={setPushNotif}
|
|
726
|
+
labelPosition="start"
|
|
727
|
+
labelSpacing="spread"
|
|
728
|
+
/>
|
|
729
|
+
<Divider />
|
|
730
|
+
</VStack>
|
|
731
|
+
</VStack>
|
|
732
|
+
)}
|
|
733
|
+
|
|
734
|
+
{activeNav === 'Payments' && (
|
|
735
|
+
<VStack gap={6}>
|
|
736
|
+
<VStack gap={4}>
|
|
737
|
+
<Heading level={3}>Payments</Heading>
|
|
738
|
+
<Divider />
|
|
739
|
+
<InfoRowItem
|
|
740
|
+
label="Payout method"
|
|
741
|
+
value="Visa ending in 4821"
|
|
742
|
+
action=""
|
|
743
|
+
/>
|
|
744
|
+
<InfoRowItem
|
|
745
|
+
label="Billing history"
|
|
746
|
+
value="No invoices yet"
|
|
747
|
+
action=""
|
|
748
|
+
/>
|
|
749
|
+
</VStack>
|
|
750
|
+
</VStack>
|
|
751
|
+
)}
|
|
752
|
+
|
|
753
|
+
{activeNav === 'Taxes' && (
|
|
754
|
+
<VStack gap={6}>
|
|
755
|
+
<VStack gap={4}>
|
|
756
|
+
<Heading level={3}>Taxes</Heading>
|
|
757
|
+
<Divider />
|
|
758
|
+
<InfoRowItem
|
|
759
|
+
label="Tax profile"
|
|
760
|
+
value="Not submitted"
|
|
761
|
+
action=""
|
|
762
|
+
/>
|
|
763
|
+
<InfoRowItem
|
|
764
|
+
label="Tax documents"
|
|
765
|
+
value="Available after your first payout"
|
|
766
|
+
action=""
|
|
767
|
+
/>
|
|
768
|
+
</VStack>
|
|
769
|
+
</VStack>
|
|
770
|
+
)}
|
|
771
|
+
|
|
772
|
+
{activeNav === 'Travel for work' && (
|
|
773
|
+
<VStack gap={6}>
|
|
774
|
+
<VStack gap={4}>
|
|
775
|
+
<Heading level={3}>Travel for work</Heading>
|
|
776
|
+
<Switch
|
|
777
|
+
label="Show work-trip options"
|
|
778
|
+
description="Adds a work-trip toggle at checkout."
|
|
779
|
+
value={workTravel}
|
|
780
|
+
onChange={setWorkTravel}
|
|
781
|
+
labelPosition="start"
|
|
782
|
+
labelSpacing="spread"
|
|
783
|
+
/>
|
|
784
|
+
<Divider />
|
|
785
|
+
</VStack>
|
|
786
|
+
</VStack>
|
|
787
|
+
)}
|
|
788
|
+
|
|
789
|
+
{activeNav === 'Privacy' && (
|
|
790
|
+
<VStack gap={6}>
|
|
791
|
+
<VStack gap={8}>
|
|
792
|
+
<VStack gap={4}>
|
|
793
|
+
<Heading level={3}>Messages</Heading>
|
|
794
|
+
<Switch
|
|
795
|
+
label="Show people when I've read their messages."
|
|
796
|
+
value={readReceipts}
|
|
797
|
+
onChange={setReadReceipts}
|
|
798
|
+
labelPosition="start"
|
|
799
|
+
labelSpacing="spread"
|
|
800
|
+
/>
|
|
801
|
+
<HStack hAlign="between" vAlign="center">
|
|
802
|
+
<Text type="body" weight="semibold">
|
|
803
|
+
Blocked people
|
|
804
|
+
</Text>
|
|
805
|
+
<Link>View</Link>
|
|
806
|
+
</HStack>
|
|
807
|
+
<Divider />
|
|
808
|
+
</VStack>
|
|
809
|
+
|
|
810
|
+
<VStack gap={4}>
|
|
811
|
+
<Heading level={3}>Listings</Heading>
|
|
812
|
+
<Switch
|
|
813
|
+
label="Include my listing(s) in search engines"
|
|
814
|
+
description="Turning this on means search engines, like Google, will display your listing page(s) in search results."
|
|
815
|
+
value={searchEngines}
|
|
816
|
+
onChange={setSearchEngines}
|
|
817
|
+
labelPosition="start"
|
|
818
|
+
labelSpacing="spread"
|
|
819
|
+
/>
|
|
820
|
+
<Divider />
|
|
821
|
+
</VStack>
|
|
822
|
+
|
|
823
|
+
<VStack gap={4}>
|
|
824
|
+
<Heading level={3}>Reviews</Heading>
|
|
825
|
+
<Text type="supporting" color="secondary">
|
|
826
|
+
Choose what's shared when you write a review.{' '}
|
|
827
|
+
<Link type="supporting">Learn more</Link>
|
|
828
|
+
</Text>
|
|
829
|
+
<VStack gap={4}>
|
|
830
|
+
<Switch
|
|
831
|
+
label="Show my home city and country"
|
|
832
|
+
description="Ex: City and country"
|
|
833
|
+
value={showCity}
|
|
834
|
+
onChange={setShowCity}
|
|
835
|
+
labelPosition="start"
|
|
836
|
+
labelSpacing="spread"
|
|
837
|
+
/>
|
|
838
|
+
<Switch
|
|
839
|
+
label="Show my trip type"
|
|
840
|
+
description="Ex: Stayed with kids or pets"
|
|
841
|
+
value={showTripType}
|
|
842
|
+
onChange={setShowTripType}
|
|
843
|
+
labelPosition="start"
|
|
844
|
+
labelSpacing="spread"
|
|
845
|
+
/>
|
|
846
|
+
<Switch
|
|
847
|
+
label="Show my length of stay"
|
|
848
|
+
description="Ex: A few nights, about a week, etc."
|
|
849
|
+
value={showStayLength}
|
|
850
|
+
onChange={setShowStayLength}
|
|
851
|
+
labelPosition="start"
|
|
852
|
+
labelSpacing="spread"
|
|
853
|
+
/>
|
|
854
|
+
<Switch
|
|
855
|
+
label="Show my booked services"
|
|
856
|
+
description="Ex: Gourmet brunch or tasting menu"
|
|
857
|
+
value={showServices}
|
|
858
|
+
onChange={setShowServices}
|
|
859
|
+
labelPosition="start"
|
|
860
|
+
labelSpacing="spread"
|
|
861
|
+
/>
|
|
862
|
+
</VStack>
|
|
863
|
+
<Divider />
|
|
864
|
+
</VStack>
|
|
865
|
+
|
|
866
|
+
<VStack gap={4}>
|
|
867
|
+
<Heading level={3}>Data privacy</Heading>
|
|
868
|
+
<Card>
|
|
869
|
+
<HStack hAlign="between" vAlign="center">
|
|
870
|
+
<Text type="body">Request my personal data</Text>
|
|
871
|
+
<Link>Request</Link>
|
|
872
|
+
</HStack>
|
|
873
|
+
</Card>
|
|
874
|
+
<Switch
|
|
875
|
+
label="Help improve AI-powered features"
|
|
876
|
+
description="When this is on, we use your data to develop and improve AI models."
|
|
877
|
+
value={aiFeatures}
|
|
878
|
+
onChange={setAiFeatures}
|
|
879
|
+
labelPosition="start"
|
|
880
|
+
labelSpacing="spread"
|
|
881
|
+
/>
|
|
882
|
+
<Card>
|
|
883
|
+
<HStack hAlign="between" vAlign="center">
|
|
884
|
+
<Text type="body">Delete my account</Text>
|
|
885
|
+
<Link>Delete</Link>
|
|
886
|
+
</HStack>
|
|
887
|
+
</Card>
|
|
888
|
+
<Card variant="muted">
|
|
889
|
+
<HStack gap={4} vAlign="start">
|
|
890
|
+
<Center width={48} height={48} style={iconBox}>
|
|
891
|
+
<Icon icon={ShieldCheck} />
|
|
892
|
+
</Center>
|
|
893
|
+
<VStack gap={1}>
|
|
894
|
+
<Text type="body" weight="bold">
|
|
895
|
+
Committed to privacy
|
|
896
|
+
</Text>
|
|
897
|
+
<Text type="supporting" color="secondary">
|
|
898
|
+
We're committed to keeping your data
|
|
899
|
+
protected. See details in our{' '}
|
|
900
|
+
<Link type="supporting">
|
|
901
|
+
Privacy Policy
|
|
902
|
+
</Link>
|
|
903
|
+
.
|
|
904
|
+
</Text>
|
|
905
|
+
</VStack>
|
|
906
|
+
</HStack>
|
|
907
|
+
</Card>
|
|
908
|
+
</VStack>
|
|
909
|
+
</VStack>
|
|
910
|
+
</VStack>
|
|
911
|
+
)}
|
|
912
|
+
</VStack>
|
|
913
|
+
</VStack>
|
|
914
|
+
</LayoutContent>
|
|
915
|
+
}
|
|
916
|
+
/>
|
|
917
|
+
</Dialog>
|
|
918
|
+
</>
|
|
919
|
+
);
|
|
920
|
+
}
|