Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ next-env.d.ts
.agents
.kilocode
.playwright-mcp
skills-lock.json
skills-lock.json

# Resume (symlink to submodule)
/public/resume
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "external/resume"]
path = external/resume
url = git@github.com:nipsysdev/resume.git
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,9 @@ elements.
git clone https://github.com/nipsysdev/site.git
cd site

# Initialize submodules (for resume PDFs)
git submodule update --init --recursive

# Install dependencies
pnpm install

Expand Down Expand Up @@ -91,6 +94,7 @@ The site uses a terminal emulator interface. Available commands:
| ------------ | --------------------------------------- |
| `welcome` | Display welcome message |
| `whoami` | About me - bio, badges, GPG fingerprint |
| `resume` | View/download resume (EN/FR) |
| `contact` | Contact information and social links |
| `status` | Self-hosted services health status |
| `help` | List available commands |
Expand Down
1 change: 1 addition & 0 deletions external/resume
Submodule resume added at da4130
25 changes: 25 additions & 0 deletions src/app/[locale]/resume/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Resume from '@/components/resume/Resume';
import StaticOutput from '@/components/StaticOutput';
import TerminalEmulator from '@/components/terminal/TerminalEmulator';
import type { RouteData } from '@/types/routing';
import { Command } from '@/types/terminal';
import { setPageMeta } from '@/utils/metadata-utils';

interface ResumePageProps {
params: Promise<{ locale: string }>;
}

export const generateMetadata = async (routeData: RouteData) =>
await setPageMeta(routeData, 'resume');

export default async function ResumePage({ params }: ResumePageProps) {
await params;
return (
<>
<StaticOutput>
<Resume />
</StaticOutput>
<TerminalEmulator initialCommand={Command.Resume} />
</>
);
}
9 changes: 9 additions & 0 deletions src/components/cmd-outputs/ResumeOutput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Component } from 'react';
import type { CommandOutputProps } from '@/types/terminal';
import Resume from '../resume/Resume';

export default class ResumeOutput extends Component<CommandOutputProps> {
render() {
return <Resume />;
}
}
57 changes: 57 additions & 0 deletions src/components/resume/Resume.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
'use client';

import { Badge, Button, Typography } from '@nipsys/lsd';
import { useLocale, useTranslations } from 'next-intl';

const RESUME_PATHS = {
en: '/resume/Xavier-SALINIERE_resume.EN.pdf',
fr: '/resume/Xavier-SALINIERE_resume.FR.pdf',
};

export default function Resume() {
const locale = useLocale();
const t = useTranslations('Terminal.cmds.resume');

const currentLocale = locale === 'fr' ? 'fr' : 'en';
const currentPdfPath = RESUME_PATHS[currentLocale];

return (
<div className="flex flex-col gap-(--lsd-spacing-large) py-(--lsd-spacing-small)">
<div className="flex flex-col gap-(--lsd-spacing-smallest)">
<Typography variant="h2">{t('title')}</Typography>
<Typography variant="body2" color="secondary">
{t('subtitle')}
</Typography>
</div>

<div className="flex items-center gap-(--lsd-spacing-smaller)">
<Badge variant="outlined" size="sm">
{t('viewing')} {currentLocale.toUpperCase()} {t('version')}
</Badge>
</div>

<div className="flex flex-wrap gap-(--lsd-spacing-smaller)">
<Button variant="outlined" size="sm" asChild>
<a href={RESUME_PATHS.en} download>
{t('downloadEN')}
</a>
</Button>
<Button variant="outlined" size="sm" asChild>
<a href={RESUME_PATHS.fr} download>
{t('downloadFR')}
</a>
</Button>
</div>

<div className="flex flex-col gap-(--lsd-spacing-base)">
<div className="w-full h-[600px] border border-(--lsd-color-border) rounded-(--lsd-shape-sm) overflow-hidden">
<iframe
src={currentPdfPath}
className="w-full h-full"
title="Resume PDF"
/>
</div>
</div>
</div>
);
}
13 changes: 9 additions & 4 deletions src/constants/commands.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import BuildInfoOutput from '@/components/cmd-outputs/BuildInfoOutput';
import ContactOutput from '@/components/cmd-outputs/ContactOutput';
import HelpOutput from '@/components/cmd-outputs/HelpOutput';
import ResumeOutput from '@/components/cmd-outputs/ResumeOutput';
import StatusOutput from '@/components/cmd-outputs/StatusOutput';
import WelcomeOutput from '@/components/cmd-outputs/WelcomeOutput';
import WhoamiOutput from '@/components/cmd-outputs/WhoamiOutput';
Expand All @@ -19,14 +20,18 @@ export const Commands: CommandInfo[] = [
name: Command.Whoami,
output: WhoamiOutput,
},
{
name: Command.Contact,
output: ContactOutput,
},
{
name: Command.Status,
output: StatusOutput,
},
{
name: Command.Resume,
output: ResumeOutput,
},
{
name: Command.Contact,
output: ContactOutput,
},
{
name: Command.Clear,
},
Expand Down
1 change: 1 addition & 0 deletions src/constants/routes.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export const Routes = {
welcome: '/',
whoami: '/whoami',
resume: '/resume',
status: '/status',
contact: '/contact',
};
12 changes: 11 additions & 1 deletion src/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"welcome": "welcome",
"whoami": "whoami",
"status": "status",
"contact": "contact"
"contact": "contact",
"resume": "resume"
},
"Status": {
"connected": "Connected",
Expand Down Expand Up @@ -123,6 +124,15 @@
"degraded": "Degraded",
"down": "Down"
}
},
"resume": {
"description": "View my resume/CV",
"title": "Resume",
"subtitle": "View and download my resume in PDF format",
"downloadEN": "Download (English)",
"downloadFR": "Download (French)",
"viewing": "Currently viewing",
"version": "version"
}
}
}
Expand Down
12 changes: 11 additions & 1 deletion src/i18n/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@
"welcome": "bienvenue",
"whoami": "qui suis-je",
"status": "statut",
"contact": "contact"
"contact": "contact",
"resume": "cv"
},
"Status": {
"connected": "Connecté",
Expand Down Expand Up @@ -123,6 +124,15 @@
"degraded": "Dégradé",
"down": "H.S."
}
},
"resume": {
"description": "Voir mon CV",
"title": "CV",
"subtitle": "Afficher et télécharger mon CV en format PDF",
"downloadEN": "Télécharger (Anglais)",
"downloadFR": "Télécharger (Français)",
"viewing": "Version",
"version": "actuellement affichée"
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/types/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export enum Command {
Status = 'status',
Welcome = 'welcome',
Whoami = 'whoami',
Resume = 'resume',
}

export interface CommandEntry {
Expand Down
Loading