added exercise table and local mysql connector. working version
This commit is contained in:
parent
964c10f417
commit
014ccacb46
4 changed files with 148 additions and 0 deletions
94
zed_workouts/tracker/migrations/0001_initial.py
Normal file
94
zed_workouts/tracker/migrations/0001_initial.py
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
# Generated by Django 6.0.3 on 2026-03-19 14:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
initial = True
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='BackTemplate',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('date', models.DateField(auto_now_add=True)),
|
||||||
|
('group', models.CharField(max_length=20)),
|
||||||
|
('type', models.CharField(max_length=100)),
|
||||||
|
('exercise', models.CharField(max_length=255)),
|
||||||
|
('set', models.IntegerField()),
|
||||||
|
('weight', models.DecimalField(decimal_places=2, default=0.0, max_digits=6)),
|
||||||
|
('reps', models.IntegerField(default=0)),
|
||||||
|
('notes', models.TextField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'back',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='ChestTemplate',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('date', models.DateField(auto_now_add=True)),
|
||||||
|
('group', models.CharField(max_length=20)),
|
||||||
|
('type', models.CharField(max_length=100)),
|
||||||
|
('exercise', models.CharField(max_length=255)),
|
||||||
|
('set', models.IntegerField()),
|
||||||
|
('weight', models.DecimalField(decimal_places=2, default=0.0, max_digits=6)),
|
||||||
|
('reps', models.IntegerField(default=0)),
|
||||||
|
('notes', models.TextField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'chest',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Exercise',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('exercise', models.CharField(max_length=255, unique=True)),
|
||||||
|
('type', models.CharField(max_length=100)),
|
||||||
|
('group', models.CharField(choices=[('Primary', 'Primary'), ('Secondary', 'Secondary'), ('Core', 'Core')], max_length=20)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'exercises',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='LegsTemplate',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('date', models.DateField(auto_now_add=True)),
|
||||||
|
('group', models.CharField(max_length=20)),
|
||||||
|
('type', models.CharField(max_length=100)),
|
||||||
|
('exercise', models.CharField(max_length=255)),
|
||||||
|
('set', models.IntegerField()),
|
||||||
|
('weight', models.DecimalField(decimal_places=2, default=0.0, max_digits=6)),
|
||||||
|
('reps', models.IntegerField(default=0)),
|
||||||
|
('notes', models.TextField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'legs',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Workout',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('date', models.DateField(auto_now_add=True)),
|
||||||
|
('group', models.CharField(max_length=20)),
|
||||||
|
('type', models.CharField(max_length=100)),
|
||||||
|
('exercise', models.CharField(max_length=255)),
|
||||||
|
('set', models.IntegerField()),
|
||||||
|
('weight', models.DecimalField(decimal_places=2, default=0.0, max_digits=6)),
|
||||||
|
('reps', models.IntegerField(default=0)),
|
||||||
|
('notes', models.TextField(blank=True, null=True)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'workouts',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
@ -11,6 +11,9 @@ class Exercise(models.Model):
|
||||||
type = models.CharField(max_length=100) # e.g., Chest, Back, Arms
|
type = models.CharField(max_length=100) # e.g., Chest, Back, Arms
|
||||||
group = models.CharField(max_length=20, choices=GROUP_CHOICES)
|
group = models.CharField(max_length=20, choices=GROUP_CHOICES)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'exercises'
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"{self.exercise} ({self.group})"
|
return f"{self.exercise} ({self.group})"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,6 +85,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const exercises = {{ exercises_json|safe }};
|
const exercises = {{ exercises_json|safe }};
|
||||||
|
const templates = {{ templates_json|safe }};
|
||||||
|
|
||||||
function filterExercises() {
|
function filterExercises() {
|
||||||
const template = document.getElementById('templateSelect').value;
|
const template = document.getElementById('templateSelect').value;
|
||||||
|
|
@ -101,6 +102,7 @@
|
||||||
populateDropdown('primarySelect', 'Primary', primaryType);
|
populateDropdown('primarySelect', 'Primary', primaryType);
|
||||||
populateDropdown('secondarySelect', 'Secondary', secondaryType);
|
populateDropdown('secondarySelect', 'Secondary', secondaryType);
|
||||||
populateDropdown('coreSelect', 'Core', ['Abs', 'Core']);
|
populateDropdown('coreSelect', 'Core', ['Abs', 'Core']);
|
||||||
|
loadTemplateData(template);
|
||||||
}
|
}
|
||||||
|
|
||||||
function populateDropdown(id, group, types) {
|
function populateDropdown(id, group, types) {
|
||||||
|
|
@ -117,6 +119,38 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadTemplateData(templateName) {
|
||||||
|
const tbody = document.getElementById('activeTableBody');
|
||||||
|
tbody.innerHTML = '';
|
||||||
|
|
||||||
|
const data = templates[templateName];
|
||||||
|
if (data && data.length > 0) {
|
||||||
|
data.forEach(row => {
|
||||||
|
// Try to sync dropdowns based on first occurrence
|
||||||
|
if (row.group === 'Primary') setDropdownIfEmpty('primarySelect', row.exercise);
|
||||||
|
if (row.group === 'Secondary') setDropdownIfEmpty('secondarySelect', row.exercise);
|
||||||
|
if (row.group === 'Core') setDropdownIfEmpty('coreSelect', row.exercise);
|
||||||
|
|
||||||
|
const html = `
|
||||||
|
<tr>
|
||||||
|
<td>${row.exercise}<input type="hidden" class="d-ex" value="${row.exercise}"></td>
|
||||||
|
<td>${row.group}<input type="hidden" class="d-gr" value="${row.group}">
|
||||||
|
<input type="hidden" class="d-ty" value="${row.type}"></td>
|
||||||
|
<td>${row.set}<input type="hidden" class="d-st" value="${row.set}"></td>
|
||||||
|
<td><input type="number" class="table-input d-rp" value="${row.reps}"></td>
|
||||||
|
<td><input type="number" class="table-input d-wt" step="0.5" value="${row.weight}"></td>
|
||||||
|
<td><input type="text" class="table-input d-nt" value="${row.notes || ''}" placeholder="Notes"></td>
|
||||||
|
</tr>`;
|
||||||
|
tbody.insertAdjacentHTML('beforeend', html);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function setDropdownIfEmpty(id, value) {
|
||||||
|
const select = document.getElementById(id);
|
||||||
|
if (select && select.value === "") select.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
function generateTable() {
|
function generateTable() {
|
||||||
const tbody = document.getElementById('activeTableBody');
|
const tbody = document.getElementById('activeTableBody');
|
||||||
tbody.innerHTML = '';
|
tbody.innerHTML = '';
|
||||||
|
|
|
||||||
|
|
@ -80,6 +80,8 @@ WSGI_APPLICATION = 'zed_workouts.wsgi.application'
|
||||||
# 'NAME': BASE_DIR / 'db.sqlite3',
|
# 'NAME': BASE_DIR / 'db.sqlite3',
|
||||||
# }
|
# }
|
||||||
#}
|
#}
|
||||||
|
|
||||||
|
# Database connector for docker container
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
|
|
@ -91,6 +93,21 @@ DATABASES = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Database connector for local mysql instance
|
||||||
|
DATABASES = {
|
||||||
|
'default': {
|
||||||
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
|
'NAME': 'workouts',
|
||||||
|
'USER': 'root',
|
||||||
|
'PASSWORD': 'Throwaway',
|
||||||
|
'HOST': 'localhost', # Or your DB server IP
|
||||||
|
'PORT': '3306', # Default MySQL port
|
||||||
|
'OPTIONS': {
|
||||||
|
'init_command': "SET sql_mode='STRICT_TRANS_TABLES'",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue