@@ -20,6 +20,21 @@ import { useUser } from "./firebase/hooks";
2020import { auth } from "./firebase/firebase" ;
2121import { multiFactor , sendEmailVerification , signOut } from "firebase/auth" ;
2222
23+ import {
24+ Item ,
25+ ItemActions ,
26+ ItemContent ,
27+ ItemDescription ,
28+ ItemFooter ,
29+ ItemGroup ,
30+ ItemMedia ,
31+ ItemSeparator ,
32+ ItemTitle ,
33+ } from "@/components/ui/item" ;
34+ import { Button } from "./components/ui/button" ;
35+ import { ArrowRightIcon , LockIcon , UserIcon } from "lucide-react" ;
36+ import React from "react" ;
37+
2338function App ( ) {
2439 const user = useUser ( ) ;
2540
@@ -36,83 +51,117 @@ function UnauthenticatedApp() {
3651 < div className = "text-center space-y-4" >
3752 < img src = "/firebase-logo-inverted.png" alt = "Firebase UI" className = "hidden dark:block h-36 mx-auto" />
3853 < img src = "/firebase-logo.png" alt = "Firebase UI" className = "block dark:hidden h-36 mx-auto" />
39- < p className = "text-sm text-gray-700 dark:text-gray-300 " >
54+ < p className = "text-sm text-muted-foreground " >
4055 Welcome to Firebase UI, choose an example screen below to get started!
4156 </ p >
4257 </ div >
43- < div className = "border border-neutral-800 rounded divide-y divide-neutral-800 overflow-hidden " >
58+ < ItemGroup className = "border rounded-md " >
4459 { routes . map ( ( route ) => (
45- < Link
46- key = { route . path }
47- to = { route . path }
48- className = "flex items-center justify-between hover:bg-neutral-100 dark:bg-neutral-900 dark:hover:bg-neutral-800 p-4"
49- >
50- < div className = "space-y-1" >
51- < h2 className = "font-medium text-sm" > { route . name } </ h2 >
52- < p className = "text-xs text-gray-400 dark:text-gray-300" > { route . description } </ p >
53- </ div >
54- < div >
55- < span className = "text-xl" > →</ span >
56- </ div >
57- </ Link >
60+ < React . Fragment key = { route . path } >
61+ < Item >
62+ < ItemContent >
63+ < ItemTitle > { route . name } </ ItemTitle >
64+ < ItemDescription className = "text-xs" > { route . description } </ ItemDescription >
65+ </ ItemContent >
66+ < ItemActions >
67+ < Link to = { route . path } >
68+ < Button size = "icon" variant = "outline" >
69+ < ArrowRightIcon />
70+ </ Button >
71+ </ Link >
72+ </ ItemActions >
73+ </ Item >
74+ < ItemSeparator />
75+ </ React . Fragment >
5876 ) ) }
59- </ div >
77+ </ ItemGroup >
6078 </ div >
6179 ) ;
6280}
6381
6482function AuthenticatedApp ( ) {
6583 const user = useUser ( ) ! ;
84+ console . log ( user ) ;
6685 const mfa = multiFactor ( user ) ;
6786 const navigate = useNavigate ( ) ;
6887
6988 return (
70- < div className = "max-w-sm mx-auto pt-36 space-y-6 pb-36" >
71- < div className = "border border-neutral-800 rounded p-4 space-y-4" >
72- < h1 className = "text-md font-medium" > Welcome, { user . displayName || user . email || user . phoneNumber } </ h1 >
73- { user . emailVerified ? (
74- < div className = "text-green-500" > Email verified</ div >
75- ) : (
76- < button
77- className = "bg-red-500 text-white px-3 py-1.5 rounded text-sm"
78- onClick = { async ( ) => {
79- try {
80- await sendEmailVerification ( user ) ;
81- alert ( "Email verification sent, please check your email" ) ;
82- } catch ( error ) {
83- console . error ( error ) ;
84- alert ( "Error sending email verification, check console" ) ;
85- }
86- } }
87- >
88- Verify Email →
89- </ button >
90- ) }
91- < hr className = "opacity-20" />
92- < h2 className = "text-sm font-medium" > Multi-factor Authentication</ h2 >
93- { mfa . enrolledFactors . map ( ( factor ) => {
94- return (
95- < div key = { factor . factorId } >
96- { factor . factorId } - { factor . displayName }
97- </ div >
98- ) ;
99- } ) }
100- < button
101- className = "bg-blue-500 text-white px-3 py-1.5 rounded text-sm"
102- onClick = { ( ) => {
103- navigate ( "/screens/mfa-enrollment-screen" ) ;
104- } }
105- >
106- Add MFA Factor →
107- </ button >
108- < hr className = "opacity-20" />
109- < button
110- className = "bg-blue-500 text-white px-3 py-1.5 rounded text-sm"
111- onClick = { async ( ) => await signOut ( auth ) }
112- >
113- Sign Out →
114- </ button >
115- </ div >
89+ < div className = "max-w-lg mx-auto pt-36 space-y-6 pb-36" >
90+ < ItemGroup className = "border rounded-md" >
91+ < Item >
92+ < ItemMedia variant = "icon" >
93+ < UserIcon />
94+ </ ItemMedia >
95+ < ItemContent >
96+ < ItemTitle > Welcome, { user . displayName || user . email || user . phoneNumber } </ ItemTitle >
97+ < ItemDescription > New login detected from unknown device.</ ItemDescription >
98+ </ ItemContent >
99+ < ItemActions >
100+ < Button size = "sm" variant = "outline" onClick = { async ( ) => await signOut ( auth ) } >
101+ Sign Out
102+ </ Button >
103+ </ ItemActions >
104+ { user . email ? (
105+ < ItemFooter className = "pl-12" >
106+ { user . emailVerified ? (
107+ < Item >
108+ < ItemDescription > Your email is verified.</ ItemDescription >
109+ </ Item >
110+ ) : (
111+ < >
112+ < ItemDescription > Your email is not verified.</ ItemDescription >
113+ < ItemActions >
114+ < Button
115+ variant = "secondary"
116+ size = "sm"
117+ onClick = { async ( ) => {
118+ await sendEmailVerification ( user ) ;
119+ alert ( "Email verification sent, please check your email" ) ;
120+ } }
121+ >
122+ Verify Email →
123+ </ Button >
124+ </ ItemActions >
125+ </ >
126+ ) }
127+ </ ItemFooter >
128+ ) : null }
129+ </ Item >
130+ < ItemSeparator />
131+ < Item >
132+ < ItemMedia variant = "icon" >
133+ < LockIcon />
134+ </ ItemMedia >
135+ < ItemContent >
136+ < ItemTitle > Multi-factor Authentication</ ItemTitle >
137+ < ItemDescription >
138+ Any multi-factor authentication factors you have enrolled will be listed here.
139+ </ ItemDescription >
140+ </ ItemContent >
141+ < ItemActions >
142+ < Button
143+ size = "sm"
144+ variant = "outline"
145+ onClick = { ( ) => {
146+ navigate ( "/screens/mfa-enrollment-screen" ) ;
147+ } }
148+ >
149+ Add Factor
150+ </ Button >
151+ </ ItemActions >
152+ { mfa . enrolledFactors . length > 0 && (
153+ < ItemFooter className = "pl-12" >
154+ { mfa . enrolledFactors . map ( ( factor ) => {
155+ return (
156+ < div key = { factor . factorId } className = "text-sm text-muted-foreground" >
157+ { factor . factorId } - { factor . displayName }
158+ </ div >
159+ ) ;
160+ } ) }
161+ </ ItemFooter >
162+ ) }
163+ </ Item >
164+ </ ItemGroup >
116165 </ div >
117166 ) ;
118167}
0 commit comments