Skip to content

Commit c40bd5d

Browse files
committed
feat: resolve hydration error and create contact page\n\nAdd to Input and build "Contact Me" page
1 parent b75eb85 commit c40bd5d

4 files changed

Lines changed: 276 additions & 0 deletions

File tree

components/contact-form.tsx

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
'use client'
2+
3+
import React from "react"
4+
5+
import { useState } from 'react'
6+
import { Mail, Linkedin, Github, Twitter } from 'lucide-react'
7+
8+
export function ContactForm() {
9+
const [formData, setFormData] = useState({
10+
name: '',
11+
email: '',
12+
subject: '',
13+
message: '',
14+
})
15+
const [submitted, setSubmitted] = useState(false)
16+
17+
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
18+
setFormData({
19+
...formData,
20+
[e.target.name]: e.target.value,
21+
})
22+
}
23+
24+
const handleSubmit = (e: React.FormEvent) => {
25+
e.preventDefault()
26+
// Open email client with pre-filled data
27+
const subject = encodeURIComponent(formData.subject || 'GitHub API Handbook Inquiry')
28+
const body = encodeURIComponent(
29+
`Name: ${formData.name}\nEmail: ${formData.email}\n\nMessage:\n${formData.message}`
30+
)
31+
window.location.href = `mailto:contact@prodhosh.com?subject=${subject}&body=${body}`
32+
33+
setSubmitted(true)
34+
setTimeout(() => {
35+
setFormData({ name: '', email: '', subject: '', message: '' })
36+
setSubmitted(false)
37+
}, 2000)
38+
}
39+
40+
return (
41+
<div className="relative min-h-screen bg-slate-950 overflow-hidden">
42+
{/* Animated stars background */}
43+
<div className="absolute inset-0">
44+
{[...Array(50)].map((_, i) => (
45+
<div
46+
key={i}
47+
className="absolute bg-white rounded-full opacity-60"
48+
style={{
49+
width: Math.random() * 2 + 1 + 'px',
50+
height: Math.random() * 2 + 1 + 'px',
51+
left: Math.random() * 100 + '%',
52+
top: Math.random() * 100 + '%',
53+
animation: `twinkle ${Math.random() * 3 + 2}s infinite`,
54+
}}
55+
/>
56+
))}
57+
</div>
58+
59+
<style>{`
60+
@keyframes twinkle {
61+
0%, 100% { opacity: 0.3; }
62+
50% { opacity: 0.8; }
63+
}
64+
`}</style>
65+
66+
{/* Content */}
67+
<div className="relative z-10 px-6 py-12">
68+
{/* Top Button */}
69+
<div className="flex justify-center mb-12">
70+
<button className="px-4 py-2 border border-blue-500 text-blue-400 rounded-lg text-sm hover:bg-blue-500/10 transition">
71+
Get In Touch
72+
</button>
73+
</div>
74+
75+
{/* Main Title */}
76+
<div className="text-center mb-16">
77+
<h1 className="text-6xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent mb-4">
78+
Contact Me
79+
</h1>
80+
<p className="text-slate-300 text-lg">
81+
Have a question or want to work together? Feel free to reach out!
82+
</p>
83+
</div>
84+
85+
{/* Two Column Layout */}
86+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8 max-w-5xl mx-auto">
87+
{/* Left: Profile Card */}
88+
<div className="space-y-6">
89+
{/* Profile Card */}
90+
<div className="bg-slate-900 border border-slate-800 rounded-2xl p-8 backdrop-blur text-center">
91+
{/* Avatar */}
92+
<div className="flex justify-center mb-6">
93+
<div className="relative">
94+
<div className="w-32 h-32 rounded-full border-4 border-blue-500 overflow-hidden">
95+
<div className="w-full h-full bg-gradient-to-br from-blue-400 to-purple-400 flex items-center justify-center">
96+
<span className="text-white text-4xl font-bold">PV</span>
97+
</div>
98+
</div>
99+
</div>
100+
</div>
101+
102+
<h2 className="text-2xl font-bold text-blue-400 mb-1">Prodhosh VS</h2>
103+
<p className="text-slate-400 text-sm mb-1">Web Developer</p>
104+
<p className="text-slate-500 text-sm mb-4">ML & AI Enthusiast</p>
105+
106+
<p className="text-slate-300 text-sm leading-relaxed">
107+
Passionate about web development, machine learning, artificial intelligence, and building
108+
innovative solutions.
109+
</p>
110+
</div>
111+
112+
{/* Social Links */}
113+
<div className="bg-slate-900 border border-slate-800 rounded-2xl p-6 backdrop-blur">
114+
<h3 className="text-lg font-semibold text-blue-400 mb-4">Connect With Me</h3>
115+
<div className="grid grid-cols-2 gap-4">
116+
<a
117+
href="mailto:contact@prodhosh.com"
118+
className="flex items-center gap-3 px-4 py-3 border border-slate-700 rounded-lg hover:bg-slate-800 transition text-slate-300"
119+
>
120+
<Mail size={20} />
121+
<span className="text-sm font-medium">Gmail</span>
122+
</a>
123+
<a
124+
href="https://linkedin.com/in/prodhosh"
125+
target="_blank"
126+
rel="noopener noreferrer"
127+
className="flex items-center gap-3 px-4 py-3 border border-slate-700 rounded-lg hover:bg-slate-800 transition text-slate-300"
128+
>
129+
<Linkedin size={20} />
130+
<span className="text-sm font-medium">LinkedIn</span>
131+
</a>
132+
<a
133+
href="https://github.com/prodhosh"
134+
target="_blank"
135+
rel="noopener noreferrer"
136+
className="flex items-center gap-3 px-4 py-3 border border-slate-700 rounded-lg hover:bg-slate-800 transition text-slate-300"
137+
>
138+
<Github size={20} />
139+
<span className="text-sm font-medium">GitHub</span>
140+
</a>
141+
<a
142+
href="https://twitter.com/prodhosh"
143+
target="_blank"
144+
rel="noopener noreferrer"
145+
className="flex items-center gap-3 px-4 py-3 border border-slate-700 rounded-lg hover:bg-slate-800 transition text-slate-300"
146+
>
147+
<Twitter size={20} />
148+
<span className="text-sm font-medium">Twitter</span>
149+
</a>
150+
</div>
151+
</div>
152+
</div>
153+
154+
{/* Right: Contact Form */}
155+
<div className="bg-slate-900 border border-slate-800 rounded-2xl p-8 backdrop-blur">
156+
<h3 className="text-2xl font-bold text-blue-400 mb-6">Send a Message</h3>
157+
158+
{submitted ? (
159+
<div className="flex items-center justify-center h-80">
160+
<div className="text-center">
161+
<div className="text-green-400 text-5xl mb-4"></div>
162+
<p className="text-slate-300 font-medium">Message sent! Thank you for reaching out.</p>
163+
</div>
164+
</div>
165+
) : (
166+
<form onSubmit={handleSubmit} className="space-y-5">
167+
{/* Name */}
168+
<div>
169+
<label className="flex items-center gap-2 text-slate-300 text-sm mb-2">
170+
<span>👤</span>
171+
Name
172+
</label>
173+
<input
174+
type="text"
175+
name="name"
176+
value={formData.name}
177+
onChange={handleChange}
178+
placeholder="Your name"
179+
className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-lg text-slate-300 placeholder-slate-500 focus:outline-none focus:border-blue-500 transition"
180+
required
181+
suppressHydrationWarning
182+
/>
183+
</div>
184+
185+
{/* Email */}
186+
<div>
187+
<label className="flex items-center gap-2 text-slate-300 text-sm mb-2">
188+
<span>📧</span>
189+
Email
190+
</label>
191+
<input
192+
type="email"
193+
name="email"
194+
value={formData.email}
195+
onChange={handleChange}
196+
placeholder="your.email@example.com"
197+
className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-lg text-slate-300 placeholder-slate-500 focus:outline-none focus:border-blue-500 transition"
198+
required
199+
suppressHydrationWarning
200+
/>
201+
</div>
202+
203+
{/* Subject */}
204+
<div>
205+
<label className="flex items-center gap-2 text-slate-300 text-sm mb-2">
206+
<span>📝</span>
207+
Subject
208+
</label>
209+
<input
210+
type="text"
211+
name="subject"
212+
value={formData.subject}
213+
onChange={handleChange}
214+
placeholder="What's this about?"
215+
className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-lg text-slate-300 placeholder-slate-500 focus:outline-none focus:border-blue-500 transition"
216+
suppressHydrationWarning
217+
/>
218+
</div>
219+
220+
{/* Message */}
221+
<div>
222+
<label className="flex items-center gap-2 text-slate-300 text-sm mb-2">
223+
<span>💬</span>
224+
Message
225+
</label>
226+
<textarea
227+
name="message"
228+
value={formData.message}
229+
onChange={handleChange}
230+
placeholder="Your message here..."
231+
rows={6}
232+
className="w-full px-4 py-3 bg-slate-800 border border-slate-700 rounded-lg text-slate-300 placeholder-slate-500 focus:outline-none focus:border-blue-500 transition resize-none"
233+
required
234+
suppressHydrationWarning
235+
/>
236+
</div>
237+
238+
{/* Submit Button */}
239+
<button
240+
type="submit"
241+
className="w-full py-3 px-6 bg-gradient-to-r from-blue-500 to-purple-500 text-white font-semibold rounded-lg hover:from-blue-600 hover:to-purple-600 transition transform hover:scale-105 flex items-center justify-center gap-2"
242+
>
243+
<span>🚀</span>
244+
Send Message
245+
</button>
246+
</form>
247+
)}
248+
</div>
249+
</div>
250+
</div>
251+
</div>
252+
)
253+
}

