Skip to content

Commit dcee72c

Browse files
committed
Add Contact page with Google Form integration and profile photo
1 parent b09486e commit dcee72c

File tree

3 files changed

+271
-1
lines changed

3 files changed

+271
-1
lines changed

src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import Simulation from "./pages/Simulation";
1111
import Documentation from "./pages/Documentation";
1212
import Quiz from "./pages/Quiz";
1313
import Auth from "./pages/Auth";
14+
import Contact from "./pages/Contact";
1415
import NotFound from "./pages/NotFound";
1516
import Starfield from "@/components/ui/Starfield";
1617

@@ -33,6 +34,7 @@ const App = () => (
3334
<Route path="/theory" element={<Theory />} />
3435
<Route path="/simulation" element={<Simulation />} />
3536
<Route path="/documentation" element={<Documentation />} />
37+
<Route path="/contact" element={<Contact />} />
3638
<Route path="/auth" element={<Auth />} />
3739
<Route path="/quiz" element={<Quiz />} />
3840
{/* ADD ALL CUSTOM ROUTES ABOVE THE CATCH-ALL "*" ROUTE */}

src/pages/Contact.tsx

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
import { useState } from 'react';
2+
import { Link } from 'react-router-dom';
3+
import { Button } from '@/components/ui/button';
4+
import { Input } from '@/components/ui/input';
5+
import { Textarea } from '@/components/ui/textarea';
6+
import { Card } from '@/components/ui/card';
7+
import { ArrowLeft, Mail, Github, Linkedin, Twitter, Send, User, MessageSquare } from 'lucide-react';
8+
import { useToast } from '@/hooks/use-toast';
9+
import Footer from '@/components/ui/Footer';
10+
11+
const Contact = () => {
12+
const { toast } = useToast();
13+
const [loading, setLoading] = useState(false);
14+
const [formData, setFormData] = useState({
15+
name: '',
16+
email: '',
17+
subject: '',
18+
message: ''
19+
});
20+
21+
const handleSubmit = async (e: React.FormEvent) => {
22+
e.preventDefault();
23+
setLoading(true);
24+
25+
try {
26+
// Create FormData for Google Form
27+
const googleFormData = new FormData();
28+
googleFormData.append('entry.1478158167', formData.name);
29+
googleFormData.append('entry.384186664', formData.email);
30+
googleFormData.append('entry.517333600', formData.subject);
31+
googleFormData.append('entry.1686267960', formData.message);
32+
33+
// Submit to Google Form silently
34+
await fetch('https://docs.google.com/forms/d/e/1FAIpQLSfWe_62YoSAQjCDKMYF-zfHJtlcu2QSqsq6sT-d4FTLND3LnQ/formResponse', {
35+
method: 'POST',
36+
mode: 'no-cors',
37+
body: googleFormData
38+
});
39+
40+
// Show success message
41+
toast({
42+
title: "Connection Successful! ✅",
43+
description: "Thanks for reaching out! I'll get back to you soon.",
44+
});
45+
46+
// Reset form
47+
setFormData({ name: '', email: '', subject: '', message: '' });
48+
} catch (error) {
49+
toast({
50+
title: "Connection Successful! ✅",
51+
description: "Thanks for reaching out! I'll get back to you soon.",
52+
});
53+
setFormData({ name: '', email: '', subject: '', message: '' });
54+
} finally {
55+
setLoading(false);
56+
}
57+
};
58+
59+
const socialLinks = [
60+
{
61+
name: 'Gmail',
62+
icon: Mail,
63+
url: 'mailto:[email protected]',
64+
color: 'hover:text-red-400'
65+
},
66+
{
67+
name: 'LinkedIn',
68+
icon: Linkedin,
69+
url: 'https://www.linkedin.com/in/prodhoshvs',
70+
color: 'hover:text-blue-400'
71+
},
72+
{
73+
name: 'GitHub',
74+
icon: Github,
75+
url: 'https://github.com/PRODHOSH',
76+
color: 'hover:text-purple-400'
77+
},
78+
{
79+
name: 'Twitter',
80+
icon: Twitter,
81+
url: 'https://x.com/itzprodhosh',
82+
color: 'hover:text-cyan-400'
83+
}
84+
];
85+
86+
return (
87+
<div className="min-h-screen bg-black text-white relative overflow-hidden flex flex-col">
88+
<div className="starfield" />
89+
90+
<div className="relative z-10 flex-1 container mx-auto px-3 sm:px-4 py-6 sm:py-12 max-w-6xl w-full">
91+
<Link to="/" className="inline-flex items-center gap-2 text-blue-400 hover:text-blue-300 mb-6 sm:mb-8 transition-colors text-sm sm:text-base">
92+
<ArrowLeft size={20} />
93+
Back to Home
94+
</Link>
95+
96+
<div className="text-center mb-8 sm:mb-12">
97+
<div className="inline-block mb-4 px-4 py-1.5 bg-blue-500/20 border border-blue-500/30 rounded-full">
98+
<span className="text-blue-400 text-sm font-medium">📬 Get In Touch</span>
99+
</div>
100+
<h1 className="text-3xl sm:text-4xl md:text-5xl font-bold mb-3 gradient-text">
101+
Contact Me
102+
</h1>
103+
<p className="text-gray-300 text-sm sm:text-base max-w-2xl mx-auto">
104+
Have a question or want to work together? Feel free to reach out!
105+
</p>
106+
</div>
107+
108+
<div className="grid md:grid-cols-2 gap-6 sm:gap-8 mb-8">
109+
{/* Left Column - Profile & Social Links */}
110+
<div className="space-y-6">
111+
{/* Profile Card */}
112+
<Card className="bg-gradient-to-br from-gray-900/50 to-gray-800/50 border-gray-700/50 p-6 sm:p-8">
113+
<div className="flex flex-col items-center text-center space-y-4">
114+
{/* Profile Photo */}
115+
<img
116+
src={`${import.meta.env.BASE_URL}images/prodhosh_photo.jpg`}
117+
alt="Prodhosh VS"
118+
className="w-32 h-32 sm:w-40 sm:h-40 rounded-full object-cover border-4 border-blue-500/50 object-[center_30%]"
119+
/>
120+
121+
<div>
122+
<h2 className="text-2xl sm:text-3xl font-bold gradient-text mb-2">Prodhosh VS</h2>
123+
<p className="text-gray-400 text-sm sm:text-base">Web Developer</p>
124+
<p className="text-gray-400 text-sm sm:text-base">ML & AI Enthusiast</p>
125+
</div>
126+
127+
<p className="text-gray-300 text-sm sm:text-base">
128+
Passionate about web development, machine learning, artificial intelligence, and building innovative solutions.
129+
</p>
130+
</div>
131+
</Card>
132+
133+
{/* Social Links Card */}
134+
<Card className="bg-gradient-to-br from-gray-900/50 to-gray-800/50 border-gray-700/50 p-6 sm:p-8">
135+
<h3 className="text-xl font-bold mb-4 gradient-text">Connect With Me</h3>
136+
<div className="grid grid-cols-2 gap-4">
137+
{socialLinks.map((link) => {
138+
const Icon = link.icon;
139+
return (
140+
<a
141+
key={link.name}
142+
href={link.url}
143+
target="_blank"
144+
rel="noopener noreferrer"
145+
className={`flex items-center gap-3 p-4 bg-black/30 rounded-lg border border-gray-700 hover:border-blue-500/50 transition-all ${link.color}`}
146+
>
147+
<Icon size={24} />
148+
<span className="font-medium text-sm">{link.name}</span>
149+
</a>
150+
);
151+
})}
152+
</div>
153+
</Card>
154+
</div>
155+
156+
{/* Right Column - Contact Form */}
157+
<Card className="bg-gradient-to-br from-gray-900/50 to-gray-800/50 border-gray-700/50 p-6 sm:p-8">
158+
<h3 className="text-xl sm:text-2xl font-bold mb-6 gradient-text">Send a Message</h3>
159+
160+
<form onSubmit={handleSubmit} className="space-y-4">
161+
<div>
162+
<label className="block text-sm font-medium mb-2 text-gray-300">
163+
<User size={16} className="inline mr-2" />
164+
Name
165+
</label>
166+
<Input
167+
type="text"
168+
placeholder="Your name"
169+
value={formData.name}
170+
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
171+
className="bg-black/30 border-gray-700 text-white"
172+
required
173+
/>
174+
</div>
175+
176+
<div>
177+
<label className="block text-sm font-medium mb-2 text-gray-300">
178+
<Mail size={16} className="inline mr-2" />
179+
Email
180+
</label>
181+
<Input
182+
type="email"
183+
placeholder="[email protected]"
184+
value={formData.email}
185+
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
186+
className="bg-black/30 border-gray-700 text-white"
187+
required
188+
/>
189+
</div>
190+
191+
<div>
192+
<label className="block text-sm font-medium mb-2 text-gray-300">
193+
<MessageSquare size={16} className="inline mr-2" />
194+
Subject
195+
</label>
196+
<Input
197+
type="text"
198+
placeholder="What's this about?"
199+
value={formData.subject}
200+
onChange={(e) => setFormData({ ...formData, subject: e.target.value })}
201+
className="bg-black/30 border-gray-700 text-white"
202+
required
203+
/>
204+
</div>
205+
206+
<div>
207+
<label className="block text-sm font-medium mb-2 text-gray-300">
208+
<MessageSquare size={16} className="inline mr-2" />
209+
Message
210+
</label>
211+
<Textarea
212+
placeholder="Your message here..."
213+
value={formData.message}
214+
onChange={(e) => setFormData({ ...formData, message: e.target.value })}
215+
className="bg-black/30 border-gray-700 text-white min-h-[150px]"
216+
required
217+
/>
218+
</div>
219+
220+
<Button
221+
type="submit"
222+
disabled={loading}
223+
className="w-full bg-gradient-to-r from-blue-600 to-purple-600 hover:from-blue-500 hover:to-purple-500 py-6 text-base"
224+
>
225+
{loading ? 'Sending...' : (
226+
<>
227+
<Send size={18} className="mr-2" />
228+
Send Message
229+
</>
230+
)}
231+
</Button>
232+
</form>
233+
</Card>
234+
</div>
235+
236+
{/* Quick Info Card */}
237+
<Card className="bg-blue-900/20 border-blue-500/30 p-6">
238+
<h3 className="text-lg font-bold mb-3 text-blue-400">Quick Response</h3>
239+
<p className="text-sm text-gray-300">
240+
💡 I typically respond within 24-48 hours. For urgent matters, feel free to reach out directly via email at{' '}
241+
<a href="mailto:[email protected]" className="text-blue-400 hover:text-blue-300 underline">
242+
243+
</a>
244+
</p>
245+
</Card>
246+
</div>
247+
248+
<Footer />
249+
</div>
250+
);
251+
};
252+
253+
export default Contact;

src/pages/Home.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Link } from "react-router-dom";
22
import { Button } from "@/components/ui/button";
3-
import { ArrowRight, Lock, Atom, Sparkles, Users, FileText, Trophy } from "lucide-react";
3+
import { ArrowRight, Lock, Atom, Sparkles, Users, FileText, Trophy, Mail } from "lucide-react";
44
import Footer from "@/components/ui/Footer";
55

66

@@ -10,6 +10,21 @@ const Home = () => {
1010
{/* Subtle starfield overlay (pure CSS) */}
1111
<div className="starfield" />
1212

13+
{/* Top Navigation Bar */}
14+
<div className="relative z-20 container mx-auto px-4 py-4">
15+
<div className="flex justify-end">
16+
<Link to="/contact">
17+
<Button
18+
variant="outline"
19+
className="border-primary/30 hover:bg-primary/10 hover:text-white group"
20+
>
21+
<Mail className="mr-2 w-4 h-4" />
22+
Contact
23+
</Button>
24+
</Link>
25+
</div>
26+
</div>
27+
1328
<div className="relative z-10 container mx-auto px-4 py-16 md:py-24">
1429
{/* Hero Section */}
1530
<div className="max-w-4xl mx-auto text-center space-y-8 animate-fade-in-up">

0 commit comments

Comments
 (0)