Skip to content

Commit 7832d11

Browse files
mikewuurazor-xseambot
authored
feat(AccessCodeForm): Show confirmation message after creating or updating an access code (#517)
Co-authored-by: Evan Sosenko <[email protected]> Co-authored-by: Seam Bot <[email protected]>
1 parent c3a43c4 commit 7832d11

File tree

7 files changed

+151
-80
lines changed

7 files changed

+151
-80
lines changed

src/lib/seam/components/AccessCodeTable/AccessCodeTable.tsx

+96-58
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import { NestedEditAccessCodeForm } from 'lib/seam/components/EditAccessCodeForm
2424
import { IconButton } from 'lib/ui/IconButton.js'
2525
import { ContentHeader } from 'lib/ui/layout/ContentHeader.js'
2626
import { LoadingToast } from 'lib/ui/LoadingToast/LoadingToast.js'
27+
import { Snackbar } from 'lib/ui/Snackbar/Snackbar.js'
2728
import { EmptyPlaceholder } from 'lib/ui/Table/EmptyPlaceholder.js'
2829
import { TableBody } from 'lib/ui/Table/TableBody.js'
2930
import { TableHeader } from 'lib/ui/Table/TableHeader.js'
@@ -130,6 +131,13 @@ export function AccessCodeTable({
130131
[setSelectedEditAccessCodeId]
131132
)
132133

134+
const [accessCodeResult, setAccessCodeResult] = useState<
135+
'created' | 'updated' | null
136+
>(null)
137+
138+
const accessCodeResultMessage =
139+
accessCodeResult === 'created' ? t.accesCodeCreated : t.accesCodeUpdated
140+
133141
if (selectedEditAccessCodeId != null) {
134142
return (
135143
<NestedEditAccessCodeForm
@@ -141,27 +149,41 @@ export function AccessCodeTable({
141149
onBack={() => {
142150
setSelectedEditAccessCodeId(null)
143151
}}
152+
onSuccess={() => {
153+
setAccessCodeResult('updated')
154+
}}
144155
className={className}
145156
/>
146157
)
147158
}
148159

149160
if (selectedViewAccessCodeId != null) {
150161
return (
151-
<NestedAccessCodeDetails
152-
accessCodeId={selectedViewAccessCodeId}
153-
onEdit={() => {
154-
setSelectedEditAccessCodeId(selectedViewAccessCodeId)
155-
}}
156-
disableLockUnlock={disableLockUnlock}
157-
disableCreateAccessCode={disableCreateAccessCode}
158-
disableEditAccessCode={disableEditAccessCode}
159-
disableDeleteAccessCode={disableDeleteAccessCode}
160-
onBack={() => {
161-
setSelectedViewAccessCodeId(null)
162-
}}
163-
className={className}
164-
/>
162+
<>
163+
<Snackbar
164+
variant='success'
165+
message={accessCodeResultMessage}
166+
visible={accessCodeResult != null}
167+
autoDismiss
168+
onClose={() => {
169+
setAccessCodeResult(null)
170+
}}
171+
/>
172+
<NestedAccessCodeDetails
173+
accessCodeId={selectedViewAccessCodeId}
174+
onEdit={() => {
175+
setSelectedEditAccessCodeId(selectedViewAccessCodeId)
176+
}}
177+
disableLockUnlock={disableLockUnlock}
178+
disableCreateAccessCode={disableCreateAccessCode}
179+
disableEditAccessCode={disableEditAccessCode}
180+
disableDeleteAccessCode={disableDeleteAccessCode}
181+
onBack={() => {
182+
setSelectedViewAccessCodeId(null)
183+
}}
184+
className={className}
185+
/>
186+
</>
165187
)
166188
}
167189

@@ -175,6 +197,9 @@ export function AccessCodeTable({
175197
disableDeleteAccessCode={disableDeleteAccessCode}
176198
onBack={toggleAddAccessCodeForm}
177199
className={className}
200+
onSuccess={() => {
201+
setAccessCodeResult('created')
202+
}}
178203
/>
179204
)
180205
}
@@ -184,52 +209,63 @@ export function AccessCodeTable({
184209
}
185210

186211
return (
187-
<div className={classNames('seam-table', className)}>
188-
<ContentHeader onBack={onBack} />
189-
<TableHeader>
190-
<div className='seam-left'>
191-
{title != null ? (
192-
<TableTitle>
193-
{heading ?? title ?? t.accessCodes}{' '}
194-
<Caption>({filteredAccessCodes.length})</Caption>
195-
</TableTitle>
196-
) : (
197-
<div className='seam-fragment' />
198-
)}
199-
{!disableCreateAccessCode && (
200-
<IconButton
201-
onClick={toggleAddAccessCodeForm}
202-
className='seam-add-button'
203-
>
204-
<AddIcon />
205-
</IconButton>
212+
<>
213+
<Snackbar
214+
variant='success'
215+
message={accessCodeResultMessage}
216+
visible={accessCodeResult != null}
217+
autoDismiss
218+
onClose={() => {
219+
setAccessCodeResult(null)
220+
}}
221+
/>
222+
<div className={classNames('seam-table', className)}>
223+
<ContentHeader onBack={onBack} />
224+
<TableHeader>
225+
<div className='seam-left'>
226+
{title != null ? (
227+
<TableTitle>
228+
{heading ?? title ?? t.accessCodes}{' '}
229+
<Caption>({filteredAccessCodes.length})</Caption>
230+
</TableTitle>
231+
) : (
232+
<div className='seam-fragment' />
233+
)}
234+
{!disableCreateAccessCode && (
235+
<IconButton
236+
onClick={toggleAddAccessCodeForm}
237+
className='seam-add-button'
238+
>
239+
<AddIcon />
240+
</IconButton>
241+
)}
242+
</div>
243+
<div className='seam-table-header-loading-wrap'>
244+
<LoadingToast
245+
isLoading={isInitialLoading}
246+
label={t.loading}
247+
top={-20}
248+
/>
249+
</div>
250+
{!disableSearch && (
251+
<SearchTextField
252+
value={searchInputValue}
253+
onChange={setSearchInputValue}
254+
disabled={(accessCodes?.length ?? 0) === 0}
255+
/>
206256
)}
207-
</div>
208-
<div className='seam-table-header-loading-wrap'>
209-
<LoadingToast
210-
isLoading={isInitialLoading}
211-
label={t.loading}
212-
top={-20}
257+
</TableHeader>
258+
<TableBody>
259+
<Content
260+
accessCodes={filteredAccessCodes}
261+
onAccessCodeClick={handleAccessCodeClick}
262+
onAccessCodeEdit={handleAccessCodeEdit}
263+
disableEditAccessCode={disableEditAccessCode}
264+
disableDeleteAccessCode={disableDeleteAccessCode}
213265
/>
214-
</div>
215-
{!disableSearch && (
216-
<SearchTextField
217-
value={searchInputValue}
218-
onChange={setSearchInputValue}
219-
disabled={(accessCodes?.length ?? 0) === 0}
220-
/>
221-
)}
222-
</TableHeader>
223-
<TableBody>
224-
<Content
225-
accessCodes={filteredAccessCodes}
226-
onAccessCodeClick={handleAccessCodeClick}
227-
onAccessCodeEdit={handleAccessCodeEdit}
228-
disableEditAccessCode={disableEditAccessCode}
229-
disableDeleteAccessCode={disableDeleteAccessCode}
230-
/>
231-
</TableBody>
232-
</div>
266+
</TableBody>
267+
</div>
268+
</>
233269
)
234270
}
235271

@@ -296,4 +332,6 @@ const t = {
296332
accessCodes: 'Access Codes',
297333
noAccessCodesMessage: 'Sorry, no access codes were found',
298334
loading: 'Loading access codes',
335+
accesCodeUpdated: 'Access code updated',
336+
accesCodeCreated: 'Access code created',
299337
}

src/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.element.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const name = 'seam-create-access-code-form'
55

66
export const props: ElementProps<CreateAccessCodeFormProps> = {
77
deviceId: 'string',
8+
onSuccess: 'object',
89
}
910

1011
export { CreateAccessCodeForm as Component } from './CreateAccessCodeForm.js'

src/lib/seam/components/CreateAccessCodeForm/CreateAccessCodeForm.tsx

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { useState } from 'react'
2-
import type { SeamError } from 'seamapi'
2+
import type { AccessCode, SeamError } from 'seamapi'
33

44
import { useComponentTelemetry } from 'lib/telemetry/index.js'
55

@@ -18,6 +18,7 @@ import {
1818

1919
export interface CreateAccessCodeFormProps extends CommonProps {
2020
deviceId: string
21+
onSuccess?: (accessCodeId: string) => void
2122
}
2223

2324
export const NestedCreateAccessCodeForm =
@@ -27,6 +28,7 @@ export function CreateAccessCodeForm({
2728
className,
2829
onBack,
2930
deviceId,
31+
onSuccess,
3032
}: CreateAccessCodeFormProps): JSX.Element | null {
3133
useComponentTelemetry('CreateAccessCodeForm')
3234

@@ -38,18 +40,30 @@ export function CreateAccessCodeForm({
3840
return null
3941
}
4042

41-
return <Content device={device} className={className} onBack={onBack} />
43+
return (
44+
<Content
45+
device={device}
46+
className={className}
47+
onBack={onBack}
48+
onSuccess={onSuccess}
49+
/>
50+
)
4251
}
4352

4453
function Content({
4554
device,
4655
className,
4756
onBack,
57+
onSuccess,
4858
}: Omit<CreateAccessCodeFormProps, 'deviceId'> & {
4959
device: NonNullable<UseDeviceData>
5060
}): JSX.Element {
5161
const { submit, isSubmitting, responseErrors } = useSubmitCreateAccessCode({
52-
onSuccess: () => {
62+
onSuccess: (accessCode: AccessCode) => {
63+
if (onSuccess != null) {
64+
onSuccess(accessCode.access_code_id)
65+
}
66+
5367
if (onBack != null) {
5468
onBack()
5569
}
@@ -68,7 +82,9 @@ function Content({
6882
)
6983
}
7084

71-
function useSubmitCreateAccessCode(params: { onSuccess: () => void }): {
85+
function useSubmitCreateAccessCode(params: {
86+
onSuccess: (accessCode: AccessCode) => void
87+
}): {
7288
submit: (data: AccessCodeFormSubmitData) => void
7389
isSubmitting: boolean
7490
responseErrors: ResponseErrors | null

src/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.element.ts

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export const name = 'seam-edit-access-code-form'
55

66
export const props: ElementProps<EditAccessCodeFormProps> = {
77
accessCodeId: 'string',
8+
onSuccess: 'object',
89
}
910

1011
export { EditAccessCodeForm as Component } from './EditAccessCodeForm.js'

src/lib/seam/components/EditAccessCodeForm/EditAccessCodeForm.tsx

+18-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919

2020
export interface EditAccessCodeFormProps extends CommonProps {
2121
accessCodeId: string
22+
onSuccess?: (accessCodeId: string) => void
2223
}
2324

2425
export const NestedEditAccessCodeForm =
@@ -28,6 +29,7 @@ export function EditAccessCodeForm({
2829
accessCodeId,
2930
onBack,
3031
className,
32+
onSuccess,
3133
}: EditAccessCodeFormProps): JSX.Element | null {
3234
useComponentTelemetry('EditAccessCodeForm')
3335

@@ -40,14 +42,20 @@ export function EditAccessCodeForm({
4042
}
4143

4244
return (
43-
<Content accessCode={accessCode} className={className} onBack={onBack} />
45+
<Content
46+
accessCode={accessCode}
47+
className={className}
48+
onBack={onBack}
49+
onSuccess={onSuccess}
50+
/>
4451
)
4552
}
4653

4754
function Content({
4855
className,
4956
onBack,
5057
accessCode,
58+
onSuccess,
5159
}: Omit<EditAccessCodeFormProps, 'accessCodeId'> & {
5260
accessCode: NonNullable<UseAccessCodeData>
5361
}): JSX.Element | null {
@@ -57,7 +65,15 @@ function Content({
5765

5866
const { submit, isSubmitting, responseErrors } = useSubmitEditAccessCode(
5967
accessCode,
60-
onBack
68+
() => {
69+
if (onSuccess != null) {
70+
onSuccess(accessCode.access_code_id)
71+
}
72+
73+
if (onBack != null) {
74+
onBack()
75+
}
76+
}
6177
)
6278

6379
if (device == null) {

0 commit comments

Comments
 (0)