Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 51 additions & 0 deletions apps/web/app/api/contact-us/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { NextRequest, NextResponse } from "next/server";
import { Resend } from "resend";


async function contactUsMail(name: string, email: string, message: string,phone:string, resend: Resend) {
try {
const { data, error } = await resend.emails.send({
from: 'Script AI <notifications@tryscriptai.com>',
to: 'afrin@tryscriptai.com',
subject: "πŸ“¬ New Contact Message",
html: `<div style="font-family: Arial, sans-serif; color: #333; background: #f9f9f9; padding: 20px;">
<div style="background: white; padding: 20px; border-radius: 8px;">
<h2 style="color: #4F46E5;">πŸ“¬ New Contact Message</h2>
<p><strong>From:</strong> ${name}</p>
<p><strong>Email:</strong> ${email}</p>
<p><strong>Phone No:</strong> ${phone}</p>
<hr style="margin: 20px 0; border: none; border-top: 1px solid #eee;">
<p style="white-space: pre-line;">${message}</p>
<hr style="margin: 20px 0; border: none; border-top: 1px solid #eee;">
<p style="font-size: 12px; color: #888;">Sent on ${new Date().toLocaleString()}</p>
</div>
</div>`,
});
if (error) {
console.error('Error sending issue mail:', error)
return { success: false, error }
}

return { success: true, data }
} catch (error) {
console.error('Error sending mail:', error);
}
}

export async function POST(req: NextRequest) {
const { email, message, name, phone } = await req.json()

try {
const resend = new Resend(process.env.RESEND_API_KEY!);

if (!email || !message || !name) {
return NextResponse.json({ success: false, error: 'Missing required fields' }, { status: 400 })
}

const result = await contactUsMail(email, message, name, phone, resend)
return NextResponse.json(result, { status: result?.success ? 200 : 500 })

} catch (error) {
console.log(error)
}
}
203 changes: 203 additions & 0 deletions apps/web/app/contact-us/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
"use client";
import Footer from "@/components/footer";
import { motion } from "motion/react";
import { useState } from "react";
import logo from "@/public/dark-logo.png"
import Image from "next/image";
import { Input } from "@/components/ui/input";
import { Textarea } from "@/components/ui/textarea";
import { toast } from "sonner";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";

export default function ContactPage() {
const [formData, setFormData] = useState({ name: "", email: "", message: "", phone: "" });
const [loading, setLoading] = useState(false)

const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};

const handleSubmit = async (e: React.FormEvent) => {
if(loading) return
setLoading(true)
console.log(formData)
e.preventDefault();
try {
const response = await fetch("/api/contact-us", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(formData),
});

if (!response.ok) throw new Error("Failed to send mail");

await response.json();
toast.success("mail sent successfully!", {
description: "Thank you for reaching out!. We'll look into it soon.",
});
setFormData({ name: "", email: "", message: "", phone:"" })
} catch (error:any) {
console.error(error, "error")
toast.error("Failed to send mail", {
description: error?.message || "Something went wrong. Please try again.",
});
}finally{
setLoading(false)
}
// TODO: integrate with backend or Supabase
};

return (
<div className="bg-white text-gray-900">
{/* Hero Section */}
<section className="relative py-24 bg-gradient-to-b from-indigo-50 to-white text-center overflow-hidden">
<div className="max-w-4xl mx-auto px-6">
<motion.h1
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
className="text-5xl font-bold mb-4"
>
Contact <span className="text-indigo-600">Us</span>
</motion.h1>
<motion.p
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: 0.2 }}
className="text-lg text-gray-600 max-w-2xl mx-auto"
>
Got questions, feedback, or ideas? We’d love to hear from you!
Our team is always ready to collaborate and support your AI-powered creative journey.
</motion.p>
</div>
</section>

{/* Contact Section */}
<section className="py-20 bg-white">
<div className="max-w-6xl mx-auto px-6 grid md:grid-cols-2 gap-12 items-center">
<motion.div className="w-full rounded-2xl flex justify-center object-cover"
initial={{ opacity: 0, x: -40 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.7 }}>
<Image src={logo} alt="Logo" width={100} height={100} />
</motion.div>

