11// components/rooms/invite-create-form.tsx
22"use client" ;
33
4- import { useState } from "react" ;
4+ import { useState , useCallback } from "react" ;
55import { Button } from "@/components/ui/button" ;
66import { Card } from "@/components/ui/card" ;
77import { Input } from "@/components/ui/input" ;
88import { Label } from "@/components/ui/label" ;
9+ import { Spinner } from "@/components/ui/spinner" ;
10+ import { toast } from "sonner" ;
911
1012export default function InviteCreateForm ( {
1113 onCreate,
@@ -18,35 +20,49 @@ export default function InviteCreateForm({
1820 const [ expiresInHours , setExpiresInHours ] = useState ( "" ) ;
1921 const [ maxUses , setMaxUses ] = useState ( "" ) ;
2022 const [ submitting , setSubmitting ] = useState ( false ) ;
23+ const [ error , setError ] = useState < string | null > ( null ) ;
2124
22- async function onSubmit ( event : React . FormEvent ) {
23- event . preventDefault ( ) ;
24- setSubmitting ( true ) ;
25+ const onSubmit = useCallback (
26+ async ( event : React . FormEvent ) => {
27+ event . preventDefault ( ) ;
28+ setError ( null ) ;
29+ setSubmitting ( true ) ;
2530
26- try {
27- await onCreate ( {
28- expires_in_hours : expiresInHours ? Number ( expiresInHours ) : undefined ,
29- max_uses : maxUses ? Number ( maxUses ) : undefined ,
30- } ) ;
31+ try {
32+ await onCreate ( {
33+ expires_in_hours : expiresInHours ? Number ( expiresInHours ) : undefined ,
34+ max_uses : maxUses ? Number ( maxUses ) : undefined ,
35+ } ) ;
3136
32- setExpiresInHours ( "" ) ;
33- setMaxUses ( "" ) ;
34- } catch ( error ) {
35- window . alert (
36- error instanceof Error ? error . message : "Invite creation failed" ,
37- ) ;
38- } finally {
39- setSubmitting ( false ) ;
40- }
41- }
37+ setExpiresInHours ( "" ) ;
38+ setMaxUses ( "" ) ;
39+ toast . success ( "Invite token created successfully!" ) ;
40+ } catch ( err ) {
41+ const message =
42+ err instanceof Error ? err . message : "Failed to create invite token" ;
43+ setError ( message ) ;
44+ toast . error ( "Failed to create invite token" , { description : message } ) ;
45+ } finally {
46+ setSubmitting ( false ) ;
47+ }
48+ } ,
49+ [ onCreate , expiresInHours , maxUses ] ,
50+ ) ;
4251
4352 return (
4453 < Card >
4554 < h3 className = "text-base font-semibold text-white" > Create invite</ h3 >
4655 < p className = "mt-0.5 text-sm text-[rgb(158,183,211)]" >
47- Both fields are optional. Leave blank for an unlimited, non-expiring token.
56+ Both fields are optional. Leave blank for an unlimited, non-expiring
57+ token.
4858 </ p >
4959
60+ { error && (
61+ < div className = "mt-4 rounded-lg border border-red-500/30 bg-red-500/5 p-3" >
62+ < p className = "text-sm text-[rgb(255,160,170)]" > { error } </ p >
63+ </ div >
64+ ) }
65+
5066 < form className = "mt-5 space-y-4" onSubmit = { onSubmit } >
5167 < div className = "grid gap-4 sm:grid-cols-2" >
5268 < div className = "space-y-1.5" >
@@ -86,10 +102,17 @@ export default function InviteCreateForm({
86102
87103 < div className = "pt-1" >
88104 < Button type = "submit" disabled = { submitting } variant = "secondary" >
89- { submitting ? "Creating…" : "Create invite token" }
105+ { submitting ? (
106+ < >
107+ < Spinner size = "sm" className = "mr-2" />
108+ Creating…
109+ </ >
110+ ) : (
111+ "Create invite token"
112+ ) }
90113 </ Button >
91114 </ div >
92115 </ form >
93116 </ Card >
94117 ) ;
95- }
118+ }
0 commit comments