diff --git a/Dockerfile b/Dockerfile index cce6d33..c03add8 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,4 +15,4 @@ RUN pip install --no-cache-dir -r requirements.txt COPY . /app/ # We'll run the server via docker-compose command, but this is a default -CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] +CMD ["python", "manage.py", "runserver", "0.0.0.0:8001"] diff --git a/docker-compose.yml b/docker-compose.yml index f17149e..657e839 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: '3.8' +version: "3.8" services: db: @@ -7,9 +7,9 @@ services: restart: always environment: MYSQL_DATABASE: workouts - MYSQL_ROOT_PASSWORD: rootpassword - MYSQL_USER: user - MYSQL_PASSWORD: userpassword + MYSQL_ROOT_PASSWORD: Throwaway + ports: + - "3306:3306" volumes: - db_data:/var/lib/mysql networks: @@ -18,19 +18,21 @@ services: web: build: . container_name: workouts_web + working_dir: /app/zed_workouts command: > - sh -c "python manage.py migrate && - python manage.py runserver 0.0.0.0:8000" + sh -c "sleep 10 && + python manage.py migrate && + python manage.py runserver 0.0.0.0:8001" volumes: - .:/app ports: - - "8000:8000" + - "8001:8001" depends_on: - db environment: - DB_NAME=workouts - - DB_USER=user - - DB_PASSWORD=userpassword + - DB_USER=root + - DB_PASSWORD=Throwaway - DB_HOST=db networks: - workout_net diff --git a/zed_workouts/tracker/templates/tracker/index.html b/zed_workouts/tracker/templates/tracker/index.html index ccd7f22..2664094 100644 --- a/zed_workouts/tracker/templates/tracker/index.html +++ b/zed_workouts/tracker/templates/tracker/index.html @@ -1,313 +1,383 @@ - + - - - - Zed Workouts - - - - -
-

Workout Tracker

+ + + + Zed Workouts + + + + +
+

Workout Tracker

+ +
+
+ + +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + + +

Current Block

+
+ + + + + + + + + + + + +
ExerciseGroupSetRepsWeightNote
+
+ + + +
+ +

Extra Exercise

+ + +
+ + +
+
+ + +
+ {% csrf_token %} + + +

Final Log