{/* Right: Contact Form */}
<motion.div
initial={{ opacity: 0, x: 40 }}
whileInView={{ opacity: 1, x: 0 }}
transition={{ duration: 0.7 }}
>
<h2 className="text-3xl font-semibold mb-6">Send Us a Message</h2>
<form onSubmit={handleSubmit} className="space-y-5">
<div>
<label className="block text-gray-700 mb-1 font-medium">Name</label>
<Input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
required
className="w-full px-4 py-3 border rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none"
placeholder="Your name"
/>
</div>
<div>
<label className="block text-gray-700 mb-1 font-medium">Email</label>
<Input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
required
className="w-full px-4 py-3 border rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none"
placeholder="you@example.com"
/>
</div>
<div>
<label className="block text-gray-700 mb-1 font-medium">Phone</label>
<Input
type="phone"
name="phone"
value={formData.phone}
onChange={handleChange}
required
className="w-full px-4 py-3 border rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none"
placeholder="Your phone"
/>
</div>
<div>
<label className="block text-gray-700 mb-1 font-medium">Message</label>
<Textarea
name="message"
value={formData.message}
onChange={handleChange}
required
className="w-full px-4 py-3 border rounded-xl focus:ring-2 focus:ring-indigo-500 outline-none"
rows={5}
placeholder="Write your message here..."
/>
</div>
<Button className={cn("w-full")} disabled={loading}>Send Message</Button>

</form>
</motion.div>
</div>
</section>

{/* Contact Info / Community Links */}
{/* <section className="py-20 bg-gradient-to-b from-gray-50 to-white">
<div className="max-w-6xl mx-auto px-6 text-center">
<motion.h2
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
className="text-3xl font-semibold mb-8"
>
Other Ways to Reach Us
</motion.h2>

<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-8">
{[
{
icon: "πŸ’¬",
title: "Join Our Discord",
text: "Collaborate and chat with the TryScript.ai community.",
link: "https://discord.gg/k9sZcq2gNG",
},
{
icon: "πŸ“§",
title: "Email Support",
text: "Reach out to us anytime at support@tryscript.ai.",
link: "mailto:support@tryscript.ai",
},
{
icon: "🌐",
title: "GitHub",
text: "Contribute to our open-source codebase and explore our projects.",
link: "https://github.com/scriptaiapp/scriptai",
},
].map((item, idx) => (
<motion.a
key={idx}
href={item.link}
target="_blank"
rel="noopener noreferrer"
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 1, delay: idx * 0.1 }}
className="block bg-white rounded-2xl shadow p-6 border hover:shadow-md transition-all duration-200"
>
<div className="text-4xl mb-3">{item.icon}</div>
<h3 className="text-xl font-semibold mb-2 text-indigo-600">{item.title}</h3>
<p className="text-gray-700">{item.text}</p>
</motion.a>
))}
</div>
</div>
</section> */}
<Footer />
</div>
);
}
4 changes: 3 additions & 1 deletion apps/web/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ export async function middleware(request: NextRequest) {
const response = NextResponse.next()

if (request.nextUrl.pathname === "/api/auth/callback" ||
request.nextUrl.pathname === "/api/track-referral"
request.nextUrl.pathname === "/api/track-referral" ||
request.nextUrl.pathname === "/api/contact-us" ||
request.nextUrl.pathname === "/api/report-issue"
) {
return response
}
Expand Down
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/cli-latest
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v2.51.0
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/gotrue-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v2.180.0
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/pooler-url
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
postgresql://postgres.sbodsmhnhzamraxlpyfd:[YOUR-PASSWORD]@aws-1-us-east-1.pooler.supabase.com:6543/postgres
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/postgres-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
17.6.1.021
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/project-ref
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbodsmhnhzamraxlpyfd
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/rest-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
v13.0.5
1 change: 1 addition & 0 deletions apps/web/supabase/.temp/storage-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
fix-object-level
9 changes: 6 additions & 3 deletions packages/ui/src/utils/data.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
export const navItem = [
{ name: "Features", href: "#features" },
{ name: "How It Works", href: "#how-it-works" },
{ name: "Pricing", href: "#pricing" },
{ name: "Features", href: "/#features" },
{ name: "How It Works", href: "/#how-it-works" },
{ name: "Pricing", href: "/#pricing" },
// { name: "About Us", href: "/about-us" },
]

export const footerItems = {
"Product": [
{ name: "Features", href: "./#features" },
{ name: "Pricing", href: "./#pricing" },
{ name: "Book a Call", href: "https://cal.com/afrin/30min" },
// { name: "About Us", href: "/about-us" },
{ name: "Contact Us", href: "/contact-us" },
// { name: "Docs", href: "/docs" },
],
"Account": [
Expand Down
Loading