Skip to content

Commit a6af3b6

Browse files
authored
Merge pull request #105 from semz-ui/feat/about-us
Feat/about us
2 parents 9d1c01d + a7c74a2 commit a6af3b6

7 files changed

Lines changed: 586 additions & 46 deletions

File tree

apps/web/app/about-us/page.tsx

Lines changed: 361 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { NextRequest, NextResponse } from "next/server";
2+
import { Resend } from "resend";
3+
4+
5+
async function contactUsMail(name: string, email: string, message: string,phone:string, resend: Resend) {
6+
try {
7+
const { data, error } = await resend.emails.send({
8+
from: 'Script AI <notifications@tryscriptai.com>',
9+
to: 'afrin@tryscriptai.com',
10+
subject: "📬 New Contact Message",
11+
html: `<div style="font-family: Arial, sans-serif; color: #333; background: #f9f9f9; padding: 20px;">
12+
<div style="background: white; padding: 20px; border-radius: 8px;">
13+
<h2 style="color: #4F46E5;">📬 New Contact Message</h2>
14+
<p><strong>From:</strong> ${name}</p>
15+
<p><strong>Email:</strong> ${email}</p>
16+
<p><strong>Phone No:</strong> ${phone}</p>
17+
<hr style="margin: 20px 0; border: none; border-top: 1px solid #eee;">
18+
<p style="white-space: pre-line;">${message}</p>
19+
<hr style="margin: 20px 0; border: none; border-top: 1px solid #eee;">
20+
<p style="font-size: 12px; color: #888;">Sent on ${new Date().toLocaleString()}</p>
21+
</div>
22+
</div>`,
23+
});
24+
if (error) {
25+
console.error('Error sending issue mail:', error)
26+
return { success: false, error }
27+
}
28+
29+
return { success: true, data }
30+
} catch (error) {
31+
console.error('Error sending mail:', error);
32+
}
33+
}
34+
35+
export async function POST(req: NextRequest) {
36+
const { email, message, name, phone } = await req.json()
37+
38+
try {
39+
const resend = new Resend(process.env.RESEND_API_KEY!);
40+
41+
if (!email || !message || !name) {
42+
return NextResponse.json({ success: false, error: 'Missing required fields' }, { status: 400 })
43+
}
44+
45+
const result = await contactUsMail(email, message, name, phone, resend)
46+
return NextResponse.json(result, { status: result?.success ? 200 : 500 })
47+
48+
} catch (error) {
49+
console.log(error)
50+
}
51+
}