+ + + + + + + + + + +
ExerciseSetRepsWeight
+ +
+ +
- -
-
- - -
-
- - -
-
- - -
-
+ - + document.getElementById('saveAdhocBtn').classList.remove('d-none'); + const opt = select.options[select.selectedIndex]; + for (let set = 1; set <= 4; set++) { + tbody.insertAdjacentHTML('beforeend', getRowHtml(select.value, opt.dataset.group, opt.dataset.type, set)); + } + } + + function saveBlock() { processSaveBlock('activeTableBody'); } + function saveAdhocBlock() { + processSaveBlock('adhocTableBody'); + document.getElementById('adhocSelect').value = ''; + document.getElementById('saveAdhocBtn').classList.add('d-none'); + } + + function processSaveBlock(tableId) { + const activeBody = document.getElementById(tableId); + const logBody = document.getElementById('logTableBody'); + const hiddenDiv = document.getElementById('hiddenInputs'); + + activeBody.querySelectorAll('tr').forEach(row => { + const data = { + ex: row.querySelector('.d-ex').value, + gr: row.querySelector('.d-gr').value, + ty: row.querySelector('.d-ty').value, + st: row.querySelector('.d-st').value, + rp: row.querySelector('.d-rp').value, + wt: row.querySelector('.d-wt').value, + nt: row.querySelector('.d-nt').value + }; + + logBody.insertAdjacentHTML('beforeend', `${data.ex}${data.st}${data.rp}${data.wt}`); + hiddenDiv.insertAdjacentHTML('beforeend', ` + + + + + + + + `); + }); + activeBody.innerHTML = ''; + window.scrollTo(0, document.body.scrollHeight); + } + + populateAdhocDropdown(); + + diff --git a/zed_workouts/zed_workouts/settings.py b/zed_workouts/zed_workouts/settings.py index 147e83a..0e321a9 100644 --- a/zed_workouts/zed_workouts/settings.py +++ b/zed_workouts/zed_workouts/settings.py @@ -10,8 +10,8 @@ For the full list of settings and their values, see https://docs.djangoproject.com/en/6.0/ref/settings/ """ -from pathlib import Path import os +from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -21,54 +21,54 @@ BASE_DIR = Path(__file__).resolve().parent.parent # See https://docs.djangoproject.com/en/6.0/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! -SECRET_KEY = 'django-insecure-a%mr&&f^u06y=$!cylb-wv&w3^booxo*48hymemf$ldj=$vkb%' +SECRET_KEY = "django-insecure-a%mr&&f^u06y=$!cylb-wv&w3^booxo*48hymemf$ldj=$vkb%" # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True -ALLOWED_HOSTS = ['*'] +ALLOWED_HOSTS = ["*"] # Application definition INSTALLED_APPS = [ - 'django.contrib.admin', - 'django.contrib.auth', - 'django.contrib.contenttypes', - 'django.contrib.sessions', - 'django.contrib.messages', - 'django.contrib.staticfiles', - 'tracker', + "django.contrib.admin", + "django.contrib.auth", + "django.contrib.contenttypes", + "django.contrib.sessions", + "django.contrib.messages", + "django.contrib.staticfiles", + "tracker", ] MIDDLEWARE = [ - 'django.middleware.security.SecurityMiddleware', - 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.middleware.common.CommonMiddleware', - 'django.middleware.csrf.CsrfViewMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware', - 'django.contrib.messages.middleware.MessageMiddleware', - 'django.middleware.clickjacking.XFrameOptionsMiddleware', + "django.middleware.security.SecurityMiddleware", + "django.contrib.sessions.middleware.SessionMiddleware", + "django.middleware.common.CommonMiddleware", + "django.middleware.csrf.CsrfViewMiddleware", + "django.contrib.auth.middleware.AuthenticationMiddleware", + "django.contrib.messages.middleware.MessageMiddleware", + "django.middleware.clickjacking.XFrameOptionsMiddleware", ] -ROOT_URLCONF = 'zed_workouts.urls' +ROOT_URLCONF = "zed_workouts.urls" TEMPLATES = [ { - 'BACKEND': 'django.template.backends.django.DjangoTemplates', - 'DIRS': [], - 'APP_DIRS': True, - 'OPTIONS': { - 'context_processors': [ - 'django.template.context_processors.request', - 'django.contrib.auth.context_processors.auth', - 'django.contrib.messages.context_processors.messages', + "BACKEND": "django.template.backends.django.DjangoTemplates", + "DIRS": [], + "APP_DIRS": True, + "OPTIONS": { + "context_processors": [ + "django.template.context_processors.request", + "django.contrib.auth.context_processors.auth", + "django.contrib.messages.context_processors.messages", ], }, }, ] -WSGI_APPLICATION = 'zed_workouts.wsgi.application' +WSGI_APPLICATION = "zed_workouts.wsgi.application" # Database @@ -79,50 +79,49 @@ WSGI_APPLICATION = 'zed_workouts.wsgi.application' # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': BASE_DIR / 'db.sqlite3', # } -#} +# } # Database connector for docker container DATABASES = { - 'default': { - 'ENGINE': 'django.db.backends.mysql', - 'NAME': os.environ.get('DB_NAME', 'workouts'), - 'USER': os.environ.get('DB_USER', 'user'), - 'PASSWORD': os.environ.get('DB_PASSWORD', 'userpassword'), - 'HOST': os.environ.get('DB_HOST', 'db'), - 'PORT': '3306', + "default": { + "ENGINE": "django.db.backends.mysql", + "NAME": os.environ.get("DB_NAME", "workouts"), + "USER": os.environ.get("DB_USER", "user"), + "PASSWORD": os.environ.get("DB_PASSWORD", "userpassword"), + "HOST": os.environ.get("DB_HOST", "db"), + "PORT": "3306", } } # 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'", - }, - } -} +# 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 AUTH_PASSWORD_VALIDATORS = [ { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] @@ -130,9 +129,9 @@ AUTH_PASSWORD_VALIDATORS = [ # Internationalization # https://docs.djangoproject.com/en/6.0/topics/i18n/ -LANGUAGE_CODE = 'en-us' +LANGUAGE_CODE = "en-us" -TIME_ZONE = 'UTC' +TIME_ZONE = "UTC" USE_I18N = True @@ -142,4 +141,4 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/6.0/howto/static-files/ -STATIC_URL = 'static/' +STATIC_URL = "static/"