Skip to content

Commit 42b39a8

Browse files
committed
feat: overhaul portfolio structure with new CSS modules, JS utilities, and optimized project assets
1 parent 0fc311e commit 42b39a8

66 files changed

Lines changed: 3501 additions & 12179 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy.yml

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
name: Deploy Portfolio
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: false
16+
17+
jobs:
18+
build-and-deploy:
19+
runs-on: ubuntu-latest
20+
environment:
21+
name: github-pages
22+
url: ${{ steps.deployment.outputs.page_url }}
23+
24+
steps:
25+
- name: Checkout repository
26+
uses: actions/checkout@v4
27+
28+
- name: Set up Python
29+
uses: actions/setup-python@v5
30+
with:
31+
python-version: "3.12"
32+
33+
- name: Install uv
34+
uses: astral-sh/setup-uv@v4
35+
36+
- name: Install dependencies
37+
run: uv pip install --system -r requirements.txt
38+
39+
- name: Generate portfolio HTML
40+
run: python generate_portfolio_modified.py
41+
42+
- name: Verify build output
43+
run: |
44+
echo "Generated files:"
45+
ls -la *.html
46+
ls -la posts/*.html
47+
echo "Sitemap:"
48+
head -5 sitemap.xml
49+
50+
- name: Upload artifact
51+
uses: actions/upload-pages-artifact@v3
52+
with:
53+
path: .
54+
55+
- name: Deploy to GitHub Pages
56+
id: deployment
57+
uses: actions/deploy-pages@v4

README.md

Lines changed: 66 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
This repository contains the complete source code and content for my personal portfolio website, built by Mit Patel. It's a fully static site generated using Python, Jinja2, and a custom build script, designed to be a living document of my projects, skills, and technical learnings.
66

7-
The entire site is generated from a single, centralized [`JSON database`](portfolio-mit_v1.json), making it incredibly easy to maintain and update.
7+
The entire site is generated from a single, centralized [`portfolio.json`](portfolio.json) database, making it incredibly easy to maintain and update.
88

99
**Live Site:** [gojo-rika.github.io](https://gojo-rika.github.io/)
1010

@@ -21,33 +21,45 @@ This approach gives me the best of both worlds:
2121
* **Easy Maintenance:** To add a new project or blog post, I only need to update the JSON and Markdown files and re-run the script. No HTML editing is required.
2222
* **High Performance:** The final output is pure, lightweight static files, which are incredibly fast, secure, and can be hosted for free on platforms like GitHub Pages.
2323

24-
2524
---
2625

2726
## Features
2827

29-
This portfolio is packed with features we've built from the ground up:
28+
This portfolio is packed with features built from the ground up:
3029

31-
* **Centralized Data Management:** All content (project details, blog posts, skills, etc.) is managed in a single [`updated-data.json`](future-work/updated-data.json) file, acting as a "single source of truth."
32-
* **Dynamic Site Generation:** A Python script ([`generate_portfolio_modified.py`](generate_portfolio_modified.py)) serves as the build engine.
30+
* **Centralized Data Management:** All content (project details, blog posts, skills, etc.) is managed in a single [`portfolio.json`](portfolio.json) file, acting as a "single source of truth." Projects and their associated blogs are grouped together under `projects_blog_db` — one place to update a GitHub URL, image, or summary.
31+
* **Dynamic Site Generation:** A Python script ([`generate_portfolio_modified.py`](generate_portfolio_modified.py)) serves as the build engine, deriving `featured_projects`, `projects`, and `blogs` lists at runtime from the unified database.
3332
* **Multi-Page Architecture:** Includes separate, fully-featured pages for:
34-
* **Homepage:** A personal introduction and high-level summary.
35-
* **Resume:** A clean, professional resume layout.
36-
* **Projects:** A beautiful, card-based gallery of my featured work.
33+
* **Homepage:** A personal introduction with "About Me" prose and an "At a Glance" sidebar.
34+
* **Resume:** A clean, professional resume layout with work experience, education, and technical skills.
35+
* **Projects:** A beautiful, card-based gallery of featured work with tech stack icons.
3736
* **Tech Stack:** A visual grid of all the technologies I'm proficient in.
38-
* **Blog:** A filterable list of all my technical articles.
39-
* **Contact:** A clear call-to-action page.
37+
* **Blog:** A filterable, paginated list of all my technical articles.
38+
* **Contact:** A direct contact form with Web3Forms (primary) + Formspree (fallback) plus social link cards.
4039
* **Markdown-Powered Blog:**
4140
* Blog posts are written in simple Markdown files.
4241
* The build script automatically converts them to styled HTML pages.
43-
* Supports multi-part blog series with automatic "Part 1 / Part 2" linking.
42+
* Supports multi-part blog series with automatic "Part 1 / Part 2 / Part 3" linking.
4443
* Includes "Previous/Next Post" navigation to encourage reader engagement.
4544
* **Interactive UI & UX:**
4645
* **Light/Dark Theme Toggle:** A site-wide, persistent theme switcher with a floating icon.
4746
* **Themed Icons:** All SVG icons (for social links and tech stacks) are theme-aware, automatically changing color to match the light or dark mode.
48-
* **Interactive Filtering:** The blog page features a sidebar that allows users to filter posts by core technologies.
47+
* **Multi-Select OR Filters:** The blog page allows filtering by multiple technologies simultaneously using OR logic.
48+
* **Dynamic Post Counter:** The "Total Posts" counter updates in real-time based on active filters.
49+
* **Load More Pagination:** Blog posts load incrementally with smooth scroll-to-new-content behavior.
50+
* **Mobile Filter Panel:** On small screens, filters collapse into a toggleable icon panel with outside-click-to-close.
51+
* **Client-Side Search:** A floating search button (with ⌘K shortcut) opens a modal overlay to search across all blog post titles, summaries, and tags.
52+
* **Horizontal Progress Bar:** A reading progress indicator at the top of blog post pages.
53+
* **Table of Contents (TOC):** Auto-generated from blog post headings with a collapsible hamburger menu on mobile.
54+
* **Sticky Sidebar:** Post metadata and TOC remain fixed while scrolling through content.
4955
* **Responsive Design:** Custom CSS ensures the site looks great on both desktop and mobile devices.
50-
* **Deep Project-Blog Integration:** Each project card on the "Projects" page links directly to its corresponding detailed "Read the Story" blog post, creating a powerful narrative flow.
56+
* **SEO & Open Graph:** Auto-generated `meta_description`, `meta_keywords`, and `og:description` for every blog post, plus proper Open Graph tags on all pages.
57+
* **Sitemap & Robots.txt:** Automatically generated `sitemap.xml` (with all pages and blog posts) and `robots.txt` at build time.
58+
* **Automated Image Optimization:** The build script converts all images in `project_images/` and `posts_assets/` to WebP format with thumbnails.
59+
* **Deep Project-Blog Integration:** Each project card on the "Projects" page links directly to its corresponding detailed "Read the Story" blog post.
60+
* **Dual Contact Form:** A contact form using Web3Forms as the primary endpoint with an automatic Formspree fallback, client-side validation, loading states, success/error toasts, and honeypot anti-spam fields.
61+
* **CI/CD Pipeline:** A GitHub Actions workflow (`.github/workflows/deploy.yml`) that automatically builds and deploys the site to GitHub Pages on every push to `main`.
62+
* **Modular Codebase:** All inline CSS and JS has been extracted into dedicated external files (`css/blog.css`, `js/blog.js`, etc.) for improved maintainability and caching.
5163

5264
---
5365

@@ -88,34 +100,17 @@ This portfolio is packed with features we've built from the ground up:
88100
89101
---
90102
91-
## Future Roadmap & To-Do List ---> Total: 18, Completed: 11; 09.03.2026
103+
## Future Roadmap & To-Do List ---> Total: 22, Completed: 20; 03.04.2026
92104
93105
This project is a continuous work in progress. Here are some of the features and improvements planned for the future:
94106
95-
* `[ ]` **Integrate a CSS Framework (e.g., Bootstrap):** To further improve the responsive design and accelerate the addition of new UI components, I plan to refactor the custom CSS to use a professional framework. This will involve updating the HTML templates to use the framework's class system.
96-
97-
* `[ ]` **Implement a Direct Contact Form:** To provide an alternative to the `mailto:` link, I plan to integrate a third-party service (like Formspree) to handle direct message submissions from a form on the contact page. This will require setting up the service and adding a `<form>` element to the [`contact_template.html`](contact_template.html).
98-
99-
* `[ ]` **Content Expansion:**
100-
* Add more projects to the [`json`](portfolio-mit_v1.json) file.
101-
* Write more technical blog posts.
102-
* Continue to expand and refine the `tech_stack` with new skills.
103-
104-
* `[ ]` **Update architecture diagram link in markdown file**
107+
* `[ ]` **Update architecture diagram link in markdown file:**
105108
* by simply adding `../` or `/` should work on local system, but that does not solve the problem in static `html` page
106109
* the current approach solves the issue for `html` page but when previewing the `markdown` file, the **image** is not shown (both in **local** as well as in **github repos**)
107110
108-
* `[ ]` **Organise data inside `json` file:**
109-
* Keep the data in a structured format so there are no duplicates.
110-
* The data for a project/blog must be together ([`project_db`](future-work/project_db.json)) to make it easier to edit details like Github URLs, blog images, project card thumbnail, blog home page summary, etc, etc, etc.
111-
* Follow the structure given in [`update-data.json`](future-work/updated-data.json) and [`project_db.json`](future-work/project_db.json) in [`future-work`](future-work/) folder.
112-
113111
* `[ ]` **Architecture diagram and video or a gif:**
114112
* Add architecture diagram of the project or the blog or create a video doing a walkthrough of the project or a gif of the working ui.
115113
116-
* `[ ]` **Clean individual html files by removing extra white space:**
117-
* Remove extra white space from individual html files to make them more readable. (see [`future-work/images/unclean-html-code-block.png`](future-work/images/unclean-html-code-block.png))
118-
119114
* `[x]` **Add a "Copy Code" Button to Code Blocks:** -- 27.02.2026
120115
* A final layer of polish for the blog, allowing visitors to easily copy code snippets. This was originally attempted with Prism.js plugins, but has now been resolved directly using a custom Javascript implementation to sidestep the plugin issues.
121116
@@ -130,25 +125,54 @@ This project is a continuous work in progress. Here are some of the features and
130125
* Add horizontal progress scroll bar to the top of the page to make it easier for users to navigate the page.
131126
132127
* `[x]` **Add dynamic pagination for blog page:** -- 08.03.2026
133-
* Add dynamic pagination for blog page to make it easier for users to navigate through the blog posts. --> `Load More Posts` button at the end of the blog page. (see [`future-work/images/dynamic-pagination.png`](future-work/images/dynamic-pagination.png))
128+
* Add dynamic pagination for blog page to make it easier for users to navigate through the blog posts. --> `Load More Posts` button at the end of the blog page.
134129
135130
* `[x]` **Add heading sections inside blog post page:** -- 09.03.2026
136-
* In the blog post page, add page headings and links for easy scrolling and navigating through the page.
137-
* This also helps in giving a brief of the blog post page.
138-
* See [`future-work/images/blog-post-page.png`](future-work/images/blog-post-page.png) for reference and [`future-work/images/reference-sample.png`](future-work/images/reference-sample.png)
131+
* In the blog post page, add page headings and links for easy scrolling and navigating through the page.
139132
140133
* `[x]` **Add table of contents in posts page:** -- 09.03.2026
141-
* Add table of contents in posts page to make it easier for users to navigate through the blog posts. (see [`future-work/images/table-of-content-2.png`](future-work/images/table-of-content-2.png) and [`future-work/images/table-of-content-3.png`](future-work/images/table-of-content-3.png))
134+
* Add table of contents in posts page to make it easier for users to navigate through the blog posts.
142135
143136
* `[x]` **Modify the code such that the sidebar is fixed in the page while scrolling down (sticky positioning):** -- 09.03.2026
144-
* where the sidebar (or an element) remains fixed in place while the rest of the page scrolls—is called "sticky positioning" in web design. (see [`future-work/images/sticky-positioning-highlight-01.png`](future-work/images/sticky-positioning-highlight-01.png) and [`future-work/images/sticky-positioning-highlight-02.png`](future-work/images/sticky-positioning-highlight-02.png))
137+
* where the sidebar (or an element) remains fixed in place while the rest of the page scrolls—is called "sticky positioning" in web design.
145138
146139
* `[x]` **Keep 3 projects columns:**
147-
* Need to make changes in [`project_template`](projects_template.html) to make sure it includes 3 project cards in each row. (see [`future-work/images/project-page.png`](future-work/images/project-page.png))
140+
* Need to make changes in [`project_template`](projects_template.html) to make sure it includes 3 project cards in each row.
148141
149142
* `[x]` **Add read story section in project page:**
150143
* In the project page, under the given project card, add a link to read the blog along with viewing it on github.
151-
* The blog will be redirected to the 1st blog in the series.
152144
153-
* `[x]` **Add a section in blog page to show the number of posts:**
154-
* Add a section in blog page to show the number of posts. (see `future-work/images/number-of-posts.png`)
145+
* `[x]` **Mobile filter panel improvements:** -- 18.03.2026
146+
* On mobile, filters collapse into a toggleable icon. The panel closes when clicking outside of it.
147+
148+
* `[x]` **Load More scroll behavior:** -- 18.03.2026
149+
* After clicking "Load More Posts," the viewport automatically scrolls to the first newly loaded post, instead of staying at the bottom.
150+
151+
* `[x]` **Dynamic "Total Posts" counter:** -- 25.03.2026
152+
* The "Total Posts" counter next to "Recent Posts" now updates in real-time based on the number of posts matching the currently selected filters.
153+
154+
* `[x]` **Multi-select OR filters for blog page:** -- 18.03.2026
155+
* Users can select multiple technology tags simultaneously. Filtering uses "OR" logic — posts matching *any* selected tag are shown.
156+
157+
* `[x]` **Organise data inside `json` file:** -- 27.03.2026
158+
* Migrated from scattered `portfolio-mit_v1.json` to a unified [`portfolio.json`](portfolio.json) with a `projects_blog_db` structure.
159+
* Blogs inherit `github_url` from their parent project; no more redundant URLs.
160+
* Updated `generate_portfolio_modified.py` to derive all template-compatible lists at runtime from the unified database.
161+
162+
* `[x]` **Implement a Direct Contact Form:** -- 27.03.2026
163+
* Integrated dual contact form with Web3Forms (primary, 250/mo limit) + Formspree (fallback, 50/mo limit). Includes client-side validation, loading states, success/error toasts, and honeypot anti-spam fields for both services.
164+
165+
* `[x]` **Extract inline CSS/JS into external files & clean HTML templates:** -- 03.04.2026
166+
* Extracted large `<style>` and `<script>` blocks from all templates into dedicated files (`css/blog.css`, `css/contact.css`, `css/post-layout.css`, `css/projects.css`, `css/tech-stack.css`, `js/blog.js`, `js/contact.js`, `js/post-toc.js`).
167+
* Added `trim_blocks=True` and `lstrip_blocks=True` to Jinja2 Environment for cleaner HTML output.
168+
* Removed all verbose HTML comments, duplicate script references (resume had app.js loaded 3x), and excess whitespace.
169+
170+
* `[x]` **Sitemap & Robots.txt Generation:** -- 03.04.2026
171+
* Added `generate_sitemap()` and `generate_robots_txt()` functions to the build script.
172+
* `sitemap.xml` includes all static pages and blog posts with `lastmod`, `changefreq`, and `priority`.
173+
174+
* `[x]` **Dynamic SEO & Open Graph Metadata:** -- 03.04.2026
175+
* Auto-generates `meta_description` (truncated to 160 chars from post content), `meta_keywords` (from core_technologies + keywords), and `og:description` for every blog post at build time.
176+
177+
* `[x]` **Automated Image Optimization (WebP):** -- 03.04.2026
178+
* Added Pillow-based image optimization to the build script. Converts all `.jpg`/`.png` images in `project_images/` and `posts_assets/` to WebP format (80% quality) with `_thumb.webp` thumbnails (400×400 max). Conversions are incremental — skipped when WebP is already up-to-date.

0 commit comments

Comments
 (0)