Seed: blog template (17 files)
This commit is contained in:
@@ -0,0 +1,136 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Separator } from "@/components/ui/separator";
|
||||||
|
import { Twitter, Github, Linkedin, Rss, Mail } from "lucide-react";
|
||||||
|
import { useSaasMutation } from "@/hooks/use-tygarun";
|
||||||
|
|
||||||
|
const categoryLinks = [
|
||||||
|
{ label: "Technology", to: "/category/technology" },
|
||||||
|
{ label: "Design", to: "/category/design" },
|
||||||
|
{ label: "Business", to: "/category/business" },
|
||||||
|
{ label: "Lifestyle", to: "/category/lifestyle" },
|
||||||
|
];
|
||||||
|
|
||||||
|
const quickLinks = [
|
||||||
|
{ label: "About", to: "/" },
|
||||||
|
{ label: "Contact", to: "/" },
|
||||||
|
{ label: "Privacy Policy", to: "/" },
|
||||||
|
{ label: "Terms of Service", to: "/" },
|
||||||
|
{ label: "RSS Feed", to: "/" },
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function Footer() {
|
||||||
|
const [email, setEmail] = useState("");
|
||||||
|
const [subscribed, setSubscribed] = useState(false);
|
||||||
|
const { mutate: subscribeNewsletter, loading: subscribing } = useSaasMutation("email", "/send/newsletter-confirm");
|
||||||
|
|
||||||
|
const handleSubscribe = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
if (!email) return;
|
||||||
|
try {
|
||||||
|
await subscribeNewsletter({ email });
|
||||||
|
setSubscribed(true);
|
||||||
|
toast.success("Subscribed! Check your inbox.");
|
||||||
|
} catch {
|
||||||
|
toast.error("Could not subscribe. Please try again.");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<footer className="bg-stone-900 text-white">
|
||||||
|
<div className="mx-auto max-w-7xl px-6 py-24">
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-4 gap-10">
|
||||||
|
{/* Brand */}
|
||||||
|
<div className="md:col-span-1">
|
||||||
|
<div className="flex items-center gap-2 mb-4">
|
||||||
|
<div className="h-8 w-8 rounded-lg bg-emerald-500 flex items-center justify-center">
|
||||||
|
<span className="text-white font-bold text-sm">B</span>
|
||||||
|
</div>
|
||||||
|
<span className="text-lg font-bold">ByteSize</span>
|
||||||
|
</div>
|
||||||
|
<p className="text-sm text-stone-400 leading-relaxed mb-6">
|
||||||
|
ByteSize is a modern publication exploring technology, design, business, and lifestyle through thoughtful long-form writing.
|
||||||
|
</p>
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<a href="#" className="h-8 w-8 rounded-full bg-stone-800 flex items-center justify-center text-stone-400 hover:text-white hover:bg-stone-700 transition-colors">
|
||||||
|
<Twitter className="h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
<a href="#" className="h-8 w-8 rounded-full bg-stone-800 flex items-center justify-center text-stone-400 hover:text-white hover:bg-stone-700 transition-colors">
|
||||||
|
<Github className="h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
<a href="#" className="h-8 w-8 rounded-full bg-stone-800 flex items-center justify-center text-stone-400 hover:text-white hover:bg-stone-700 transition-colors">
|
||||||
|
<Linkedin className="h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
<a href="#" className="h-8 w-8 rounded-full bg-stone-800 flex items-center justify-center text-stone-400 hover:text-white hover:bg-stone-700 transition-colors">
|
||||||
|
<Rss className="h-4 w-4" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Categories */}
|
||||||
|
<div>
|
||||||
|
<h4 className="font-semibold text-sm mb-4 text-stone-300 uppercase tracking-wider">Categories</h4>
|
||||||
|
<ul className="space-y-3">
|
||||||
|
{categoryLinks.map((link) => (
|
||||||
|
<li key={link.label}>
|
||||||
|
<Link to={link.to} className="text-sm text-stone-400 hover:text-white transition-colors">{link.label}</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Quick Links */}
|
||||||
|
<div>
|
||||||
|
<h4 className="font-semibold text-sm mb-4 text-stone-300 uppercase tracking-wider">Quick Links</h4>
|
||||||
|
<ul className="space-y-3">
|
||||||
|
{quickLinks.map((link) => (
|
||||||
|
<li key={link.label}>
|
||||||
|
<Link to={link.to} className="text-sm text-stone-400 hover:text-white transition-colors">{link.label}</Link>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{/* Newsletter */}
|
||||||
|
<div>
|
||||||
|
<h4 className="font-semibold text-sm mb-4 text-stone-300 uppercase tracking-wider">Newsletter</h4>
|
||||||
|
<p className="text-sm text-stone-400 mb-4">
|
||||||
|
Get the best articles delivered to your inbox weekly.
|
||||||
|
</p>
|
||||||
|
{subscribed ? (
|
||||||
|
<p className="text-sm text-emerald-400 font-medium">Subscribed! Check your inbox.</p>
|
||||||
|
) : (
|
||||||
|
<form onSubmit={handleSubscribe} className="flex gap-2">
|
||||||
|
<Input
|
||||||
|
type="email"
|
||||||
|
required
|
||||||
|
placeholder="your@email.com"
|
||||||
|
value={email}
|
||||||
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
|
className="bg-stone-800 border-stone-700 text-white placeholder:text-stone-500 focus-visible:ring-emerald-500 text-sm"
|
||||||
|
/>
|
||||||
|
<Button type="submit" disabled={subscribing} className="bg-emerald-600 hover:bg-emerald-700 active:scale-[0.98] text-white flex-shrink-0">
|
||||||
|
<Mail className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</form>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Separator className="my-10 bg-stone-800" />
|
||||||
|
|
||||||
|
<div className="flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||||
|
<p className="text-xs text-stone-500">
|
||||||
|
© 2025 ByteSize. All rights reserved.
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-stone-500">
|
||||||
|
Built with care for readers who love great writing.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</footer>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user