diff --git a/.gitignore b/.gitignore index 074922c..2bbc967 100644 --- a/.gitignore +++ b/.gitignore @@ -28,6 +28,7 @@ yarn-error.log* # local env files .env*.local +.env # vercel .vercel diff --git a/api/send-telegram.ts b/api/send-telegram.ts new file mode 100644 index 0000000..06318b5 --- /dev/null +++ b/api/send-telegram.ts @@ -0,0 +1,55 @@ +import type { VercelRequest, VercelResponse } from '@vercel/node'; + +export default async function handler( + req: VercelRequest, + res: VercelResponse +) { + if (req.method !== 'POST') { + return res.status(405).json({ message: 'Method not allowed' }); + } + + try { + const { projectName, description, timeline, customTimeline, contact } = req.body; + + // Validate required fields + if (!projectName || !description || !contact || !(timeline || customTimeline)) { + return res.status(400).json({ message: 'Missing required fields' }); + } + + // Format message for Telegram + const message = ` +🚀 New Project Request + +📋 Project Name: ${projectName} + +📝 Description: ${description} + +⏰ Timeline: ${timeline === 'custom' ? customTimeline : timeline} + +📧 Contact: ${contact} + `; + + // Send to Telegram + const response = await fetch(`https://api.telegram.org/bot${process.env.TELEGRAM_BOT_TOKEN}/sendMessage`, { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ + chat_id: process.env.TELEGRAM_CHANNEL_ID, + text: message, + parse_mode: 'HTML', + }), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.description || 'Failed to send message to Telegram'); + } + + return res.status(200).json({ message: 'Project request sent successfully' }); + } catch (error) { + console.error('Error sending to Telegram:', error); + return res.status(500).json({ message: 'Error sending project request' }); + } +} diff --git a/bun.lockb b/bun.lockb index ff7d326..69ec259 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index f04d269..99e57f6 100644 --- a/package.json +++ b/package.json @@ -27,17 +27,18 @@ }, "dependencies": { "lucide-react": "^0.344.0", + "nodemailer": "^6.9.16", "react": "^18.3.1", "react-dom": "^18.3.1", "react-router-dom": "^6.22.3" }, "devDependencies": { + "@eslint/js": "^9.9.1", "@playwright/test": "^1.46.1", "@types/node": "^20.11.0", - "prettier": "^3.3.3", - "@eslint/js": "^9.9.1", "@types/react": "^18.3.5", "@types/react-dom": "^18.3.0", + "@vercel/node": "^5.0.0", "@vitejs/plugin-react": "^4.3.1", "autoprefixer": "^10.4.18", "eslint": "^9.9.1", @@ -45,6 +46,7 @@ "eslint-plugin-react-refresh": "^0.4.11", "globals": "^15.9.0", "postcss": "^8.4.35", + "prettier": "^3.3.3", "tailwindcss": "^3.4.1", "typescript": "^5.5.3", "typescript-eslint": "^8.3.0", diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx index db3cc63..c87bdf4 100644 --- a/src/components/Navigation.tsx +++ b/src/components/Navigation.tsx @@ -8,7 +8,7 @@ export default function Navigation() {
- Build DAO + {/* Build DAO */}
diff --git a/src/pages/Process.tsx b/src/pages/Process.tsx index b0cffd4..0c356a4 100644 --- a/src/pages/Process.tsx +++ b/src/pages/Process.tsx @@ -84,9 +84,9 @@ export default function Process() {

{step.title}

- + {/* {step.duration} - + */}

{step.description}

diff --git a/src/pages/SubmitProject.tsx b/src/pages/SubmitProject.tsx index 3492bc4..e9a186f 100644 --- a/src/pages/SubmitProject.tsx +++ b/src/pages/SubmitProject.tsx @@ -1,7 +1,76 @@ import { ArrowLeft, CheckCircle, Clock, Rocket } from "lucide-react"; import { Link } from "react-router-dom"; +import { useState, FormEvent } from "react"; + +interface FormData { + projectName: string; + description: string; + timeline: string; + customTimeline: string; + contact: string; +} export default function SubmitProject() { + const [formData, setFormData] = useState({ + customTimeline: "", + projectName: "", + description: "", + timeline: "", + contact: "" + }); + + const [isSubmitting, setIsSubmitting] = useState(false); + + const handleSubmit = async (e: FormEvent) => { + e.preventDefault(); + + // Basic validation + if (!formData.projectName || !formData.description || !formData.contact || + (formData.timeline === 'custom' ? !formData.customTimeline : !formData.timeline)) { + alert("Please fill in all fields"); + return; + } + + try { + setIsSubmitting(true); + const response = await fetch('/api/send-telegram', { + method: 'POST', + headers: { + 'Content-Type': 'application/json', + }, + body: JSON.stringify(formData), + }); + + if (!response.ok) { + const error = await response.json(); + throw new Error(error.message || 'Failed to send contact'); + } + + // Clear form on success + setFormData({ + projectName: "", + description: "", + timeline: "", + customTimeline: "", + contact: "" + }); + + alert('Project submitted successfully! We will get back to you soon.'); + } catch (error) { + alert(error instanceof Error ? error.message : 'Failed to submit project. Please try again.'); + } finally { + setIsSubmitting(false); + } + }; + + const handleInputChange = (e: React.ChangeEvent) => { + const { name, value } = e.target; + setFormData(prev => ({ + ...prev, + [name]: value + })); + }; + return (
@@ -21,13 +90,16 @@ export default function SubmitProject() { our team will get back to you within 24 hours.

-
+
@@ -39,6 +111,9 @@ export default function SubmitProject() {