Skip to content

feat: live activity, interactive terminal, command palette, project case studies, SEO#7

Merged
anhvuFE merged 6 commits into
mainfrom
feat/portfolio-enhancements
May 9, 2026
Merged

feat: live activity, interactive terminal, command palette, project case studies, SEO#7
anhvuFE merged 6 commits into
mainfrom
feat/portfolio-enhancements

Conversation

@anhvuFE
Copy link
Copy Markdown
Owner

@anhvuFE anhvuFE commented May 9, 2026

Summary

Five new portfolio features plus an SEO upgrade — each shipped in its own commit so they can be reviewed independently.

# Feature Commit
1 Pre-fetched GitHub recent activity widget 6f95526
2 Interactive footer terminal (real shell) ee2848d
3 ⌘K command palette c1b43f9
4 Project case studies section 64923a1
5 OG / Twitter / JSON-LD structured data 8b31e86

1. GitHub Recent Activity

A widget below the contributions calendar lists the latest 5 public events (commits, PRs, issues, stars, forks, branch creations) with relative time and a deep link.

The first version fetched live in the browser and hit the 60-req/hr unauthenticated rate limit, so it was rewritten as a build-time pre-fetch. scripts/fetch-github-activity.js runs as a prebuild hook, calls the GitHub events API once, and writes src/components/github/recent-activity.json which the widget imports statically. If the API call fails the existing JSON is kept, so the build never breaks. Set GITHUB_TOKEN in CI to authenticate.

2. Interactive footer terminal

The footer terminal is now a real shell. Commands:

help              # list commands
whoami            # name + role
about             # short bio
skills            # tech stack
cat about|skills  # equivalent
projects | ls     # nudge towards the Projects bento card
contact           # github / linkedin / email links
echo <text>
clear
sudo / rm         # easter eggs

ArrowUp / ArrowDown walk through prior commands. Clicking anywhere in the terminal body focuses the input. The cursor blink and the existing terminal chrome are preserved.

3. ⌘K command palette

Lazy-loaded MUI dialog. ⌘K (or Ctrl+K on non-Apple) toggles it. Fuzzy search over Sections (home / about / skills / github / experience / certificates / services / projects / contact), Contact (email), and Links (GitHub / LinkedIn / CV). Arrow keys navigate, Enter opens, Esc closes. The header gets a small chip on desktop showing the platform-aware shortcut, or a search icon button on mobile.

4. Project case studies

A new bento card (purple accent, full-width row above "Let's Connect") opens a drawer with three project case studies. Each card lays out:

  • One-line summary
  • Problem (lightbulb)
  • Approach (numbered list)
  • Result (checkmarks — currently [TODO: ...] placeholders the author fills in)
  • Stack chips

The data lives in src/components/projects/projectsData.ts so it's easy to edit without touching JSX.

5. SEO

Added everything that lets Google return a rich result and LinkedIn / Facebook / Twitter / Slack render a preview when the URL is shared:

  • 12 Open Graph tags (og:type=profile, url, title, description, image with width / height / alt, site_name, locale, profile:*)
  • Twitter summary_large_image card
  • Canonical URL
  • JSON-LD Person schema (jobTitle, sameAs, knowsAbout, worksFor, alumniOf, address)
  • JSON-LD WebSite schema
  • 1200×630 og-image.png generated from the avatar via scripts/generate-og-image.js (sharp + SVG composition)

Realistic keyword expectations:

Query Expectation
"Vũ Xuân Anh", "Vu Xuan Anh", "anhvuFE" top 3-5 within ~1-2 weeks of indexing
"Vu Xuan Anh full stack developer / portfolio" top 1-3 within ~1 month
"react developer hanoi" / generic skill keywords not feasible without backlinks + custom domain

Test plan

  • npm run dev — all four sections work; ⌘K opens palette; terminal accepts help, whoami, clear
  • Bento Projects card opens a drawer with 3 case studies
  • GitHub section shows the calendar and the new activity widget below
  • npm run build — prebuild logs [github] fetched N events, build succeeds
  • Paste deployed URL into https://developers.facebook.com/tools/debug/ — preview shows the OG image and title
  • Paste deployed URL into https://search.google.com/test/rich-results — Person schema is detected
  • Mobile (≤md) — palette opens via search icon, terminal still focuses on tap

Notes for the author

  • projectsData.ts has [TODO: ...] placeholders for real numbers (lighthouse scores, time saved, ship metrics). Replace before showing this PR's deploy to recruiters.
  • GITHUB_TOKEN (or GH_TOKEN) is supported in scripts/fetch-github-activity.js. Add it to CI to refresh authenticated and skip the rate limit.

anhvuFE added 6 commits May 9, 2026 15:02
Fetches public events from GitHub API for anhvuFE, maps them to a
compact list with relative time. Cached in sessionStorage for 5 min
to stay friendly with the unauthenticated rate limit. The widget
appears below the contributions calendar and only fetches when the
GitHub section actually scrolls into view.
The footer terminal now accepts real input. Commands include:
help, whoami, about, skills, projects, contact, echo, clear,
plus a couple of easter eggs for sudo and rm. ArrowUp/Down walks
through prior commands. Input lives inside the terminal box, so
clicking anywhere in the body focuses it.
Lazy-loaded dialog with fuzzy search across sections, contact actions
and external links. Cmd/Ctrl+K toggles it; Arrow keys navigate, Enter
opens, Esc closes. The header gets a small search button next to the
nav (chip on desktop with platform-aware shortcut hint, icon button
on mobile).
New bento card opens a drawer with three project case studies, each
laid out as Problem -> Approach -> Result with the stack as chips at
the bottom. Lazy-loaded like the other sections. Numbers in the
result blocks are placeholders the user fills in.
Replace runtime fetch (which hit the unauthenticated 60-req/hr GitHub
rate limit) with a prebuild script. The script writes a JSON snapshot
that the widget imports statically. The build never blocks on a failed
GitHub call — if the request fails, the existing JSON is reused.

Set GITHUB_TOKEN in CI to refresh authenticated and skip the rate
limit.
Adds the SEO surface that lets Google return a rich result and
LinkedIn/Facebook/Twitter render a preview when the site is shared:

- Open Graph tags (type=profile, url, title, description, image,
  locale, profile:* fields)
- Twitter summary_large_image card
- canonical URL
- JSON-LD Person schema (jobTitle, sameAs, knowsAbout, worksFor,
  alumniOf, address)
- JSON-LD WebSite schema
- 1200x630 og-image generated from the avatar via sharp + SVG
  composition (scripts/generate-og-image.js)
@anhvuFE anhvuFE merged commit 8cac926 into main May 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant