diff --git a/package.json b/package.json index 57d1570..374eef9 100644 --- a/package.json +++ b/package.json @@ -44,6 +44,7 @@ "protobufjs": "^7.5.7", "react": "^19.2.4", "react-dom": "^19.2.4", + "sonner": "^2.0.7", "tailwindcss": "^4.2.1" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a2c36be..463cc67 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -47,6 +47,9 @@ importers: react-dom: specifier: ^19.2.4 version: 19.2.6(react@19.2.6) + sonner: + specifier: ^2.0.7 + version: 2.0.7(react-dom@19.2.6(react@19.2.6))(react@19.2.6) tailwindcss: specifier: ^4.2.1 version: 4.3.0 diff --git a/src/app/layout.tsx b/src/app/layout.tsx index c9a0c4d..dffbc40 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -29,7 +29,7 @@ export default function RootLayout({ diff --git a/src/assets/Pro-Hacked.png b/src/assets/Pro-Hacked.png new file mode 100644 index 0000000..f1411d5 Binary files /dev/null and b/src/assets/Pro-Hacked.png differ diff --git a/src/assets/gpg-fingerprint.json b/src/assets/gpg-fingerprint.json new file mode 100644 index 0000000..e4d99b6 --- /dev/null +++ b/src/assets/gpg-fingerprint.json @@ -0,0 +1,3 @@ +{ + "fingerprint": "3C79 D440 DC6D 7167 36A8 BD41 70E8 63D2 6824 D0F5" +} diff --git a/src/components/about-me/AboutMe.tsx b/src/components/about-me/AboutMe.tsx index a5258e4..ec8f421 100644 --- a/src/components/about-me/AboutMe.tsx +++ b/src/components/about-me/AboutMe.tsx @@ -1,3 +1,118 @@ +'use client'; + +import { + Avatar, + AvatarFallback, + AvatarImage, + Badge, + Button, + Typography, +} from '@nipsys/lsd'; +import { + BriefcaseIcon, + CopyIcon, + LockKeyIcon, + MapPinIcon, + TargetIcon, +} from '@phosphor-icons/react'; +import { useTranslations } from 'next-intl'; +import { useState } from 'react'; +import { toast } from 'sonner'; +import gpgFingerprint from '@/assets/gpg-fingerprint.json'; +import profileImage from '@/assets/Pro-Hacked.png'; + +const GPG_FINGERPRINT = gpgFingerprint.fingerprint; + export default function AboutMe() { - return
about me / todo
; + const t = useTranslations('AboutMe'); + const [copied, setCopied] = useState(false); + + const quickInfo = [ + { icon: MapPinIcon, textKey: 'badges.location' }, + { icon: BriefcaseIcon, textKey: 'badges.experience' }, + { icon: LockKeyIcon, textKey: 'badges.focus' }, + { icon: TargetIcon, textKey: 'badges.goal' }, + ]; + + const handleCopy = async () => { + await navigator.clipboard.writeText(GPG_FINGERPRINT); + setCopied(true); + toast.success(t('copyToast')); + setTimeout(() => setCopied(false), 200); + }; + + return ( +
+
+ + + X + + +
+
+ {t('name')} + + {t('tagline')} + +
+ +
+ {quickInfo.map(({ icon: Icon, textKey }) => ( + } + > + {t(textKey)} + + ))} +
+
+
+ +
+ {t('bio.intro1')} + {t('bio.intro2')} + + + {t('bio.para1')} + + + + {t('bio.para2')} + + + + {t('bio.para3')} + + + + {t('bio.para4')} + + + + {t('bio.para5')} + + + {t('bio.current')} +
+ +
+
+ + {t('gpgLabel')} + + +
+ + {GPG_FINGERPRINT} + +
+
+ ); } diff --git a/src/components/layout/MainWrapper.tsx b/src/components/layout/MainWrapper.tsx index d4c529a..884074a 100644 --- a/src/components/layout/MainWrapper.tsx +++ b/src/components/layout/MainWrapper.tsx @@ -1,5 +1,6 @@ 'use client'; +import { Toaster } from 'sonner'; import Sidenav from './Sidenav'; export default function MainWrapper({ @@ -7,5 +8,33 @@ export default function MainWrapper({ }: Readonly<{ children: React.ReactNode; }>) { - return {children}; + return ( + <> + {children} + {/* TODO: Fix toaster export in @nipsys/lsd package to avoid doing all of this */} + + + ); } diff --git a/src/i18n/messages/en.json b/src/i18n/messages/en.json index 6d219fd..c56638f 100644 --- a/src/i18n/messages/en.json +++ b/src/i18n/messages/en.json @@ -29,11 +29,33 @@ "switchToDarkMode": "Switch to dark mode" }, "Sidebar": { - "p2pMessaging": "P2P Messaging", + "p2pMessaging": "Logos Delivery", "aboutSite": "About this site", "checkOutCode": "Check out its code", "andItsUI": "and its UI!" }, + "AboutMe": { + "name": "Xav [nipsysdev]", + "tagline": "cypherpunk / builder / digital sovereignty advocate", + "badges": { + "location": "France → Canada → Switzerland", + "experience": "10+ yrs building for the web", + "focus": "Privacy, Decentralization, FLOSS", + "goal": "Aspiring penetration tester" + }, + "bio": { + "intro1": "My name is Xavier Saliniere — a cypherpunk at heart, building and breaking things for a freer internet.", + "intro2": "I'm driven by a simple question: what if the internet actually worked for the people using it?", + "para1": "I started coding at 14, hacking together PSP homebrews in my bedroom. What began as teenage curiosity evolved into a decade-long journey through the web development world — from dropping out of school at 21 to join a startup, to building enterprise security platforms at Bell Canada's Operations Center.", + "para2": "But the real story isn't in the job titles. It's in the late nights experimenting and learning about alternative systems and technologies.", + "para3": "Diving into Linux, the FLOSS philosophy, self-hosting various services, and gradually extricating myself from the walled gardens of Big Tech. The more I learned about centralized systems and the organizations behind them, the more I developed a passion for their alternatives.", + "para4": "After 4 years in Canada, I'm now heading to Switzerland — bringing my passion for decentralized, permissionless, and privacy-preserving technologies with me.", + "para5": "Career-wise, following 10 years in web development, I'm working on shifting towards cybersecurity, with a strong interest in penetration testing.", + "current": "Currently focused on: building AnyMaps and its decentralized infrastructure, contributing to the ecosystems powering my work, getting into cybersecurity, and breaking things to see how they work :)" + }, + "gpgLabel": "GPG Fingerprint", + "copyToast": "GPG fingerprint copied to clipboard" + }, "Terminal": { "unknownCmdErr": "command not recognized", "noMatch": "no match", diff --git a/src/i18n/messages/fr.json b/src/i18n/messages/fr.json index bb5a756..f0528bd 100644 --- a/src/i18n/messages/fr.json +++ b/src/i18n/messages/fr.json @@ -29,11 +29,33 @@ "switchToDarkMode": "Passer au mode nuit" }, "Sidebar": { - "p2pMessaging": "Messagerie P2P", + "p2pMessaging": "Logos Delivery", "aboutSite": "À propos de ce site", "checkOutCode": "Voir son code", "andItsUI": "et sa lib UI !" }, + "AboutMe": { + "name": "Xav [nipsysdev]", + "tagline": "cypherpunk / développeur / défenseur de la souveraineté numérique", + "badges": { + "location": "France → Canada → Suisse", + "experience": "10+ ans à construire pour le web", + "focus": "Confidentialité, Décentralisation, FLOSS", + "goal": "Pentester en devenir" + }, + "bio": { + "intro1": "Je m'appelle Xavier Saliniere — cypherpunk dans l'âme, je développe et j'expérimente pour un internet plus libre.", + "intro2": "Une simple question me motive : et si l'internet pouvait réellement être au service de ceux qui l'utilisent ?", + "para1": "J'ai commencé à coder à 14 ans, en bricolant des homebrews PSP dans ma chambre. Ce qui a commencé comme une curiosité d'adolescent s'est transformé en un voyage d'une décennie à travers le monde du développement web — depuis l'abandon de mes études à 21 ans pour rejoindre une startup, jusqu'à développer des plateformes de sécurité d'entreprise au Centre des Opérations de Bell Canada.", + "para2": "Mais la vraie histoire n'est pas dans les postes que j'ai occupé. Elle est dans les nuits blanches à expérimenter et à découvrir des systèmes et technologies alternatifs.", + "para3": "Plonger dans Linux, la philosophie FLOSS, l'auto-hébergement de divers services, et progressivement m'extraire des \"walled gardens\" de la Big Tech. Plus j'apprenais sur les systèmes centralisés et les organisations qui les contrôlent, plus je suis devenu passioné par leurs alternatives.", + "para4": "Après 4 ans au Canada, je m'installe maintenant en Suisse — emportant avec moi ma passion pour les technologies décentralisées, \"permissionless\" et respectueuses de la vie privée.", + "para5": "Côté carrière, après 10 ans en développement web, je me forme pour transitionner vers la cybersécurité, avec un fort intérêt pour le pentesting.", + "current": "Ce que je fais actuellement : Développement d'AnyMaps et de son infrastructure décentralisée, contribution aux écosystèmes qui alimentent mes projets, formation en cybersécurité, et mes expérimentations routinières :)" + }, + "gpgLabel": "Empreinte GPG", + "copyToast": "Empreinte GPG copiée dans le presse-papier" + }, "Terminal": { "unknownCmdErr": "commande non reconnue", "noMatch": "aucune correspondance",