@@ -2,8 +2,9 @@ import { Button, Input } from "@opencircle/ui";
22import { createFileRoute } from "@tanstack/react-router" ;
33import { Zap } from "lucide-react" ;
44import { METADATA } from "../constants/metadata" ;
5-
5+ import { useAppSettings } from "../features/appSettings/hooks/useAppSettings" ;
66import { useLogin } from "../features/auth/hooks/useLogin" ;
7+ import { useRegister } from "../features/auth/hooks/useRegister" ;
78
89export const Route = createFileRoute ( "/" ) ( {
910 head : ( ) => ( {
@@ -39,7 +40,42 @@ export const Route = createFileRoute("/")({
3940} ) ;
4041
4142function RouteComponent ( ) {
43+ const { installationStatus, isInstallationLoading } = useAppSettings ( ) ;
4244 const { username, setUsername, password, setPassword, login } = useLogin ( ) ;
45+ const {
46+ name,
47+ setName,
48+ username : regUsername ,
49+ setUsername : setRegUsername ,
50+ email,
51+ setEmail,
52+ password : regPassword ,
53+ setPassword : setRegPassword ,
54+ register,
55+ validationErrors,
56+ } = useRegister ( ) ;
57+
58+ if ( isInstallationLoading ) {
59+ return (
60+ < main className = "m-auto max-w-sm" >
61+ < div className = "flex h-screen flex-col justify-center gap-10" >
62+ < section className = "space-y-8 text-center" >
63+ < section className = "ml-2 flex items-center justify-center gap-2" >
64+ < div className = "flex h-6 w-6 items-center justify-center rounded-lg bg-foreground text-background" >
65+ < Zap size = { 12 } fill = "currentColor" />
66+ </ div >
67+ < h2 className = "font-medium" > Opencircle</ h2 >
68+ </ section >
69+ < div className = "space-y-2" >
70+ < p className = "text-foreground/50" > Loading...</ p >
71+ </ div >
72+ </ section >
73+ </ div >
74+ </ main >
75+ ) ;
76+ }
77+
78+ const showRegisterForm = ! installationStatus ?. is_installed ;
4379
4480 return (
4581 < main className = "m-auto max-w-sm" >
@@ -52,29 +88,114 @@ function RouteComponent() {
5288 < h2 className = "font-medium" > Opencircle</ h2 >
5389 </ section >
5490 < div className = "space-y-2" >
55- < p className = "text-foreground/50" > Sign in to Admin account</ p >
91+ { showRegisterForm ? (
92+ < >
93+ < h1 className = "font-medium text-2xl" > Setup Admin Account</ h1 >
94+ < p className = "text-foreground/50" >
95+ Create your admin account to get started
96+ </ p >
97+ < p className = "font-medium text-amber-600 text-sm dark:text-amber-400" >
98+ ⚠️ This registration form appears only once - save your
99+ credentials!
100+ </ p >
101+ </ >
102+ ) : (
103+ < p className = "text-foreground/50" > Sign in to Admin account</ p >
104+ ) }
56105 </ div >
57106 </ section >
58107 < div className = "space-y-6 rounded-xl border border-border p-8 shadow-2xl" >
59108 < section className = "space-y-3" >
60- < section className = "space-y-2" >
61- < Input
62- placeholder = "Username"
63- value = { username }
64- onChange = { ( v ) => setUsername ( v . target . value ) }
65- />
66- </ section >
67- < section className = "space-y-2" >
68- < Input
69- placeholder = "Password"
70- type = "password"
71- value = { password }
72- onChange = { ( v ) => setPassword ( v . target . value ) }
73- />
74- </ section >
75- < Button radius = "xl" className = "mt-2 w-full" onClick = { ( ) => login ( ) } >
76- Login
77- </ Button >
109+ { showRegisterForm ? (
110+ < >
111+ < section className = "space-y-2" >
112+ < Input
113+ placeholder = "Full Name"
114+ value = { name }
115+ onChange = { ( v ) => setName ( v . target . value ) }
116+ />
117+ { validationErrors . name && (
118+ < p className = "text-red-500 text-xs" >
119+ { validationErrors . name }
120+ </ p >
121+ ) }
122+ </ section >
123+ < section className = "space-y-2" >
124+ < Input
125+ placeholder = "Username"
126+ value = { regUsername }
127+ onChange = { ( v ) =>
128+ setRegUsername (
129+ v . target . value . toLowerCase ( ) . replace ( / \s / g, "" ) ,
130+ )
131+ }
132+ />
133+ { validationErrors . username && (
134+ < p className = "text-red-500 text-xs" >
135+ { validationErrors . username }
136+ </ p >
137+ ) }
138+ </ section >
139+ < section className = "space-y-2" >
140+ < Input
141+ placeholder = "Email"
142+ type = "email"
143+ value = { email }
144+ onChange = { ( v ) => setEmail ( v . target . value ) }
145+ />
146+ { validationErrors . email && (
147+ < p className = "text-red-500 text-xs" >
148+ { validationErrors . email }
149+ </ p >
150+ ) }
151+ </ section >
152+ < section className = "space-y-2" >
153+ < Input
154+ placeholder = "Password"
155+ type = "password"
156+ value = { regPassword }
157+ onChange = { ( v ) => setRegPassword ( v . target . value ) }
158+ />
159+ { validationErrors . password && (
160+ < p className = "text-red-500 text-xs" >
161+ { validationErrors . password }
162+ </ p >
163+ ) }
164+ </ section >
165+ < Button
166+ radius = "xl"
167+ className = "mt-2 w-full"
168+ onClick = { ( ) => register ( ) }
169+ >
170+ Create Admin Account
171+ </ Button >
172+ </ >
173+ ) : (
174+ < >
175+ < section className = "space-y-2" >
176+ < Input
177+ placeholder = "Username"
178+ value = { username }
179+ onChange = { ( v ) => setUsername ( v . target . value ) }
180+ />
181+ </ section >
182+ < section className = "space-y-2" >
183+ < Input
184+ placeholder = "Password"
185+ type = "password"
186+ value = { password }
187+ onChange = { ( v ) => setPassword ( v . target . value ) }
188+ />
189+ </ section >
190+ < Button
191+ radius = "xl"
192+ className = "mt-2 w-full"
193+ onClick = { ( ) => login ( ) }
194+ >
195+ Login
196+ </ Button >
197+ </ >
198+ ) }
78199 </ section > { " " }
79200 </ div >
80201 </ div >
0 commit comments