WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Commit b9993f7

Browse files
author
mlavanga
committed
reskills
1 parent a065dc8 commit b9993f7

18 files changed

+183
-28
lines changed

.next.pid

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9132
1+
11383

GEMINI.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# Project Context: Mario Lavanga's Personal Website (v2)
2+
3+
## Overview
4+
This project contains the source code for the personal academic and professional website of **Mario Lavanga**.
5+
6+
**Current Status (Nov 2025):**
7+
The website has been migrated from **Jekyll** to **Next.js**.
8+
* **Root**: The new Next.js application (v2).
9+
* **`v_old/`**: The legacy Jekyll application (v1), preserved for reference.
10+
11+
## Architecture & Technologies (New Site)
12+
* **Framework**: [Next.js 16](https://nextjs.org/) (App Router).
13+
* **Language**: TypeScript.
14+
* **Styling**: Tailwind CSS 4.
15+
* **Deployment**: GitHub Pages (Static Export).
16+
* **CI/CD**: GitHub Actions (`.github/workflows/nextjs.yml`).
17+
18+
## Directory Structure
19+
* **`app/`**: Main Next.js application code (components, pages, data).
20+
* `components/`: Reusable UI components (Hero, Navbar, ProjectCard, etc.).
21+
* `data/`: Content files (e.g., `content.ts`) replacing the old `_config.yml`.
22+
* **`public/`**: Static assets (images, SVGs).
23+
* **`v_old/`**: The complete legacy Jekyll codebase.
24+
* **`old_content/`**: Backup of raw markdown content/config from the legacy site.
25+
26+
## Development Workflow
27+
28+
### 1. Managing the New Site (Next.js)
29+
The site runs on **Port 3000**. Use the helper script `serve.sh` to manage the background process.
30+
31+
* **Start**: `./serve.sh start`
32+
* **Stop**: `./serve.sh stop`
33+
* **Status**: `./serve.sh status`
34+
* **Logs**: `./serve.sh logs` (or `tail -f next.log`)
35+
36+
*Standard Method*: `npm run dev`
37+
38+
### 2. Managing the Legacy Site (Jekyll)
39+
The legacy site runs on **Port 4000**. Use the helper script `serve_old.sh` (which wraps the old `serve.sh` inside `v_old`).
40+
41+
* **Start**: `./serve_old.sh start`
42+
* **Stop**: `./serve_old.sh stop`
43+
* **Status**: `./serve_old.sh status`
44+
* **Logs**: `./serve_old.sh logs` (or `tail -f v_old/jekyll.log`)
45+
46+
**Note:** Ensure Port 4000 is free before starting the legacy site.
47+
48+
### 3. Deployment
49+
The site is deployed automatically to GitHub Pages via GitHub Actions.
50+
* **Trigger**: Push to `master` or `main`.
51+
* **Config**: `.github/workflows/nextjs.yml`.
52+
* **Build Mode**: Static Export (`output: 'export'` in `next.config.ts`).
53+
54+
## Key Configuration Files
55+
* **`next.config.ts`**: Configures static export and image optimization settings for GitHub Pages.
56+
* **`tailwind.config.ts`** (or internal theme): Configures the design system.
57+
* **`app/data/content.ts`**: Central file for editing website content (Bio, Experience, Projects, Publications). This replaces Jekyll's `_config.yml`.
58+
59+
## Migration Notes
60+
* The legacy content has been ported to `app/data/content.ts`.
61+
* New features should be developed in the Next.js app (`app/`).
62+
* The `v_old` directory is frozen and should typically not be modified unless necessary for historical reference.

app/components/Footer.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,12 @@ export default function Footer({ info }: { info: PersonalInfo }) {
66
<div className="container mx-auto px-6 text-center">
77
<h2 className="text-2xl font-bold text-white mb-6">{info.name}</h2>
88

9-
<div className="flex justify-center gap-8 mb-8">
9+
<div className="flex justify-center gap-8 mb-8 flex-wrap">
1010
<a href={`mailto:${info.email[0]}`} className="hover:text-blue-400 transition-colors">Email</a>
1111
<a href={`https://github.com/${info.socials.github}`} className="hover:text-blue-400 transition-colors">GitHub</a>
1212
<a href={`https://linkedin.com/in/${info.socials.linkedin}`} className="hover:text-blue-400 transition-colors">LinkedIn</a>
13-
<a href={`https://twitter.com/${info.socials.twitter}`} className="hover:text-blue-400 transition-colors">Twitter</a>
13+
<a href={`https://scholar.google.com/citations?user=${info.socials.scholar}`} className="hover:text-blue-400 transition-colors">Google Scholar</a>
14+
<a href={`https://youtube.com/channel/${info.socials.youtube}`} className="hover:text-blue-400 transition-colors">YouTube</a>
1415
</div>
1516

1617
<p className="text-slate-500 text-sm">

app/components/Hero.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,16 @@ export default function Hero({ info }: { info: PersonalInfo }) {
3636
<div className="flex gap-4 pt-4">
3737
<SocialLink href={`https://github.com/${info.socials.github}`} icon="github" />
3838
<SocialLink href={`https://linkedin.com/in/${info.socials.linkedin}`} icon="linkedin" />
39-
<SocialLink href={`https://twitter.com/${info.socials.twitter}`} icon="twitter" />
39+
<SocialLink href={`https://scholar.google.com/citations?user=${info.socials.scholar}`} icon="scholar" />
40+
<SocialLink href={`https://youtube.com/channel/${info.socials.youtube}`} icon="youtube" />
4041
</div>
4142
</div>
4243

4344
<div className="relative flex justify-center">
4445
{/* Placeholder for 3D Brain or Neural Network Visual */}
4546
<div className="w-80 h-80 md:w-96 md:h-96 bg-gradient-to-br from-blue-500 to-cyan-400 rounded-full opacity-20 blur-2xl absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2"></div>
4647
<div className="relative w-64 h-64 md:w-80 md:h-80 rounded-2xl overflow-hidden shadow-2xl border-4 border-white dark:border-slate-800 rotate-3 hover:rotate-0 transition-all duration-500">
47-
{/* Use a placeholder image if local image is tricky to reference correctly without moving it */}
48-
<img src="https://mlavanga.github.io/images/profile.jpg" alt={info.name} className="w-full h-full object-cover" />
48+
<img src="/images/profile.jpg" alt={info.name} className="w-full h-full object-cover" />
4949
</div>
5050
</div>
5151
</div>
@@ -54,19 +54,20 @@ export default function Hero({ info }: { info: PersonalInfo }) {
5454
}
5555

5656
function SocialLink({ href, icon }: { href: string; icon: string }) {
57-
// Simple text fallback or icon placeholder
5857
return (
5958
<a href={href} target="_blank" rel="noreferrer" className="p-2 text-slate-400 hover:text-blue-500 transition-colors">
6059
<span className="sr-only">{icon}</span>
61-
{/* Simple SVG Icons */}
6260
{icon === 'github' && (
6361
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
6462
)}
6563
{icon === 'linkedin' && (
6664
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>
6765
)}
68-
{icon === 'twitter' && (
69-
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M24 4.557c-.883.392-1.832.656-2.828.775 1.017-.609 1.798-1.574 2.165-2.724-.951.564-2.005.974-3.127 1.195-.897-.957-2.178-1.555-3.594-1.555-3.179 0-5.515 2.966-4.797 6.045-4.091-.205-7.719-2.165-10.148-5.144-1.29 2.213-.669 5.108 1.523 6.574-.806-.026-1.566-.247-2.229-.616-.054 2.281 1.581 4.415 3.949 4.89-.693.188-1.452.232-2.224.084.626 1.956 2.444 3.379 4.6 3.419-2.07 1.623-4.678 2.348-7.29 2.04 2.179 1.397 4.768 2.212 7.548 2.212 9.142 0 14.307-7.721 13.995-14.646.962-.695 1.797-1.562 2.457-2.549z"/></svg>
66+
{icon === 'scholar' && (
67+
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M12 24a7 7 0 1 1 0-14 7 7 0 0 1 0 14zm0-24L0 9.5l4.838 3.94A8 8 0 0 1 12 9a8 8 0 0 1 7.162 4.44L24 9.5z"/></svg>
68+
)}
69+
{icon === 'youtube' && (
70+
<svg className="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"><path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/></svg>
7071
)}
7172
</a>
7273
);

app/components/Media.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { MediaItem } from '../data/content';
2+
3+
export default function Media({ items }: { items: MediaItem[] }) {
4+
return (
5+
<div className="grid md:grid-cols-2 gap-8">
6+
{items.map((item, index) => (
7+
<div key={index} className="bg-white dark:bg-slate-800 rounded-xl overflow-hidden border border-slate-200 dark:border-slate-700">
8+
<div className="p-6">
9+
<h3 className="text-xl font-bold text-slate-900 dark:text-white mb-2">{item.title}</h3>
10+
<p className="text-slate-600 dark:text-slate-300 mb-4">{item.description}</p>
11+
12+
{item.video_id && item.video_id !== "PLACEHOLDER_VIDEO_ID" ? (
13+
<div className="aspect-video rounded-lg overflow-hidden bg-slate-900">
14+
<iframe
15+
width="100%"
16+
height="100%"
17+
src={`https://www.youtube.com/embed/${item.video_id}`}
18+
title={item.title}
19+
frameBorder="0"
20+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
21+
allowFullScreen
22+
></iframe>
23+
</div>
24+
) : item.channel_id ? (
25+
<div className="aspect-video rounded-lg overflow-hidden bg-slate-100 dark:bg-slate-900 flex items-center justify-center flex-col p-6 text-center border-2 border-dashed border-slate-300 dark:border-slate-700">
26+
<div className="text-red-600 mb-2">
27+
<svg className="w-12 h-12 mx-auto" fill="currentColor" viewBox="0 0 24 24"><path d="M19.615 3.184c-3.604-.246-11.631-.245-15.23 0-3.897.266-4.356 2.62-4.385 8.816.029 6.185.484 8.549 4.385 8.816 3.6.245 11.626.246 15.23 0 3.897-.266 4.356-2.62 4.385-8.816-.029-6.185-.484-8.549-4.385-8.816zm-10.615 12.816v-8l8 3.993-8 4.007z"/></svg>
28+
</div>
29+
<p className="text-slate-600 dark:text-slate-400 mb-4">Watch videos on my channel</p>
30+
<a
31+
href={`https://youtube.com/channel/${item.channel_id}`}
32+
target="_blank"
33+
rel="noreferrer"
34+
className="inline-flex items-center px-4 py-2 bg-red-600 hover:bg-red-700 text-white rounded-md transition-colors font-medium"
35+
>
36+
Visit Channel
37+
</a>
38+
</div>
39+
) : (
40+
<div className="aspect-video bg-slate-100 dark:bg-slate-900 flex items-center justify-center text-slate-400">
41+
Video content coming soon
42+
</div>
43+
)}
44+
</div>
45+
</div>
46+
))}
47+
</div>
48+
);
49+
}

app/components/Navbar.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ export default function Navbar() {
1313
<NavLink href="#experience">Experience</NavLink>
1414
<NavLink href="#projects">Projects</NavLink>
1515
<NavLink href="#publications">Publications</NavLink>
16+
<NavLink href="#skills">Skills</NavLink>
17+
<NavLink href="#media">Media</NavLink>
1618
<NavLink href="#contact">Contact</NavLink>
1719
</div>
1820

app/components/Skills.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { SkillItem } from '../data/content';
2+
3+
export default function Skills({ items }: { items: SkillItem[] }) {
4+
return (
5+
<div className="grid grid-cols-2 md:grid-cols-4 gap-4">
6+
{items.map((item, index) => (
7+
<div key={index} className="bg-white dark:bg-slate-800/50 p-4 rounded-lg border border-slate-100 dark:border-slate-700 text-center hover:border-blue-500/30 transition-colors">
8+
<h3 className="font-bold text-slate-900 dark:text-white">{item.name}</h3>
9+
<p className="text-sm text-blue-600 dark:text-blue-400 mt-1">{item.level}</p>
10+
</div>
11+
))}
12+
</div>
13+
);
14+
}

app/data/content.ts

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ export interface SkillItem {
2222
level: string;
2323
}
2424

25+
export interface MediaItem {
26+
title: string;
27+
video_id?: string;
28+
channel_id?: string;
29+
description: string;
30+
}
31+
2532
export interface PersonalInfo {
2633
name: string;
2734
title: string;
@@ -32,7 +39,6 @@ export interface PersonalInfo {
3239
socials: {
3340
github: string;
3441
linkedin: string;
35-
twitter: string;
3642
scholar: string;
3743
orcid: string;
3844
youtube: string;
@@ -43,14 +49,13 @@ export interface PersonalInfo {
4349
export const personalInfo: PersonalInfo = {
4450
name: "Mario Lavanga",
4551
title: "Computational Neuroscientist, Data Scientist, Postdoctoral researcher at the Theoretical Neuroscience Group - INS - Aix-Marseille University",
46-
52+
4753
phone: "+33 6 52 93 31 80",
4854
website: "https://mlavanga.github.io",
49-
cv: "https://mlavanga.github.io/documents/LAVANGA_CV.pdf",
55+
cv: "/documents/LAVANGA_CV.pdf",
5056
socials: {
5157
github: "mlavanga",
5258
linkedin: "mario-lavanga-87a0a7a3",
53-
twitter: "mario_lavanga",
5459
scholar: "oM1rUeIAAAAJ&hl",
5560
orcid: "0000-0002-3615-033X",
5661
youtube: "UCPGcAPYLko6G6p-1ZfM8CvQ",
@@ -203,3 +208,16 @@ export const skills: SkillItem[] = [
203208
{ name: "Slurm", level: "Basic" },
204209
{ name: "LabView", level: "Basic" }
205210
];
211+
212+
export const media: MediaItem[] = [
213+
{
214+
title: "PhD Graduation Video",
215+
description: "Video recording of the PhD graduation ceremony.",
216+
video_id: "PLACEHOLDER_VIDEO_ID" // Replace with actual ID if available, or use channel logic
217+
},
218+
{
219+
title: "YouTube Channel",
220+
description: "Check out my YouTube channel for more videos.",
221+
channel_id: "UCPGcAPYLko6G6p-1ZfM8CvQ"
222+
}
223+
];

app/page.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,10 @@ import Hero from './components/Hero';
33
import Section from './components/Section';
44
import ExperienceCard from './components/ExperienceCard';
55
import ProjectCard from './components/ProjectCard';
6+
import Skills from './components/Skills';
7+
import Media from './components/Media';
68
import Footer from './components/Footer';
7-
import { personalInfo, experience, education, projects, publications } from './data/content';
9+
import { personalInfo, experience, education, projects, publications, skills, media } from './data/content';
810

911
export default function Home() {
1012
return (
@@ -45,6 +47,16 @@ export default function Home() {
4547
</div>
4648
</Section>
4749

50+
<Section id="skills" title="Skills & Proficiency" className="bg-slate-50 dark:bg-slate-800/30">
51+
<div className="max-w-4xl mx-auto">
52+
<Skills items={skills} />
53+
</div>
54+
</Section>
55+
56+
<Section id="media" title="Media" className="bg-white dark:bg-slate-900">
57+
<Media items={media} />
58+
</Section>
59+
4860
<Section id="contact" title="Get in Touch" className="bg-blue-600 text-white">
4961
<div className="text-center max-w-2xl mx-auto">
5062
<p className="text-xl mb-8 opacity-90">

next.log

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,5 @@
77
- Network: http://192.168.1.177:3000
88

99
✓ Starting...
10-
✓ Ready in 651ms
11-
GET / 200 in 2.2s (compile: 1918ms, render: 331ms)
12-
GET / 200 in 249ms (compile: 4ms, render: 245ms)
13-
⚠ Found a change in next.config.ts. Restarting the server to apply the changes...
14-
▲ Next.js 16.0.4 (Turbopack)
15-
- Local: http://localhost:3000
16-
- Network: http://192.168.1.177:3000
17-
18-
✓ Starting...
19-
✓ Ready in 679ms
20-
GET / 200 in 2.6s (compile: 1991ms, render: 620ms)
21-
GET / 200 in 287ms (compile: 10ms, render: 277ms)
22-
✓ Compiled in 70ms
10+
✓ Ready in 721ms
11+
GET / 200 in 2.7s (compile: 2.2s, render: 473ms)

0 commit comments

Comments
 (0)