diff --git a/config/__pycache__/settings.cpython-311.pyc b/config/__pycache__/settings.cpython-311.pyc index 5be02db..8217311 100644 Binary files a/config/__pycache__/settings.cpython-311.pyc and b/config/__pycache__/settings.cpython-311.pyc differ diff --git a/config/__pycache__/urls.cpython-311.pyc b/config/__pycache__/urls.cpython-311.pyc index 28817aa..bd0741a 100644 Binary files a/config/__pycache__/urls.cpython-311.pyc and b/config/__pycache__/urls.cpython-311.pyc differ diff --git a/config/settings.py b/config/settings.py index 291d043..3543cec 100644 --- a/config/settings.py +++ b/config/settings.py @@ -56,8 +56,11 @@ INSTALLED_APPS = [ 'django.contrib.messages', 'django.contrib.staticfiles', 'core', + 'polar_integration', ] +AUTH_USER_MODEL = 'core.User' + MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', @@ -96,11 +99,15 @@ WSGI_APPLICATION = 'config.wsgi.application' # Database # https://docs.djangoproject.com/en/5.2/ref/settings/#databases +# IMPORTANT: The following database settings are a temporary workaround. +# The application is configured to use environment variables, but they are not +# currently set correctly. These settings allow the application to run in a +# local development environment. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', - 'NAME': os.getenv('DB_NAME', ''), - 'USER': os.getenv('DB_USER', ''), + 'NAME': os.getenv('DB_NAME', 'db'), + 'USER': os.getenv('DB_USER', 'root'), 'PASSWORD': os.getenv('DB_PASS', ''), 'HOST': os.getenv('DB_HOST', '127.0.0.1'), 'PORT': os.getenv('DB_PORT', '3306'), @@ -151,10 +158,13 @@ STATIC_ROOT = BASE_DIR / 'staticfiles' STATICFILES_DIRS = [ BASE_DIR / 'static', - BASE_DIR / 'assets', - BASE_DIR / 'node_modules', ] +# Polar.sh Integration Settings +# These values should be set in your .env file. +POLAR_API_KEY = os.getenv("POLAR_API_KEY", "") +POLAR_WEBHOOK_SECRET = os.getenv("POLAR_WEBHOOK_SECRET", "") + # Email EMAIL_BACKEND = os.getenv( "EMAIL_BACKEND", diff --git a/config/urls.py b/config/urls.py index bcfc074..9d24092 100644 --- a/config/urls.py +++ b/config/urls.py @@ -22,6 +22,7 @@ from django.conf.urls.static import static urlpatterns = [ path("admin/", admin.site.urls), path("", include("core.urls")), + path("polar/", include("polar_integration.urls")), ] if settings.DEBUG: diff --git a/core/__pycache__/forms.cpython-311.pyc b/core/__pycache__/forms.cpython-311.pyc new file mode 100644 index 0000000..ffcb260 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..37be8c4 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..6a0d66f 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..93236cd 100644 Binary files a/core/__pycache__/views.cpython-311.pyc and b/core/__pycache__/views.cpython-311.pyc differ diff --git a/core/forms.py b/core/forms.py new file mode 100644 index 0000000..9d151f4 --- /dev/null +++ b/core/forms.py @@ -0,0 +1,8 @@ +from django import forms +from django.contrib.auth.forms import UserCreationForm +from .models import User + +class SignUpForm(UserCreationForm): + class Meta(UserCreationForm.Meta): + model = User + fields = UserCreationForm.Meta.fields + ('email', 'role',) \ No newline at end of file diff --git a/core/migrations/0001_initial.py b/core/migrations/0001_initial.py new file mode 100644 index 0000000..dbb3946 --- /dev/null +++ b/core/migrations/0001_initial.py @@ -0,0 +1,67 @@ +# Generated by Django 5.2.7 on 2025-12-18 13:22 + +import django.contrib.auth.models +import django.contrib.auth.validators +import django.db.models.deletion +import django.utils.timezone +from django.conf import settings +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ('auth', '0012_alter_user_first_name_max_length'), + ] + + operations = [ + migrations.CreateModel( + name='User', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('password', models.CharField(max_length=128, verbose_name='password')), + ('last_login', models.DateTimeField(blank=True, null=True, verbose_name='last login')), + ('is_superuser', models.BooleanField(default=False, help_text='Designates that this user has all permissions without explicitly assigning them.', verbose_name='superuser status')), + ('username', models.CharField(error_messages={'unique': 'A user with that username already exists.'}, help_text='Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.', max_length=150, unique=True, validators=[django.contrib.auth.validators.UnicodeUsernameValidator()], verbose_name='username')), + ('first_name', models.CharField(blank=True, max_length=150, verbose_name='first name')), + ('last_name', models.CharField(blank=True, max_length=150, verbose_name='last name')), + ('email', models.EmailField(blank=True, max_length=254, verbose_name='email address')), + ('is_staff', models.BooleanField(default=False, help_text='Designates whether the user can log into this admin site.', verbose_name='staff status')), + ('is_active', models.BooleanField(default=True, help_text='Designates whether this user should be treated as active. Unselect this instead of deleting accounts.', verbose_name='active')), + ('date_joined', models.DateTimeField(default=django.utils.timezone.now, verbose_name='date joined')), + ('role', models.CharField(choices=[('admin', 'Admin'), ('manager', 'Manager'), ('employee', 'Employee')], default='employee', max_length=10)), + ('groups', models.ManyToManyField(blank=True, help_text='The groups this user belongs to. A user will get all permissions granted to each of their groups.', related_name='user_set', related_query_name='user', to='auth.group', verbose_name='groups')), + ('user_permissions', models.ManyToManyField(blank=True, help_text='Specific permissions for this user.', related_name='user_set', related_query_name='user', to='auth.permission', verbose_name='user permissions')), + ], + options={ + 'verbose_name': 'user', + 'verbose_name_plural': 'users', + 'abstract': False, + }, + managers=[ + ('objects', django.contrib.auth.models.UserManager()), + ], + ), + migrations.CreateModel( + name='Shift', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_time', models.DateTimeField()), + ('end_time', models.DateTimeField()), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='shifts', to=settings.AUTH_USER_MODEL)), + ], + ), + migrations.CreateModel( + name='TimeOffRequest', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('start_date', models.DateField()), + ('end_date', models.DateField()), + ('reason', models.TextField()), + ('status', models.CharField(choices=[('pending', 'Pending'), ('approved', 'Approved'), ('denied', 'Denied')], default='pending', max_length=10)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='time_off_requests', to=settings.AUTH_USER_MODEL)), + ], + ), + ] 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..156b4a7 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..35ef026 100644 --- a/core/models.py +++ b/core/models.py @@ -1,3 +1,33 @@ from django.db import models +from django.contrib.auth.models import AbstractUser -# Create your models here. +class User(AbstractUser): + ROLE_CHOICES = ( + ('admin', 'Admin'), + ('manager', 'Manager'), + ('employee', 'Employee'), + ) + role = models.CharField(max_length=10, choices=ROLE_CHOICES, default='employee') + +class Shift(models.Model): + start_time = models.DateTimeField() + end_time = models.DateTimeField() + employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='shifts') + + def __str__(self): + return f'{self.employee.username} - {self.start_time} to {self.end_time}' + +class TimeOffRequest(models.Model): + STATUS_CHOICES = ( + ('pending', 'Pending'), + ('approved', 'Approved'), + ('denied', 'Denied'), + ) + employee = models.ForeignKey(User, on_delete=models.CASCADE, related_name='time_off_requests') + start_date = models.DateField() + end_date = models.DateField() + reason = models.TextField() + status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='pending') + + def __str__(self): + return f'{self.employee.username} - {self.start_date} to {self.end_date} ({self.get_status_display()})' diff --git a/core/templates/base.html b/core/templates/base.html index 1e7e5fb..9eed4cf 100644 --- a/core/templates/base.html +++ b/core/templates/base.html @@ -13,6 +13,10 @@ {% endif %} + + + + {% load static %} {% block head %}{% endblock %} @@ -20,6 +24,7 @@ {% block content %}{% endblock %} + diff --git a/core/templates/core/index.html b/core/templates/core/index.html index faec813..7d9ac0d 100644 --- a/core/templates/core/index.html +++ b/core/templates/core/index.html @@ -1,145 +1,74 @@ {% extends "base.html" %} +{% load static %} -{% block title %}{{ project_name }}{% endblock %} +{% block title %}Shiftly Scheduler - Employee Scheduling Software{% endblock %} {% block head %} - - - + {% endblock %} {% block content %} -
-
-

Analyzing your requirements and generating your app…

-
- Loading… +
-