components/content.tsx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Breadcrumb } from '@/components/ui/breadcrumb'
22
import { ChevronRight } from 'lucide-react'
3+
import { ContactForm } from './contact-form'
34

45
interface ContentProps {
56
pageId: string
@@ -25,6 +26,7 @@ const contentMap: Record<
2526
heading: string
2627
content: string
2728
}>
29+
isContact?: boolean
2830
}
2931
> = {
3032
intro: {
@@ -663,6 +665,14 @@ const contentMap: Record<
663665
},
664666
],
665667
},
668+
'contact-developer': {
669+
title: 'Contact Developer',
670+
subtitle: 'Get in touch with Prodhosh',
671+
breadcrumb: ['Home', 'Contact', 'Contact Developer'],
672+
description:
673+
'Have a question about the GitHub API Handbook or want to collaborate? Feel free to reach out!',
674+
isContact: true,
675+
},
666676
}
667677

668678
export function Content({ pageId }: ContentProps) {
@@ -678,8 +688,14 @@ export function Content({ pageId }: ContentProps) {
678688
response,
679689
useCases,
680690
sections,
691+
isContact,
681692
} = content
682693

694+
// Render contact form for contact page
695+
if (isContact) {
696+
return <ContactForm />
697+
}
698+
683699
return (
684700
<div className="flex-1 overflow-y-auto bg-slate-950">
685701
{/* Header Banner */}

components/sidebar.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ const sections: SidebarSection[] = [
8585
{ id: 'status-codes', label: 'Status Codes' },
8686
],
8787
},
88+
{
89+
title: 'Contact',
90+
items: [
91+
{ id: 'contact-developer', label: 'Contact Developer' },
92+
],
93+
},
8894
]
8995

9096
const FREQUENTLY_USED_IDS = new Set([

components/ui/input.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const Input = React.forwardRef<HTMLInputElement, React.ComponentProps<'input'>>(
1212
className,
1313
)}
1414
ref={ref}
15+
suppressHydrationWarning
1516
{...props}
1617
/>
1718
)

0 commit comments

Comments
 (0)