Skip to content

Commit 3de1190

Browse files
committed
add emojis for logo
1 parent ae1c6d5 commit 3de1190

File tree

6 files changed

+104
-10
lines changed

6 files changed

+104
-10
lines changed

src/Footer/Component.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,28 @@ import React from 'react'
44

55
import type { Footer } from '@/payload-types'
66

7+
import { findFeedBySlug } from '@/queries/feeds'
8+
79
import { ThemeSelector } from '@/providers/Theme/ThemeSelector'
810
import { CMSLink } from '@/components/Link'
911
import { Logo } from '@/components/Logo/Logo'
1012

1113
export async function Footer() {
1214
const footerData: Footer = await getCachedGlobal('footer', 1)()
13-
1415
const navItems = footerData?.navItems || []
1516

17+
let emojis: string[] = []
18+
const emojiData = await findFeedBySlug('logo-emojis')
19+
if (emojiData) {
20+
const json = emojiData.json || []
21+
emojis = Array.isArray(json) ? json.filter((v): v is string => typeof v === 'string') : []
22+
}
23+
1624
return (
1725
<footer className="mt-auto border-t border-border bg-black dark:bg-card text-white">
1826
<div className="container py-8 gap-8 flex flex-col md:flex-row md:justify-between">
1927
<Link className="flex items-center" href="/">
20-
<Logo />
28+
<Logo emojis={emojis} />
2129
</Link>
2230

2331
<div className="flex flex-col-reverse items-start md:flex-row gap-4 md:items-center">

src/Header/Component.client.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ import { HeaderNav } from './Nav'
1111

1212
interface HeaderClientProps {
1313
data: Header
14+
emojis: string[]
1415
}
1516

16-
export const HeaderClient: React.FC<HeaderClientProps> = ({ data }) => {
17+
export const HeaderClient: React.FC<HeaderClientProps> = ({ data, emojis }) => {
1718
/* Storing the value in a useState to avoid hydration errors */
1819
const [theme, setTheme] = useState<string | null>(null)
1920
const { headerTheme, setHeaderTheme } = useHeaderTheme()
@@ -33,7 +34,7 @@ export const HeaderClient: React.FC<HeaderClientProps> = ({ data }) => {
3334
<header className="container relative z-20 " {...(theme ? { 'data-theme': theme } : {})}>
3435
<div className="py-8 flex justify-between">
3536
<Link className="flex items-center" href="/">
36-
<Logo />
37+
<Logo emojis={emojis} />
3738
</Link>
3839
<HeaderNav data={data} />
3940
</div>

src/Header/Component.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,17 @@ import React from 'react'
44

55
import type { Header } from '@/payload-types'
66

7+
import { findFeedBySlug } from '@/queries/feeds'
8+
79
export async function Header() {
810
const headerData: Header = await getCachedGlobal('header', 1)()
911

10-
return <HeaderClient data={headerData} />
12+
let emojis: string[] = []
13+
const emojiData = await findFeedBySlug('logo-emojis')
14+
if (emojiData) {
15+
const json = emojiData.json || []
16+
emojis = Array.isArray(json) ? json.filter((v): v is string => typeof v === 'string') : []
17+
}
18+
19+
return <HeaderClient data={headerData} emojis={emojis} />
1120
}

src/components/Logo/Logo.tsx

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
1-
import React from 'react'
1+
'use client'
2+
import React, { useEffect, useRef, useState } from 'react'
23
import clsx from 'clsx'
34

45
interface Props {
56
className?: string
6-
loading?: 'lazy' | 'eager'
7-
priority?: 'auto' | 'high' | 'low'
7+
emojis: string[]
88
}
99

10-
export const Logo = (props: Props) => {
11-
return <span className={clsx('text-2xl font-bold font-logo')}>XC@F</span>
10+
export const Logo = ({ emojis = [] }: Props) => {
11+
const [hovered, setHovered] = useState(false)
12+
const [emoji, setEmoji] = useState(emojis[0])
13+
const indexRef = useRef(0)
14+
const timerRef = useRef<NodeJS.Timeout | null>(null)
15+
16+
useEffect(() => {
17+
if (!hovered || !emoji) {
18+
if (timerRef.current) {
19+
clearInterval(timerRef.current)
20+
timerRef.current = null
21+
}
22+
return
23+
}
24+
25+
timerRef.current = setInterval(() => {
26+
indexRef.current = (indexRef.current + 1) % emojis.length
27+
setEmoji(emojis[indexRef.current])
28+
}, 250)
29+
30+
return () => {
31+
if (timerRef.current) clearInterval(timerRef.current)
32+
}
33+
}, [hovered])
34+
35+
return (
36+
<span
37+
className="text-2xl font-bold font-logo cursor-pointer select-none"
38+
onMouseEnter={() => setHovered(!!emoji)}
39+
onMouseLeave={() => setHovered(false)}
40+
>
41+
XC
42+
<span
43+
className={clsx(
44+
'inline-flex w-[1em] justify-center leading-none',
45+
hovered && 'scale-[0.9] relative bottom-[3px] right-px',
46+
)}
47+
>
48+
{!hovered && '@'}
49+
{hovered && emoji}
50+
</span>
51+
F
52+
</span>
53+
)
1254
}

src/queries/feeds.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'server-only'
2+
import { getPayloadClient } from './payloadClient'
3+
4+
export async function findFeedBySlug(slug: string) {
5+
const payload = await getPayloadClient()
6+
7+
const { docs } = await payload.find({
8+
collection: 'feeds',
9+
where: {
10+
slug: { equals: slug },
11+
enabled: { equals: true },
12+
_status: { equals: 'published' },
13+
},
14+
limit: 1,
15+
})
16+
17+
return docs[0] ?? null
18+
}

src/queries/payloadClient.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import 'server-only'
2+
3+
import { getPayload } from 'payload'
4+
import config from '@payload-config'
5+
6+
let payloadInstance: Awaited<ReturnType<typeof getPayload>> | null = null
7+
8+
export async function getPayloadClient() {
9+
if (!payloadInstance) {
10+
payloadInstance = await getPayload({
11+
config,
12+
})
13+
}
14+
15+
return payloadInstance
16+
}

0 commit comments

Comments
 (0)