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
|
||||
group = models.CharField(max_length=20, choices=GROUP_CHOICES)
|
||||
|
||||
class Meta:
|
||||
db_table = 'exercises'
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.exercise} ({self.group})"
|
||||
|
||||
|
|
|
|||
|
|
@ -85,6 +85,7 @@
|
|||
|
||||
<script>
|
||||
const exercises = {{ exercises_json|safe }};
|
||||
const templates = {{ templates_json|safe }};
|
||||
|
||||
function filterExercises() {
|
||||
const template = document.getElementById('templateSelect').value;
|
||||
|
|
@ -101,6 +102,7 @@
|
|||
populateDropdown('primarySelect', 'Primary', primaryType);
|
||||
populateDropdown('secondarySelect', 'Secondary', secondaryType);
|
||||
populateDropdown('coreSelect', 'Core', ['Abs', 'Core']);
|
||||
loadTemplateData(template);
|
||||
}
|
||||
|
||||
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() {
|
||||
const tbody = document.getElementById('activeTableBody');
|
||||
tbody.innerHTML = '';
|
||||
|
|
|
|||
|
|
@ -80,6 +80,8 @@ WSGI_APPLICATION = 'zed_workouts.wsgi.application'
|
|||
# 'NAME': BASE_DIR / 'db.sqlite3',
|
||||
# }
|
||||
#}
|
||||
|
||||
# Database connector for docker container
|
||||
DATABASES = {
|
||||
'default': {
|
||||
'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
|
||||
# https://docs.djangoproject.com/en/6.0/ref/settings/#auth-password-validators
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue