feat: Sochboard logo with dynamic accent color as favicon and header icon
- New SochboardLogo SVG component used in dashboard header - Favicon generated from theme accent color - Bump version to 0.2.0
This commit is contained in:
parent
d36f16cea1
commit
4807899b38
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "sochboard",
|
||||
"version": "0.1.0",
|
||||
"version": "0.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "node node_modules/next/dist/bin/next dev",
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import type { Metadata } from "next"
|
||||
import { Inter } from "next/font/google"
|
||||
import { getConfig } from "@/lib/config"
|
||||
import { SochboardLogoDataUri } from "@/components/ui/SochboardLogo"
|
||||
import "./globals.css"
|
||||
|
||||
const inter = Inter({
|
||||
|
|
@ -15,12 +16,17 @@ export async function generateMetadata(): Promise<Metadata> {
|
|||
return {
|
||||
title: config.site.name,
|
||||
description: config.site.title,
|
||||
icons: config.site.favicon ? { icon: config.site.favicon } : undefined,
|
||||
icons: {
|
||||
icon: config.site.favicon ?? SochboardLogoDataUri(config.theme.accent),
|
||||
},
|
||||
}
|
||||
} catch {
|
||||
return {
|
||||
title: "Sochboard",
|
||||
description: "Dashboard",
|
||||
icons: {
|
||||
icon: SochboardLogoDataUri(),
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ export function Dashboard({ config, isAuthenticated = false, username = null, cu
|
|||
authentication={config.authentication}
|
||||
isAuthenticated={isAuthenticated}
|
||||
username={username}
|
||||
accent={config.theme.accent}
|
||||
/>
|
||||
<main className="flex flex-col gap-12">
|
||||
{config.sections.map((section, index) => (
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { useState, useEffect } from "react"
|
||||
import type { SiteConfig, AuthenticationConfig } from "@/types/config"
|
||||
import { SochboardLogo } from "@/components/ui/SochboardLogo"
|
||||
|
||||
interface DashboardHeaderProps {
|
||||
site: SiteConfig
|
||||
|
|
@ -9,9 +10,10 @@ interface DashboardHeaderProps {
|
|||
authentication?: AuthenticationConfig
|
||||
isAuthenticated?: boolean
|
||||
username?: string | null
|
||||
accent?: string
|
||||
}
|
||||
|
||||
export function DashboardHeader({ site, initialTheme, authentication, isAuthenticated = false, username = null }: DashboardHeaderProps) {
|
||||
export function DashboardHeader({ site, initialTheme, authentication, isAuthenticated = false, username = null, accent }: DashboardHeaderProps) {
|
||||
const [isLight, setIsLight] = useState(initialTheme === "light")
|
||||
|
||||
useEffect(() => {
|
||||
|
|
@ -33,12 +35,7 @@ export function DashboardHeader({ site, initialTheme, authentication, isAuthenti
|
|||
className="size-12 rounded-xl object-cover"
|
||||
/>
|
||||
) : (
|
||||
<div
|
||||
className="flex size-12 items-center justify-center rounded-xl bg-gradient-to-br from-[#8b5cf6] to-[#6d28d9] text-lg font-bold text-white shadow-lg shadow-[#8b5cf6]/20"
|
||||
aria-hidden="true"
|
||||
>
|
||||
S
|
||||
</div>
|
||||
<SochboardLogo size={48} accent={accent} />
|
||||
)}
|
||||
<div>
|
||||
<h1 className="text-xl font-bold text-[var(--text-primary)]">
|
||||
|
|
|
|||
69
src/components/ui/SochboardLogo.tsx
Normal file
69
src/components/ui/SochboardLogo.tsx
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
interface SochboardLogoProps {
|
||||
size?: number
|
||||
accent?: string
|
||||
className?: string
|
||||
}
|
||||
|
||||
export function SochboardLogo({ size = 48, accent = "#f59e0b", className }: SochboardLogoProps) {
|
||||
return (
|
||||
<svg
|
||||
width={size}
|
||||
height={size}
|
||||
viewBox="0 0 48 48"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
className={className}
|
||||
aria-hidden="true"
|
||||
>
|
||||
<rect width="48" height="48" rx="12" fill={accent} />
|
||||
<rect x="4" y="4" width="40" height="40" rx="10" fill={`${accent}20`} />
|
||||
<path
|
||||
d="M24 12C21.5 12 19 13.5 19 16.5C19 18 20 19 21 19.5C19.5 20 18 21.5 18 24C18 26.5 20 28 22 28C20.5 28.5 19 30 19 32.5C19 35.5 21.5 37 24 37C26.5 37 29 35.5 29 32.5C29 31 28 30 27 29.5C28.5 29 30 27.5 30 25C30 22.5 28 21 26 21C27.5 20.5 29 19 29 16.5C29 13.5 26.5 12 24 12Z"
|
||||
fill="white"
|
||||
fillOpacity="0.95"
|
||||
/>
|
||||
<path
|
||||
d="M12 12H36"
|
||||
stroke="white"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M12 36H36"
|
||||
stroke="white"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M12 24H36"
|
||||
stroke="white"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeOpacity="0.2"
|
||||
/>
|
||||
<path
|
||||
d="M24 12V36"
|
||||
stroke="white"
|
||||
strokeWidth="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeOpacity="0.2"
|
||||
/>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
export function SochboardLogoDataUri(accent: string = "#f59e0b"): string {
|
||||
const hex = accent.replace("#", "%23")
|
||||
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48" fill="none">
|
||||
<rect width="48" height="48" rx="12" fill="${hex}"/>
|
||||
<rect x="4" y="4" width="40" height="40" rx="10" fill="${hex}20"/>
|
||||
<path d="M24 12C21.5 12 19 13.5 19 16.5C19 18 20 19 21 19.5C19.5 20 18 21.5 18 24C18 26.5 20 28 22 28C20.5 28.5 19 30 19 32.5C19 35.5 21.5 37 24 37C26.5 37 29 35.5 29 32.5C29 31 28 30 27 29.5C28.5 29 30 27.5 30 25C30 22.5 28 21 26 21C27.5 20.5 29 19 29 16.5C29 13.5 26.5 12 24 12Z" fill="white" fill-opacity="0.95"/>
|
||||
<path d="M12 12H36" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.2"/>
|
||||
<path d="M12 36H36" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.2"/>
|
||||
<path d="M12 24H36" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.2"/>
|
||||
<path d="M24 12V36" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-opacity="0.2"/>
|
||||
</svg>`
|
||||
return `data:image/svg+xml,${encodeURIComponent(svg)}`
|
||||
}
|
||||
Loading…
Reference in a new issue