From ad849b8debb76687fc5ad9d377a16959c864002e Mon Sep 17 00:00:00 2001 From: Thomas Camlong Date: Thu, 17 Apr 2025 15:42:07 +0200 Subject: [PATCH] styling --- web/src/app/icons/components/icon-search.tsx | 23 --- web/src/app/page.tsx | 12 +- web/src/components/hero.tsx | 159 +++++++++++------- .../magicui/interactive-hover-button.tsx | 7 +- web/src/constants.ts | 1 + 5 files changed, 114 insertions(+), 88 deletions(-) diff --git a/web/src/app/icons/components/icon-search.tsx b/web/src/app/icons/components/icon-search.tsx index cb534905..0aa979b1 100644 --- a/web/src/app/icons/components/icon-search.tsx +++ b/web/src/app/icons/components/icon-search.tsx @@ -19,7 +19,6 @@ import { Input } from "@/components/ui/input" import { Separator } from "@/components/ui/separator" import { BASE_URL } from "@/constants" import type { Icon, IconSearchProps } from "@/types/icons" -import { useInView } from "framer-motion" import { ArrowDownAZ, ArrowUpZA, Calendar, Filter, Search, SortAsc, X } from "lucide-react" import { useTheme } from "next-themes" import Image from "next/image" @@ -420,28 +419,6 @@ function IconCard({ data: Icon matchedAlias?: string | null }) { - const ref = useRef(null) - const isInView = useInView(ref, { - once: false, - amount: 0.2, - margin: "100px 0px", - }) - - const variants = { - hidden: { opacity: 0, y: 20, scale: 0.95 }, - visible: { - opacity: 1, - y: 0, - scale: 1, - transition: { duration: 0.4, ease: [0.25, 0.1, 0.25, 1.0] }, - }, - exit: { - opacity: 0, - y: -10, - scale: 0.98, - transition: { duration: 0.3, ease: [0.25, 0.1, 0.25, 1.0] }, - }, - } return ( diff --git a/web/src/app/page.tsx b/web/src/app/page.tsx index b48b12f9..4553c0f0 100644 --- a/web/src/app/page.tsx +++ b/web/src/app/page.tsx @@ -1,6 +1,6 @@ import { HeroSection } from "@/components/hero" import { RecentlyAddedIcons } from "@/components/recently-added-icons" -import { BASE_URL } from "@/constants" +import { BASE_URL, REPO_NAME, REPO_PATH } from "@/constants" import { getRecentlyAddedIcons, getTotalIcons } from "@/lib/api" import type { Metadata } from "next" @@ -37,13 +37,21 @@ export async function generateMetadata(): Promise { } } +async function getGitHubStars() { + const response = await fetch(`https://api.github.com/repos/${REPO_NAME}`) + const data = await response.json() + console.log(`GitHub stars: ${data.stargazers_count}`) + return data.stargazers_count +} + export default async function Home() { const { totalIcons } = await getTotalIcons() const recentIcons = await getRecentlyAddedIcons(10) + const stars = await getGitHubStars() return (
- +
) diff --git a/web/src/components/hero.tsx b/web/src/components/hero.tsx index 28e4d097..0ffc83e8 100644 --- a/web/src/components/hero.tsx +++ b/web/src/components/hero.tsx @@ -1,20 +1,19 @@ -"use client" +"use client"; -import { Button } from "@/components/ui/button" -import { Card } from "@/components/ui/card" -import { Input } from "@/components/ui/input" -import { cn } from "@/lib/utils" -import { motion, useAnimation, useInView } from "framer-motion" -import { Github, Heart, Search } from "lucide-react" -import Link from "next/link" -import { useEffect, useRef, useState } from "react" -import { AnimatedShinyText } from "./magicui/animated-shiny-text" -import { AuroraText } from "./magicui/aurora-text" -import { InteractiveHoverButton } from "./magicui/interactive-hover-button" +import { Button } from "@/components/ui/button"; +import { Card } from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { cn } from "@/lib/utils"; +import { motion, useAnimation, useInView } from "framer-motion"; +import { DollarSign, Heart, Search, Star } from "lucide-react"; +import Link from "next/link"; +import { useEffect, useRef, useState } from "react"; +import { AuroraText } from "./magicui/aurora-text"; +import { InteractiveHoverButton } from "./magicui/interactive-hover-button"; interface IconCardProps { - name: string - imageUrl: string + name: string; + imageUrl: string; } function IconCard({ name, imageUrl }: IconCardProps) { @@ -23,9 +22,11 @@ function IconCard({ name, imageUrl }: IconCardProps) {
{name}
-

{name}

+

+ {name} +

- ) + ); } function ElegantShape({ @@ -38,28 +39,28 @@ function ElegantShape({ mobileWidth, mobileHeight, }: { - className?: string - delay?: number - width?: number - height?: number - rotate?: number - gradient?: string - mobileWidth?: number - mobileHeight?: number + className?: string; + delay?: number; + width?: number; + height?: number; + rotate?: number; + gradient?: string; + mobileWidth?: number; + mobileHeight?: number; }) { - const controls = useAnimation() - const [isMobile, setIsMobile] = useState(false) - const ref = useRef(null) - const isInView = useInView(ref, { once: true, amount: 0.1 }) + const controls = useAnimation(); + const [isMobile, setIsMobile] = useState(false); + const ref = useRef(null); + const isInView = useInView(ref, { once: true, amount: 0.1 }); useEffect(() => { const checkMobile = () => { - setIsMobile(window.innerWidth < 768) - } - checkMobile() - window.addEventListener("resize", checkMobile) - return () => window.removeEventListener("resize", checkMobile) - }, []) + setIsMobile(window.innerWidth < 768); + }; + checkMobile(); + window.addEventListener("resize", checkMobile); + return () => window.removeEventListener("resize", checkMobile); + }, []); useEffect(() => { if (isInView) { @@ -76,9 +77,9 @@ function ElegantShape({ ease: [0.23, 0.86, 0.39, 0.96], opacity: { duration: 1.2 }, }, - }) + }); } - }, [controls, delay, isInView, rotate]) + }, [controls, delay, isInView, rotate]); return ( - ) + ); } -export function HeroSection({ totalIcons }: { totalIcons: number }) { - const [searchQuery, setSearchQuery] = useState("") +export function HeroSection({ + totalIcons, + stars, +}: { totalIcons: number; stars: number }) { + const [searchQuery, setSearchQuery] = useState(""); return (
@@ -189,26 +193,40 @@ export function HeroSection({ totalIcons }: { totalIcons: number }) {
- + - Made with love by Homarr Labs + + Made with love by Homarr Labs +

Your definitive source for
- dashboard icons + + dashboard icons +

- +

- A collection of {totalIcons} curated icons for services, applications and tools, - designed specifically for dashboards and app directories. + A collection of {totalIcons}{" "} + curated icons for services, applications and tools, designed + specifically for dashboards and app directories.

@@ -216,12 +234,17 @@ export function HeroSection({ totalIcons }: { totalIcons: number }) { custom={3} className="flex flex-col items-center gap-4 md:gap-6 mb-8 md:mb-12 motion-safe:motion-preset-slide-up motion-duration-1500" > -
+ setSearchQuery(e.target.value)} /> @@ -235,19 +258,35 @@ export function HeroSection({ totalIcons }: { totalIcons: number }) {
- Explore icons + + Explore icons + + + + + + {/* Give us money */} + + -
@@ -255,5 +294,5 @@ export function HeroSection({ totalIcons }: { totalIcons: number }) {
- ) + ); } diff --git a/web/src/components/magicui/interactive-hover-button.tsx b/web/src/components/magicui/interactive-hover-button.tsx index bd72e24d..a8432139 100644 --- a/web/src/components/magicui/interactive-hover-button.tsx +++ b/web/src/components/magicui/interactive-hover-button.tsx @@ -1,13 +1,14 @@ import { cn } from "@/lib/utils" import { ArrowRight } from "lucide-react" import React from "react" +import { Button } from "../ui/button" interface InteractiveHoverButtonProps extends React.ButtonHTMLAttributes {} export const InteractiveHoverButton = React.forwardRef( ({ children, className, ...props }, ref) => { return ( -
-
+
{children}
- + ) }, ) diff --git a/web/src/constants.ts b/web/src/constants.ts index 47018799..36800875 100644 --- a/web/src/constants.ts +++ b/web/src/constants.ts @@ -2,3 +2,4 @@ export const BASE_URL = "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons export const REPO_PATH = "https://github.com/homarr-labs/dashboard-icons" export const METADATA_URL = "https://raw.githubusercontent.com/homarr-labs/dashboard-icons/refs/heads/main/metadata.json" export const WEB_URL = "https://icons.homarr.dev" +export const REPO_NAME = "homarr-labs/dashboard-icons" \ No newline at end of file