diff --git a/web/src/app/icons/page.tsx b/web/src/app/icons/page.tsx index ae8f4b5a..0b12ce33 100644 --- a/web/src/app/icons/page.tsx +++ b/web/src/app/icons/page.tsx @@ -52,19 +52,14 @@ export const dynamic = "force-static" export default async function IconsPage() { const icons = await getIconsArray() return ( -
-
-
-
-
-

Browse icons

-

Search through our collection of {icons.length} beautiful icons.

-
-
- - +
+
+
+

Browse icons

+

Search through our collection of {icons.length} beautiful icons.

+
) } diff --git a/web/src/components/footer.tsx b/web/src/components/footer.tsx index 2395d748..5ffdb603 100644 --- a/web/src/components/footer.tsx +++ b/web/src/components/footer.tsx @@ -1,36 +1,12 @@ -"use client" - import { REPO_PATH } from "@/constants" -import { motion } from "framer-motion" -import { ExternalLink, Heart } from "lucide-react" +import { ExternalLink } from "lucide-react" import Link from "next/link" -import { useState } from "react" - -// Pre-define unique IDs for animations to avoid using array indices as keys -const HOVER_HEART_IDS = [ - "hover-heart-1", - "hover-heart-2", - "hover-heart-3", - "hover-heart-4", - "hover-heart-5", - "hover-heart-6", - "hover-heart-7", - "hover-heart-8", -] -const BURST_HEART_IDS = ["burst-heart-1", "burst-heart-2", "burst-heart-3", "burst-heart-4", "burst-heart-5"] +import { HeartEasterEgg } from "./heart" export function Footer() { - const [isHeartHovered, setIsHeartHovered] = useState(false) - const [isHeartFilled, setIsHeartFilled] = useState(false) - - // Toggle heart fill state and add extra mini hearts on click - const handleHeartClick = () => { - setIsHeartFilled(!isHeartFilled) - } - return (
-
+
@@ -53,117 +29,9 @@ export function Footer() {
- +

Community

-
- Made with{" "} -
- setIsHeartHovered(true)} - onMouseLeave={() => setIsHeartHovered(false)} - onClick={handleHeartClick} - whileTap={{ scale: 0.85 }} - > - - - - - - {/* Easter egg mini hearts */} - {isHeartHovered && ( - <> - {HOVER_HEART_IDS.map((id, i) => ( - - - - ))} - - {/* Subtle particle glow */} - - - )} - - {/* Heart fill animation extras */} - {isHeartFilled && ( - <> - {/* Radiating circles on heart fill */} - - - {/* Extra burst of mini hearts when filled */} - {BURST_HEART_IDS.map((id, i) => ( - - - - ))} - - )} -
{" "} - by Homarr Labs and the open source community. -
+ - +
diff --git a/web/src/components/header.tsx b/web/src/components/header.tsx index 48d4ad99..2551d556 100644 --- a/web/src/components/header.tsx +++ b/web/src/components/header.tsx @@ -12,12 +12,7 @@ import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/t export function Header() { return ( - +
@@ -54,6 +49,6 @@ export function Header() {
- +
) } diff --git a/web/src/components/heart.tsx b/web/src/components/heart.tsx new file mode 100644 index 00000000..896baff5 --- /dev/null +++ b/web/src/components/heart.tsx @@ -0,0 +1,121 @@ +"use client" + +import { Heart } from "lucide-react" + +import { motion } from "framer-motion" +import { useState } from "react" + +export function HeartEasterEgg() { + const [isHeartHovered, setIsHeartHovered] = useState(false) + const [isHeartFilled, setIsHeartFilled] = useState(false) + + const handleHeartClick = () => { + setIsHeartFilled(!isHeartFilled) + } + + return ( +
+ Made with{" "} +
+ setIsHeartHovered(true)} + onMouseLeave={() => setIsHeartHovered(false)} + onClick={handleHeartClick} + whileTap={{ scale: 0.85 }} + > + + + + + + {/* Easter egg mini hearts */} + {isHeartHovered && ( + <> + {[...Array(8)].map((_, i) => ( + + + + ))} + + {/* Subtle particle glow */} + + + )} + + {/* Heart fill animation extras */} + {isHeartFilled && ( + <> + {/* Radiating circles on heart fill */} + + + {/* Extra burst of mini hearts when filled */} + {[...Array(8)].map((_, i) => ( + + + + ))} + + )} +
{" "} + by Homarr Labs and the open source community. +
+ ) +} diff --git a/web/src/components/icon-card.tsx b/web/src/components/icon-card.tsx index cc3ea24d..bcd02316 100644 --- a/web/src/components/icon-card.tsx +++ b/web/src/components/icon-card.tsx @@ -11,7 +11,7 @@ export function IconCard({ }: { name: string data: Icon - matchedAlias?: string | null + matchedAlias?: string }) { return ( diff --git a/web/src/components/icon-grid.tsx b/web/src/components/icon-grid.tsx index 241b069f..f406cab7 100644 --- a/web/src/components/icon-grid.tsx +++ b/web/src/components/icon-grid.tsx @@ -9,13 +9,10 @@ interface IconsGridProps { export function IconsGrid({ filteredIcons, matchedAliases }: IconsGridProps) { return ( - <> -
- {filteredIcons.slice(0, 120).map(({ name, data }) => ( - - ))} -
- {filteredIcons.length > 120 &&

And {filteredIcons.length - 120} more...

} - +
+ {filteredIcons.slice(0, 120).map(({ name, data }) => ( + + ))} +
) }