Make the resume bilingual and part of the shared site chrome
Adds a Russian version (data/resume.ru.json, default language) with an RU/EN switch stored under the key shared with the front page and the portfolio. The top bar becomes the site-wide one (brand, Resume, Portfolio, Gitea, Contact, language, theme) with a second row of anchors for this page's sections, and the fonts move to Unbounded and Onest so the three pages share one type system. Portfolio links now point at /portfolio/. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XtcZtnG4GQA1d6mW5PNrS9
This commit is contained in:
+18
-12
@@ -6,18 +6,20 @@ 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: 'https://git.shanaty.ru/explore/repos?q=portfolio&topic=1' }
|
||||
const PORTFOLIO_FALLBACK: Portfolio = { href: `${process.env.NEXT_PUBLIC_SITE_ORIGIN ?? 'https://shanaty.ru'}/portfolio/` }
|
||||
|
||||
type Status = 'loading' | 'live' | 'offline'
|
||||
|
||||
export default function Site({ initial }: Readonly<{ initial: Resume }>) {
|
||||
const [resume, setResume] = useState<Resume>(initial)
|
||||
export default function Site({ initialEn, initialRu }: Readonly<{ initialEn: Resume; initialRu: Resume }>) {
|
||||
const [en, setEn] = useState<Resume>(initialEn)
|
||||
const [ru, setRu] = useState<Resume>(initialRu)
|
||||
const [projects, setProjects] = useState<Project[]>([])
|
||||
const [portfolio, setPortfolio] = useState<Portfolio>(PORTFOLIO_FALLBACK)
|
||||
const [generatedAt, setGeneratedAt] = useState<string>()
|
||||
@@ -29,7 +31,8 @@ export default function Site({ initial }: Readonly<{ initial: Resume }>) {
|
||||
.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')
|
||||
setResume(data.resume)
|
||||
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)
|
||||
@@ -43,20 +46,23 @@ export default function Site({ initial }: Readonly<{ initial: Resume }>) {
|
||||
|
||||
// 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 = resume.contacts[0].href
|
||||
const mailHref = en.contacts[0].href
|
||||
|
||||
return (
|
||||
<>
|
||||
<TopBar name={resume.name} portfolio={portfolio} showProjects={showProjects} />
|
||||
<TitleSync />
|
||||
<TopBar showProjects={showProjects} />
|
||||
<Gizmo />
|
||||
<main>
|
||||
<Hero resume={resume} portfolio={portfolio} mailHref={mailHref} showProjects={showProjects} />
|
||||
{showProjects && <Projects projects={projects} status={status} generatedAt={generatedAt} profileUrl={GITEA_PROFILE} portfolio={portfolio} />}
|
||||
<Skills resume={resume} />
|
||||
<Experience resume={resume} />
|
||||
<Education resume={resume} />
|
||||
<Hero en={en} ru={ru} portfolio={portfolio} mailHref={mailHref} showProjects={showProjects} />
|
||||
{showProjects && (
|
||||
<Projects projects={projects} status={status} generatedAt={generatedAt} profileUrl={GITEA_PROFILE} portfolio={portfolio} />
|
||||
)}
|
||||
<Skills en={en} ru={ru} />
|
||||
<Experience en={en} ru={ru} />
|
||||
<Education en={en} ru={ru} />
|
||||
</main>
|
||||
<Contact resume={resume} />
|
||||
<Contact en={en} ru={ru} />
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user