A dynamic, full-stack personal portfolio and content management system built with Flask, SQLite, JavaScript, and modern web development practices.
Designed as a long-term portfolio platform that can continuously evolve without requiring complete rewrites.
This repository contains my personal portfolio website, redesigned from the ground up as a complete full-stack web application rather than a simple collection of static pages.
The original version of my portfolio was built using only HTML, CSS, and JavaScript and was hosted through GitHub Pages. Although this approach was effective for displaying information, it had limitations: every update required manually editing source files, rebuilding sections, and redeploying the entire website.
This project represents a major transition in my development journey. Instead of creating another static portfolio, I wanted to build a platform that could continue growing with me. The goal was to create a lightweight personal Content Management System (CMS) where portfolio content could be updated through an administrative interface rather than directly modifying code.
The application now uses a backend architecture where projects, skills, and portfolio information are stored in a database and dynamically displayed through Flask templates. This allows the website to behave more like a real-world application rather than a simple webpage.
This repository is intentionally structured so that other developers can download, study, modify, and reuse the codebase. The only exclusions are my personal assets such as profile images, private database information, and authentication credentials.
This project represents a significant upgrade from my original portfolio website. The purpose of this change was not simply to add more technology, but to gain practical experience building applications that solve real maintenance and scalability problems.
| Area | Previous Portfolio | Current Full-Stack Portfolio |
|---|---|---|
| Architecture | Static HTML, CSS and JavaScript files hosted through GitHub Pages. | Flask-powered web application using server-side rendering, templates, routes, and database communication. |
| Content Management | Every project or skill update required manually editing HTML files. | Content is stored in SQLite and managed through an administrator dashboard. |
| Data Storage | Information was hardcoded directly into webpage files. | Projects, skills, and administrator data are stored in structured database tables. |
| Authentication | No authentication system was required. | Secure login system using sessions, CSRF protection, and Argon2 password hashing. |
| Scalability | Adding new sections required modifying the website structure manually. | The application is designed as a foundation that can continue receiving features and improvements. |
| Development Experience | Focused mainly on frontend design and presentation. | Expanded experience into backend development, databases, authentication, security, deployment, and application architecture. |
The biggest learning experience from this transition was understanding that professional software development is not only about creating something visually impressive. It is about designing systems that are maintainable, secure, adaptable, and practical for future changes.
- Responsive portfolio design across mobile, tablet, and desktop devices.
- Hero introduction section with personal branding.
- About section explaining development journey.
- Dynamic skills section loaded from database records.
- Featured projects displayed automatically.
- Complete project archive page.
- Project searching functionality.
- Project filtering by technology tags.
- Dark mode support using JavaScript and CSS variables.
- Animated page elements using Intersection Observer.
- Interactive project technology tags.
- Social media and contact integration.
The administrative area allows portfolio information to be updated without directly changing source files.
- Add new skills.
- Add new projects.
- Edit existing projects.
- Edit existing skills.
- Delete outdated content.
- Manage featured projects.
This was created to simulate how a simplified CMS works. Instead of manually editing a website every time information changes, the administrator can manage content through an interface.
Security was an important learning area during this project. Although this is a personal portfolio application, I wanted to implement practices used in professional applications.
- Passwords are never stored in plain text.
- Administrator credentials are protected using
Argon2hashing. - Password verification is performed securely during authentication.
- Administrative routes are protected using login decorators.
- Unauthorised users are redirected away from protected areas.
- User sessions are managed through Flask session handling.
- Forms require CSRF tokens before processing sensitive actions.
- Requests without valid tokens are rejected.
The security implementation is intentionally lightweight because this is a personal CMS system, but it demonstrates understanding of authentication principles and secure application design.
| Technology | Purpose |
|---|---|
| Python | Backend programming language powering application logic. |
| Flask | Lightweight web framework handling routing, templates, and server-side processing. |
| SQLite | Database engine storing projects, skills, and administrator information. |
| Jinja Templates | Dynamic HTML rendering system used by Flask. |
| HTML5 | Website structure and semantic content. |
| CSS3 | Responsive styling, themes, animations, and layout design. |
| JavaScript | Client-side interactions including animations, menu handling, and theme switching. |
| Argon2 | Secure password hashing algorithm. |
| Gunicorn | Production WSGI server for deployment. |
Portfolio-CMS/ โ โโโ app.py # Flask application entry point โโโ auth.py # Authentication and security functions โโโ requirements.txt # Python dependencies โโโ README.md # Project documentation โ โโโ instance/ โ โโโ portfolio.db # SQLite database โ โโโ services/ โ โโโ database.py # Database queries and CRUD operations โ โโโ templates/ โ โโโ layout.html # Main website template โ โโโ home.html # Homepage โ โโโ all_projects.html # Project archive page โ โโโ admin_panel.html # Administrator dashboard โ โโโ error pages # Application error templates โ โโโ static/ โ โ โ โโโ css/ โ โ โโโ styles.css # Website styling โ โ โ โโโ js/ โ โ โโโ script.js # Client-side functionality โ โ โ โโโ media/ โ โโโ images/ # Personal website assets โ โโโ .env # Environment variables
The application is separated into different responsibilities to keep the code organised and maintainable.
-
csrf_required()
Checks submitted forms for valid CSRF tokens before allowing sensitive actions to continue. -
login_required()
A Flask decorator that protects administrator routes by checking whether an authenticated session exists. -
login_user(username, password)
Retrieves administrator information, verifies the supplied password using Argon2, and confirms successful authentication.
-
connect_database()
Creates a connection to SQLite and configures returned rows for easier access. -
all_tags()
Extracts project technology tags from stored projects and creates a list for filtering. -
search_projects()
Searches project titles, descriptions, and tags using SQL queries. -
get_projects()
Retrieves projects from the database and supports limiting returned results for featured sections. -
get_project()
Retrieves one specific project using its database ID. -
insert_project()
Creates a new project database record. -
update_project()
Updates existing project information. -
delete_project()
Removes projects from the database. -
get_skills()
Retrieves all stored skills. -
insert_skill()
Creates a new skill record. -
update_skill()
Updates skill information and progress tracking. -
delete_skill()
Removes skills from the database. -
get_user()
Retrieves administrator account information for authentication.
The application uses SQLite because it provides a lightweight database solution suitable for a personal CMS platform.
id skill progress
Stores technologies and learning progress displayed on the portfolio.
id title description image_url github_link demo_link completion tags featured
Stores portfolio projects and controls how they appear throughout the website.
id first_name last_name username password
Stores administrator authentication information.
- Install Python 3.10 or above.
-
Clone the repository:
git clone https://github.com/Sheikh-H/Sheikh-Hussain.git
-
Navigate into the project:
cd Sheikh-Hussain (You can rename the file)
-
Create a virtual environment:
python -m venv venv
-
Activate the environment:
source venv/bin/activate
-
Install dependencies:
pip install -r requirements.txt
- Create your environment variables and configure your own database credentials.
-
Run Flask:
flask run
This application is designed to be deployed using platforms such as Render.
A production deployment uses Gunicorn as the application server:
gunicorn app:app
Environment variables should be configured through the hosting provider rather than stored directly inside the repository.
This project is intentionally considered a continuous work in progress.
The purpose was not to create a one-time portfolio website, but to create a foundation that can continue improving as my development skills grow.
Possible future improvements include:
- Moving from SQLite to PostgreSQL for larger-scale deployment.
- Adding image upload management.
- Adding user roles and permissions.
- Adding automated testing.
- Adding database migrations.
- Adding analytics tracking.
- Creating a richer CMS editing experience.
- Python: 3.10+
- Flask
- python-dotenv
- argon2-cffi
- Gunicorn
This project is licensed under the MIT Licence โ see the LICENCE file for details.
MIT Licence Copyright (c) 2026 Sheikh Hussain Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.