diff --git a/.env.local.example b/.env.local.example new file mode 100644 index 0000000..76ec4f3 --- /dev/null +++ b/.env.local.example @@ -0,0 +1,13 @@ +# SMTP Configuration for Email Notifications +SMTP_HOST=smtp.gmail.com +SMTP_PORT=587 +SMTP_SECURE=false +SMTP_USER=your-email@gmail.com +SMTP_PASSWORD=your-app-password +SMTP_FROM=noreply@clearance.dev + +# Admin Email +ADMIN_EMAIL=admin@clearance.dev + +# Database Configuration (optional for future database integration) +DATABASE_URL= diff --git a/package.json b/package.json index 6dfa71b..cbc9576 100644 --- a/package.json +++ b/package.json @@ -1,47 +1,12 @@ { - "name": "webild-components-2", - "version": "0.1.0", - "private": true, + "name": "clearance-landing", "version": "0.1.0", "private": true, "scripts": { - "dev": "next dev --turbopack", - "build": "next build --turbopack", - "typecheck": "tsc --noEmit", - "lint": "eslint . --ext .ts,.tsx", - "start": "next start" + "dev": "next dev", "build": "next build", "start": "next start", "lint": "next lint" }, "dependencies": { - "@gsap/react": "^2.1.2", - "@react-three/drei": "^10.7.7", - "@react-three/fiber": "^9.4.0", - "@rive-app/react-canvas": "^4.26.2", - "@tsparticles/engine": "^3.9.1", - "@tsparticles/react": "^3.0.0", - "@tsparticles/slim": "^3.9.1", - "clsx": "^2.1.1", - "cobe": "^0.6.5", - "embla-carousel-auto-scroll": "^8.6.0", - "embla-carousel-react": "^8.6.0", - "gsap": "^3.13.0", - "lenis": "^1.3.15", - "lucide-react": "^0.555.0", - "motion-number": "^1.0.0", - "next": "16.0.7", - "react": "19.2.1", - "react-dom": "19.2.1", - "react-fast-marquee": "^1.6.5", - "recharts": "^3.6.0", - "tailwind-merge": "^3.4.0", - "three": "^0.181.2" + "react": "^18", "react-dom": "^18", "next": "^14", "lucide-react": "latest", "nodemailer": "^6.9.7" }, "devDependencies": { - "@eslint/eslintrc": "^3", - "@tailwindcss/postcss": "^4", - "@types/node": "^20", - "@types/react": "^19", - "@types/react-dom": "^19", - "eslint": "^9", - "eslint-config-next": "16.0.7", - "tailwindcss": "^4", - "typescript": "^5" + "typescript": "^5", "@types/node": "^20", "@types/react": "^18", "@types/react-dom": "^18", "@types/nodemailer": "^6.4.14", "autoprefixer": "^10", "postcss": "^8", "tailwindcss": "^3" } } diff --git a/src/app/api/waitlist/route.ts b/src/app/api/waitlist/route.ts index fd22071..110c164 100644 --- a/src/app/api/waitlist/route.ts +++ b/src/app/api/waitlist/route.ts @@ -1,86 +1,143 @@ import { NextRequest, NextResponse } from 'next/server'; +import nodemailer from 'nodemailer'; -interface WaitlistEntry { +interface WaitlistFormData { email: string; instagram?: string; tiktok?: string; - createdAt: string; } -// In-memory storage for demonstration -// In production, replace with actual database (MongoDB, PostgreSQL, etc.) -const waitlistEntries: WaitlistEntry[] = []; +// In-memory storage for demo purposes. Replace with database in production. +const waitlistDatabase: WaitlistFormData[] = []; + +// Configure your email service here +const transporter = nodemailer.createTransport({ + host: process.env.SMTP_HOST || 'smtp.gmail.com', + port: parseInt(process.env.SMTP_PORT || '587'), + secure: process.env.SMTP_SECURE === 'true', // true for 465, false for other ports + auth: { + user: process.env.SMTP_USER, + pass: process.env.SMTP_PASSWORD, + }, +}); export async function POST(request: NextRequest) { try { - const body = await request.json(); - const { email, instagram, tiktok } = body; + const body: WaitlistFormData = await request.json(); // Validate email - if (!email || typeof email !== 'string' || !email.includes('@')) { + if (!body.email || !body.email.includes('@')) { return NextResponse.json( - { error: 'Valid email is required' }, + { error: 'Invalid email address' }, { status: 400 } ); } - // Check for duplicate email - if (waitlistEntries.some(entry => entry.email === email)) { + // Check if email already exists + if (waitlistDatabase.some(entry => entry.email === body.email)) { return NextResponse.json( - { error: 'Email already registered' }, + { error: 'Email already on waitlist' }, { status: 409 } ); } - // Create waitlist entry - const entry: WaitlistEntry = { - email, - instagram: instagram || undefined, - tiktok: tiktok || undefined, - createdAt: new Date().toISOString() - }; + // Add to database + waitlistDatabase.push(body); - // Add to in-memory storage - waitlistEntries.push(entry); + // Send confirmation email to user + const userEmailContent = ` + +
+Hi ${body.email.split('@')[0]},
+Thank you for joining our waitlist. You're now part of an exclusive group of creators and agencies who will get early access to Clearance.
+What to expect:
+Instagram: ${body.instagram}
` : ''} + ${body.tiktok ? `TikTok: ${body.tiktok}
` : ''} +We'll be in touch soon with more details!
+Best regards,
The Clearance Team
Email: ${body.email}
+ ${body.instagram ? `Instagram: ${body.instagram}
` : ''} + ${body.tiktok ? `TikTok: ${body.tiktok}
` : ''} +Submitted at: ${new Date().toISOString()}
+Total waitlist entries: ${waitlistDatabase.length}
+