Footer 01
Footer 01 é um componente de layout para React e Tailwind CSS, da biblioteca Eldora UI, com licença MIT. Copia e cola no teu projeto.
Eldora UI
MIT
layout
O que é
Footer 01 é um componente de layout para React e Tailwind CSS, da biblioteca Eldora UI, com licença MIT. Copia e cola no teu projeto.
Como usar
Abre o componente no catálogo, carrega em copiar, e cola no teu projeto. O prompt copiado leva o código e as regras para o teu agente o reproduzir sem alterar nada.
Cinco cópias grátis por mês. Sem cartão.
Precisa de
npm i lucide-react
Licença
Este componente vem de Eldora UI e é redistribuído sob a licença MIT, que permite uso comercial. O aviso de copyright viaja com o código.
Footer 01
import { Footer } from "@/registry/blocks/footer-01/components/footer"
export default function Page() {
return (
<div className="flex min-h-screen w-full flex-col">
<Footer />
</div>
)
}
import Link from "next/link"
import { ChevronDownIcon, SquareArrowOutUpRightIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Icons } from "@/components/icons"
import { PingDot } from "@/components/ping-dot"
import { ThemeSwitcher } from "./theme-toggler"
const linksPro = [
{
group: "Product",
items: [
{
title: "AI",
href: "#",
},
{
title: "Enterprise",
href: "#",
},
{
title: "Fluid Compute",
href: "#",
},
{
title: "Next.js",
href: "#",
},
{
title: "Observability",
href: "#",
},
{
title: "Previews",
href: "#",
},
{
title: "Rendering",
href: "#",
},
{
title: "Security",
href: "#",
},
{
title: "Turbo",
href: "#",
},
{
title: "Domains",
href: "#",
},
],
},
]
const linksRes = [
{
group: "Resources",
items: [
{
title: "Docs",
href: "#",
},
{
title: "Guides",
href: "#",
},
{
title: "Academy",
href: "#",
},
{
title: "Help",
href: "#",
},
{
title: "Integrations",
href: "#",
},
{
title: "Pricing",
href: "#",
},
{
title: "Resources",
href: "#",
},
{
title: "Solution Partners",
href: "#",
},
{
title: "Startups",
href: "#",
},
{
title: "Templates",
href: "#",
},
],
},
]
const linksCom = [
{
group: "Company",
items: [
{
title: "About",
href: "#",
},
{
title: "Blog",
href: "#",
},
{
title: "Careers",
href: "#",
},
{
title: "Changelog",
href: "#",
},
{
title: "Contact Us",
href: "#",
},
{
title: "Customers",
href: "#",
},
{
title: "Events",
href: "#",
},
{
title: "Partners",
href: "#",
},
{
title: "Shipped",
href: "#",
},
{
title: "Privacy Policy",
href: "#",
},
],
},
]
export function Footer() {
return (
<footer className="py-16">
<div className="mx-auto max-w-6xl px-6">
<div className="">
<div className="grid grid-cols-2 gap-14 md:grid-cols-3 lg:grid-cols-5">
<div className="grid gap-3">
{linksPro.map((link, index) => (
<div key={index} className="space-y-3 text-sm">
<span className="block font-medium">{link.group}</span>
{link.items.map((item, index) => (
<Link
key={index}
href={item.href}
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span>{item.title}</span>
</Link>
))}
<Link
href={"#"}
className="text-muted-foreground flex items-center gap-1 text-sm duration-150 hover:text-cyan-500"
>
v0
<SquareArrowOutUpRightIcon strokeWidth={2} size={16} />
</Link>
</div>
))}
</div>
<div className="grid gap-3">
{linksRes.map((link, index) => (
<div key={index} className="space-y-3 text-sm">
<span className="block font-medium">{link.group}</span>
<Link
href={"#"}
className="text-muted-foreground flex items-center gap-1 text-sm duration-150 hover:text-cyan-500"
>
Community
<SquareArrowOutUpRightIcon strokeWidth={2} size={16} />
</Link>
{link.items.map((item, index) => (
<Link
key={index}
href={item.href}
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span>{item.title}</span>
</Link>
))}
<DropdownMenu>
<DropdownMenuTrigger className="text-muted-foreground flex items-center gap-1 text-sm hover:text-cyan-500">
SDKs by Vercel{" "}
<ChevronDownIcon strokeWidth={2} size={16} />
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="end"
className="w-60 p-1"
>
<DropdownMenuItem className="h-10 px-4">
AI SDK{" "}
<SquareArrowOutUpRightIcon strokeWidth={2} size={16} />
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Flags SDK{" "}
<SquareArrowOutUpRightIcon strokeWidth={2} size={16} />
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Chat SDK{" "}
<SquareArrowOutUpRightIcon strokeWidth={2} size={16} />
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Streamdown AI{" "}
<SquareArrowOutUpRightIcon strokeWidth={2} size={16} />
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
))}
</div>
<div className="grid gap-3">
{linksCom.map((link, index) => (
<div key={index} className="space-y-3 text-sm">
<span className="block font-medium">{link.group}</span>
{link.items.map((item, index) => (
<Link
key={index}
href={item.href}
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span>{item.title}</span>
</Link>
))}
<DropdownMenu>
<DropdownMenuTrigger className="text-muted-foreground flex items-center gap-1 text-sm hover:text-cyan-500">
Legal <ChevronDownIcon strokeWidth={2} size={16} />
</DropdownMenuTrigger>
<DropdownMenuContent
side="top"
align="end"
className="w-60 p-1"
>
<DropdownMenuItem className="h-10 px-4">
Cookie Policy
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Cookie Preferences
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
DMCA Policy
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
DORA Addendum
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
DPA
</DropdownMenuItem>
<DropdownMenuItem className="h-16 px-4">
Domain Name Registration and Services Terms
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Event Code of Conduct
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Event Terms and Conditions
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Inactivity Policy
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Job Applicant Privacy Notice
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Privacy Policy
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
SLA
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Sub-processors
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Support Terms
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Terms of Service
</DropdownMenuItem>
<DropdownMenuItem className="h-10 px-4">
Trademark Policy
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div>
))}
</div>
<div className="grid gap-3">
<div className="space-y-3 text-sm">
<span className="block font-medium">Social</span>
<Link
href="#"
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span className="flex items-center gap-2">Github</span>
</Link>
<Link
href="#"
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span className="flex items-center gap-2">LinkedIn</span>
</Link>
<Link
href="#"
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span className="flex items-center gap-2">Twitter</span>
</Link>
<Link
href="#"
className="text-muted-foreground block duration-150 hover:text-cyan-500"
>
<span className="flex items-center gap-2">YouTube</span>
</Link>
</div>
</div>
</div>
</div>
<div className="mt-10 flex flex-wrap items-end justify-between gap-6 py-6">
<Button
className="cursor-pointer text-cyan-500 hover:text-cyan-500"
variant={"ghost"}
>
<PingDot />
All systems normal.
</Button>
<ThemeSwitcher />
</div>
</div>
</footer>
)
}
"use client"
import { useCallback, useEffect, useState } from "react"
import { MonitorIcon, MoonIcon, SunIcon } from "lucide-react"
import { useTheme } from "next-themes"
import { cn } from "@/lib/utils"
const themes = [
{
key: "system",
icon: MonitorIcon,
label: "System theme",
},
{
key: "light",
icon: SunIcon,
label: "Light theme",
},
{
key: "dark",
icon: MoonIcon,
label: "Dark theme",
},
]
export type ThemeSwitcherProps = {
value?: "light" | "dark" | "system"
onChange?: (theme: "light" | "dark" | "system") => void
defaultValue?: "light" | "dark" | "system"
className?: string
}
export const ThemeSwitcher = ({ className }: ThemeSwitcherProps) => {
const { theme, setTheme } = useTheme()
const [mounted, setMounted] = useState(false)
const handleThemeClick = useCallback(
(themeKey: "light" | "dark" | "system") => {
setTheme(themeKey)
},
[setTheme]
)
// Prevent hydration mismatch
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
return (
<div
className={cn(
"bg-background ring-border relative isolate flex h-7 rounded-full p-1 ring-1",
className
)}
>
{themes.map(({ key, icon: Icon, label }) => {
const isActive = theme === key
return (
<button
aria-label={label}
className="relative h-5 w-6 rounded-full"
key={key}
onClick={() => handleThemeClick(key as "light" | "dark" | "system")}
type="button"
>
{isActive && (
<div className="bg-secondary absolute inset-0 rounded-full" />
)}
<Icon
className={cn(
"relative z-10 m-auto h-3.5 w-3.5",
isActive ? "text-foreground" : "text-muted-foreground"
)}
/>
</button>
)
})}
</div>
)
}