22
33import { Button } from "@/components/ui/button" ;
44import { ApiError } from "@/lib/api" ;
5- import { acceptInvite , InviteDetails } from "@/models/invite" ;
5+ import { acceptInvite , inviteQueryOptions } from "@/models/invite" ;
66import Link from "next/link" ;
77import { useEffect , useState } from "react" ;
88import { useRouter } from "next/navigation" ;
9+ import { useQuery } from "@tanstack/react-query" ;
910
1011type Props = {
1112 code : string ;
12- invite : InviteDetails ;
1313 dict : any ;
14- mockMode ?: boolean ;
1514} ;
1615
17- export default function InviteClient ( { code, invite , dict, mockMode = false } : Props ) {
16+ export default function InviteClient ( { code, dict } : Props ) {
1817 const [ status , setStatus ] = useState < "idle" | "loading" | "success" | "error" > ( "idle" ) ;
1918 const [ message , setMessage ] = useState < string | null > ( null ) ;
2019 const router = useRouter ( ) ;
20+ const { data : invite } = useQuery ( inviteQueryOptions ( code ) ) ;
2121
2222 // After successful acceptance, redirect after a short delay.
2323 useEffect ( ( ) => {
@@ -32,43 +32,51 @@ export default function InviteClient({ code, invite, dict, mockMode = false }: P
3232 const handleAccept = async ( ) => {
3333 setStatus ( "loading" ) ;
3434 setMessage ( null ) ;
35- try {
36- if ( ! mockMode ) {
37- await acceptInvite ( code ) ;
38- }
39- setStatus ( "success" ) ;
40- setMessage ( dict . dashboard . invite . accepted ) ;
41- } catch ( err ) {
42- setStatus ( "error" ) ;
43- if ( err instanceof ApiError ) {
44- if ( err . status === 401 ) {
45- setMessage ( dict . dashboard . invite . login_required ?? "Please log in to accept this invite." ) ;
35+
36+ acceptInvite ( code )
37+ . then ( ( ) => {
38+ setStatus ( "success" ) ;
39+ setMessage ( dict . dashboard . invite . accepted ) ;
40+ } )
41+ . catch ( ( err ) => {
42+ setStatus ( "error" ) ;
43+ if ( err instanceof ApiError ) {
44+ if ( err . status === 401 ) {
45+ setMessage ( dict . dashboard . invite . login_required ?? "Please log in to accept this invite." ) ;
46+ } else {
47+ setMessage ( err . message ) ;
48+ }
4649 } else {
47- setMessage ( err . message ) ;
50+ setMessage ( "Something went wrong. Please try again." ) ;
4851 }
49- } else {
50- setMessage ( "Something went wrong. Please try again." ) ;
51- }
52- }
52+ } ) ;
5353 } ;
5454
55- const inviteInvalid = invite . expired || invite . used || status === "success" ;
55+ const inviteInvalid = ! invite || invite . expired || invite . used || status === "success" ;
5656
5757 return (
5858 < div className = "max-w-xl mx-auto p-6 flex flex-col gap-4" >
5959 < h1 className = "text-2xl font-bold" > { dict . dashboard . invite . title } </ h1 >
6060 < p className = "text-sm text-muted-foreground" >
61- { dict . dashboard . invite . invited_by . replace ( "{org}" , invite . organisation_name ) }
62- </ p >
63- < p className = "text-sm text-muted-foreground" >
64- { dict . dashboard . invite . sent_to } : < span className = "font-medium" > { invite . email } </ span >
61+ { invite
62+ ? dict . dashboard . invite . invited_by . replace ( "{org}" , invite . organisation_name )
63+ : dict ?. common ?. loading ?? "Loading..." }
6564 </ p >
66- { invite . expired && (
65+ { /* Show the email the invite was sent to */ }
66+ { invite && (
67+ < p className = "text-sm text-muted-foreground" >
68+ { dict . dashboard . invite . sent_to } : < span className = "font-medium" > { invite . email } </ span >
69+ </ p >
70+ ) }
71+ { /* Show the expired message if the invite has expired */ }
72+ { invite ?. expired && (
6773 < p className = "text-sm text-red-600" > { dict . dashboard . invite . expired } </ p >
6874 ) }
69- { invite . used && (
75+ { /* Show the used message if the invite has been used */ }
76+ { invite ?. used && (
7077 < p className = "text-sm text-red-600" > { dict . dashboard . invite . used } </ p >
7178 ) }
79+ { /* Show the message if there is an error */ }
7280 { message && (
7381 < p className = { `text-sm ${ status === "success" ? "text-green-600" : "text-red-600" } ` } >
7482 { message }
@@ -87,6 +95,7 @@ export default function InviteClient({ code, invite, dict, mockMode = false }: P
8795 >
8896 { status === "loading" ? "Loading..." : dict . dashboard . invite . accept_cta }
8997 </ Button >
98+ { /* Show the wrong account message if the account is not invited */ }
9099 < p className = "text-xs text-muted-foreground" >
91100 { dict . dashboard . invite . wrong_account }
92101 </ p >
0 commit comments