@shipfox/client-auth 21.0.0 → 22.0.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +15 -0
- package/dist/pages/workspace-onboarding-page.d.ts.map +1 -1
- package/dist/pages/workspace-onboarding-page.js +98 -240
- package/dist/pages/workspace-onboarding-page.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/pages/workspace-onboarding-page.tsx +5 -83
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 42 files with swc (
|
|
2
|
+
Successfully compiled: 42 files with swc (701.38ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# @shipfox/client-auth
|
|
2
2
|
|
|
3
|
+
## 22.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 50b3867: Consolidate authentication, onboarding, integration-install, and callback surfaces onto the shared focused frame.
|
|
8
|
+
- Updated dependencies [50b3867]
|
|
9
|
+
- Updated dependencies [00c1cb8]
|
|
10
|
+
- Updated dependencies [7693eb3]
|
|
11
|
+
- Updated dependencies [00c1cb8]
|
|
12
|
+
- Updated dependencies [56f4526]
|
|
13
|
+
- @shipfox/client-invitations@22.0.0
|
|
14
|
+
- @shipfox/client-shell@22.0.0
|
|
15
|
+
- @shipfox/react-ui@2.1.0
|
|
16
|
+
- @shipfox/client-ui@22.0.0
|
|
17
|
+
|
|
3
18
|
## 21.0.0
|
|
4
19
|
|
|
5
20
|
### Patch Changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace-onboarding-page.d.ts","sourceRoot":"","sources":["../../src/pages/workspace-onboarding-page.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"workspace-onboarding-page.d.ts","sourceRoot":"","sources":["../../src/pages/workspace-onboarding-page.tsx"],"names":[],"mappings":"AAwBA,wBAAgB,uBAAuB,gCA8KtC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { slugifyName, slugSchema } from '@shipfox/api-common-dto';
|
|
3
3
|
import { createWorkspaceBodySchema } from '@shipfox/api-workspaces-dto';
|
|
4
|
+
import { FocusedFrame } from '@shipfox/client-shell/runtime';
|
|
4
5
|
import { displayNameFieldError, SlugField } from '@shipfox/client-ui';
|
|
5
6
|
import { Button } from '@shipfox/react-ui/button';
|
|
6
7
|
import { Callout } from '@shipfox/react-ui/callout';
|
|
@@ -17,58 +18,6 @@ import { checkWorkspaceSlugAvailability, useCreateWorkspaceAuth } from '#hooks/a
|
|
|
17
18
|
import { useAuthState } from '#hooks/use-auth-state.js';
|
|
18
19
|
import { lastWorkspaceIdAtom, rememberLastWorkspaceId } from '#state/last-workspace.js';
|
|
19
20
|
import { workspaceOnboardingErrorToFormError } from './form-errors.js';
|
|
20
|
-
const previewMetrics = [
|
|
21
|
-
{
|
|
22
|
-
label: 'Runs',
|
|
23
|
-
value: '--'
|
|
24
|
-
},
|
|
25
|
-
{
|
|
26
|
-
label: 'Passed',
|
|
27
|
-
value: '--'
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
label: 'Failed',
|
|
31
|
-
value: '--'
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
label: 'Duration',
|
|
35
|
-
value: '--'
|
|
36
|
-
}
|
|
37
|
-
];
|
|
38
|
-
const previewBars = [
|
|
39
|
-
{
|
|
40
|
-
id: 'runs-start',
|
|
41
|
-
height: 32
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
id: 'runs-mid-low',
|
|
45
|
-
height: 48
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
id: 'runs-dip',
|
|
49
|
-
height: 28
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
id: 'runs-mid-high',
|
|
53
|
-
height: 66
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
id: 'runs-mid',
|
|
57
|
-
height: 54
|
|
58
|
-
},
|
|
59
|
-
{
|
|
60
|
-
id: 'runs-peak',
|
|
61
|
-
height: 82
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
id: 'runs-late-low',
|
|
65
|
-
height: 44
|
|
66
|
-
},
|
|
67
|
-
{
|
|
68
|
-
id: 'runs-late-high',
|
|
69
|
-
height: 74
|
|
70
|
-
}
|
|
71
|
-
];
|
|
72
21
|
function isSlugValid(value) {
|
|
73
22
|
return slugSchema.safeParse(value).success;
|
|
74
23
|
}
|
|
@@ -125,8 +74,8 @@ export function WorkspaceOnboardingPage() {
|
|
|
125
74
|
});
|
|
126
75
|
return /*#__PURE__*/ _jsx("main", {
|
|
127
76
|
className: "min-h-screen px-frame py-frame max-[520px]:px-row",
|
|
128
|
-
children: /*#__PURE__*/ _jsxs(
|
|
129
|
-
className: "
|
|
77
|
+
children: /*#__PURE__*/ _jsxs(FocusedFrame, {
|
|
78
|
+
className: "flex min-h-[calc(100vh-64px)] flex-col gap-section",
|
|
130
79
|
children: [
|
|
131
80
|
/*#__PURE__*/ _jsx("header", {
|
|
132
81
|
className: "flex items-center justify-between",
|
|
@@ -148,211 +97,120 @@ export function WorkspaceOnboardingPage() {
|
|
|
148
97
|
]
|
|
149
98
|
})
|
|
150
99
|
}),
|
|
151
|
-
/*#__PURE__*/
|
|
152
|
-
className: "
|
|
153
|
-
children:
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
children: /*#__PURE__*/ _jsxs(Panel, {
|
|
164
|
-
children: [
|
|
165
|
-
/*#__PURE__*/ _jsxs(PanelHeader, {
|
|
166
|
-
variant: "plain",
|
|
167
|
-
className: "flex-col items-start gap-inline",
|
|
168
|
-
children: [
|
|
169
|
-
/*#__PURE__*/ _jsx(PanelTitle, {
|
|
170
|
-
id: "workspace-onboarding-title",
|
|
171
|
-
variant: "h1",
|
|
172
|
-
children: "Create your workspace"
|
|
173
|
-
}),
|
|
174
|
-
/*#__PURE__*/ _jsx(Text, {
|
|
175
|
-
size: "sm",
|
|
176
|
-
className: "text-foreground-neutral-muted",
|
|
177
|
-
children: "Give your team a place to collaborate."
|
|
178
|
-
})
|
|
179
|
-
]
|
|
180
|
-
}),
|
|
181
|
-
/*#__PURE__*/ _jsxs(PanelBody, {
|
|
182
|
-
className: "flex flex-col gap-section p-panel",
|
|
183
|
-
children: [
|
|
184
|
-
formError ? /*#__PURE__*/ _jsx(Callout, {
|
|
185
|
-
role: "alert",
|
|
186
|
-
type: "error",
|
|
187
|
-
children: formError
|
|
188
|
-
}) : null,
|
|
189
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
190
|
-
className: "flex flex-col gap-inline",
|
|
191
|
-
children: [
|
|
192
|
-
/*#__PURE__*/ _jsx(form.Field, {
|
|
193
|
-
name: "name",
|
|
194
|
-
validators: {
|
|
195
|
-
onBlur: ({ value })=>displayNameFieldError(value, 'Workspace name', createWorkspaceBodySchema.shape.name),
|
|
196
|
-
onSubmit: ({ value })=>displayNameFieldError(value, 'Workspace name', createWorkspaceBodySchema.shape.name)
|
|
197
|
-
},
|
|
198
|
-
children: (field)=>/*#__PURE__*/ _jsx(FormField, {
|
|
199
|
-
label: "Workspace name",
|
|
200
|
-
id: "workspace-name",
|
|
201
|
-
error: fieldError(field),
|
|
202
|
-
children: /*#__PURE__*/ _jsx(FormFieldInput, {
|
|
203
|
-
autoComplete: "organization",
|
|
204
|
-
name: "name",
|
|
205
|
-
placeholder: "Acme",
|
|
206
|
-
type: "text",
|
|
207
|
-
value: field.state.value,
|
|
208
|
-
onChange: (event)=>{
|
|
209
|
-
const name = event.target.value;
|
|
210
|
-
field.handleChange(name);
|
|
211
|
-
if (!slugTouched) {
|
|
212
|
-
form.setFieldValue('slug', name ? slugifyName(name, {
|
|
213
|
-
fallback: 'workspace'
|
|
214
|
-
}) : '');
|
|
215
|
-
}
|
|
216
|
-
},
|
|
217
|
-
onBlur: field.handleBlur
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
}),
|
|
221
|
-
/*#__PURE__*/ _jsx(form.Field, {
|
|
222
|
-
name: "slug",
|
|
223
|
-
validators: {
|
|
224
|
-
onBlur: createWorkspaceBodySchema.shape.slug,
|
|
225
|
-
onSubmit: createWorkspaceBodySchema.shape.slug
|
|
226
|
-
},
|
|
227
|
-
children: (field)=>/*#__PURE__*/ _jsx(SlugField, {
|
|
228
|
-
id: "workspace-slug",
|
|
229
|
-
label: "Workspace slug",
|
|
230
|
-
name: "slug",
|
|
231
|
-
value: field.state.value,
|
|
232
|
-
onChange: (value)=>{
|
|
233
|
-
setSlugTouched(true);
|
|
234
|
-
field.handleChange(value);
|
|
235
|
-
},
|
|
236
|
-
onBlur: field.handleBlur,
|
|
237
|
-
error: fieldError(field),
|
|
238
|
-
description: /*#__PURE__*/ _jsx("span", {
|
|
239
|
-
className: "break-all font-code",
|
|
240
|
-
children: `${window.location.origin}/w/${field.state.value || 'acme'}`
|
|
241
|
-
}),
|
|
242
|
-
placeholder: "acme",
|
|
243
|
-
checkEnabled: slugTouched,
|
|
244
|
-
isValid: isSlugValid,
|
|
245
|
-
checkAvailability: checkWorkspaceSlugAvailability
|
|
246
|
-
})
|
|
247
|
-
})
|
|
248
|
-
]
|
|
249
|
-
}),
|
|
250
|
-
/*#__PURE__*/ _jsx(Button, {
|
|
251
|
-
className: "w-full",
|
|
252
|
-
iconRight: "chevronRight",
|
|
253
|
-
isLoading: createWorkspace.isPending,
|
|
254
|
-
type: "submit",
|
|
255
|
-
children: createWorkspace.isPending ? 'Creating workspace...' : 'Create workspace'
|
|
256
|
-
})
|
|
257
|
-
]
|
|
258
|
-
})
|
|
259
|
-
]
|
|
260
|
-
})
|
|
261
|
-
}),
|
|
262
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
263
|
-
className: "hidden flex-col gap-group lg:flex",
|
|
264
|
-
"aria-hidden": "true",
|
|
100
|
+
/*#__PURE__*/ _jsx("section", {
|
|
101
|
+
className: "flex flex-1 items-center",
|
|
102
|
+
children: /*#__PURE__*/ _jsx("form", {
|
|
103
|
+
className: "w-full",
|
|
104
|
+
noValidate: true,
|
|
105
|
+
"aria-labelledby": "workspace-onboarding-title",
|
|
106
|
+
onSubmit: (event)=>{
|
|
107
|
+
event.preventDefault();
|
|
108
|
+
event.stopPropagation();
|
|
109
|
+
void form.handleSubmit();
|
|
110
|
+
},
|
|
111
|
+
children: /*#__PURE__*/ _jsxs(Panel, {
|
|
265
112
|
children: [
|
|
266
|
-
/*#__PURE__*/
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
className: "rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact shadow-button-neutral",
|
|
270
|
-
children: [
|
|
271
|
-
/*#__PURE__*/ _jsx(Text, {
|
|
272
|
-
size: "xs",
|
|
273
|
-
className: "text-foreground-neutral-muted",
|
|
274
|
-
children: metric.label
|
|
275
|
-
}),
|
|
276
|
-
/*#__PURE__*/ _jsx(Text, {
|
|
277
|
-
size: "xl",
|
|
278
|
-
bold: true,
|
|
279
|
-
children: metric.value
|
|
280
|
-
})
|
|
281
|
-
]
|
|
282
|
-
}, metric.label))
|
|
283
|
-
}),
|
|
284
|
-
/*#__PURE__*/ _jsxs("div", {
|
|
285
|
-
className: "grid grid-cols-2 gap-group",
|
|
113
|
+
/*#__PURE__*/ _jsxs(PanelHeader, {
|
|
114
|
+
variant: "plain",
|
|
115
|
+
className: "flex-col items-start gap-inline",
|
|
286
116
|
children: [
|
|
287
|
-
/*#__PURE__*/ _jsx(
|
|
288
|
-
|
|
117
|
+
/*#__PURE__*/ _jsx(PanelTitle, {
|
|
118
|
+
id: "workspace-onboarding-title",
|
|
119
|
+
variant: "h1",
|
|
120
|
+
children: "Create your workspace"
|
|
289
121
|
}),
|
|
290
|
-
/*#__PURE__*/ _jsx(
|
|
291
|
-
|
|
292
|
-
|
|
122
|
+
/*#__PURE__*/ _jsx(Text, {
|
|
123
|
+
size: "sm",
|
|
124
|
+
className: "text-foreground-neutral-muted",
|
|
125
|
+
children: "Give your team a place to collaborate."
|
|
293
126
|
})
|
|
294
127
|
]
|
|
295
128
|
}),
|
|
296
|
-
/*#__PURE__*/ _jsxs(
|
|
297
|
-
className: "flex flex-col gap-
|
|
129
|
+
/*#__PURE__*/ _jsxs(PanelBody, {
|
|
130
|
+
className: "flex flex-col gap-section p-panel",
|
|
298
131
|
children: [
|
|
299
|
-
/*#__PURE__*/ _jsx(
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
children:
|
|
303
|
-
}),
|
|
304
|
-
/*#__PURE__*/
|
|
132
|
+
formError ? /*#__PURE__*/ _jsx(Callout, {
|
|
133
|
+
role: "alert",
|
|
134
|
+
type: "error",
|
|
135
|
+
children: formError
|
|
136
|
+
}) : null,
|
|
137
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
305
138
|
className: "flex flex-col gap-inline",
|
|
306
139
|
children: [
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
children:
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
140
|
+
/*#__PURE__*/ _jsx(form.Field, {
|
|
141
|
+
name: "name",
|
|
142
|
+
validators: {
|
|
143
|
+
onBlur: ({ value })=>displayNameFieldError(value, 'Workspace name', createWorkspaceBodySchema.shape.name),
|
|
144
|
+
onSubmit: ({ value })=>displayNameFieldError(value, 'Workspace name', createWorkspaceBodySchema.shape.name)
|
|
145
|
+
},
|
|
146
|
+
children: (field)=>/*#__PURE__*/ _jsx(FormField, {
|
|
147
|
+
label: "Workspace name",
|
|
148
|
+
id: "workspace-name",
|
|
149
|
+
error: fieldError(field),
|
|
150
|
+
children: /*#__PURE__*/ _jsx(FormFieldInput, {
|
|
151
|
+
autoComplete: "organization",
|
|
152
|
+
name: "name",
|
|
153
|
+
placeholder: "Acme",
|
|
154
|
+
type: "text",
|
|
155
|
+
value: field.state.value,
|
|
156
|
+
onChange: (event)=>{
|
|
157
|
+
const name = event.target.value;
|
|
158
|
+
field.handleChange(name);
|
|
159
|
+
if (!slugTouched) {
|
|
160
|
+
form.setFieldValue('slug', name ? slugifyName(name, {
|
|
161
|
+
fallback: 'workspace'
|
|
162
|
+
}) : '');
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
onBlur: field.handleBlur
|
|
166
|
+
})
|
|
167
|
+
})
|
|
168
|
+
}),
|
|
169
|
+
/*#__PURE__*/ _jsx(form.Field, {
|
|
170
|
+
name: "slug",
|
|
171
|
+
validators: {
|
|
172
|
+
onBlur: createWorkspaceBodySchema.shape.slug,
|
|
173
|
+
onSubmit: createWorkspaceBodySchema.shape.slug
|
|
174
|
+
},
|
|
175
|
+
children: (field)=>/*#__PURE__*/ _jsx(SlugField, {
|
|
176
|
+
id: "workspace-slug",
|
|
177
|
+
label: "Workspace slug",
|
|
178
|
+
name: "slug",
|
|
179
|
+
value: field.state.value,
|
|
180
|
+
onChange: (value)=>{
|
|
181
|
+
setSlugTouched(true);
|
|
182
|
+
field.handleChange(value);
|
|
183
|
+
},
|
|
184
|
+
onBlur: field.handleBlur,
|
|
185
|
+
error: fieldError(field),
|
|
186
|
+
description: /*#__PURE__*/ _jsx("span", {
|
|
187
|
+
className: "break-all font-code",
|
|
188
|
+
children: `${window.location.origin}/w/${field.state.value || 'acme'}`
|
|
189
|
+
}),
|
|
190
|
+
placeholder: "acme",
|
|
191
|
+
checkEnabled: slugTouched,
|
|
192
|
+
isValid: isSlugValid,
|
|
193
|
+
checkAvailability: checkWorkspaceSlugAvailability
|
|
322
194
|
})
|
|
323
|
-
|
|
324
|
-
|
|
195
|
+
})
|
|
196
|
+
]
|
|
197
|
+
}),
|
|
198
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
199
|
+
className: "w-full",
|
|
200
|
+
iconRight: "chevronRight",
|
|
201
|
+
isLoading: createWorkspace.isPending,
|
|
202
|
+
type: "submit",
|
|
203
|
+
children: createWorkspace.isPending ? 'Creating workspace...' : 'Create workspace'
|
|
325
204
|
})
|
|
326
205
|
]
|
|
327
206
|
})
|
|
328
207
|
]
|
|
329
208
|
})
|
|
330
|
-
|
|
209
|
+
})
|
|
331
210
|
})
|
|
332
211
|
]
|
|
333
212
|
})
|
|
334
213
|
});
|
|
335
214
|
}
|
|
336
|
-
function PreviewPanel({ title, bars = false }) {
|
|
337
|
-
return /*#__PURE__*/ _jsxs("div", {
|
|
338
|
-
className: "flex flex-col gap-group rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact shadow-button-neutral",
|
|
339
|
-
children: [
|
|
340
|
-
/*#__PURE__*/ _jsx(Text, {
|
|
341
|
-
size: "sm",
|
|
342
|
-
bold: true,
|
|
343
|
-
children: title
|
|
344
|
-
}),
|
|
345
|
-
/*#__PURE__*/ _jsx("div", {
|
|
346
|
-
className: "flex h-[220px] items-end gap-inline border-b border-l border-border-neutral-base px-row pb-[10px]",
|
|
347
|
-
children: previewBars.map((bar)=>/*#__PURE__*/ _jsx("div", {
|
|
348
|
-
className: bars ? 'w-full rounded-t-4 bg-background-neutral-disabled' : 'w-full rounded-full bg-background-neutral-disabled',
|
|
349
|
-
style: {
|
|
350
|
-
height: `${bar.height}%`
|
|
351
|
-
}
|
|
352
|
-
}, `${title}-${bar.id}`))
|
|
353
|
-
})
|
|
354
|
-
]
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
215
|
|
|
358
216
|
//# sourceMappingURL=workspace-onboarding-page.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pages/workspace-onboarding-page.tsx"],"sourcesContent":["import {slugifyName, slugSchema} from '@shipfox/api-common-dto';\nimport {createWorkspaceBodySchema} from '@shipfox/api-workspaces-dto';\nimport {displayNameFieldError, SlugField} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {FormField, FormFieldInput, fieldError} from '@shipfox/react-ui/form-field';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Panel, PanelBody, PanelHeader, PanelTitle} from '@shipfox/react-ui/panel';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {useForm} from '@tanstack/react-form';\nimport {useNavigate} from '@tanstack/react-router';\nimport {useSetAtom} from 'jotai';\nimport {useState} from 'react';\nimport {checkWorkspaceSlugAvailability, useCreateWorkspaceAuth} from '#hooks/api/workspace-auth.js';\nimport {useAuthState} from '#hooks/use-auth-state.js';\nimport {lastWorkspaceIdAtom, rememberLastWorkspaceId} from '#state/last-workspace.js';\nimport {workspaceOnboardingErrorToFormError} from './form-errors.js';\n\nconst previewMetrics = [\n {label: 'Runs', value: '--'},\n {label: 'Passed', value: '--'},\n {label: 'Failed', value: '--'},\n {label: 'Duration', value: '--'},\n];\nconst previewBars = [\n {id: 'runs-start', height: 32},\n {id: 'runs-mid-low', height: 48},\n {id: 'runs-dip', height: 28},\n {id: 'runs-mid-high', height: 66},\n {id: 'runs-mid', height: 54},\n {id: 'runs-peak', height: 82},\n {id: 'runs-late-low', height: 44},\n {id: 'runs-late-high', height: 74},\n];\n\nfunction isSlugValid(value: string): boolean {\n return slugSchema.safeParse(value).success;\n}\n\nexport function WorkspaceOnboardingPage() {\n const createWorkspace = useCreateWorkspaceAuth();\n const {user} = useAuthState();\n const navigate = useNavigate();\n const setLastWorkspaceId = useSetAtom(lastWorkspaceIdAtom);\n const [formError, setFormError] = useState<string | undefined>();\n const [slugTouched, setSlugTouched] = useState(false);\n\n const form = useForm({\n defaultValues: {name: '', slug: ''},\n onSubmit: async ({value}) => {\n setFormError(undefined);\n try {\n const command = createWorkspaceBodySchema.parse({name: value.name, slug: value.slug});\n const created = await createWorkspace.mutateAsync(command);\n toast.success('Workspace created.');\n // Pin the new workspace as the last-active one so a page refresh and\n // future visits to `/` land on it.\n try {\n setLastWorkspaceId(created.id);\n if (user?.id) rememberLastWorkspaceId(user.id, created.id);\n } catch {\n // localStorage may throw in private browsing or quota-exceeded.\n }\n await navigate({to: '/w/$workspaceSlug', params: {workspaceSlug: created.slug}});\n } catch (error) {\n const mapped = workspaceOnboardingErrorToFormError(error);\n if (mapped.kind === 'field') {\n form.setFieldMeta(mapped.field, (previous) => ({\n ...previous,\n errorMap: {...previous.errorMap, onServer: mapped.message},\n }));\n } else {\n setFormError(mapped.message);\n }\n }\n },\n });\n\n return (\n <main className=\"min-h-screen px-frame py-frame max-[520px]:px-row\">\n <div className=\"mx-auto flex min-h-[calc(100vh-64px)] w-full flex-col gap-section\">\n <header className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-inline\">\n <div className=\"flex size-36 items-center justify-center rounded-8 border border-border-neutral-base bg-background-neutral-base shadow-button-neutral\">\n <Icon name=\"shipfox\" className=\"size-24 text-background-highlight-interactive\" />\n </div>\n <Text size=\"md\" bold>\n Shipfox\n </Text>\n </div>\n </header>\n\n <section className=\"grid flex-1 items-center gap-region lg:grid-cols-[minmax(0,440px)_minmax(0,1fr)]\">\n <form\n className=\"relative z-10 w-full\"\n noValidate\n aria-labelledby=\"workspace-onboarding-title\"\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void form.handleSubmit();\n }}\n >\n <Panel>\n <PanelHeader variant=\"plain\" className=\"flex-col items-start gap-inline\">\n <PanelTitle id=\"workspace-onboarding-title\" variant=\"h1\">\n Create your workspace\n </PanelTitle>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Give your team a place to collaborate.\n </Text>\n </PanelHeader>\n\n <PanelBody className=\"flex flex-col gap-section p-panel\">\n {formError ? (\n <Callout role=\"alert\" type=\"error\">\n {formError}\n </Callout>\n ) : null}\n\n <div className=\"flex flex-col gap-inline\">\n <form.Field\n name=\"name\"\n validators={{\n onBlur: ({value}) =>\n displayNameFieldError(\n value,\n 'Workspace name',\n createWorkspaceBodySchema.shape.name,\n ),\n onSubmit: ({value}) =>\n displayNameFieldError(\n value,\n 'Workspace name',\n createWorkspaceBodySchema.shape.name,\n ),\n }}\n >\n {(field) => (\n <FormField\n label=\"Workspace name\"\n id=\"workspace-name\"\n error={fieldError(field)}\n >\n <FormFieldInput\n autoComplete=\"organization\"\n name=\"name\"\n placeholder=\"Acme\"\n type=\"text\"\n value={field.state.value}\n onChange={(event) => {\n const name = event.target.value;\n field.handleChange(name);\n if (!slugTouched) {\n form.setFieldValue(\n 'slug',\n name ? slugifyName(name, {fallback: 'workspace'}) : '',\n );\n }\n }}\n onBlur={field.handleBlur}\n />\n </FormField>\n )}\n </form.Field>\n <form.Field\n name=\"slug\"\n validators={{\n onBlur: createWorkspaceBodySchema.shape.slug,\n onSubmit: createWorkspaceBodySchema.shape.slug,\n }}\n >\n {(field) => (\n <SlugField\n id=\"workspace-slug\"\n label=\"Workspace slug\"\n name=\"slug\"\n value={field.state.value}\n onChange={(value) => {\n setSlugTouched(true);\n field.handleChange(value);\n }}\n onBlur={field.handleBlur}\n error={fieldError(field)}\n description={\n <span className=\"break-all font-code\">\n {`${window.location.origin}/w/${field.state.value || 'acme'}`}\n </span>\n }\n placeholder=\"acme\"\n checkEnabled={slugTouched}\n isValid={isSlugValid}\n checkAvailability={checkWorkspaceSlugAvailability}\n />\n )}\n </form.Field>\n </div>\n\n <Button\n className=\"w-full\"\n iconRight=\"chevronRight\"\n isLoading={createWorkspace.isPending}\n type=\"submit\"\n >\n {createWorkspace.isPending ? 'Creating workspace...' : 'Create workspace'}\n </Button>\n </PanelBody>\n </Panel>\n </form>\n\n <div className=\"hidden flex-col gap-group lg:flex\" aria-hidden=\"true\">\n <div className=\"grid grid-cols-4 gap-cluster\">\n {previewMetrics.map((metric) => (\n <div\n className=\"rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact shadow-button-neutral\"\n key={metric.label}\n >\n <Text size=\"xs\" className=\"text-foreground-neutral-muted\">\n {metric.label}\n </Text>\n <Text size=\"xl\" bold>\n {metric.value}\n </Text>\n </div>\n ))}\n </div>\n <div className=\"grid grid-cols-2 gap-group\">\n <PreviewPanel title=\"Performance over time\" />\n <PreviewPanel title=\"Duration distribution\" bars />\n </div>\n <div className=\"flex flex-col gap-cluster rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact shadow-button-neutral\">\n <Text size=\"sm\" bold>\n Jobs breakdown\n </Text>\n <div className=\"flex flex-col gap-inline\">\n {[0, 1, 2, 3].map((row) => (\n <div\n className=\"grid grid-cols-[1fr_80px_80px] gap-cluster border-t border-border-neutral-base pt-[10px]\"\n key={row}\n >\n <div className=\"h-12 rounded-full bg-background-neutral-disabled\" />\n <div className=\"h-12 rounded-full bg-background-neutral-disabled\" />\n <div className=\"h-12 rounded-full bg-background-neutral-disabled\" />\n </div>\n ))}\n </div>\n </div>\n </div>\n </section>\n </div>\n </main>\n );\n}\n\nfunction PreviewPanel({title, bars = false}: {title: string; bars?: boolean}) {\n return (\n <div className=\"flex flex-col gap-group rounded-8 border border-border-neutral-base bg-background-neutral-base p-panel-compact shadow-button-neutral\">\n <Text size=\"sm\" bold>\n {title}\n </Text>\n <div className=\"flex h-[220px] items-end gap-inline border-b border-l border-border-neutral-base px-row pb-[10px]\">\n {previewBars.map((bar) => (\n <div\n className={\n bars\n ? 'w-full rounded-t-4 bg-background-neutral-disabled'\n : 'w-full rounded-full bg-background-neutral-disabled'\n }\n key={`${title}-${bar.id}`}\n style={{height: `${bar.height}%`}}\n />\n ))}\n </div>\n </div>\n );\n}\n"],"names":["slugifyName","slugSchema","createWorkspaceBodySchema","displayNameFieldError","SlugField","Button","Callout","FormField","FormFieldInput","fieldError","Icon","Panel","PanelBody","PanelHeader","PanelTitle","toast","Text","useForm","useNavigate","useSetAtom","useState","checkWorkspaceSlugAvailability","useCreateWorkspaceAuth","useAuthState","lastWorkspaceIdAtom","rememberLastWorkspaceId","workspaceOnboardingErrorToFormError","previewMetrics","label","value","previewBars","id","height","isSlugValid","safeParse","success","WorkspaceOnboardingPage","createWorkspace","user","navigate","setLastWorkspaceId","formError","setFormError","slugTouched","setSlugTouched","form","defaultValues","name","slug","onSubmit","undefined","command","parse","created","mutateAsync","to","params","workspaceSlug","error","mapped","kind","setFieldMeta","field","previous","errorMap","onServer","message","main","className","div","header","size","bold","section","noValidate","aria-labelledby","event","preventDefault","stopPropagation","handleSubmit","variant","role","type","Field","validators","onBlur","shape","autoComplete","placeholder","state","onChange","target","handleChange","setFieldValue","fallback","handleBlur","description","span","window","location","origin","checkEnabled","isValid","checkAvailability","iconRight","isLoading","isPending","aria-hidden","map","metric","PreviewPanel","title","bars","row","bar","style"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/pages/workspace-onboarding-page.tsx"],"sourcesContent":["import {slugifyName, slugSchema} from '@shipfox/api-common-dto';\nimport {createWorkspaceBodySchema} from '@shipfox/api-workspaces-dto';\nimport {FocusedFrame} from '@shipfox/client-shell/runtime';\nimport {displayNameFieldError, SlugField} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {FormField, FormFieldInput, fieldError} from '@shipfox/react-ui/form-field';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Panel, PanelBody, PanelHeader, PanelTitle} from '@shipfox/react-ui/panel';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Text} from '@shipfox/react-ui/typography';\nimport {useForm} from '@tanstack/react-form';\nimport {useNavigate} from '@tanstack/react-router';\nimport {useSetAtom} from 'jotai';\nimport {useState} from 'react';\nimport {checkWorkspaceSlugAvailability, useCreateWorkspaceAuth} from '#hooks/api/workspace-auth.js';\nimport {useAuthState} from '#hooks/use-auth-state.js';\nimport {lastWorkspaceIdAtom, rememberLastWorkspaceId} from '#state/last-workspace.js';\nimport {workspaceOnboardingErrorToFormError} from './form-errors.js';\n\nfunction isSlugValid(value: string): boolean {\n return slugSchema.safeParse(value).success;\n}\n\nexport function WorkspaceOnboardingPage() {\n const createWorkspace = useCreateWorkspaceAuth();\n const {user} = useAuthState();\n const navigate = useNavigate();\n const setLastWorkspaceId = useSetAtom(lastWorkspaceIdAtom);\n const [formError, setFormError] = useState<string | undefined>();\n const [slugTouched, setSlugTouched] = useState(false);\n\n const form = useForm({\n defaultValues: {name: '', slug: ''},\n onSubmit: async ({value}) => {\n setFormError(undefined);\n try {\n const command = createWorkspaceBodySchema.parse({name: value.name, slug: value.slug});\n const created = await createWorkspace.mutateAsync(command);\n toast.success('Workspace created.');\n // Pin the new workspace as the last-active one so a page refresh and\n // future visits to `/` land on it.\n try {\n setLastWorkspaceId(created.id);\n if (user?.id) rememberLastWorkspaceId(user.id, created.id);\n } catch {\n // localStorage may throw in private browsing or quota-exceeded.\n }\n await navigate({to: '/w/$workspaceSlug', params: {workspaceSlug: created.slug}});\n } catch (error) {\n const mapped = workspaceOnboardingErrorToFormError(error);\n if (mapped.kind === 'field') {\n form.setFieldMeta(mapped.field, (previous) => ({\n ...previous,\n errorMap: {...previous.errorMap, onServer: mapped.message},\n }));\n } else {\n setFormError(mapped.message);\n }\n }\n },\n });\n\n return (\n <main className=\"min-h-screen px-frame py-frame max-[520px]:px-row\">\n <FocusedFrame className=\"flex min-h-[calc(100vh-64px)] flex-col gap-section\">\n <header className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-inline\">\n <div className=\"flex size-36 items-center justify-center rounded-8 border border-border-neutral-base bg-background-neutral-base shadow-button-neutral\">\n <Icon name=\"shipfox\" className=\"size-24 text-background-highlight-interactive\" />\n </div>\n <Text size=\"md\" bold>\n Shipfox\n </Text>\n </div>\n </header>\n\n <section className=\"flex flex-1 items-center\">\n <form\n className=\"w-full\"\n noValidate\n aria-labelledby=\"workspace-onboarding-title\"\n onSubmit={(event) => {\n event.preventDefault();\n event.stopPropagation();\n void form.handleSubmit();\n }}\n >\n <Panel>\n <PanelHeader variant=\"plain\" className=\"flex-col items-start gap-inline\">\n <PanelTitle id=\"workspace-onboarding-title\" variant=\"h1\">\n Create your workspace\n </PanelTitle>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Give your team a place to collaborate.\n </Text>\n </PanelHeader>\n\n <PanelBody className=\"flex flex-col gap-section p-panel\">\n {formError ? (\n <Callout role=\"alert\" type=\"error\">\n {formError}\n </Callout>\n ) : null}\n\n <div className=\"flex flex-col gap-inline\">\n <form.Field\n name=\"name\"\n validators={{\n onBlur: ({value}) =>\n displayNameFieldError(\n value,\n 'Workspace name',\n createWorkspaceBodySchema.shape.name,\n ),\n onSubmit: ({value}) =>\n displayNameFieldError(\n value,\n 'Workspace name',\n createWorkspaceBodySchema.shape.name,\n ),\n }}\n >\n {(field) => (\n <FormField\n label=\"Workspace name\"\n id=\"workspace-name\"\n error={fieldError(field)}\n >\n <FormFieldInput\n autoComplete=\"organization\"\n name=\"name\"\n placeholder=\"Acme\"\n type=\"text\"\n value={field.state.value}\n onChange={(event) => {\n const name = event.target.value;\n field.handleChange(name);\n if (!slugTouched) {\n form.setFieldValue(\n 'slug',\n name ? slugifyName(name, {fallback: 'workspace'}) : '',\n );\n }\n }}\n onBlur={field.handleBlur}\n />\n </FormField>\n )}\n </form.Field>\n <form.Field\n name=\"slug\"\n validators={{\n onBlur: createWorkspaceBodySchema.shape.slug,\n onSubmit: createWorkspaceBodySchema.shape.slug,\n }}\n >\n {(field) => (\n <SlugField\n id=\"workspace-slug\"\n label=\"Workspace slug\"\n name=\"slug\"\n value={field.state.value}\n onChange={(value) => {\n setSlugTouched(true);\n field.handleChange(value);\n }}\n onBlur={field.handleBlur}\n error={fieldError(field)}\n description={\n <span className=\"break-all font-code\">\n {`${window.location.origin}/w/${field.state.value || 'acme'}`}\n </span>\n }\n placeholder=\"acme\"\n checkEnabled={slugTouched}\n isValid={isSlugValid}\n checkAvailability={checkWorkspaceSlugAvailability}\n />\n )}\n </form.Field>\n </div>\n\n <Button\n className=\"w-full\"\n iconRight=\"chevronRight\"\n isLoading={createWorkspace.isPending}\n type=\"submit\"\n >\n {createWorkspace.isPending ? 'Creating workspace...' : 'Create workspace'}\n </Button>\n </PanelBody>\n </Panel>\n </form>\n </section>\n </FocusedFrame>\n </main>\n );\n}\n"],"names":["slugifyName","slugSchema","createWorkspaceBodySchema","FocusedFrame","displayNameFieldError","SlugField","Button","Callout","FormField","FormFieldInput","fieldError","Icon","Panel","PanelBody","PanelHeader","PanelTitle","toast","Text","useForm","useNavigate","useSetAtom","useState","checkWorkspaceSlugAvailability","useCreateWorkspaceAuth","useAuthState","lastWorkspaceIdAtom","rememberLastWorkspaceId","workspaceOnboardingErrorToFormError","isSlugValid","value","safeParse","success","WorkspaceOnboardingPage","createWorkspace","user","navigate","setLastWorkspaceId","formError","setFormError","slugTouched","setSlugTouched","form","defaultValues","name","slug","onSubmit","undefined","command","parse","created","mutateAsync","id","to","params","workspaceSlug","error","mapped","kind","setFieldMeta","field","previous","errorMap","onServer","message","main","className","header","div","size","bold","section","noValidate","aria-labelledby","event","preventDefault","stopPropagation","handleSubmit","variant","role","type","Field","validators","onBlur","shape","label","autoComplete","placeholder","state","onChange","target","handleChange","setFieldValue","fallback","handleBlur","description","span","window","location","origin","checkEnabled","isValid","checkAvailability","iconRight","isLoading","isPending"],"mappings":";AAAA,SAAQA,WAAW,EAAEC,UAAU,QAAO,0BAA0B;AAChE,SAAQC,yBAAyB,QAAO,8BAA8B;AACtE,SAAQC,YAAY,QAAO,gCAAgC;AAC3D,SAAQC,qBAAqB,EAAEC,SAAS,QAAO,qBAAqB;AACpE,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,SAAS,EAAEC,cAAc,EAAEC,UAAU,QAAO,+BAA+B;AACnF,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,KAAK,EAAEC,SAAS,EAAEC,WAAW,EAAEC,UAAU,QAAO,0BAA0B;AAClF,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,IAAI,QAAO,+BAA+B;AAClD,SAAQC,OAAO,QAAO,uBAAuB;AAC7C,SAAQC,WAAW,QAAO,yBAAyB;AACnD,SAAQC,UAAU,QAAO,QAAQ;AACjC,SAAQC,QAAQ,QAAO,QAAQ;AAC/B,SAAQC,8BAA8B,EAAEC,sBAAsB,QAAO,+BAA+B;AACpG,SAAQC,YAAY,QAAO,2BAA2B;AACtD,SAAQC,mBAAmB,EAAEC,uBAAuB,QAAO,2BAA2B;AACtF,SAAQC,mCAAmC,QAAO,mBAAmB;AAErE,SAASC,YAAYC,KAAa;IAChC,OAAO5B,WAAW6B,SAAS,CAACD,OAAOE,OAAO;AAC5C;AAEA,OAAO,SAASC;IACd,MAAMC,kBAAkBV;IACxB,MAAM,EAACW,IAAI,EAAC,GAAGV;IACf,MAAMW,WAAWhB;IACjB,MAAMiB,qBAAqBhB,WAAWK;IACtC,MAAM,CAACY,WAAWC,aAAa,GAAGjB;IAClC,MAAM,CAACkB,aAAaC,eAAe,GAAGnB,SAAS;IAE/C,MAAMoB,OAAOvB,QAAQ;QACnBwB,eAAe;YAACC,MAAM;YAAIC,MAAM;QAAE;QAClCC,UAAU,OAAO,EAAChB,KAAK,EAAC;YACtBS,aAAaQ;YACb,IAAI;gBACF,MAAMC,UAAU7C,0BAA0B8C,KAAK,CAAC;oBAACL,MAAMd,MAAMc,IAAI;oBAAEC,MAAMf,MAAMe,IAAI;gBAAA;gBACnF,MAAMK,UAAU,MAAMhB,gBAAgBiB,WAAW,CAACH;gBAClD/B,MAAMe,OAAO,CAAC;gBACd,qEAAqE;gBACrE,mCAAmC;gBACnC,IAAI;oBACFK,mBAAmBa,QAAQE,EAAE;oBAC7B,IAAIjB,MAAMiB,IAAIzB,wBAAwBQ,KAAKiB,EAAE,EAAEF,QAAQE,EAAE;gBAC3D,EAAE,OAAM;gBACN,gEAAgE;gBAClE;gBACA,MAAMhB,SAAS;oBAACiB,IAAI;oBAAqBC,QAAQ;wBAACC,eAAeL,QAAQL,IAAI;oBAAA;gBAAC;YAChF,EAAE,OAAOW,OAAO;gBACd,MAAMC,SAAS7B,oCAAoC4B;gBACnD,IAAIC,OAAOC,IAAI,KAAK,SAAS;oBAC3BhB,KAAKiB,YAAY,CAACF,OAAOG,KAAK,EAAE,CAACC,WAAc,CAAA;4BAC7C,GAAGA,QAAQ;4BACXC,UAAU;gCAAC,GAAGD,SAASC,QAAQ;gCAAEC,UAAUN,OAAOO,OAAO;4BAAA;wBAC3D,CAAA;gBACF,OAAO;oBACLzB,aAAakB,OAAOO,OAAO;gBAC7B;YACF;QACF;IACF;IAEA,qBACE,KAACC;QAAKC,WAAU;kBACd,cAAA,MAAC9D;YAAa8D,WAAU;;8BACtB,KAACC;oBAAOD,WAAU;8BAChB,cAAA,MAACE;wBAAIF,WAAU;;0CACb,KAACE;gCAAIF,WAAU;0CACb,cAAA,KAACtD;oCAAKgC,MAAK;oCAAUsB,WAAU;;;0CAEjC,KAAChD;gCAAKmD,MAAK;gCAAKC,IAAI;0CAAC;;;;;8BAMzB,KAACC;oBAAQL,WAAU;8BACjB,cAAA,KAACxB;wBACCwB,WAAU;wBACVM,UAAU;wBACVC,mBAAgB;wBAChB3B,UAAU,CAAC4B;4BACTA,MAAMC,cAAc;4BACpBD,MAAME,eAAe;4BACrB,KAAKlC,KAAKmC,YAAY;wBACxB;kCAEA,cAAA,MAAChE;;8CACC,MAACE;oCAAY+D,SAAQ;oCAAQZ,WAAU;;sDACrC,KAAClD;4CAAWoC,IAAG;4CAA6B0B,SAAQ;sDAAK;;sDAGzD,KAAC5D;4CAAKmD,MAAK;4CAAKH,WAAU;sDAAgC;;;;8CAK5D,MAACpD;oCAAUoD,WAAU;;wCAClB5B,0BACC,KAAC9B;4CAAQuE,MAAK;4CAAQC,MAAK;sDACxB1C;6CAED;sDAEJ,MAAC8B;4CAAIF,WAAU;;8DACb,KAACxB,KAAKuC,KAAK;oDACTrC,MAAK;oDACLsC,YAAY;wDACVC,QAAQ,CAAC,EAACrD,KAAK,EAAC,GACdzB,sBACEyB,OACA,kBACA3B,0BAA0BiF,KAAK,CAACxC,IAAI;wDAExCE,UAAU,CAAC,EAAChB,KAAK,EAAC,GAChBzB,sBACEyB,OACA,kBACA3B,0BAA0BiF,KAAK,CAACxC,IAAI;oDAE1C;8DAEC,CAACgB,sBACA,KAACnD;4DACC4E,OAAM;4DACNjC,IAAG;4DACHI,OAAO7C,WAAWiD;sEAElB,cAAA,KAAClD;gEACC4E,cAAa;gEACb1C,MAAK;gEACL2C,aAAY;gEACZP,MAAK;gEACLlD,OAAO8B,MAAM4B,KAAK,CAAC1D,KAAK;gEACxB2D,UAAU,CAACf;oEACT,MAAM9B,OAAO8B,MAAMgB,MAAM,CAAC5D,KAAK;oEAC/B8B,MAAM+B,YAAY,CAAC/C;oEACnB,IAAI,CAACJ,aAAa;wEAChBE,KAAKkD,aAAa,CAChB,QACAhD,OAAO3C,YAAY2C,MAAM;4EAACiD,UAAU;wEAAW,KAAK;oEAExD;gEACF;gEACAV,QAAQvB,MAAMkC,UAAU;;;;8DAKhC,KAACpD,KAAKuC,KAAK;oDACTrC,MAAK;oDACLsC,YAAY;wDACVC,QAAQhF,0BAA0BiF,KAAK,CAACvC,IAAI;wDAC5CC,UAAU3C,0BAA0BiF,KAAK,CAACvC,IAAI;oDAChD;8DAEC,CAACe,sBACA,KAACtD;4DACC8C,IAAG;4DACHiC,OAAM;4DACNzC,MAAK;4DACLd,OAAO8B,MAAM4B,KAAK,CAAC1D,KAAK;4DACxB2D,UAAU,CAAC3D;gEACTW,eAAe;gEACfmB,MAAM+B,YAAY,CAAC7D;4DACrB;4DACAqD,QAAQvB,MAAMkC,UAAU;4DACxBtC,OAAO7C,WAAWiD;4DAClBmC,2BACE,KAACC;gEAAK9B,WAAU;0EACb,GAAG+B,OAAOC,QAAQ,CAACC,MAAM,CAAC,GAAG,EAAEvC,MAAM4B,KAAK,CAAC1D,KAAK,IAAI,QAAQ;;4DAGjEyD,aAAY;4DACZa,cAAc5D;4DACd6D,SAASxE;4DACTyE,mBAAmB/E;;;;;sDAM3B,KAAChB;4CACC2D,WAAU;4CACVqC,WAAU;4CACVC,WAAWtE,gBAAgBuE,SAAS;4CACpCzB,MAAK;sDAEJ9C,gBAAgBuE,SAAS,GAAG,0BAA0B;;;;;;;;;;;AASzE"}
|