'use client' import { useEffect, useState } from 'react' import type { Live, Portfolio, Project, Resume } from '@/lib/types' import Gizmo from './Gizmo' import Hero from './Hero' import Projects from './Projects' import { Contact, Education, Experience, Skills } from './Sections' import TitleSync from './TitleSync' import TopBar from './TopBar' // Deployed on shanaty.ru the build points at the same-origin file; elsewhere (dev, GitHub Pages) it uses the public URL. const DATA_URL = process.env.NEXT_PUBLIC_DATA_URL ?? 'https://shanaty.ru/data/resume.json' const GITEA_PROFILE = 'https://git.shanaty.ru/Emil_Shanaty' // Used until (or unless) the live data supplies the link, so the portfolio button is always there. const PORTFOLIO_FALLBACK: Portfolio = { href: `${process.env.NEXT_PUBLIC_SITE_ORIGIN ?? 'https://shanaty.ru'}/portfolio/` } type Status = 'loading' | 'live' | 'offline' export default function Site({ initialEn, initialRu }: Readonly<{ initialEn: Resume; initialRu: Resume }>) { const [en, setEn] = useState(initialEn) const [ru, setRu] = useState(initialRu) const [projects, setProjects] = useState([]) const [portfolio, setPortfolio] = useState(PORTFOLIO_FALLBACK) const [generatedAt, setGeneratedAt] = useState() const [status, setStatus] = useState('loading') useEffect(() => { const controller = new AbortController() fetch(DATA_URL, { cache: 'no-store', signal: controller.signal }) .then((response) => (response.ok ? response.json() : Promise.reject(new Error(`HTTP ${response.status}`)))) .then((data: Live) => { if (!data?.resume || !Array.isArray(data.projects)) throw new Error('unexpected data') setEn(data.resume) if (data.resume_ru) setRu(data.resume_ru) setProjects(data.projects) if (data.portfolio?.href) setPortfolio(data.portfolio) setGeneratedAt(data.generated_at) setStatus('live') }) .catch((error: Error) => { if (error.name !== 'AbortError') setStatus('offline') }) return () => controller.abort() }, []) // Once the list has loaded and is empty (no repository carries the `resume` topic yet) the section is left out. const showProjects = status !== 'live' || projects.length > 0 const mailHref = en.contacts[0].href return ( <>
{showProjects && ( )}
) }