chore: format codebase

This commit is contained in:
Thomas Camlong
2025-09-29 11:01:14 +02:00
parent 68970f5908
commit b5c72677fc
30 changed files with 220 additions and 290 deletions

View File

@@ -1,11 +1,5 @@
import { useEffect, useRef } from "react"
export function Carbon() {
// biome-ignore lint/style/noNonNullAssertion: <explanation>
const ref = useRef<HTMLDivElement>(null!)
if (process.env.NODE_ENV === "development") {
return null
}
useEffect(() => {
const serve = "CW7IKKQM"
const placement = "dashboardiconscom"
@@ -16,6 +10,11 @@ export function Carbon() {
ref.current.appendChild(s)
}, [])
const ref = useRef<HTMLDivElement>(null!)
if (process.env.NODE_ENV === "development") {
return null
}
return (
<>
<style>

View File

@@ -1,13 +1,13 @@
"use client"
import { Badge } from "@/components/ui/badge"
import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"
import { useMediaQuery } from "@/hooks/use-media-query"
import { filterAndSortIcons, formatIconName, fuzzySearch } from "@/lib/utils"
import type { IconWithName } from "@/types/icons"
import { Info, Search as SearchIcon, Tag } from "lucide-react"
import { useRouter } from "next/navigation"
import { useCallback, useEffect, useMemo, useState } from "react"
import { Badge } from "@/components/ui/badge"
import { CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@/components/ui/command"
import { useMediaQuery } from "@/hooks/use-media-query"
import { filterAndSortIcons, formatIconName } from "@/lib/utils"
import type { IconWithName } from "@/types/icons"
interface CommandMenuProps {
icons: IconWithName[]
@@ -20,7 +20,7 @@ export function CommandMenu({ icons, open: externalOpen, onOpenChange: externalO
const router = useRouter()
const [internalOpen, setInternalOpen] = useState(false)
const [query, setQuery] = useState("")
const isDesktop = useMediaQuery("(min-width: 768px)")
const _isDesktop = useMediaQuery("(min-width: 768px)")
// Use either external or internal state for controlling open state
const isOpen = externalOpen !== undefined ? externalOpen : internalOpen

View File

@@ -1,6 +1,6 @@
import { REPO_PATH } from "@/constants"
import { ExternalLink } from "lucide-react"
import Link from "next/link"
import { REPO_PATH } from "@/constants"
import { HeartEasterEgg } from "./heart"
export function Footer() {

View File

@@ -1,8 +1,8 @@
"use client"
import { cn } from "@/lib/utils"
import Link from "next/link"
import { usePathname } from "next/navigation"
import { cn } from "@/lib/utils"
export function HeaderNav() {
const pathname = usePathname()

View File

@@ -1,13 +1,13 @@
"use client"
import { Github, PlusCircle, Search } from "lucide-react"
import Link from "next/link"
import { useEffect, useState } from "react"
import { IconSubmissionForm } from "@/components/icon-submission-form"
import { ThemeSwitcher } from "@/components/theme-switcher"
import { REPO_PATH } from "@/constants"
import { getIconsArray } from "@/lib/api"
import type { IconWithName } from "@/types/icons"
import { Github, PlusCircle, Search } from "lucide-react"
import Link from "next/link"
import { useEffect, useState } from "react"
import { CommandMenu } from "./command-menu"
import { HeaderNav } from "./header-nav"
import { Button } from "./ui/button"

View File

@@ -1,8 +1,7 @@
"use client"
import { Heart } from "lucide-react"
import { motion } from "framer-motion"
import { Heart } from "lucide-react"
import { useState } from "react"
export function HeartEasterEgg() {

View File

@@ -1,9 +1,5 @@
"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 { Separator } from "@radix-ui/react-dropdown-menu"
import { motion, useAnimation, useInView } from "framer-motion"
import {
@@ -25,6 +21,10 @@ import {
} from "lucide-react"
import Link from "next/link"
import { useEffect, useRef, useState } from "react"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { cn } from "@/lib/utils"
import { AuroraText } from "./magicui/aurora-text"
import { InteractiveHoverButton } from "./magicui/interactive-hover-button"
import { NumberTicker } from "./magicui/number-ticker"
@@ -35,7 +35,7 @@ interface IconCardProps {
imageUrl: string
}
function IconCard({ name, imageUrl }: IconCardProps) {
function _IconCard({ name, imageUrl }: IconCardProps) {
return (
<Card className="p-4 flex flex-col items-center gap-2 cursor-pointer group hover-lift card-hover">
<div className="w-16 h-16 flex items-center justify-center">

View File

@@ -1,122 +1,109 @@
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import { Check, Copy, Download, Github, Link as LinkIcon } from "lucide-react";
import Link from "next/link";
import type React from "react";
import { Check, Copy, Download, Github, Link as LinkIcon } from "lucide-react"
import Link from "next/link"
import type React from "react"
import { Button } from "@/components/ui/button"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
export type IconActionsProps = {
imageUrl: string;
githubUrl: string;
iconName: string;
format: string;
variantKey: string;
copiedUrlKey: string | null;
copiedImageKey: string | null;
handleDownload: (event: React.MouseEvent, url: string, filename: string) => Promise<void>;
handleCopyUrl: (url: string, variantKey: string, event?: React.MouseEvent) => void;
handleCopyImage: (imageUrl: string, format: string, variantKey: string, event?: React.MouseEvent) => Promise<void>;
};
imageUrl: string
githubUrl: string
iconName: string
format: string
variantKey: string
copiedUrlKey: string | null
copiedImageKey: string | null
handleDownload: (event: React.MouseEvent, url: string, filename: string) => Promise<void>
handleCopyUrl: (url: string, variantKey: string, event?: React.MouseEvent) => void
handleCopyImage: (imageUrl: string, format: string, variantKey: string, event?: React.MouseEvent) => Promise<void>
}
export function IconActions({
imageUrl,
githubUrl,
iconName,
format,
variantKey,
copiedUrlKey,
copiedImageKey,
handleDownload,
handleCopyUrl,
handleCopyImage,
imageUrl,
githubUrl,
iconName,
format,
variantKey,
copiedUrlKey,
copiedImageKey,
handleDownload,
handleCopyUrl,
handleCopyImage,
}: IconActionsProps) {
const downloadFilename = `${iconName}.${format}`;
const isUrlCopied = copiedUrlKey === variantKey;
const isImageCopied = copiedImageKey === variantKey;
const downloadFilename = `${iconName}.${format}`
const isUrlCopied = copiedUrlKey === variantKey
const isImageCopied = copiedImageKey === variantKey
return (
<TooltipProvider delayDuration={300}>
<div className="flex gap-2 mt-3 w-full justify-center">
{/* Download Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleDownload(e, imageUrl, downloadFilename)}
aria-label={`Download ${iconName} as ${format.toUpperCase()}`}
>
<Download className="w-4 h-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Download {format.toUpperCase()}</p>
</TooltipContent>
</Tooltip>
return (
<TooltipProvider delayDuration={300}>
<div className="flex gap-2 mt-3 w-full justify-center">
{/* Download Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleDownload(e, imageUrl, downloadFilename)}
aria-label={`Download ${iconName} as ${format.toUpperCase()}`}
>
<Download className="w-4 h-4" />
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Download {format.toUpperCase()}</p>
</TooltipContent>
</Tooltip>
{/* Copy Image Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleCopyImage(imageUrl, format, variantKey, e)}
aria-label={`Copy ${iconName} image as ${format.toUpperCase()}`}
>
{isImageCopied ? (
<Check className="w-4 h-4 text-green-500" />
) : (
<Copy className="w-4 h-4" />
)}
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Copy image to clipboard</p>
</TooltipContent>
</Tooltip>
{/* Copy Image Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleCopyImage(imageUrl, format, variantKey, e)}
aria-label={`Copy ${iconName} image as ${format.toUpperCase()}`}
>
{isImageCopied ? <Check className="w-4 h-4 text-green-500" /> : <Copy className="w-4 h-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Copy image to clipboard</p>
</TooltipContent>
</Tooltip>
{/* Copy URL Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleCopyUrl(imageUrl, variantKey, e)}
aria-label={`Copy direct URL for ${iconName} ${format.toUpperCase()}`}
>
{isUrlCopied ? (
<Check className="w-4 h-4 text-green-500" />
) : (
<LinkIcon className="w-4 h-4" />
)}
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Copy direct URL</p>
</TooltipContent>
</Tooltip>
{/* Copy URL Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
size="icon"
className="h-8 w-8 rounded-lg cursor-pointer"
onClick={(e) => handleCopyUrl(imageUrl, variantKey, e)}
aria-label={`Copy direct URL for ${iconName} ${format.toUpperCase()}`}
>
{isUrlCopied ? <Check className="w-4 h-4 text-green-500" /> : <LinkIcon className="w-4 h-4" />}
</Button>
</TooltipTrigger>
<TooltipContent>
<p>Copy direct URL</p>
</TooltipContent>
</Tooltip>
{/* View on GitHub Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="icon" className="h-8 w-8 rounded-lg" asChild>
<Link
href={githubUrl}
target="_blank"
rel="noopener noreferrer"
aria-label={`View ${iconName} ${format} file on GitHub`}
>
<Github className="w-4 h-4" />
</Link>
</Button>
</TooltipTrigger>
<TooltipContent>
<p>View on GitHub</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
);
}
{/* View on GitHub Button */}
<Tooltip>
<TooltipTrigger asChild>
<Button variant="outline" size="icon" className="h-8 w-8 rounded-lg" asChild>
<Link href={githubUrl} target="_blank" rel="noopener noreferrer" aria-label={`View ${iconName} ${format} file on GitHub`}>
<Github className="w-4 h-4" />
</Link>
</Button>
</TooltipTrigger>
<TooltipContent>
<p>View on GitHub</p>
</TooltipContent>
</Tooltip>
</div>
</TooltipProvider>
)
}

View File

@@ -1,19 +1,11 @@
import Image from "next/image"
import Link from "next/link"
import { MagicCard } from "@/components/magicui/magic-card"
import { BASE_URL } from "@/constants"
import { formatIconName } from "@/lib/utils"
import type { Icon } from "@/types/icons"
import Image from "next/image"
import Link from "next/link"
export function IconCard({
name,
data: iconData,
matchedAlias,
}: {
name: string
data: Icon
matchedAlias?: string
}) {
export function IconCard({ name, data: iconData, matchedAlias }: { name: string; data: Icon; matchedAlias?: string }) {
const formatedIconName = formatIconName(name)
return (
<MagicCard className="rounded-md shadow-md">

View File

@@ -1,13 +1,5 @@
"use client"
import { IconsGrid } from "@/components/icon-grid"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
import { BASE_URL, REPO_PATH } from "@/constants"
import { formatIconName } from "@/lib/utils"
import type { AuthorData, Icon, IconFile } from "@/types/icons"
import confetti from "canvas-confetti"
import { motion } from "framer-motion"
import { ArrowRight, Check, FileType, Github, Moon, PaletteIcon, Sun, Type } from "lucide-react"
@@ -16,16 +8,20 @@ import Link from "next/link"
import type React from "react"
import { useCallback, useState } from "react"
import { toast } from "sonner"
import { IconsGrid } from "@/components/icon-grid"
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"
import { Button } from "@/components/ui/button"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
import { BASE_URL, REPO_PATH } from "@/constants"
import { formatIconName } from "@/lib/utils"
import type { AuthorData, Icon, IconFile } from "@/types/icons"
import { Carbon } from "./carbon"
import { IconActions } from "./icon-actions"
import { MagicCard } from "./magicui/magic-card"
import { Badge } from "./ui/badge"
type RenderVariantFn = (
format: string,
iconName: string,
theme?: "light" | "dark"
) => React.ReactNode
type RenderVariantFn = (format: string, iconName: string, theme?: "light" | "dark") => React.ReactNode
type IconVariantsSectionProps = {
title: string
@@ -76,11 +72,7 @@ type WordmarkSectionProps = {
renderVariant: RenderVariantFn
}
function WordmarkSection({
iconData,
aavailableFormats,
renderVariant,
}: WordmarkSectionProps) {
function WordmarkSection({ iconData, aavailableFormats, renderVariant }: WordmarkSectionProps) {
if (!iconData.wordmark) return null
return (
@@ -89,9 +81,7 @@ function WordmarkSection({
<Type className="w-4 h-4 text-green-500" />
Wordmark Variants
</h3>
<p className="text-sm text-muted-foreground mb-4">
Icon variants that include the brand name. Click to copy URL.
</p>
<p className="text-sm text-muted-foreground mb-4">Icon variants that include the brand name. Click to copy URL.</p>
<div className="space-y-6">
{iconData.wordmark.light && (
<div>
@@ -135,14 +125,14 @@ export type IconDetailsProps = {
export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetailsProps) {
const authorName = authorData.name || authorData.login || ""
const iconColorVariants = iconData.colors
const iconWordmarkVariants = iconData.wordmark
const _iconColorVariants = iconData.colors
const _iconWordmarkVariants = iconData.wordmark
const formattedDate = new Date(iconData.update.timestamp).toLocaleDateString("en-GB", {
day: "numeric",
month: "long",
year: "numeric",
})
const getAvailableFormats = () => {
switch (iconData.base) {
case "svg":
@@ -155,7 +145,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
}
const availableFormats = getAvailableFormats()
const [copiedVariants, setCopiedVariants] = useState<Record<string, boolean>>({})
const [copiedVariants, _setCopiedVariants] = useState<Record<string, boolean>>({})
const [copiedUrlKey, setCopiedUrlKey] = useState<string | null>(null)
const [copiedImageKey, setCopiedImageKey] = useState<string | null>(null)
@@ -207,16 +197,11 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
})
}
const handleCopyImage = async (
imageUrl: string,
format: string,
variantKey: string,
event?: React.MouseEvent
) => {
const handleCopyImage = async (imageUrl: string, format: string, variantKey: string, event?: React.MouseEvent) => {
try {
toast.loading("Copying image...")
if (format === 'svg') {
if (format === "svg") {
const response = await fetch(imageUrl)
if (!response.ok) {
throw new Error(`Failed to fetch SVG: ${response.statusText}`)
@@ -240,8 +225,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
toast.success("SVG Markup Copied", {
description: "The SVG code has been copied to your clipboard.",
})
} else if (format === 'png' || format === 'webp') {
} else if (format === "png" || format === "webp") {
const mimeType = `image/${format}`
const response = await fetch(imageUrl)
if (!response.ok) {
@@ -250,10 +234,10 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
const blob = await response.blob()
if (!blob) {
throw new Error('Failed to generate image blob')
throw new Error("Failed to generate image blob")
}
await navigator.clipboard.write([new ClipboardItem({ [mimeType]: blob })]);
await navigator.clipboard.write([new ClipboardItem({ [mimeType]: blob })])
setCopiedImageKey(variantKey)
setTimeout(() => {
@@ -270,11 +254,9 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
toast.success("Image copied", {
description: `The ${format.toUpperCase()} image has been copied to your clipboard.`,
})
} else {
throw new Error(`Unsupported format for image copy: ${format}`)
}
} catch (error) {
console.error("Copy error:", error)
toast.dismiss()
@@ -445,9 +427,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
{authorName}
</Link>
)}
{!authorData.html_url && (
<span className="text-sm">{authorName}</span>
)}
{!authorData.html_url && <span className="text-sm">{authorName}</span>}
</div>
</div>
</div>
@@ -696,6 +676,7 @@ export function IconDetails({ icon, iconData, authorData, allIcons }: IconDetail
<Card className="bg-background/50 border shadow-lg">
<CardHeader>
<CardTitle>
{/** biome-ignore lint/correctness/useUniqueElementIds: I want the ID to be fixed */}
<h2 id="related-icons-title">Related Icons</h2>
</CardTitle>
<CardDescription>

View File

@@ -1,7 +1,6 @@
import type { Icon } from "@/types/icons"
import { useWindowVirtualizer } from "@tanstack/react-virtual"
import { useEffect, useMemo, useRef, useState } from "react"
import type { Icon } from "@/types/icons"
import { IconCard } from "./icon-card"
interface IconsGridProps {

View File

@@ -1,5 +1,11 @@
"use client"
import { ArrowDownAZ, ArrowUpZA, Calendar, Filter, Search, SortAsc, X } from "lucide-react"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import { useTheme } from "next-themes"
import posthog from "posthog-js"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { toast } from "sonner"
import { VirtualizedIconsGrid } from "@/components/icon-grid"
import { IconSubmissionContent } from "@/components/icon-submission-form"
import { Badge } from "@/components/ui/badge"
@@ -17,14 +23,8 @@ import {
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
import { Separator } from "@/components/ui/separator"
import { type SortOption, filterAndSortIcons } from "@/lib/utils"
import { filterAndSortIcons, type SortOption } from "@/lib/utils"
import type { IconSearchProps } from "@/types/icons"
import { ArrowDownAZ, ArrowUpZA, Calendar, Filter, Search, SortAsc, X } from "lucide-react"
import { useTheme } from "next-themes"
import { usePathname, useRouter, useSearchParams } from "next/navigation"
import posthog from "posthog-js"
import { useCallback, useEffect, useMemo, useRef, useState } from "react"
import { toast } from "sonner"
export function IconSearch({ icons }: IconSearchProps) {
const searchParams = useSearchParams()
@@ -359,6 +359,7 @@ export function IconSearch({ icons }: IconSearchProps) {
<p className="text-lg text-muted-foreground mt-2">Help us expand our collection</p>
</div>
<div className="flex flex-col gap-4 items-center w-full">
{/** biome-ignore lint/correctness/useUniqueElementIds: I want the ID to be fixed */}
<div id="icon-submission-content" className="w-full">
<IconSubmissionContent />
</div>

View File

@@ -1,12 +1,12 @@
"use client"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { REPO_PATH } from "@/constants"
import { DialogDescription } from "@radix-ui/react-dialog"
import { ExternalLink, PlusCircle } from "lucide-react"
import Link from "next/link"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { REPO_PATH } from "@/constants"
export const ISSUE_TEMPLATES = [
{

View File

@@ -1,11 +1,11 @@
"use client"
import { Button } from "@/components/ui/button"
import { REPO_PATH } from "@/constants"
import { AnimatePresence, motion } from "framer-motion"
import { X } from "lucide-react"
import Link from "next/link"
import { useEffect, useState } from "react"
import { Button } from "@/components/ui/button"
import { REPO_PATH } from "@/constants"
const LOCAL_STORAGE_KEY = "licenseNoticeDismissed"

View File

@@ -1,6 +1,6 @@
import { cn } from "@/lib/utils"
import { ArrowRight } from "lucide-react"
import React from "react"
import { cn } from "@/lib/utils"
import { Button } from "../ui/button"
interface InteractiveHoverButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {}

View File

@@ -1,5 +1,5 @@
import { cn } from "@/lib/utils"
import type { ComponentPropsWithoutRef } from "react"
import { cn } from "@/lib/utils"
interface MarqueeProps extends ComponentPropsWithoutRef<"div"> {
/**

View File

@@ -1,13 +1,13 @@
"use client"
import { Marquee } from "@/components/magicui/marquee"
import { BASE_URL } from "@/constants"
import { cn, formatIconName } from "@/lib/utils"
import type { Icon, IconWithName } from "@/types/icons"
import { format, isToday, isYesterday } from "date-fns"
import { ArrowRight, Clock, ExternalLink } from "lucide-react"
import Image from "next/image"
import Link from "next/link"
import { Marquee } from "@/components/magicui/marquee"
import { BASE_URL } from "@/constants"
import { cn, formatIconName } from "@/lib/utils"
import type { Icon, IconWithName } from "@/types/icons"
function formatIconDate(timestamp: string): string {
const date = new Date(timestamp)
@@ -71,13 +71,7 @@ export function RecentlyAddedIcons({ icons }: { icons: IconWithName[] }) {
}
// Marquee-compatible icon card
function RecentIconCard({
name,
data,
}: {
name: string
data: Icon
}) {
function RecentIconCard({ name, data }: { name: string; data: Icon }) {
const formattedIconName = formatIconName(name)
return (
<Link

View File

@@ -2,11 +2,10 @@
import { Moon, Sun } from "lucide-react"
import { useTheme } from "next-themes"
import { useState } from "react"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip"
import { useState } from "react"
export function ThemeSwitcher() {
const { setTheme } = useTheme()