Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
VENV := .venv
PYTHON := python

ifeq ($(OS),Windows_NT)
PY := $(VENV)\Scripts\python.exe
PIP := $(VENV)\Scripts\pip.exe
else
PY := $(VENV)/bin/python
PIP := $(VENV)/bin/pip
endif

.PHONY: run venv install

venv:
$(PYTHON) -m venv $(VENV)
$(PIP) install --upgrade pip
$(PIP) install -r requirements.txt

run: venv
$(PY) manage.py runserver 0.0.0.0:8000
25 changes: 25 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,28 @@ pip install -r requirements.txt
```bash
python manage.py runserver
```

## ⚙️ Run with Make

- **Run locally:**

```bash
make run
```

- **Notes:**
- On first run the `Makefile` creates a virtual environment in `.venv` and installs `requirements.txt`.
- If you don't have `make` (common on Windows), run these commands instead:

```bash
python -m venv .venv
.venv\Scripts\pip install -r requirements.txt # Windows
.venv\Scripts\python manage.py runserver 0.0.0.0:8000
```

Or on Unix/macOS:

```bash
.venv/bin/pip install -r requirements.txt
.venv/bin/python manage.py runserver 0.0.0.0:8000
```
53 changes: 53 additions & 0 deletions static/js/script.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,56 @@ if (photoInput)
// Scroll to Bottom
const conversationThread = document.querySelector(".room__box");
if (conversationThread) conversationThread.scrollTop = conversationThread.scrollHeight;

// Theme toggle: persist preference in localStorage and apply on load
const themeToggle = document.getElementById('theme-toggle');
const themeKey = 'studybuddy_theme';

function applyTheme(theme) {
if (theme === 'light') {
document.body.classList.add('light');
} else {
document.body.classList.remove('light');
}
updateThemeIcon(theme);
}

function updateThemeIcon(theme) {
if (!themeToggle) return;
const icon = document.getElementById('theme-icon');
if (!icon) return;
if (theme === 'light') {
// show moon (switch to dark)
icon.innerHTML = '<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" fill="currentColor"></path>';
} else {
// show sun (switch to light)
icon.innerHTML = '<path d="M6.76 4.84l-1.8-1.79L3.17 5.84l1.79 1.79 1.8-2.79zM1 13h3v-2H1v2zm10 9h2v-3h-2v3zm7.03-2.03l1.79 1.79 1.79-1.79-1.79-1.79-1.79 1.79zM20 13h3v-2h-3v2zM12 6a6 6 0 100 12 6 6 0 000-12z" fill="currentColor"></path>';
}
}

// On load: read saved preference or system preference
(function() {
let saved = null;
try {
saved = localStorage.getItem(themeKey);
} catch (e) {
// ignore
}
if (saved === 'light' || saved === 'dark') {
applyTheme(saved);
} else {
const prefersLight = window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches;
applyTheme(prefersLight ? 'light' : 'dark');
}
})();

if (themeToggle) {
themeToggle.addEventListener('click', () => {
const isLight = document.body.classList.contains('light');
const newTheme = isLight ? 'dark' : 'light';
applyTheme(newTheme);
try {
localStorage.setItem(themeKey, newTheme);
} catch (e) {}
});
}
3 changes: 2 additions & 1 deletion static/styles/main.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* Keep minimal — main colors are defined in style.css variables */
body{
background-color: aquamarine;
background-color: var(--color-bg);
}
16 changes: 16 additions & 0 deletions static/styles/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@
--color-error: #fc4b0b;
}

/* Light theme overrides (applied when `body` has the `light` class) */
body.light {
--color-main: #1f8feb;
--color-main-light: #e6f6ff;
--color-dark: #0f1720;
--color-dark-medium: #2b3440;
--color-dark-light: #56606f;
--color-light: #0b0b0b;
--color-gray: #6b6b6b;
--color-light-gray: #3b3b3b;
--color-bg: #ffffff;
--color-success: #17b978;
--color-error: #d64545;
}

/*========== base styles ==========*/

* {
Expand Down Expand Up @@ -50,6 +65,7 @@ body {
color: var(--color-light-gray);
background-color: var(--color-bg);
min-height: 100vh;
transition: background-color 0.25s ease, color 0.25s ease;
}

img {
Expand Down
5 changes: 5 additions & 0 deletions templates/navbar.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ <h1>StudyBuddy</h1>
</label>
</form>
<nav class="header__menu">
<button id="theme-toggle" class="btn btn--link" aria-label="Toggle theme" title="Toggle light/dark theme">
<svg id="theme-icon" width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M21 12.79A9 9 0 1111.21 3 7 7 0 0021 12.79z" fill="currentColor"></path>
</svg>
</button>


<!-- Logged In -->
Expand Down