Skip to content
This repository has been archived by the owner on Jan 31, 2024. It is now read-only.

Commit

Permalink
Merge pull request #19 from Faraphel/extra-pages
Browse files Browse the repository at this point in the history
Added styles and improved some configurations
  • Loading branch information
biloute02 authored Jan 17, 2024
2 parents 07812d2 + 964647e commit 5fec4cb
Show file tree
Hide file tree
Showing 35 changed files with 1,075 additions and 240 deletions.
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# IDE
.idea

# Virtual Environment
venv
.venv

# Django
media
static-collected
db.sqlite3
.env
11 changes: 9 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,22 @@ FROM python:3.12

# Set environment variables for Django
ENV DJANGO_SETTINGS_MODULE=Palto.settings
ENV DJANGO_SECRET_KEY=""
ENV DATABASE_ENGINE="sqlite"
ENV DEBUG=false

# Set the working directory in the container
WORKDIR /App

# Copy the current directory contents into the container
COPY . /App

# Install any needed packages specified in requirements.txt
RUN pip install -r requirements.txt
# Install requirements
RUN python -m pip install -r requirements.txt

# Prepare the server
RUN python manage.py collectstatic --no-input
RUN python manage.py migrate

# Expose the port on which your Django application will run
EXPOSE 80
Expand Down
21 changes: 15 additions & 6 deletions Palto/Palto/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,49 +24,58 @@ class AdminUser(admin.ModelAdmin):
class AdminDepartment(admin.ModelAdmin):
list_display = ("id", "name", "email")
search_fields = ("id", "name", "email")
readonly_fields = ("id",)


@admin.register(models.StudentGroup)
class AdminStudentGroup(admin.ModelAdmin):
list_display = ("id", "name", "owner", "department")
search_fields = ("id", "name", "owner", "department")
list_filter = ("department",)
readonly_fields = ("id",)


@admin.register(models.TeachingUnit)
class AdminTeachingUnit(admin.ModelAdmin):
list_display = ("id", "name", "email")
search_fields = ("id", "name", "email")
readonly_fields = ("id",)


@admin.register(models.StudentCard)
class AdminStudentCard(admin.ModelAdmin):
list_display = ("id", "uid", "owner")
search_fields = ("id", "uid", "owner")
readonly_fields = ("uid",)
list_display = ("id", "uid", "department", "owner")
search_fields = ("id", "uid", "department", "owner")
readonly_fields = ("id", "uid",)
list_filter = ("department",)


@admin.register(models.TeachingSession)
class AdminTeachingSession(admin.ModelAdmin):
list_display = ("id", "start", "end", "duration", "teacher")
search_fields = ("id", "start", "end", "duration", "teacher")
list_filter = ("start", "duration")
list_display = ("id", "start", "end", "unit", "duration", "teacher")
search_fields = ("id", "start", "end", "unit", "duration", "teacher")
readonly_fields = ("id",)
list_filter = ("unit",)


@admin.register(models.Attendance)
class AdminAttendance(admin.ModelAdmin):
list_display = ("id", "date", "student")
search_fields = ("id", "date", "student")
readonly_fields = ("id",)
list_filter = ("date",)


@admin.register(models.Absence)
class AdminAbsence(admin.ModelAdmin):
list_display = ("id", "message", "student", "start", "end")
search_fields = ("id", "message", "student", "start", "end")
readonly_fields = ("id",)
list_filter = ("start", "end")


@admin.register(models.AbsenceAttachment)
class AdminAbsenceAttachment(admin.ModelAdmin):
list_display = ("id", "content", "absence")
search_fields = ("id", "content", "absence")
readonly_fields = ("id",)
167 changes: 167 additions & 0 deletions Palto/Palto/migrations/0001_initial.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Generated by Django 5.0.1 on 2024-01-15 17:37

import Palto.Palto.models
import django.contrib.auth.models
import django.contrib.auth.validators
import django.db.models.deletion
import django.utils.timezone
import uuid
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='Absence',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('message', models.TextField()),
('start', models.DateTimeField()),
('end', models.DateTimeField()),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.CreateModel(
name='Department',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64, unique=True)),
('email', models.EmailField(max_length=254)),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.CreateModel(
name='AbsenceAttachment',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('content', models.FileField(upload_to='absence/attachment/')),
('absence', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attachments', to='Palto.absence')),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.AddField(
model_name='absence',
name='department',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absences', to='Palto.department'),
),
migrations.CreateModel(
name='StudentGroup',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=128)),
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_groups', to='Palto.department')),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.CreateModel(
name='User',
fields=[
('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')),
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('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,
},
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.CreateModel(
name='TeachingUnit',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('name', models.CharField(max_length=64)),
('email', models.EmailField(blank=True, max_length=254, null=True)),
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teaching_units', to='Palto.department')),
('student_groups', models.ManyToManyField(blank=True, related_name='studying_units', to='Palto.studentgroup')),
('managers', models.ManyToManyField(blank=True, related_name='managing_units', to=settings.AUTH_USER_MODEL)),
('teachers', models.ManyToManyField(blank=True, related_name='teaching_units', to=settings.AUTH_USER_MODEL)),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.CreateModel(
name='TeachingSession',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('start', models.DateTimeField()),
('duration', models.DurationField()),
('note', models.TextField(blank=True)),
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teaching_sessions', to='Palto.studentgroup')),
('unit', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='sessions', to='Palto.teachingunit')),
('teacher', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='teaching_sessions', to=settings.AUTH_USER_MODEL)),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.AddField(
model_name='studentgroup',
name='owner',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='owning_groups', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='studentgroup',
name='students',
field=models.ManyToManyField(blank=True, related_name='student_groups', to=settings.AUTH_USER_MODEL),
),
migrations.CreateModel(
name='StudentCard',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('uid', models.BinaryField(max_length=7)),
('department', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_cards', to='Palto.department')),
('owner', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='student_cards', to=settings.AUTH_USER_MODEL)),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.AddField(
model_name='department',
name='managers',
field=models.ManyToManyField(blank=True, related_name='managing_departments', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='department',
name='students',
field=models.ManyToManyField(blank=True, related_name='studying_departments', to=settings.AUTH_USER_MODEL),
),
migrations.AddField(
model_name='department',
name='teachers',
field=models.ManyToManyField(blank=True, related_name='teaching_departments', to=settings.AUTH_USER_MODEL),
),
migrations.CreateModel(
name='Attendance',
fields=[
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
('date', models.DateTimeField()),
('session', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attendances', to='Palto.teachingsession')),
('student', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='attended_sessions', to=settings.AUTH_USER_MODEL)),
],
bases=(models.Model, Palto.Palto.models.ModelPermissionHelper),
),
migrations.AddField(
model_name='absence',
name='student',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='absences', to=settings.AUTH_USER_MODEL),
),
]
25 changes: 25 additions & 0 deletions Palto/Palto/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,31 @@ def user_fields_contraints(cls, user: "User") -> dict[str, Callable[[dict], Quer
@classmethod
@abstractmethod
def all_editable_by_user(cls, user: "User") -> QuerySet:
"""
Return the list of object that the user can edit
"""

def is_editable_by_user(self, user: "User") -> bool:
"""
Return True if the user can edit this object
"""

return self in self.all_editable_by_user(user)

@classmethod
@abstractmethod
def all_visible_by_user(cls, user: "User") -> QuerySet:
"""
Return the list of object that the user can see
"""

def is_visible_by_user(self, user: "User") -> bool:
"""
Return True if the user can see this object
"""

return self in self.all_visible_by_user(user)


class User(AbstractUser, ModelPermissionHelper):
"""
Expand Down Expand Up @@ -522,6 +536,17 @@ def short_id(self) -> str:
def end(self) -> datetime:
return self.start + self.duration

@property
def related_absences(self) -> QuerySet["Absence"]:
"""
Return the sessions that match the user absence
"""

return Absence.objects.filter(
student__in=self.group.students.all(),
start__lte=self.start, end__gte=self.end
).distinct()

# validations

def clean(self):
Expand Down
47 changes: 47 additions & 0 deletions Palto/Palto/static/Palto/css/base.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* font */
* {
font-family: "Century Gothic", sans-serif;
}

/* color-scheme */
@media (prefers-color-scheme: light) {
:root {
--primary: #00345F;
--secondary: #EF800A;

--foreground: #1B1B1B;
--background: #FFFFFF;
}
}

@media (prefers-color-scheme: dark) {
:root {
--primary: #00549F;
--secondary: #EF800A;

--foreground: #FFFFFF;
--background: #1B1B1B;
}
}

/* links */
*:link, *:visited {
color: var(--primary);
text-decoration: none;
}

*:link:hover, *:visited:hover {
color: var(--secondary);
}

/* table */
table, tr, th, td {
border-color: var(--foreground) !important;
}

/* tweaks */
body {
margin: 0;
color: var(--foreground);
background-color: var(--background);
}
9 changes: 9 additions & 0 deletions Palto/Palto/static/Palto/css/homepage.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.title {
font-size: 500%;
text-align: center;
}

.text {
width: 60%;
margin: auto;
}
11 changes: 11 additions & 0 deletions Palto/Palto/static/Palto/css/login.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#login-form {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}

#login-form input {
box-sizing: border-box;
width: 100%;
}
Loading

0 comments on commit 5fec4cb

Please sign in to comment.