apps/web/app/contact-us/page.tsx

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
"use client"
2+
3+
import type React from "react"
4+
import { useState } from "react"
5+
import Link from "next/link"
6+
import Image from "next/image"
7+
import { motion } from "motion/react"
8+
import { toast } from "sonner"
9+
10+
import { Button } from "@/components/ui/button"
11+
import { Input } from "@/components/ui/input"
12+
import { Label } from "@/components/ui/label"
13+
import { Textarea } from "@/components/ui/textarea"
14+
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
15+
import { AuroraBackground } from "@/components/ui/aurora-background"
16+
import LandingPageNavbar from "@/components/landingPage/LandingPageNavbar"
17+
import Footer from "@/components/footer"
18+
import logo from "@/public/dark-logo.png"
19+
20+
const formFields = [
21+
{ name: "name", label: "Name", type: "text", placeholder: "Your name" },
22+
{ name: "email", label: "Email", type: "email", placeholder: "you@example.com" },
23+
{ name: "phone", label: "Phone", type: "tel", placeholder: "Your phone number" },
24+
] as const
25+
26+
export default function ContactPage() {
27+
const [formData, setFormData] = useState({ name: "", email: "", message: "", phone: "" })
28+
const [loading, setLoading] = useState(false)
29+
30+
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
31+
setFormData({ ...formData, [e.target.name]: e.target.value })
32+
}
33+
34+
const handleSubmit = async (e: React.FormEvent) => {
35+
e.preventDefault()
36+
if (loading) return
37+
setLoading(true)
38+
39+
try {
40+
const response = await fetch("/api/contact-us", {
41+
method: "POST",
42+
headers: { "Content-Type": "application/json" },
43+
body: JSON.stringify(formData),
44+
})
45+
46+
if (!response.ok) throw new Error("Failed to send mail")
47+
48+
await response.json()
49+
toast.success("Mail sent successfully!", {
50+
description: "Thank you for reaching out! We'll get back to you soon.",
51+
})
52+
setFormData({ name: "", email: "", message: "", phone: "" })
53+
} catch (error: any) {
54+
toast.error("Failed to send mail", {
55+
description: error?.message || "Something went wrong. Please try again.",
56+
})
57+
} finally {
58+
setLoading(false)
59+
}
60+
}
61+
62+
return (
63+
<>
64+
<LandingPageNavbar />
65+
<AuroraBackground>
66+
<div className="relative grid min-h-screen w-full grid-cols-1 items-start justify-center gap-8 px-4 pt-24 md:grid-cols-2 md:items-center md:px-8 md:pt-0 lg:px-16">
67+
68+
{/* Left Column: Brand Messaging */}
69+
<motion.div
70+
initial={{ opacity: 0, x: -40 }}
71+
whileInView={{ opacity: 1, x: 0 }}
72+
transition={{ delay: 0.2, duration: 0.8, ease: "easeInOut" }}
73+
className="hidden flex-col justify-center gap-4 md:flex"
74+
>
75+
<Link href="/">
76+
<Image src={logo} alt="Script AI" width={80} height={80} className="mb-4" />
77+
</Link>
78+
<h1 className="text-4xl lg:text-5xl font-bold text-slate-900">
79+
We'd Love to Hear From You.
80+
</h1>
81+
<p className="max-w-md text-lg text-slate-600">
82+
Got questions, feedback, or ideas? Our team is always ready to collaborate and support your AI-powered creative journey.
83+
</p>
84+
</motion.div>
85+
86+
{/* Right Column: Contact Form */}
87+
<motion.div
88+
initial={{ opacity: 0, y: 40 }}
89+
whileInView={{ opacity: 1, y: 0 }}
90+
transition={{ delay: 0.3, duration: 0.8, ease: "easeInOut" }}
91+
className="flex w-full justify-center md:justify-end"
92+
>
93+
<Card className="w-full max-w-md bg-white/20 dark:bg-black/20 backdrop-blur-lg border border-white/30 shadow-2xl rounded-2xl">
94+
<CardHeader className="space-y-1 pt-6">
95+
<div className="flex justify-center md:hidden">
96+
<Image src={logo} alt="Script AI" width={60} height={60} />
97+
</div>
98+
<CardTitle className="text-2xl text-center text-slate-900 dark:text-white">
99+
Send Us a Message
100+
</CardTitle>
101+
</CardHeader>
102+
103+
<CardContent>
104+
<form onSubmit={handleSubmit} className="space-y-4">
105+
{formFields.map((field) => (
106+
<div key={field.name} className="space-y-2">
107+
<Label htmlFor={field.name} className="dark:text-slate-200">{field.label}</Label>
108+
<Input
109+
id={field.name}
110+
type={field.type}
111+
name={field.name}
112+
placeholder={field.placeholder}
113+
value={formData[field.name as keyof typeof formData]}
114+
onChange={handleChange}
115+
required
116+
className="bg-white/30 dark:bg-black/30 placeholder:text-slate-500 dark:placeholder:text-slate-400 focus-visible:ring-pink-500"
117+
/>
118+
</div>
119+
))}
120+
121+
<div className="space-y-2">
122+
<Label htmlFor="message" className="dark:text-slate-200">Message</Label>
123+
<Textarea
124+
id="message"
125+
name="message"
126+
value={formData.message}
127+
onChange={handleChange}
128+
required
129+
rows={4}
130+
placeholder="Write your message here..."
131+
className="bg-white/30 dark:bg-black/30 placeholder:text-slate-500 dark:placeholder:text-slate-400 focus-visible:ring-pink-500"
132+
/>
133+
</div>
134+
135+
<Button
136+
type="submit"
137+
className="w-full bg-slate-900 text-white hover:bg-slate-800 shadow-md"
138+
disabled={loading}
139+
>
140+
{loading ? "Sending..." : "Send Message"}
141+
</Button>
142+
</form>
143+
</CardContent>
144+
</Card>
145+
</motion.div>
146+
</div>
147+
</AuroraBackground>
148+
<Footer />
149+
</>
150+
)
151+
}

apps/web/components/footer.tsx

Lines changed: 3 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ const socialLinks = [
1818
];
1919

