Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

Tisha Patience Malongo — Developer Portfolio

A modern, dark-themed developer portfolio built with Python, Django, Tailwind CSS, HTML, and CSS. Features a light/dark mode toggle, animated hero section, skill tags, project showcase with image uploads, and a working contact form — all managed via Django admin.


Features

  • Light / dark mode toggle (preference saved in browser)
  • Typing hero animation
  • Scroll-reveal animations
  • Skill tags by category (no progress bars — clean and honest)
  • Dynamic project cards with image support (managed via Django admin)
  • Contact form that saves messages to the database and sends email
  • Django admin panel to manage all content
  • Secrets managed with python-decouple (no passwords in code)

Tech Stack

LayerTechnology
BackendPython, Django
FrontendHTML5, Tailwind CSS (CDN), Vanilla JS
DatabaseSQLite (dev)
StylingInter font, CSS custom properties
Package manageruv
DeploymentPythonAnywhere

Quick Start

1. Clone the repository

git clone https://github.com/Tisha-patience/portfolio.git
cd portfolio

2. Install uv (if you don't have it)

pip install uv

3. Create and activate the virtual environment

uv venv
source .venv/Scripts/activate # Windows (Git Bash)source .venv/bin/activate # macOS / Linux

4. Install dependencies

uv sync

5. Set up environment variables

Create a .env file in the project root:

SECRET_KEY=your-django-secret-key
DEBUG=True
EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-gmail-app-password

Never commit .env to GitHub — it is already in .gitignore.

6. Run migrations

uv run manage.py migrate

7. Create an admin user

uv run manage.py createsuperuser

8. Run the development server

uv run manage.py runserver

Visit http://127.0.0.1:8000 to see the portfolio. Visit http://127.0.0.1:8000/admin to manage content.


Managing Content

Projects

Go to /admin → Projects → Add Project.

  • Set Featured = True for the top 3 (shown as cards with images)
  • Other projects appear as a compact list below
  • Upload a project image directly from the admin panel

Skills

Go to /admin → Skills → Add Skill. Categories: languages, frameworks, tools, databases

Contact messages

Go to /admin → Contact Messages to read and manage messages sent through the contact form.


Email Setup

To receive real emails from the contact form, add your Gmail SMTP credentials to .env:

EMAIL_HOST_USER=your@gmail.com
EMAIL_HOST_PASSWORD=your-16-character-app-password

Generate a Gmail App Password at: Google Account → Security → App Passwords.


Deploying to PythonAnywhere

Before deploying, export a requirements.txt from uv:

uv export --no-hashes > requirements.txt

Then follow the standard PythonAnywhere Django deployment guide.


Project Structure

portfolio/
├── config/
│ ├── settings.py # Project settings (reads from .env)
│ ├── urls.py
│ └── wsgi.py
├── core/
│ ├── models.py # Project, Skill, ContactMessage
│ ├── views.py # Single home view
│ ├── forms.py # ContactForm
│ ├── admin.py # Admin configuration
│ └── urls.py
├── templates/
│ └── core/
│ └── home.html # Main template
├── static/
│ ├── css/style.css # Custom styles + light mode
│ ├── js/main.js # Animations & interactions
│ └── images/ # Profile photo
├── media/ # Uploaded project images
├── .env # Secrets (never commit this)
├── .gitignore
├── pyproject.toml # uv dependencies
├── manage.py
└── seed_data.py # Optional sample data loader

About

Personal portfolio website built with Python and Django. Features animated hero section, skills tracker, project showcase with image uploads, and a contact form — all managed via Django admin. Styled with Tailwind CSS.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages