diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..ed9a9f96 --- /dev/null +++ b/.env.example @@ -0,0 +1,3 @@ +VITE_EMAILJS_SERVICE_ID=your_service_id +VITE_EMAILJS_TEMPLATE_ID=your_template_id +VITE_EMAILJS_PUBLIC_KEY=your_public_key \ No newline at end of file diff --git a/package.json b/package.json index 43ad31cc..28198c2b 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,6 @@ "private": true, "version": "0.0.0", "type": "module", - "scripts": { "dev": "vite --host", "build": "vite build", @@ -14,8 +13,8 @@ "docker:dev": "docker compose --profile dev up --build", "docker:prod": "docker compose --profile prod up -d --build" }, - "dependencies": { + "@emailjs/browser": "^4.4.1", "@emotion/react": "^11.11.3", "@emotion/styled": "^11.11.0", "@mui/icons-material": "^5.15.6", @@ -37,7 +36,6 @@ "recharts": "^3.8.1", "tailwindcss": "^3.4.14" }, - "devDependencies": { "@eslint/js": "^9.13.0", "@testing-library/jest-dom": "^6.9.1", @@ -49,33 +47,22 @@ "@types/react-dom": "^18.3.7", "@types/react-redux": "^7.1.34", "@types/react-router-dom": "^5.3.3", - "@vitejs/plugin-react-swc": "^3.5.0", - "autoprefixer": "^10.4.20", "bcryptjs": "^3.0.3", - "eslint": "^9.13.0", "eslint-plugin-react": "^7.37.2", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.14", - "express-session": "^1.18.2", - "globals": "^15.11.0", - "jasmine": "^5.13.0", "jasmine-spec-reporter": "^7.0.0", - "jsdom": "^29.1.1", - "passport": "^0.7.0", "passport-local": "^1.0.0", - "supertest": "^7.2.2", - "typescript-eslint": "^8.59.3", - "vite": "^5.4.10", "vitest": "^4.1.6" } diff --git a/src/components/Footer.tsx b/src/components/Footer.tsx index 3ad55184..5c75b515 100644 --- a/src/components/Footer.tsx +++ b/src/components/Footer.tsx @@ -1,5 +1,7 @@ import { useState } from 'react'; import { Link } from 'react-router-dom'; +import emailjs from '@emailjs/browser'; +import toast from 'react-hot-toast'; import { FaGithub, FaTwitter, @@ -12,15 +14,40 @@ import { function Footer() { const [email, setEmail] = useState(''); - - const handleSubscribe = (e: React.FormEvent) => { - e.preventDefault(); - - // Replace with API call - alert('Thank you for subscribing!'); - +const [isSubmitting, setIsSubmitting] = useState(false); + const handleSubscribe = async ( + e: React.FormEvent +) => { + e.preventDefault(); + + if (!email) { + toast.error('Please enter a valid email'); + return; + } + + setIsSubmitting(true); + + try { + await emailjs.send( + import.meta.env.VITE_EMAILJS_SERVICE_ID, + import.meta.env.VITE_EMAILJS_TEMPLATE_ID, + { + user_email: email, + }, + { + publicKey: import.meta.env.VITE_EMAILJS_PUBLIC_KEY, + } + ); + + toast.success('Subscribed successfully!'); setEmail(''); - }; + } catch (error) { + console.error(error); + toast.error('Subscription failed. Please try again.'); + } finally { + setIsSubmitting(false); + } +}; return (