1
1
"use client" ;
2
- import { Fieldset , TextInput , Textarea , Drawer } from "@mantine/core" ;
3
- import { Button } from "./ui/button" ;
4
- import { zodResolver } from "mantine-form-zod-resolver" ;
5
- import { z } from "zod" ;
6
- import { useForm } from "@mantine/form" ;
2
+ import { useState } from "react" ;
3
+ import { useRouter } from "next/navigation" ;
7
4
import { db } from "@/lib/firebase" ;
8
5
import { collection , addDoc } from "firebase/firestore" ;
9
- import { useRouter } from "next/navigation" ;
10
- import { useState } from "react" ;
11
6
12
7
export function BookingForm ( ) {
13
8
const router = useRouter ( ) ;
14
- const [ opened , setOpened ] = useState ( false ) ;
15
- const schema = z . object ( {
16
- name : z . string ( ) . min ( 2 , { message : "Name is required" } ) ,
17
- email : z . string ( ) . email ( { message : "Invalid email" } ) ,
18
- message : z . string ( ) . min ( 2 , { message : "Message is required" } ) ,
9
+ const [ isOpen , setIsOpen ] = useState ( false ) ;
10
+ const [ formData , setFormData ] = useState ( {
11
+ name : "" ,
12
+ email : "" ,
13
+ message : "" ,
19
14
} ) ;
20
-
21
- const form = useForm ( {
22
- initialValues : {
23
- name : "" ,
24
- email : "" ,
25
- message : "" ,
26
- } ,
27
- validate : zodResolver ( schema ) ,
15
+ const [ errors , setErrors ] = useState ( {
16
+ name : "" ,
17
+ email : "" ,
18
+ message : "" ,
28
19
} ) ;
29
20
30
- const handleSubmit = async ( values : {
31
- name : string ;
32
- email : string ;
33
- message : string ;
34
- } ) => {
35
- try {
36
- if ( form . validate ( ) ) {
21
+ const handleChange = ( e : React . ChangeEvent < HTMLInputElement | HTMLTextAreaElement > ) => {
22
+ const { name, value } = e . target ;
23
+ setFormData ( prev => ( { ...prev , [ name ] : value } ) ) ;
24
+ setErrors ( prev => ( { ...prev , [ name ] : "" } ) ) ;
25
+ } ;
26
+
27
+ const validate = ( ) => {
28
+ let isValid = true ;
29
+ const newErrors = { name : "" , email : "" , message : "" } ;
30
+
31
+ if ( formData . name . length < 2 ) {
32
+ newErrors . name = "Name is required" ;
33
+ isValid = false ;
34
+ }
35
+ if ( ! / ^ \S + @ \S + $ / . test ( formData . email ) ) {
36
+ newErrors . email = "Invalid email" ;
37
+ isValid = false ;
38
+ }
39
+ if ( formData . message . length < 2 ) {
40
+ newErrors . message = "Message is required" ;
41
+ isValid = false ;
42
+ }
43
+
44
+ setErrors ( newErrors ) ;
45
+ return isValid ;
46
+ } ;
47
+
48
+ const handleSubmit = async ( e : React . FormEvent < HTMLFormElement > ) => {
49
+ e . preventDefault ( ) ;
50
+ if ( validate ( ) ) {
51
+ try {
37
52
const docRef = await addDoc ( collection ( db , "bookings" ) , {
38
- name : values . name ,
39
- email : values . email ,
40
- message : values . message ,
53
+ ...formData ,
41
54
createdAt : new Date ( ) ,
42
55
} ) ;
43
- alert ( "Submitted successfully " ) ;
56
+ alert ( "Submitted successfully" ) ;
44
57
console . log ( "Document written with ID: " , docRef . id ) ;
45
58
router . push ( "/chat" ) ;
46
- } else {
47
- alert ( "Wrong credential" ) ;
59
+ setIsOpen ( false ) ;
60
+ setFormData ( { name : "" , email : "" , message : "" } ) ;
61
+ } catch ( e ) {
62
+ console . error ( "Error adding document: " , e ) ;
63
+ alert ( "An error occurred while submitting the form" ) ;
48
64
}
49
-
50
- form . reset ( ) ;
51
- } catch ( e ) {
52
- console . error ( "Error adding document: " , e ) ;
53
65
}
54
66
} ;
55
67
56
68
return (
57
69
< >
58
- < Button
59
- onClick = { ( ) => setOpened ( true ) }
70
+ < button
71
+ onClick = { ( ) => setIsOpen ( true ) }
60
72
className = "bg-blue-400 rounded-full p-6 hover:bg-blue-300 text-black border-none outline-none mt-8 w-full"
61
73
>
62
74
Book by Loca
63
- </ Button >
64
- < Drawer
65
- opened = { opened }
66
- onClose = { ( ) => setOpened ( false ) }
67
- title = "Booking Form"
68
- padding = "xl"
69
- // size="25%"
70
- styles = { {
71
- content : {
72
- backgroundColor : '#000'
73
- } ,
74
- header : {
75
- backgroundColor : '#000'
76
- }
77
- } }
78
-
79
- transitionProps = { {
80
- transition : "rotate-left" ,
81
- duration : 150 ,
82
- timingFunction : "linear" ,
83
- } }
84
- className = " text-white"
85
- overlayProps = { { backgroundOpacity : 0.5 , blur : 4 } }
86
- >
87
- < div className = "" >
88
- < form onSubmit = { form . onSubmit ( handleSubmit ) } >
89
- < Fieldset
90
- legend = "Please fill in the form"
91
- styles = { {
92
- root : { backgroundColor : "black" , borderColor : "white" } ,
93
- legend : { color : "white" } ,
94
- } }
95
- >
96
- < TextInput
97
- withAsterisk
98
- label = "Your name"
99
- placeholder = "Your name"
100
- { ...form . getInputProps ( "name" ) }
101
- styles = { { label : { color : "white" } , input : { color : "white" , backgroundColor : "#333" } } }
102
- />
103
- < TextInput
104
- withAsterisk
105
- label = "Email"
106
- placeholder = "Email"
107
- mt = "md"
108
- { ...form . getInputProps ( "email" ) }
109
- styles = { { label : { color : "white" } , input : { color : "white" , backgroundColor : "#333" } } }
110
- />
111
- < Textarea
112
- withAsterisk
113
- label = "Description"
114
- description = "Describe the type of services you want"
115
- placeholder = "Describe your services here"
116
- autosize
117
- minRows = { 2 }
118
- maxRows = { 4 }
119
- { ...form . getInputProps ( "message" ) }
120
- styles = { {
121
- label : { color : "white" } ,
122
- description : { color : "white" } ,
123
- input : { color : "white" , backgroundColor : "#333" }
124
- } }
125
- />
126
- </ Fieldset >
127
- < Button
128
- type = "submit"
129
- className = "bg-blue-400 rounded-full p-8 hover:bg-blue-300 text-black border-none outline-none mt-8 w-full"
130
- >
131
- Submit
132
- </ Button >
133
- </ form >
134
-
75
+ </ button >
76
+ { isOpen && (
77
+ < div className = "fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center p-4" >
78
+ < div className = "bg-gray-800 rounded-lg p-6 w-full max-w-md" >
79
+ < div className = "flex justify-between items-center mb-4" >
80
+ < h2 className = "text-white text-xl font-bold" > Booking Form</ h2 >
81
+ < button onClick = { ( ) => setIsOpen ( false ) } className = "text-white" > ×</ button >
82
+ </ div >
83
+ < form onSubmit = { handleSubmit } className = "space-y-4" >
84
+ < div >
85
+ < label htmlFor = "name" className = "block text-white text-sm font-bold mb-2" > Your name</ label >
86
+ < input
87
+ type = "text"
88
+ id = "name"
89
+ name = "name"
90
+ value = { formData . name }
91
+ onChange = { handleChange }
92
+ className = "w-full px-3 py-2 text-white bg-gray-700 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400"
93
+ placeholder = "Your name"
94
+ />
95
+ { errors . name && < p className = "text-red-500 text-xs mt-1" > { errors . name } </ p > }
96
+ </ div >
97
+ < div >
98
+ < label htmlFor = "email" className = "block text-white text-sm font-bold mb-2" > Email</ label >
99
+ < input
100
+ type = "email"
101
+ id = "email"
102
+ name = "email"
103
+ value = { formData . email }
104
+ onChange = { handleChange }
105
+ className = "w-full px-3 py-2 text-white bg-gray-700 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400"
106
+ placeholder = "Email"
107
+ />
108
+ { errors . email && < p className = "text-red-500 text-xs mt-1" > { errors . email } </ p > }
109
+ </ div >
110
+ < div >
111
+ < label htmlFor = "message" className = "block text-white text-sm font-bold mb-2" > Description</ label >
112
+ < textarea
113
+ id = "message"
114
+ name = "message"
115
+ value = { formData . message }
116
+ onChange = { handleChange }
117
+ className = "w-full px-3 py-2 text-white bg-gray-700 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-400"
118
+ placeholder = "Describe your services here"
119
+ rows = { 4 }
120
+ />
121
+ { errors . message && < p className = "text-red-500 text-xs mt-1" > { errors . message } </ p > }
122
+ </ div >
123
+ < button
124
+ type = "submit"
125
+ className = "w-full bg-blue-400 text-black font-bold py-2 px-4 rounded-full hover:bg-blue-300 focus:outline-none focus:shadow-outline"
126
+ >
127
+ Submit
128
+ </ button >
129
+ </ form >
130
+ </ div >
135
131
</ div >
136
- </ Drawer >
132
+ ) }
137
133
</ >
138
134
) ;
139
- }
135
+ }
0 commit comments