|
1 | | -import React from "react"; |
| 1 | +import React, { useRef, useState } from "react"; |
2 | 2 | import Layout from "@theme/Layout"; |
| 3 | +import useDocusaurusContext from "@docusaurus/useDocusaurusContext"; |
| 4 | +import emailjs from "@emailjs/browser"; |
3 | 5 | import { Mail, MapPin, Clock } from "lucide-react"; |
4 | 6 | import "./index.css"; |
5 | 7 |
|
| 8 | +type FormStatus = "idle" | "sending" | "success" | "error"; |
| 9 | + |
6 | 10 | const ContactUs: React.FC = () => { |
| 11 | + const { siteConfig } = useDocusaurusContext(); |
| 12 | + const formRef = useRef<HTMLFormElement>(null); |
| 13 | + const [status, setStatus] = useState<FormStatus>("idle"); |
| 14 | + const [errorMessage, setErrorMessage] = useState(""); |
| 15 | + |
| 16 | + const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => { |
| 17 | + e.preventDefault(); |
| 18 | + if (!formRef.current) return; |
| 19 | + |
| 20 | + const publicKey = siteConfig.customFields?.EMAILJS_PUBLIC_KEY as string; |
| 21 | + const serviceId = siteConfig.customFields?.EMAILJS_SERVICE_ID as string; |
| 22 | + const templateId = siteConfig.customFields?.EMAILJS_TEMPLATE_ID as string; |
| 23 | + |
| 24 | + if (!publicKey || !serviceId || !templateId) { |
| 25 | + setErrorMessage( |
| 26 | + "Email service is not configured. Please contact us directly at sanjay@recodehive.com.", |
| 27 | + ); |
| 28 | + setStatus("error"); |
| 29 | + return; |
| 30 | + } |
| 31 | + |
| 32 | + setStatus("sending"); |
| 33 | + setErrorMessage(""); |
| 34 | + |
| 35 | + try { |
| 36 | + await emailjs.sendForm(serviceId, templateId, formRef.current, { |
| 37 | + publicKey, |
| 38 | + }); |
| 39 | + setStatus("success"); |
| 40 | + formRef.current.reset(); |
| 41 | + } catch (err) { |
| 42 | + console.error("EmailJS send error:", err); |
| 43 | + const detail = |
| 44 | + err && typeof err === "object" && "text" in err |
| 45 | + ? ` (${(err as { status?: number; text?: string }).status ?? ""}: ${(err as { text?: string }).text ?? ""})` |
| 46 | + : ""; |
| 47 | + setErrorMessage( |
| 48 | + `Something went wrong${detail}. Please try again or email us directly at sanjay@recodehive.com.`, |
| 49 | + ); |
| 50 | + setStatus("error"); |
| 51 | + } |
| 52 | + }; |
| 53 | + |
7 | 54 | return ( |
8 | 55 | <Layout |
9 | 56 | title="Contact Us" |
@@ -123,88 +170,121 @@ const ContactUs: React.FC = () => { |
123 | 170 | <div className="contact-form-section"> |
124 | 171 | <h2 className="contact-form-title">Send us a message</h2> |
125 | 172 |
|
126 | | - <form className="contact-form"> |
127 | | - <div className="form-row"> |
| 173 | + {status === "success" ? ( |
| 174 | + <div className="form-success-message"> |
| 175 | + <div className="form-success-icon">✅</div> |
| 176 | + <h3>Message Sent!</h3> |
| 177 | + <p> |
| 178 | + Thank you for reaching out. We'll get back to you within |
| 179 | + 24-48 hours. |
| 180 | + </p> |
| 181 | + <button |
| 182 | + className="submit-button form-success-button" |
| 183 | + onClick={() => setStatus("idle")} |
| 184 | + > |
| 185 | + Send Another Message |
| 186 | + </button> |
| 187 | + </div> |
| 188 | + ) : ( |
| 189 | + <form |
| 190 | + ref={formRef} |
| 191 | + className="contact-form" |
| 192 | + onSubmit={handleSubmit} |
| 193 | + > |
| 194 | + <div className="form-row"> |
| 195 | + <div className="form-group"> |
| 196 | + <label htmlFor="firstName" className="form-label"> |
| 197 | + First Name |
| 198 | + </label> |
| 199 | + <input |
| 200 | + type="text" |
| 201 | + id="firstName" |
| 202 | + name="firstName" |
| 203 | + className="form-input" |
| 204 | + placeholder="Your first name" |
| 205 | + required |
| 206 | + /> |
| 207 | + </div> |
| 208 | + <div className="form-group"> |
| 209 | + <label htmlFor="lastName" className="form-label"> |
| 210 | + Last Name |
| 211 | + </label> |
| 212 | + <input |
| 213 | + type="text" |
| 214 | + id="lastName" |
| 215 | + name="lastName" |
| 216 | + className="form-input" |
| 217 | + placeholder="Your last name" |
| 218 | + required |
| 219 | + /> |
| 220 | + </div> |
| 221 | + </div> |
| 222 | + |
128 | 223 | <div className="form-group"> |
129 | | - <label htmlFor="firstName" className="form-label"> |
130 | | - First Name |
| 224 | + <label htmlFor="email" className="form-label"> |
| 225 | + Email Address |
131 | 226 | </label> |
132 | 227 | <input |
133 | | - type="text" |
134 | | - id="firstName" |
135 | | - name="firstName" |
| 228 | + type="email" |
| 229 | + id="email" |
| 230 | + name="email" |
136 | 231 | className="form-input" |
137 | | - placeholder="Your first name" |
| 232 | + placeholder="your.email@example.com" |
138 | 233 | required |
139 | 234 | /> |
140 | 235 | </div> |
| 236 | + |
141 | 237 | <div className="form-group"> |
142 | | - <label htmlFor="lastName" className="form-label"> |
143 | | - Last Name |
| 238 | + <label htmlFor="subject" className="form-label"> |
| 239 | + Subject |
144 | 240 | </label> |
145 | | - <input |
146 | | - type="text" |
147 | | - id="lastName" |
148 | | - name="lastName" |
149 | | - className="form-input" |
150 | | - placeholder="Your last name" |
| 241 | + <select |
| 242 | + id="subject" |
| 243 | + name="subject" |
| 244 | + className="form-select" |
151 | 245 | required |
152 | | - /> |
| 246 | + > |
| 247 | + <option value="">Select a subject</option> |
| 248 | + <option value="general">General Inquiry</option> |
| 249 | + <option value="support">Technical Support</option> |
| 250 | + <option value="collaboration">Collaboration</option> |
| 251 | + <option value="partnership">Partnership</option> |
| 252 | + <option value="feedback">Feedback</option> |
| 253 | + <option value="other">Other</option> |
| 254 | + </select> |
153 | 255 | </div> |
154 | | - </div> |
155 | | - |
156 | | - <div className="form-group"> |
157 | | - <label htmlFor="email" className="form-label"> |
158 | | - Email Address |
159 | | - </label> |
160 | | - <input |
161 | | - type="email" |
162 | | - id="email" |
163 | | - name="email" |
164 | | - className="form-input" |
165 | | - placeholder="your.email@example.com" |
166 | | - required |
167 | | - /> |
168 | | - </div> |
169 | 256 |
|
170 | | - <div className="form-group"> |
171 | | - <label htmlFor="subject" className="form-label"> |
172 | | - Subject |
173 | | - </label> |
174 | | - <select |
175 | | - id="subject" |
176 | | - name="subject" |
177 | | - className="form-select" |
178 | | - required |
179 | | - > |
180 | | - <option value="">Select a subject</option> |
181 | | - <option value="general">General Inquiry</option> |
182 | | - <option value="support">Technical Support</option> |
183 | | - <option value="collaboration">Collaboration</option> |
184 | | - <option value="partnership">Partnership</option> |
185 | | - <option value="feedback">Feedback</option> |
186 | | - <option value="other">Other</option> |
187 | | - </select> |
188 | | - </div> |
| 257 | + <div className="form-group"> |
| 258 | + <label htmlFor="message" className="form-label"> |
| 259 | + Message |
| 260 | + </label> |
| 261 | + <textarea |
| 262 | + id="message" |
| 263 | + name="message" |
| 264 | + rows={6} |
| 265 | + className="form-textarea" |
| 266 | + placeholder="Tell us more about your inquiry..." |
| 267 | + required |
| 268 | + ></textarea> |
| 269 | + </div> |
189 | 270 |
|
190 | | - <div className="form-group"> |
191 | | - <label htmlFor="message" className="form-label"> |
192 | | - Message |
193 | | - </label> |
194 | | - <textarea |
195 | | - id="message" |
196 | | - name="message" |
197 | | - rows={6} |
198 | | - className="form-textarea" |
199 | | - placeholder="Tell us more about your inquiry..." |
200 | | - required |
201 | | - ></textarea> |
202 | | - </div> |
| 271 | + {status === "error" && ( |
| 272 | + <div className="form-error-message">{errorMessage}</div> |
| 273 | + )} |
203 | 274 |
|
204 | | - <button type="submit" className="submit-button"> |
205 | | - Send Message |
206 | | - </button> |
207 | | - </form> |
| 275 | + <button |
| 276 | + type="submit" |
| 277 | + className="submit-button" |
| 278 | + disabled={status === "sending"} |
| 279 | + aria-busy={status === "sending"} |
| 280 | + aria-label={ |
| 281 | + status === "sending" ? "Sending message…" : "Send message" |
| 282 | + } |
| 283 | + > |
| 284 | + {status === "sending" ? "Sending…" : "Send Message"} |
| 285 | + </button> |
| 286 | + </form> |
| 287 | + )} |
208 | 288 | </div> |
209 | 289 | </div> |
210 | 290 |
|
|
0 commit comments