mirror of
https://github.com/walkxcode/dashboard-icons.git
synced 2025-06-28 15:30:22 +08:00
fix(web): Run Biome checks and apply fixes
This commit is contained in:
parent
34fef44222
commit
40482771fa
@ -22,6 +22,9 @@
|
|||||||
"recommended": true,
|
"recommended": true,
|
||||||
"suspicious": {
|
"suspicious": {
|
||||||
"noArrayIndexKey": "off"
|
"noArrayIndexKey": "off"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"noDangerouslySetInnerHtml": "off"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
import { readFile } from "node:fs/promises"
|
import { readFile } from "node:fs/promises"
|
||||||
import { join } from "node:path"
|
import { join } from "node:path"
|
||||||
|
import { SITE_NAME, SITE_TAGLINE, WEB_URL, getIconDescription } from "@/constants"
|
||||||
import { getAllIcons } from "@/lib/api"
|
import { getAllIcons } from "@/lib/api"
|
||||||
import { ImageResponse } from "next/og"
|
import { ImageResponse } from "next/og"
|
||||||
import {
|
|
||||||
SITE_NAME,
|
|
||||||
SITE_TAGLINE,
|
|
||||||
getIconDescription,
|
|
||||||
WEB_URL
|
|
||||||
} from "@/constants"
|
|
||||||
|
|
||||||
export const dynamic = "force-static"
|
export const dynamic = "force-static"
|
||||||
|
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
import { IconDetails } from "@/components/icon-details"
|
import { IconDetails } from "@/components/icon-details"
|
||||||
import { StructuredData } from "@/components/structured-data"
|
import { StructuredData } from "@/components/structured-data"
|
||||||
import { BASE_URL, GITHUB_URL, ICON_DETAIL_KEYWORDS, SITE_NAME, SITE_TAGLINE, TITLE_SEPARATOR, WEB_URL, getIconDescription, getIconSchema } from "@/constants"
|
import {
|
||||||
|
BASE_URL,
|
||||||
|
GITHUB_URL,
|
||||||
|
ICON_DETAIL_KEYWORDS,
|
||||||
|
SITE_NAME,
|
||||||
|
SITE_TAGLINE,
|
||||||
|
TITLE_SEPARATOR,
|
||||||
|
WEB_URL,
|
||||||
|
getIconDescription,
|
||||||
|
getIconSchema,
|
||||||
|
} from "@/constants"
|
||||||
import { getAllIcons, getAuthorData } from "@/lib/api"
|
import { getAllIcons, getAuthorData } from "@/lib/api"
|
||||||
import type { Metadata, ResolvingMetadata } from "next"
|
import type { Metadata, ResolvingMetadata } from "next"
|
||||||
import Script from "next/script"
|
|
||||||
import { notFound } from "next/navigation"
|
import { notFound } from "next/navigation"
|
||||||
|
import Script from "next/script"
|
||||||
|
|
||||||
export const dynamicParams = false
|
export const dynamicParams = false
|
||||||
|
|
||||||
@ -109,7 +119,7 @@ export default async function IconPage({ params }: { params: { icon: string } })
|
|||||||
authorName,
|
authorName,
|
||||||
authorData.html_url,
|
authorData.html_url,
|
||||||
updateDate.toISOString(),
|
updateDate.toISOString(),
|
||||||
Object.keys(iconsData).length
|
Object.keys(iconsData).length,
|
||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,7 +1,19 @@
|
|||||||
import { BASE_URL, BROWSE_KEYWORDS, DEFAULT_OG_IMAGE, GITHUB_URL, ORGANIZATION_NAME, ORGANIZATION_SCHEMA, SITE_NAME, SITE_TAGLINE, TITLE_SEPARATOR, WEB_URL, getBrowseDescription } from "@/constants"
|
import { StructuredData } from "@/components/structured-data"
|
||||||
|
import {
|
||||||
|
BASE_URL,
|
||||||
|
BROWSE_KEYWORDS,
|
||||||
|
DEFAULT_OG_IMAGE,
|
||||||
|
GITHUB_URL,
|
||||||
|
ORGANIZATION_NAME,
|
||||||
|
ORGANIZATION_SCHEMA,
|
||||||
|
SITE_NAME,
|
||||||
|
SITE_TAGLINE,
|
||||||
|
TITLE_SEPARATOR,
|
||||||
|
WEB_URL,
|
||||||
|
getBrowseDescription,
|
||||||
|
} from "@/constants"
|
||||||
import { getIconsArray } from "@/lib/api"
|
import { getIconsArray } from "@/lib/api"
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
import { StructuredData } from "@/components/structured-data"
|
|
||||||
import { IconSearch } from "./components/icon-search"
|
import { IconSearch } from "./components/icon-search"
|
||||||
|
|
||||||
export async function generateMetadata(): Promise<Metadata> {
|
export async function generateMetadata(): Promise<Metadata> {
|
||||||
@ -42,15 +54,15 @@ export default async function IconsPage() {
|
|||||||
const gallerySchema = {
|
const gallerySchema = {
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "ImageGallery",
|
"@type": "ImageGallery",
|
||||||
"name": `${SITE_NAME} - Browse ${icons.length} Icons - ${SITE_TAGLINE}`,
|
name: `${SITE_NAME} - Browse ${icons.length} Icons - ${SITE_TAGLINE}`,
|
||||||
"description": getBrowseDescription(icons.length),
|
description: getBrowseDescription(icons.length),
|
||||||
"url": `${WEB_URL}/icons`,
|
url: `${WEB_URL}/icons`,
|
||||||
"numberOfItems": icons.length,
|
numberOfItems: icons.length,
|
||||||
"creator": {
|
creator: {
|
||||||
"@type": "Organization",
|
"@type": "Organization",
|
||||||
"name": ORGANIZATION_NAME,
|
name: ORGANIZATION_NAME,
|
||||||
"url": GITHUB_URL
|
url: GITHUB_URL,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -62,7 +74,9 @@ export default async function IconsPage() {
|
|||||||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold">Icons</h1>
|
<h1 className="text-3xl font-bold">Icons</h1>
|
||||||
<p className="text-muted-foreground">Search our collection of {icons.length} icons - {SITE_TAGLINE}.</p>
|
<p className="text-muted-foreground">
|
||||||
|
Search our collection of {icons.length} icons - {SITE_TAGLINE}.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -8,7 +8,20 @@ import type { Metadata, Viewport } from "next"
|
|||||||
import { Inter } from "next/font/google"
|
import { Inter } from "next/font/google"
|
||||||
import { Toaster } from "sonner"
|
import { Toaster } from "sonner"
|
||||||
import "./globals.css"
|
import "./globals.css"
|
||||||
import { DEFAULT_KEYWORDS, DEFAULT_OG_IMAGE, GITHUB_URL, ORGANIZATION_NAME, ORGANIZATION_SCHEMA, SITE_NAME, SITE_TAGLINE, WEB_URL, getDescription, getWebsiteSchema, websiteFullTitle, websiteTitle } from "@/constants"
|
import {
|
||||||
|
DEFAULT_KEYWORDS,
|
||||||
|
DEFAULT_OG_IMAGE,
|
||||||
|
GITHUB_URL,
|
||||||
|
ORGANIZATION_NAME,
|
||||||
|
ORGANIZATION_SCHEMA,
|
||||||
|
SITE_NAME,
|
||||||
|
SITE_TAGLINE,
|
||||||
|
WEB_URL,
|
||||||
|
getDescription,
|
||||||
|
getWebsiteSchema,
|
||||||
|
websiteFullTitle,
|
||||||
|
websiteTitle,
|
||||||
|
} from "@/constants"
|
||||||
import { ThemeProvider } from "./theme-provider"
|
import { ThemeProvider } from "./theme-provider"
|
||||||
|
|
||||||
const inter = Inter({
|
const inter = Inter({
|
||||||
@ -102,10 +115,7 @@ export default async function RootLayout({ children }: Readonly<{ children: Reac
|
|||||||
<html lang="en" suppressHydrationWarning>
|
<html lang="en" suppressHydrationWarning>
|
||||||
<body className={`${inter.variable} antialiased bg-background flex flex-col min-h-screen`}>
|
<body className={`${inter.variable} antialiased bg-background flex flex-col min-h-screen`}>
|
||||||
<PostHogProvider>
|
<PostHogProvider>
|
||||||
<WebsiteStructuredData
|
<WebsiteStructuredData websiteSchema={websiteSchema} organizationSchema={ORGANIZATION_SCHEMA} />
|
||||||
websiteSchema={websiteSchema}
|
|
||||||
organizationSchema={ORGANIZATION_SCHEMA}
|
|
||||||
/>
|
|
||||||
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
||||||
<HeaderWrapper />
|
<HeaderWrapper />
|
||||||
<main className="flex-grow">{children}</main>
|
<main className="flex-grow">{children}</main>
|
||||||
|
@ -1,6 +1,20 @@
|
|||||||
import { HeroSection } from "@/components/hero"
|
import { HeroSection } from "@/components/hero"
|
||||||
import { RecentlyAddedIcons } from "@/components/recently-added-icons"
|
import { RecentlyAddedIcons } from "@/components/recently-added-icons"
|
||||||
import { BASE_URL, DEFAULT_KEYWORDS, DEFAULT_OG_IMAGE, GITHUB_URL, ORGANIZATION_NAME, ORGANIZATION_SCHEMA, SITE_NAME, SITE_TAGLINE, WEB_URL, REPO_NAME, getHomeDescription, websiteFullTitle, websiteTitle } from "@/constants"
|
import {
|
||||||
|
BASE_URL,
|
||||||
|
DEFAULT_KEYWORDS,
|
||||||
|
DEFAULT_OG_IMAGE,
|
||||||
|
GITHUB_URL,
|
||||||
|
ORGANIZATION_NAME,
|
||||||
|
ORGANIZATION_SCHEMA,
|
||||||
|
REPO_NAME,
|
||||||
|
SITE_NAME,
|
||||||
|
SITE_TAGLINE,
|
||||||
|
WEB_URL,
|
||||||
|
getHomeDescription,
|
||||||
|
websiteFullTitle,
|
||||||
|
websiteTitle,
|
||||||
|
} from "@/constants"
|
||||||
import { getRecentlyAddedIcons, getTotalIcons } from "@/lib/api"
|
import { getRecentlyAddedIcons, getTotalIcons } from "@/lib/api"
|
||||||
import type { Metadata } from "next"
|
import type { Metadata } from "next"
|
||||||
|
|
||||||
|
@ -1,31 +1,22 @@
|
|||||||
type StructuredDataProps = {
|
type StructuredDataProps = {
|
||||||
data: any
|
data: Record<string, unknown>
|
||||||
id?: string
|
id?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const StructuredData = ({ data, id }: StructuredDataProps) => {
|
export const StructuredData = ({ data, id }: StructuredDataProps) => {
|
||||||
return (
|
return <script id={id} type="application/ld+json" dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }} />
|
||||||
<script
|
|
||||||
id={id}
|
|
||||||
type="application/ld+json"
|
|
||||||
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
|
|
||||||
/>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WebsiteStructuredDataProps = {
|
type WebsiteStructuredDataProps = {
|
||||||
websiteSchema: any
|
websiteSchema: Record<string, unknown>
|
||||||
organizationSchema: any
|
organizationSchema: Record<string, unknown>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WebsiteStructuredData = ({
|
export const WebsiteStructuredData = ({ websiteSchema, organizationSchema }: WebsiteStructuredDataProps) => {
|
||||||
websiteSchema,
|
return (
|
||||||
organizationSchema
|
<>
|
||||||
}: WebsiteStructuredDataProps) => {
|
<StructuredData data={websiteSchema} id="website-schema" />
|
||||||
return (
|
<StructuredData data={organizationSchema} id="organization-schema" />
|
||||||
<>
|
</>
|
||||||
<StructuredData data={websiteSchema} id="website-schema" />
|
)
|
||||||
<StructuredData data={organizationSchema} id="organization-schema" />
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
@ -34,7 +34,7 @@ export const DEFAULT_KEYWORDS = [
|
|||||||
"free icons",
|
"free icons",
|
||||||
"SVG icons",
|
"SVG icons",
|
||||||
"web dashboard",
|
"web dashboard",
|
||||||
"app directory"
|
"app directory",
|
||||||
]
|
]
|
||||||
|
|
||||||
export const BROWSE_KEYWORDS = [
|
export const BROWSE_KEYWORDS = [
|
||||||
@ -44,7 +44,7 @@ export const BROWSE_KEYWORDS = [
|
|||||||
"minimal icons",
|
"minimal icons",
|
||||||
"dashboard design",
|
"dashboard design",
|
||||||
"UI icons",
|
"UI icons",
|
||||||
...DEFAULT_KEYWORDS
|
...DEFAULT_KEYWORDS,
|
||||||
]
|
]
|
||||||
|
|
||||||
// Add format-specific keywords
|
// Add format-specific keywords
|
||||||
@ -56,63 +56,67 @@ export const ICON_DETAIL_KEYWORDS = (iconName: string): string[] => [
|
|||||||
`${iconName} webp icon`, // e.g., "Homarr webp icon"
|
`${iconName} webp icon`, // e.g., "Homarr webp icon"
|
||||||
`${iconName} download`, // e.g., "Homarr download"
|
`${iconName} download`, // e.g., "Homarr download"
|
||||||
`${iconName} dashboard icon`, // e.g., "Homarr dashboard icon"
|
`${iconName} dashboard icon`, // e.g., "Homarr dashboard icon"
|
||||||
...DEFAULT_KEYWORDS
|
...DEFAULT_KEYWORDS,
|
||||||
]
|
]
|
||||||
|
|
||||||
// Core structured data for the website (JSON-LD)
|
// Core structured data for the website (JSON-LD)
|
||||||
export const getWebsiteSchema = (totalIcons: number) => ({
|
export const getWebsiteSchema = (totalIcons: number) => ({
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "WebSite",
|
"@type": "WebSite",
|
||||||
"name": SITE_NAME,
|
name: SITE_NAME,
|
||||||
"url": WEB_URL,
|
url: WEB_URL,
|
||||||
"description": getDescription(totalIcons),
|
description: getDescription(totalIcons),
|
||||||
"potentialAction": {
|
potentialAction: {
|
||||||
"@type": "SearchAction",
|
"@type": "SearchAction",
|
||||||
"target": {
|
target: {
|
||||||
"@type": "EntryPoint",
|
"@type": "EntryPoint",
|
||||||
"urlTemplate": `${WEB_URL}/icons?q={search_term_string}`
|
urlTemplate: `${WEB_URL}/icons?q={search_term_string}`,
|
||||||
},
|
},
|
||||||
"query-input": "required name=search_term_string"
|
"query-input": "required name=search_term_string",
|
||||||
},
|
},
|
||||||
"slogan": SITE_TAGLINE
|
slogan: SITE_TAGLINE,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Organization schema
|
// Organization schema
|
||||||
export const ORGANIZATION_SCHEMA = {
|
export const ORGANIZATION_SCHEMA = {
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "Organization",
|
"@type": "Organization",
|
||||||
"name": ORGANIZATION_NAME,
|
name: ORGANIZATION_NAME,
|
||||||
"url": `https://github.com/${REPO_NAME}`,
|
url: `https://github.com/${REPO_NAME}`,
|
||||||
"logo": `${WEB_URL}/og-image.png`,
|
logo: `${WEB_URL}/og-image.png`,
|
||||||
"sameAs": [
|
sameAs: [`https://github.com/${REPO_NAME}`, "https://homarr.dev"],
|
||||||
`https://github.com/${REPO_NAME}`,
|
slogan: SITE_TAGLINE,
|
||||||
"https://homarr.dev"
|
|
||||||
],
|
|
||||||
"slogan": SITE_TAGLINE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Social media
|
// Social media
|
||||||
export const GITHUB_URL = `https://github.com/${REPO_NAME}`
|
export const GITHUB_URL = `https://github.com/${REPO_NAME}`
|
||||||
|
|
||||||
// Image schemas
|
// Image schemas
|
||||||
export const getIconSchema = (iconName: string, iconId: string, authorName: string, authorUrl: string, updateDate: string, totalIcons: number) => ({
|
export const getIconSchema = (
|
||||||
|
iconName: string,
|
||||||
|
iconId: string,
|
||||||
|
authorName: string,
|
||||||
|
authorUrl: string,
|
||||||
|
updateDate: string,
|
||||||
|
totalIcons: number,
|
||||||
|
) => ({
|
||||||
"@context": "https://schema.org",
|
"@context": "https://schema.org",
|
||||||
"@type": "ImageObject",
|
"@type": "ImageObject",
|
||||||
"name": `${iconName} Icon`,
|
name: `${iconName} Icon`,
|
||||||
"description": getIconDescription(iconName, totalIcons),
|
description: getIconDescription(iconName, totalIcons),
|
||||||
"contentUrl": `${BASE_URL}/png/${iconId}.png`,
|
contentUrl: `${BASE_URL}/png/${iconId}.png`,
|
||||||
"thumbnailUrl": `${BASE_URL}/png/${iconId}.png`,
|
thumbnailUrl: `${BASE_URL}/png/${iconId}.png`,
|
||||||
"uploadDate": updateDate,
|
uploadDate: updateDate,
|
||||||
"author": {
|
author: {
|
||||||
"@type": "Person",
|
"@type": "Person",
|
||||||
"name": authorName,
|
name: authorName,
|
||||||
"url": authorUrl
|
url: authorUrl,
|
||||||
},
|
},
|
||||||
"encodingFormat": ["image/png", "image/svg+xml", "image/webp"],
|
encodingFormat: ["image/png", "image/svg+xml", "image/webp"],
|
||||||
"contentSize": "Variable",
|
contentSize: "Variable",
|
||||||
"representativeOfPage": true,
|
representativeOfPage: true,
|
||||||
"creditText": `Icon contributed by ${authorName} to the ${SITE_NAME} collection by ${ORGANIZATION_NAME}`,
|
creditText: `Icon contributed by ${authorName} to the ${SITE_NAME} collection by ${ORGANIZATION_NAME}`,
|
||||||
"embedUrl": `${WEB_URL}/icons/${iconId}`
|
embedUrl: `${WEB_URL}/icons/${iconId}`,
|
||||||
})
|
})
|
||||||
|
|
||||||
// OpenGraph defaults
|
// OpenGraph defaults
|
||||||
@ -121,5 +125,5 @@ export const DEFAULT_OG_IMAGE = {
|
|||||||
width: 1200,
|
width: 1200,
|
||||||
height: 630,
|
height: 630,
|
||||||
alt: `${SITE_NAME} - ${SITE_TAGLINE}`,
|
alt: `${SITE_NAME} - ${SITE_TAGLINE}`,
|
||||||
type: "image/png"
|
type: "image/png",
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user