feat: enhance footer with social links and horizontal mode toggle
This commit is contained in:
parent
c83bd1ca6a
commit
28f4fc8880
@ -10,6 +10,8 @@ import type * as React from "react";
|
||||
import Container from "@/components/container";
|
||||
import { Logo } from "@/components/logo";
|
||||
import BuiltWithButton from "@/components/shared/built-with-button";
|
||||
import { ModeToggleHorizontal } from "@/components/layout/mode-toggle-horizontal";
|
||||
import { ModeToggle } from "./mode-toggle";
|
||||
|
||||
export function Footer({ className }: React.HTMLAttributes<HTMLElement>) {
|
||||
const { theme } = useTheme();
|
||||
@ -29,8 +31,80 @@ export function Footer({ className }: React.HTMLAttributes<HTMLElement>) {
|
||||
<p className="text-muted-foreground text-base p4-4 md:pr-12">
|
||||
{siteConfig.tagline}
|
||||
</p>
|
||||
|
||||
|
||||
<BuiltWithButton />
|
||||
|
||||
{/* social links */}
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
{siteConfig.links.github && (
|
||||
<Link
|
||||
href={siteConfig.links.github}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="GitHub"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.github className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.twitter && (
|
||||
<Link
|
||||
href={siteConfig.links.twitter}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Twitter"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.twitter className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.twitter_cn && (
|
||||
<Link
|
||||
href={siteConfig.links.twitter_cn}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Twitter(CN)"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.twitter className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.bluesky && (
|
||||
<Link
|
||||
href={siteConfig.links.bluesky}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Bluesky"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.bluesky className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.youtube && (
|
||||
<Link
|
||||
href={siteConfig.links.youtube}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="YouTube"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.youtube className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.mail && (
|
||||
<Link
|
||||
href={`mailto:${siteConfig.mail}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Email"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.email className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -69,76 +143,7 @@ export function Footer({ className }: React.HTMLAttributes<HTMLElement>) {
|
||||
© {new Date().getFullYear()} All Rights Reserved.
|
||||
</span>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="flex items-center gap-2">
|
||||
{siteConfig.links.github && (
|
||||
<Link
|
||||
href={siteConfig.links.github}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="GitHub"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.github className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.twitter && (
|
||||
<Link
|
||||
href={siteConfig.links.twitter}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Twitter"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.twitter className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.twitter_cn && (
|
||||
<Link
|
||||
href={siteConfig.links.twitter_cn}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Twitter(CN)"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.twitter className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.bluesky && (
|
||||
<Link
|
||||
href={siteConfig.links.bluesky}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Bluesky"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.bluesky className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.links.youtube && (
|
||||
<Link
|
||||
href={siteConfig.links.youtube}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="YouTube"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.youtube className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
{siteConfig.mail && (
|
||||
<Link
|
||||
href={`mailto:${siteConfig.mail}`}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label="Email"
|
||||
className="inline-flex h-8 w-8 items-center justify-center rounded-md hover:bg-accent hover:text-accent-foreground"
|
||||
>
|
||||
<Icons.email className="size-4" aria-hidden="true" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<ModeToggleHorizontal />
|
||||
</Container>
|
||||
</div>
|
||||
</footer>
|
||||
|
70
src/components/layout/mode-toggle-horizontal.tsx
Normal file
70
src/components/layout/mode-toggle-horizontal.tsx
Normal file
@ -0,0 +1,70 @@
|
||||
"use client";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { LaptopIcon, MoonIcon, SunIcon } from "lucide-react";
|
||||
import { useTheme } from "next-themes";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export function ModeToggleHorizontal() {
|
||||
const { theme, setTheme } = useTheme();
|
||||
const [mounted, setMounted] = useState(false);
|
||||
|
||||
// Only show the UI after hydration to prevent hydration mismatch
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
if (!mounted) {
|
||||
return (
|
||||
<div className="flex items-center gap-2 rounded-full border bg-background p-1">
|
||||
<div className="size-6 px-0 rounded-full" />
|
||||
<div className="size-6 px-0 rounded-full" />
|
||||
<div className="size-6 px-0 rounded-full" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="flex items-center gap-2 rounded-full border bg-background p-1">
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={cn(
|
||||
"size-6 px-0 rounded-full",
|
||||
theme === "light" && "bg-muted text-foreground"
|
||||
)}
|
||||
onClick={() => setTheme("light")}
|
||||
aria-label="Light mode"
|
||||
>
|
||||
<SunIcon className="size-4" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={cn(
|
||||
"size-6 px-0 rounded-full",
|
||||
theme === "dark" && "bg-muted text-foreground"
|
||||
)}
|
||||
onClick={() => setTheme("dark")}
|
||||
aria-label="Dark mode"
|
||||
>
|
||||
<MoonIcon className="size-4" />
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={cn(
|
||||
"size-6 px-0 rounded-full",
|
||||
theme === "system" && "bg-muted text-foreground"
|
||||
)}
|
||||
onClick={() => setTheme("system")}
|
||||
aria-label="System mode"
|
||||
>
|
||||
<LaptopIcon className="size-4" />
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
@ -28,7 +28,7 @@ import { authClient } from "@/lib/auth-client";
|
||||
export function UserButton() {
|
||||
const { data: session, error } = authClient.useSession();
|
||||
const user = session?.user;
|
||||
console.log('UserButton, user:', user);
|
||||
// console.log('UserButton, user:', user);
|
||||
// if (error) {
|
||||
// console.error("UserButton, error:", error);
|
||||
// return (
|
||||
|
@ -23,8 +23,8 @@ export const siteConfig: SiteConfig = {
|
||||
links: {
|
||||
twitter: "https://x.com/javay_hu",
|
||||
bluesky: "https://bsky.app/profile/javayhu.com",
|
||||
github: "https://github.com/MkSaaS",
|
||||
youtube: "https://www.youtube.com/@MkSaaS",
|
||||
github: "https://github.com/MkSaaSHQ",
|
||||
youtube: "https://www.youtube.com/@MkSaaSHQ",
|
||||
docs: "https://docs.mksaas.com",
|
||||
demo: "https://demo.mksaas.com",
|
||||
studio: "https://demo.mksaas.com/studio",
|
||||
|
Loading…
Reference in New Issue
Block a user