@@ -13,6 +13,7 @@ const ArchitectsPage = () => {
1313 const [ loading , setLoading ] = useState ( true ) ;
1414 const [ search , setSearch ] = useState ( "" ) ;
1515 const [ showForm , setShowForm ] = useState ( false ) ;
16+ const [ uploading , setUploading ] = useState ( false ) ;
1617 const [ formData , setFormData ] = useState ( {
1718 name : "" ,
1819 specialization : "" ,
@@ -21,6 +22,7 @@ const ArchitectsPage = () => {
2122 } ) ;
2223 const [ message , setMessage ] = useState ( "" ) ;
2324
25+ // Fetch architects
2426 const fetchArchitects = async ( ) => {
2527 setLoading ( true ) ;
2628 const { data, error } = await supabase . from ( "architects" ) . select ( "*" ) ;
@@ -33,14 +35,60 @@ const ArchitectsPage = () => {
3335 fetchArchitects ( ) ;
3436 } , [ ] ) ;
3537
38+ // Handle input
3639 const handleChange = (
3740 e : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement >
3841 ) => {
3942 setFormData ( { ...formData , [ e . target . name ] : e . target . value } ) ;
4043 } ;
4144
45+ // ✅ Handle file upload
46+ const handleFileUpload = async ( e : React . ChangeEvent < HTMLInputElement > ) => {
47+ try {
48+ const file = e . target . files ?. [ 0 ] ;
49+ if ( ! file ) return ;
50+
51+ if ( ! user ) {
52+ setMessage ( "Please log in to upload an image." ) ;
53+ return ;
54+ }
55+
56+ setUploading ( true ) ;
57+ const fileExt = file . name . split ( "." ) . pop ( ) ;
58+ const fileName = `${ user . id } _${ Date . now ( ) } .${ fileExt } ` ;
59+
60+ const { data, error : uploadError } = await supabase . storage
61+ . from ( "Architects" )
62+ . upload ( fileName , file , {
63+ cacheControl : "3600" ,
64+ upsert : false ,
65+ } ) ;
66+
67+ if ( uploadError ) throw uploadError ;
68+
69+ const { data : publicUrlData } = supabase . storage
70+ . from ( "Architects" )
71+ . getPublicUrl ( fileName ) ;
72+
73+ if ( publicUrlData ?. publicUrl ) {
74+ setFormData ( ( prev ) => ( {
75+ ...prev ,
76+ image_url : publicUrlData . publicUrl ,
77+ } ) ) ;
78+ setMessage ( "Image uploaded successfully!" ) ;
79+ }
80+ } catch ( error : any ) {
81+ console . error ( error ) ;
82+ setMessage ( `Upload failed: ${ error . message } ` ) ;
83+ } finally {
84+ setUploading ( false ) ;
85+ }
86+ } ;
87+
88+ // Handle form submit
4289 const handleRegister = async ( e : React . FormEvent ) => {
4390 e . preventDefault ( ) ;
91+
4492 if ( ! user ) {
4593 setMessage ( "Please log in first." ) ;
4694 return ;
@@ -83,6 +131,14 @@ const ArchitectsPage = () => {
83131 }
84132 } ;
85133
134+ const handleRegisterClick = ( ) => {
135+ if ( ! user ) {
136+ navigate ( "/auth/login" ) ;
137+ } else {
138+ setShowForm ( true ) ;
139+ }
140+ } ;
141+
86142 const filteredArchitects = architects . filter (
87143 ( arch ) =>
88144 arch . name ?. toLowerCase ( ) . includes ( search . toLowerCase ( ) ) ||
@@ -93,22 +149,22 @@ const ArchitectsPage = () => {
93149 < div className = "bg-white min-h-screen font-sans" >
94150 < Navbar />
95151
96- { /* Hero Section (Professional Look) */ }
152+ { /* Hero Section */ }
97153 < section className = "max-w-7xl mx-auto px-6 py-24 grid grid-cols-1 md:grid-cols-2 gap-10 items-center" >
98- { /* Left content */ }
99154 < div >
100155 < h1 className = "text-4xl md:text-5xl font-extrabold leading-tight mb-4" >
101- Hire < span className = "text-blue-600" > Skilled </ span > Architect < br /> in { " " }
102- < span className = "text-blue-600" > Minutes </ span >
156+ Hire < span className = "text-blue-600" > Top Architects </ span > < br /> for
157+ Your Dream Project
103158 </ h1 >
104159 < p className = "text-gray-600 text-lg mb-6" >
105- Connect with expert architects to design your dream spaces — from modern homes to smart offices, all with precision and creativity
160+ Design your ideal space with the best architects — experts in
161+ innovative planning, interior design, and modern construction
162+ solutions.
106163 </ p >
107-
108164 < div className = "relative w-full max-w-md mb-6" >
109165 < input
110166 type = "text"
111- placeholder = "Search services "
167+ placeholder = "Search architects... "
112168 className = "w-full py-3 px-5 rounded-lg border border-gray-300 focus:ring-2 focus:ring-blue-500 outline-none"
113169 value = { search }
114170 onChange = { ( e ) => setSearch ( e . target . value ) }
@@ -117,38 +173,28 @@ const ArchitectsPage = () => {
117173 Search →
118174 </ button >
119175 </ div >
120-
121- < div className = "flex flex-wrap gap-3 text-sm text-gray-700 mb-4" >
122- < span > Popular Services:</ span >
123- < span className = "px-3 py-1 bg-gray-100 rounded-full" > Aashiana Architect</ span >
124- < span className = "px-3 py-1 bg-gray-100 rounded-full" > Aviral Design Studio</ span >
125- </ div >
126-
127- { user && (
128- < button
129- onClick = { ( ) => setShowForm ( ! showForm ) }
130- className = "bg-blue-600 text-white px-6 py-2 rounded-lg font-semibold hover:bg-blue-700 transition"
131- >
132- { showForm ? "Cancel" : "Register as Architect" }
133- </ button >
134- ) }
176+ < button
177+ onClick = { handleRegisterClick }
178+ className = "bg-blue-600 text-white px-6 py-2 rounded-lg font-semibold hover:bg-blue-700 transition"
179+ >
180+ Register as Architect
181+ </ button >
135182 </ div >
136183
137- { /* Right Video */ }
184+ { /* Right Side Video */ }
138185 < div className = "relative" >
139186 < div className = "rounded-2xl overflow-hidden shadow-xl border border-gray-200" >
140187 < iframe
141188 width = "100%"
142189 height = "320"
143190 src = "https://www.youtube.com/embed/5aJjXXQPqpM"
144- title = "Customer Review "
191+ title = "Architect Promo Video "
145192 allow = "accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
146193 allowFullScreen
147194 className = "w-full rounded-2xl"
148195 > </ iframe >
149196 </ div >
150197
151- { /* Floating Popups */ }
152198 < div className = "absolute top-4 right-4 bg-white shadow-lg rounded-xl px-4 py-2 flex items-center gap-2" >
153199 < CheckCircle2 className = "text-green-500 w-5 h-5" />
154200 < div className = "text-sm" >
@@ -160,15 +206,23 @@ const ArchitectsPage = () => {
160206 < div className = "absolute bottom-4 left-4 bg-white shadow-lg rounded-xl px-4 py-2 flex items-center gap-2" >
161207 < Smile className = "text-blue-500 w-5 h-5" />
162208 < div className = "text-sm" >
163- < p className = "font-semibold text-gray-800" > Happy Customers </ p >
209+ < p className = "font-semibold text-gray-800" > Happy Clients </ p >
164210 </ div >
165211 </ div >
166212 </ div >
167213 </ section >
168214
169- { /* Architect Registration Form */ }
170- { showForm && (
171- < section className = "max-w-4xl mx-auto mt-10 bg-gray-50 p-6 rounded-2xl shadow-md border border-gray-200" >
215+ { /* ✅ Registration Form with Close Button */ }
216+ { showForm && user && (
217+ < section className = "max-w-4xl mx-auto mt-10 bg-gray-50 p-6 rounded-2xl shadow-md border border-gray-200 relative" >
218+ { /* ❌ Close Button */ }
219+ < button
220+ onClick = { ( ) => setShowForm ( false ) }
221+ className = "absolute top-4 right-4 text-gray-600 hover:text-gray-800 text-3xl font-bold"
222+ >
223+ ×
224+ </ button >
225+
172226 < h2 className = "text-2xl font-bold mb-4 text-center text-blue-700" >
173227 Register as an Architect
174228 </ h2 >
@@ -201,27 +255,45 @@ const ArchitectsPage = () => {
201255 rows = { 4 }
202256 required
203257 />
204- < input
205- type = "text"
206- name = "image_url"
207- placeholder = "Image URL (optional)"
208- value = { formData . image_url }
209- onChange = { handleChange }
210- className = "p-3 rounded-lg border border-gray-300 focus:ring-2 focus:ring-blue-600 focus:outline-none"
211- />
258+
259+ { /* Image Upload */ }
260+ < div className = "flex flex-col gap-2" >
261+ < label className = "text-gray-700 font-medium" >
262+ Upload Profile Image
263+ </ label >
264+ < input
265+ type = "file"
266+ accept = "image/*"
267+ onChange = { handleFileUpload }
268+ className = "p-2 border border-gray-300 rounded-lg"
269+ />
270+ { uploading && (
271+ < p className = "text-blue-500 text-sm" > Uploading...</ p >
272+ ) }
273+ { formData . image_url && (
274+ < img
275+ src = { formData . image_url }
276+ alt = "Preview"
277+ className = "w-40 h-40 rounded-lg object-cover mt-2 border border-gray-200"
278+ />
279+ ) }
280+ </ div >
212281
213282 < button
214283 type = "submit"
215284 className = "bg-blue-600 text-white px-6 py-3 rounded-lg font-semibold hover:bg-blue-700 transition"
285+ disabled = { uploading }
216286 >
217- Register
287+ { uploading ? "Please wait..." : " Register" }
218288 </ button >
219289 </ form >
220290
221291 { message && (
222292 < p
223293 className = { `mt-3 text-center font-medium ${
224- message . includes ( "Successfully" ) ? "text-green-600" : "text-red-600"
294+ message . includes ( "Successfully" )
295+ ? "text-green-600"
296+ : "text-red-600"
225297 } `}
226298 >
227299 { message }
0 commit comments