import {useState, type ReactNode} from 'react'; import type {ChronicleItem, PeopleItem, ReadingItem, SongItem} from '@o2o/shared'; import {useSite} from '@site/lib/site-context'; import {sectionItems, sectionName} from '@site/lib/derive'; import {PhotoCard} from '../kit/Card'; import {Sheet} from './Sheet'; const COUNT_WORD: Record = {1: '한', 2: '두', 3: '세', 4: '네'}; function More({rest, unit, children}: {rest: number; unit: string; children: ReactNode}) { if (rest <= 0) return null; return (
{rest} {unit} 더 보기 {children}
); } interface Open { title: string; meta?: string; body?: string; image?: string; } export function Story() { const payload = useSite(); const region = payload.place.addressLocality?.replace(/시$|군$/, '') ?? '지역'; const songs = sectionItems(payload, 'songs'); const people = sectionItems(payload, 'people'); const chronicle = sectionItems(payload, 'chronicle'); const reading = sectionItems(payload, 'reading'); const [open, setOpen] = useState(null); const parts = [ songs.items.length > 0 && '노래', people.items.length > 0 && '인물', chronicle.items.length > 0 && '연표', reading.items.length > 0 && '읽기', ].filter(Boolean) as string[]; if (parts.length === 0) return null; const peopleSorted = [...people.items].sort((a, b) => Number(Boolean(b.imageUrl)) - Number(Boolean(a.imageUrl))); const withPhoto = people.items.filter((p) => p.imageUrl).length; const song = (item: SongItem) => ( ); const person = (item: PeopleItem) => { const show = () => setOpen({ title: item.name, meta: [item.role, item.years].filter(Boolean).join(' · '), body: item.oneLine, image: item.imageUrl, }); if (item.imageUrl) return ( ); return ( ); }; const event = (item: ChronicleItem) => ( ); const book = (item: ReadingItem) => ( ); return ( <>

STORY

{sectionName(payload, 'story', `${region} 이야기`)} {parts.join(' · ')}

이 도시를 {COUNT_WORD[parts.length] ?? parts.length} 갈래로 봅니다. 하나씩 골라 보세요.

{songs.items.length > 0 && (

MUSIC

{songs.title || '가요 다방'} {songs.items.length}곡

{region}을 노래한 곡들입니다.

{songs.items.slice(0, 6).map(song)} {songs.items.slice(6).map(song)}
)} {people.items.length > 0 && (

PEOPLE

{people.title || '인물 열전'} {people.items.length}명

{region}과 얽힌 사람들입니다.

{peopleSorted.slice(0, 4).map(person)}
{peopleSorted.slice(4).map(person)}
{withPhoto > 0 && withPhoto < people.items.length && (

사진이 있는 {withPhoto}명을 먼저 뒀습니다.

)}
)} {chronicle.items.length > 0 && (

CHRONICLE

{chronicle.title || '시간의 골목'}

개항부터 지금까지, 이 도시의 연표입니다.

{chronicle.items.map(event)}
)} {reading.items.length > 0 && (

READING

{reading.title || `${region} 읽기`} {reading.items.length}편

{region}을 배경으로 한 문학입니다.

{reading.items.slice(0, 3).map(book)} {reading.items.slice(3).map(book)}
)} setOpen(null)} label={open?.title ?? ''}> {open && ( <> {open.image && {open.title}}

{open.title}

{open.meta &&

{open.meta}

} {open.body &&

{open.body}

} )}
); }