diff --git a/core/__pycache__/admin.cpython-311.pyc b/core/__pycache__/admin.cpython-311.pyc index cd6f855..5fbdebe 100644 Binary files a/core/__pycache__/admin.cpython-311.pyc and b/core/__pycache__/admin.cpython-311.pyc differ diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..34e02c6 Binary files /dev/null and b/core/__pycache__/forms.cpython-311.pyc differ diff --git a/core/__pycache__/models.cpython-311.pyc b/core/__pycache__/models.cpython-311.pyc index 9aa598b..c3611c7 100644 Binary files a/core/__pycache__/models.cpython-311.pyc and b/core/__pycache__/models.cpython-311.pyc differ diff --git a/core/__pycache__/urls.cpython-311.pyc b/core/__pycache__/urls.cpython-311.pyc index 1f807fa..90287b6 100644 Binary files a/core/__pycache__/urls.cpython-311.pyc and b/core/__pycache__/urls.cpython-311.pyc differ diff --git a/core/__pycache__/views.cpython-311.pyc b/core/__pycache__/views.cpython-311.pyc index 6867ddf..cf8d99b 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/admin.py b/core/admin.py index 8c38f3f..72f18b7 100644 --- a/core/admin.py +++ b/core/admin.py @@ -1,3 +1,18 @@ from django.contrib import admin +from .models import Program, Exercise -# Register your models here. +class ExerciseInline(admin.TabularInline): + model = Exercise + extra = 1 + +@admin.register(Program) +class ProgramAdmin(admin.ModelAdmin): + list_display = ('patient_name', 'clinician_name', 'created_at', 'updated_at') + search_fields = ('patient_name', 'clinician_name') + inlines = [ExerciseInline] + +@admin.register(Exercise) +class ExerciseAdmin(admin.ModelAdmin): + list_display = ('title', 'program') + list_filter = ('program',) + search_fields = ('title', 'notes') \ No newline at end of file diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..cd37356 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,12 @@ +from django import forms +from .models import Exercise + +class ExerciseForm(forms.ModelForm): + class Meta: + model = Exercise + fields = ['title', 'description', 'video_url'] + widgets = { + 'title': forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Exercise Title'}), + 'description': forms.Textarea(attrs={'class': 'form-control', 'placeholder': 'Exercise Notes', 'rows': 3}), + 'video_url': forms.URLInput(attrs={'class': 'form-control', 'placeholder': 'YouTube Video URL'}), + } diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..c24f079 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,41 @@ +# Generated by Django 5.2.7 on 2026-01-19 00:07 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Program', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('patient_name', models.CharField(max_length=255)), + ('patient_email', models.EmailField(max_length=254)), + ('clinician_name', models.CharField(max_length=255)), + ('created_at', models.DateTimeField(auto_now_add=True)), + ('updated_at', models.DateTimeField(auto_now=True)), + ], + ), + migrations.CreateModel( + name='Exercise', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('youtube_url', models.URLField()), + ('title', models.CharField(blank=True, max_length=255)), + ('thumbnail_url', models.URLField(blank=True)), + ('notes', models.TextField(blank=True)), + ('order', models.PositiveIntegerField(default=0)), + ('program', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='exercises', to='core.program')), + ], + options={ + 'ordering': ['order'], + }, + ), + ] diff --git a/core/migrations/__pycache__/0001_initial.cpython-311.pyc b/core/migrations/__pycache__/0001_initial.cpython-311.pyc new file mode 100644 index 0000000..3f0016e Binary files /dev/null and b/core/migrations/__pycache__/0001_initial.cpython-311.pyc differ diff --git a/core/models.py b/core/models.py index 71a8362..655838c 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,55 @@ from django.db import models -# Create your models here. +class Program(models.Model): + patient_name = models.CharField(max_length=255) + patient_email = models.EmailField() + clinician_name = models.CharField(max_length=255) + created_at = models.DateTimeField(auto_now_add=True) + updated_at = models.DateTimeField(auto_now=True) + + def __str__(self): + return f"Program for {self.patient_name} by {self.clinician_name}" + +class Exercise(models.Model): + + program = models.ForeignKey(Program, on_delete=models.CASCADE, related_name='exercises') + + title = models.CharField(max_length=200) + + description = models.TextField() + + video_url = models.URLField(blank=True, null=True) + + + + def __str__(self): + + return self.title + + + + def get_video_id(self): + + if self.video_url: + + if 'youtube.com/watch' in self.video_url: + + return self.video_url.split('v=')[1].split('&')[0] + + elif 'youtu.be/' in self.video_url: + + return self.video_url.split('/')[-1] + + return None + + + + def get_video_thumbnail(self): + + video_id = self.get_video_id() + + if video_id: + + return f'https://img.youtube.com/vi/{video_id}/default.jpg' + + return None diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..a655a5b 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -1,25 +1,40 @@ +{% load static %} -
- -