Skip to content

Commit c1bdc12

Browse files
committed
feat: enhance ContactPage layout and add Footer component with ripple effect
1 parent c768e70 commit c1bdc12

2 files changed

Lines changed: 53 additions & 57 deletions

File tree

src/app/contact/page.tsx

Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { Textarea, LoadingSpinner } from "@components/ui";
1111
import { useState, FormEvent, useCallback } from "react";
1212
import { Send, AlertCircle } from "lucide-react";
1313
import { cn } from "@lib/utils";
14+
import Footer from '../../components/layouts/footer';
1415

1516
const BorderBeam = dynamic(() => import("@components/ui/border-beam").then(mod => ({ default: mod.BorderBeam })));
1617
const GridPattern = dynamic(() => import("@components/ui/grid-pattern").then(mod => ({ default: mod.GridPattern })));
@@ -132,8 +133,8 @@ export default function ContactPage() {
132133

133134
return (
134135
<>
135-
<NavigationBar/>
136-
<ContactHero/>
136+
<NavigationBar />
137+
<ContactHero />
137138
<main className="relative pt-24 bg-linear-to-b from-background via-muted/30 to-background">
138139
<div className="absolute inset-0 pointer-events-none" aria-hidden="true">
139140
<GridPattern
@@ -145,10 +146,10 @@ export default function ContactPage() {
145146
className={"mask-[radial-gradient(300px_circle_at_center,white,transparent)] absolute w-full "}
146147
/>
147148
</div>
148-
<div className="absolute overflow-hidden inset-0 pointer-events-none" aria-hidden="true">
149+
{/* <div className="absolute overflow-hidden inset-0 pointer-events-none" aria-hidden="true">
149150
<Ripple mainCircleSize={300} numCircles={10} className="opacity-30"/>
150-
</div>
151-
<BlurFade delay={0.2} className="max-w-3xl mx-auto px-4 sm:px-6 lg:px-8">
151+
</div> */}
152+
<BlurFade delay={0.2} className="max-w-3xl mx-auto px-4 sm:px-6 mb-20 lg:px-8">
152153
<div>
153154
{/* Contact Form */}
154155
<div className="translate-y-2">
@@ -177,26 +178,27 @@ export default function ContactPage() {
177178
</div>
178179
)}
179180

180-
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6"> <div className="space-y-2">
181-
<Label htmlFor="name">Your Name</Label>
182-
<Input
183-
id="name"
184-
name="name"
185-
placeholder="John Doe"
186-
required
187-
value={formData.name}
188-
onChange={handleChange}
189-
className={cn(formErrors.name ? "border-destructive ring-primary" : "", "rounded-xl bg-transparent")}
190-
aria-invalid={Boolean(formErrors.name)}
191-
/>
192-
{formErrors.name && (
193-
<p className="text-sm text-destructive flex items-center gap-1 mt-1">
194-
<AlertCircle className="h-3 w-3" />
195-
{formErrors.name}
196-
</p>
197-
)}
198-
</div>
199-
<div className="space-y-2">
181+
<div className="grid grid-cols-1 sm:grid-cols-2 gap-6">
182+
<div className="gap-3 flex flex-col">
183+
<Label htmlFor="name">Your Name</Label>
184+
<Input
185+
id="name"
186+
name="name"
187+
placeholder="John Doe"
188+
required
189+
value={formData.name}
190+
onChange={handleChange}
191+
className={cn(formErrors.name ? "border-destructive ring-primary" : "", "rounded-xl bg-transparent")}
192+
aria-invalid={Boolean(formErrors.name)}
193+
/>
194+
{formErrors.name && (
195+
<p className="text-sm text-destructive flex items-center gap-1 mt-1">
196+
<AlertCircle className="h-3 w-3" />
197+
{formErrors.name}
198+
</p>
199+
)}
200+
</div>
201+
<div className="gap-3 flex flex-col">
200202
<Label htmlFor="email">Your Email</Label>
201203
<Input
202204
id="email"
@@ -216,9 +218,10 @@ export default function ContactPage() {
216218
</p>
217219
)}
218220
</div>
221+
219222
</div>
220223

221-
<div className="space-y-2">
224+
<div className="gap-3 flex flex-col">
222225
<Label htmlFor="subject">Subject</Label>
223226
<Input
224227
id="subject"
@@ -238,7 +241,7 @@ export default function ContactPage() {
238241
)}
239242
</div>
240243

241-
<div className="space-y-2">
244+
<div className="gap-3 flex flex-col">
242245
<Label htmlFor="message">Your Message</Label>
243246
<Textarea
244247
id="message"
@@ -248,7 +251,7 @@ export default function ContactPage() {
248251
required
249252
value={formData.message}
250253
onChange={handleChange}
251-
className={cn(formErrors.message ? "border-destructive ring-primary" : "", "rounded-xl bg-transparent")}
254+
className={cn("resize-none", formErrors.message ? "border-destructive ring-primary" : "", "rounded-xl bg-transparent")}
252255
aria-invalid={Boolean(formErrors.message)}
253256
/>
254257
{formErrors.message && (
@@ -261,7 +264,7 @@ export default function ContactPage() {
261264
<Button
262265
type="submit"
263266
variant="default"
264-
className="w-full sm:w-auto rounded-full"
267+
className="w-full mx-auto border sm:w-auto rounded-full"
265268
disabled={isSubmitting}
266269
>
267270
{isSubmitting ? (
@@ -294,6 +297,8 @@ export default function ContactPage() {
294297
</div>
295298
</div>
296299
</BlurFade>
300+
301+
<Footer />
297302
</main>
298303
</>
299304
);

src/components/layouts/footer.tsx

Lines changed: 19 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { GitHubIcon } from "../icons/github";
1212
// import { TwitterLogoIcon } from "@radix-ui/react-icons";
1313
import { ArrowRightIcon, MailCheckIcon } from "lucide-react";
1414
import { Button } from "../ui";
15+
import { Ripple } from "../ui/ripple";
1516
// import { Github, Linkedin, Twitter, Mail } from "lucide-react";
1617

1718
const footerLinks = {
@@ -55,20 +56,17 @@ export default function Footer() {
5556

5657
return (
5758
<footer className="w-full border-t sm:px-3 border-border/40 bg-linear-to-b from-background via-background/95 to-background backdrop-blur supports-backdrop-filter:bg-background/60">
58-
<div className="max-w-5xl mx-auto max-sm:px-5 py-12 md:py-16">
59-
{/* Main Footer Content */}
60-
<div className="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-5 gap-8 md:gap-12 mb-12 md:px-5">
61-
{/* Brand Section */}
62-
<div className="col-span-2 md:col-span-4 lg:col-span-1 space-y-4">
63-
<Link href="/" className="inline-block group">
64-
<h2 className="text-xl font-bold text-primary group-hover:text-primary transition-colors">Sophat L.</h2>
65-
</Link>
66-
<p className="text-sm text-muted-foreground max-w-xs leading-relaxed"> Building scalable systems & crafting digital experiences. </p>
67-
</div>
6859

60+
<div className="absolute overflow-hidden inset-0 pointer-events-none" aria-hidden="true">
61+
<Ripple mainCircleSize={150} numCircles={12} className="opacity-30" />
62+
</div>
63+
64+
<div className="max-w-5xl mx-auto max-sm:px-5 py-12">
65+
{/* Main Footer Content */}
66+
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 md:gap-12 mb-12 md:px-5">
6967
{/* Product Links */}
7068
<div className="space-y-4">
71-
<h3 className="font-semibold text-base text-primary sm:pl-2">Product</h3>
69+
<h3 className="font-semibold text-base text-primary sm:pl-1">Product</h3>
7270
<ul className="max-sm:gap-2 flex flex-col">
7371
{footerLinks.product.map((link) => (
7472
<li key={link.href}>
@@ -84,7 +82,7 @@ export default function Footer() {
8482

8583
{/* Company Links */}
8684
<div className="space-y-4">
87-
<h3 className="font-semibold text-base text-primary sm:pl-2">Company</h3>
85+
<h3 className="font-semibold text-base text-primary sm:pl-1">Company</h3>
8886
<ul className="max-sm:gap-2 flex flex-col">
8987
{footerLinks.company.map((link) => (
9088
<li key={link.href}>
@@ -100,7 +98,7 @@ export default function Footer() {
10098

10199
{/* Resources Links */}
102100
<div className="space-y-4">
103-
<h3 className="font-semibold text-base text-primary sm:pl-2">Resources</h3>
101+
<h3 className="font-semibold text-base text-primary sm:pl-1">Resources</h3>
104102
<ul className="max-sm:gap-2 flex flex-col">
105103
{footerLinks.resources.map((link) => (
106104
<li key={link.href}>
@@ -116,7 +114,7 @@ export default function Footer() {
116114

117115
{/* Social Links */}
118116
<div className="space-y-4">
119-
<h3 className="font-semibold text-base sm:pl-2 text-primary">Social</h3>
117+
<h3 className="font-semibold text-base sm:pl-1 text-primary">Social</h3>
120118
<ul className="max-sm:gap-2 flex flex-col">
121119
{socialLinks.map((link) => {
122120
const Icon = link.icon;
@@ -136,20 +134,13 @@ export default function Footer() {
136134
</div>
137135

138136
{/* Bottom Bar */}
139-
<div className="pt-8 border-t border-border/40">
140-
<div className="flex flex-col md:flex-row justify-between items-center gap-4 sm:px-5">
141-
<div className="flex items-center gap-2">
142-
<p className="text-sm text-muted-foreground text-center md:text-left">
143-
Copyright © {currentYear}{" "}
144-
<Link
145-
href="/"
146-
className="font-semibold text-foreground hover:text-primary transition-colors"
147-
>
148-
{appTitle}
149-
</Link>
150-
{" "}· All rights reserved
151-
</p>
152-
</div>
137+
<div className="pt-8 border-t border-border/40 bg-background">
138+
<div className="flex flex-col md:flex-row justify-center items-center gap-4 sm:px-5">
139+
<p className="text-sm text-muted-foreground text-center md:text-left">
140+
Copyright © {currentYear}{" "}
141+
<Link href="/" className="font-semibold text-foreground hover:text-primary transition-colors" > {appTitle} </Link>
142+
{" "}· All rights reserved
143+
</p>
153144

154145
{/* <div className="flex items-center gap-6">
155146
<Link

0 commit comments

Comments
 (0)