2020
const Footer = () => {
21-
const allLinks = Object.values(footerItems).flat();
2221
return (
2322
<footer className="bg-slate-100 dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800">
2423
<div className="max-w-7xl mx-auto px-6 lg:px-8 py-12">
@@ -28,40 +27,17 @@ const Footer = () => {
2827
<Image src={logo} alt="Creator AI Logo" width={40} height={40} />
2928
<span className="text-3xl font-bold text-slate-800 dark:text-slate-100">Creator AI</span>
3029
</div>
31-
<p className="text-sm text-slate-600 dark:text-slate-400 max-w-sm">
30+
<p className="text-sm text-slate-600 dark:text-slate-400 max-w-xs">
3231
Personalized AI assistant for content creators.
3332
</p>
34-
35-
36-
</div>
37-
38-
<nav className="flex flex-wrap justify-center gap-x-6 gap-y-2" aria-label="Footer">
39-
{allLinks.map((item) => (
40-
<Link
41-
key={item.name}
42-
href={item.href}
43-
className="text-sm text-slate-600 dark:text-slate-400 dark:hover:text-slate-100 transition-colors hover:text-purple-500"
44-
>
45-
{item.name}
46-
</Link>
47-
))}
48-
49-
<ReportIssue useIcon={false} />
50-
</nav>
51-
52-
<div className="relative mb-8 mt-6">
5333
<FloatingDock
54-
desktopClassName='bg-transparent'
34+
desktopClassName="bg-transparent"
5535
items={socialLinks.map((item) => ({
5636
title: item.name,
5737
icon: <item.icon className="h-5 w-5 text-slate-500 dark:text-slate-400 hover:text-purple-500" />,
5838
href: item.href,
5939
}))}
6040
/>
61-
62-
{/* <p className="text-sm max-w-sm mt-3">
63-
Connect with us: <a href="mailto:support@tryscriptai.com" className="text-purple-500 hover:underline">support@tryscriptai.com</a>
64-
</p> */}
6541
</div>
6642
<div className="border-t border-slate-200 dark:border-slate-700 w-full pt-8 text-sm text-slate-600 dark:text-slate-400 flex flex-col items-center gap-2">
6743
&copy; {new Date().getFullYear()} Creator AI. All rights reserved.
@@ -72,4 +48,4 @@ const Footer = () => {
7248
);
7349
};
7450

75-
export default Footer;
51+
export default Footer;

apps/web/middleware.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,13 @@ import type { NextRequest } from "next/server"
55
export async function middleware(request: NextRequest) {
66
const response = NextResponse.next()
77

8-
if (request.nextUrl.pathname.startsWith("/api/auth/callback") ||
9-
request.nextUrl.pathname.startsWith("/api/youtube/callback")) {
8+
if (request.nextUrl.pathname === "/api/auth/callback" ||
9+
request.nextUrl.pathname === "/api/track-referral" ||
10+
request.nextUrl.pathname === "/api/contact-us" ||
11+
request.nextUrl.pathname === "/api/report-issue" ||
12+
request.nextUrl.pathname.startsWith("/api/auth/callback") ||
13+
request.nextUrl.pathname.startsWith("/api/youtube/callback")
14+
) {
1015
return response
1116
}
1217

apps/web/tailwind.config.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,8 +258,10 @@ const config: Config = {
258258
'0%, 100%': { opacity: '0.5' },
259259
'50%': { opacity: '1' },
260260
},
261-
262-
},
261+
'scroll': {
262+
to: { transform: 'translate(calc(-50% - 0.5rem))' },
263+
},
264+
},
263265
animation: {
264266
'wobble': 'wobble 0.8s infinite',
265267
'accordion-down': 'accordion-down 0.2s ease-out',
@@ -286,7 +288,7 @@ const config: Config = {
286288
'shimmer': 'shimmer 2s linear infinite',
287289
'slow-pan': 'slow-pan 25s ease-in-out infinite alternate',
288290
'twinkle': 'twinkle 4s ease-in-out infinite',
289-
291+
'scroll': 'scroll var(--animation-duration, 40s) var(--animation-direction, forwards) linear infinite',
290292
}
291293
}
292294
},

packages/ui/src/utils/data.ts

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,17 @@
1-
interface NavItem {
2-
name: string
3-
href: string
4-
}
5-
6-
interface FooterSection {
7-
[category: string]: NavItem[]
8-
}
9-
10-
export const navItem: NavItem[] = [
11-
{ name: "Features", href: "#features" },
12-
{ name: "How It Works", href: "#how-it-works" },
13-
{ name: "Pricing", href: "#pricing" },
1+
export const navItem = [
2+
{ name: "Features", href: "/#features" },
3+
{ name: "How It Works", href: "/#how-it-works" },
4+
{ name: "Pricing", href: "/#pricing" },
145
]
156

167
export const footerItems: FooterSection = {
178
"Product": [
189
{ name: "Features", href: "./#features" },
1910
{ name: "Pricing", href: "./#pricing" },
20-
{ name: "Book a Call", href: "https://cal.com/afrin/30min" },
11+
{ name: "Contact Us", href: "/contact-us" },
12+
],
13+
"Company": [
14+
{ name: "About Us", href: "/about-us" },
2115
],
2216
"Account": [
2317
{ name: "Login", href: "/login" },

0 commit comments

Comments
 (0)