From f1fefd3c1b402dc77108a4933a6989429b2cd072 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20Johan=20G=C3=BCtzkow?= <70779496+CJGutz@users.noreply.github.com> Date: Wed, 17 Jan 2024 20:38:29 +0100 Subject: [PATCH] Create application portal for group leaders (#780) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Listing group applications (WIP) * Fixed displayed application names on internal portal * Applicants' names are hyperlinks to individual applications * Finished basic application look * Admin of first choice group processes the application * Fixed authentication error for applications page * create view to move application to next group * create application email text and upgrade views * functionality to send email to person in group * check if group exists before send mail * check for superuser permissions * empty commit * delete unused file and remove superuser privelige * create card for application * add approve application page and separate into components * add link to applications * add comments for future work * separate into own personalia box * send email on successful new application * create form to send email to applicant * better styled and working form for writing email * add timepicker * translation and email header and back button * translate internalportal * add badge to internalportal and translations * empty application list message and group choice list order * edit email url to be full path * create modal before sending to next group * better links for error on sending application further * change permission on applications view * update locale file * create translation for interview email * email for deny and approve with translations * more translations to emails. debugging * finish application translations * change translation in approve page * remove newline on top of email, fix email copy bug and translate Subject * delete weirdly created file I dont understand * remove static/ from gitignore to add to new static files * change to group names --------- Co-authored-by: Njål Telstø Co-authored-by: zara <496122@student.fontys.nl> --- .gitignore | 1 - applications/admin.py | 15 + applications/forms.py | 24 +- applications/locale/en/LC_MESSAGES/django.po | 2 +- applications/locale/nb/LC_MESSAGES/django.po | 2 +- ...20_alter_applicationgroupchoice_options.py | 17 + applications/models.py | 3 + .../applications/new_application_email.txt | 22 + authentication/views.py | 21 +- files/locale/en/LC_MESSAGES/django.po | 2 +- files/locale/nb/LC_MESSAGES/django.po | 2 +- fixtures.json | 2 +- internalportal/forms.py | 25 + .../locale/en/LC_MESSAGES/django.po | 434 ++++++++++++++++++ .../locale/nb/LC_MESSAGES/django.po | 393 ++++++++++++++++ .../internalportal/css/applications.css | 15 + .../internalportal/applications/answers.html | 31 ++ .../applications/application.html | 87 ++++ .../application_confirm_delete.html | 34 ++ .../applications/application_list_card.html | 10 + .../applications/applications.html | 26 ++ .../internalportal/applications/approve.html | 57 +++ .../applications/approved_email.txt | 10 + .../applications/denied_email.txt | 9 + .../applications/interview_email.txt | 15 + .../applications/interview_email_form.html | 53 +++ .../applications/personalia_box.html | 13 + .../applications/text_box_copy.html | 17 + .../internalportal/internalportal.html | 14 + internalportal/urls.py | 22 + internalportal/views.py | 282 +++++++++++- inventory/locale/en/LC_MESSAGES/django.po | 2 +- inventory/locale/nb/LC_MESSAGES/django.po | 2 +- news/forms.py | 5 + news/locale/en/LC_MESSAGES/django.po | 12 +- news/locale/nb/LC_MESSAGES/django.po | 8 +- news/static/news/js/edit_event.js | 45 -- news/templates/news/edit_event.html | 6 +- .../locale/en/LC_MESSAGES/django.po | 2 +- .../locale/nb/LC_MESSAGES/django.po | 2 +- reservations/locale/en/LC_MESSAGES/django.po | 2 +- reservations/locale/nb/LC_MESSAGES/django.po | 2 +- userprofile/locale/en/LC_MESSAGES/django.po | 2 +- userprofile/locale/nb/LC_MESSAGES/django.po | 2 +- watchlist/locale/en/LC_MESSAGES/django.po | 2 +- watchlist/locale/nb/LC_MESSAGES/django.po | 2 +- website/locale/en/LC_MESSAGES/django.po | 2 +- website/locale/nb/LC_MESSAGES/django.po | 2 +- website/settings.py | 6 +- website/static/website/js/datetimepicker.js | 53 +++ website/templates/website/page_header.html | 9 + 51 files changed, 1748 insertions(+), 80 deletions(-) create mode 100644 applications/migrations/0020_alter_applicationgroupchoice_options.py create mode 100644 applications/templates/applications/new_application_email.txt create mode 100644 internalportal/forms.py create mode 100644 internalportal/locale/en/LC_MESSAGES/django.po create mode 100644 internalportal/locale/nb/LC_MESSAGES/django.po create mode 100644 internalportal/static/internalportal/css/applications.css create mode 100644 internalportal/templates/internalportal/applications/answers.html create mode 100644 internalportal/templates/internalportal/applications/application.html create mode 100644 internalportal/templates/internalportal/applications/application_confirm_delete.html create mode 100644 internalportal/templates/internalportal/applications/application_list_card.html create mode 100644 internalportal/templates/internalportal/applications/applications.html create mode 100644 internalportal/templates/internalportal/applications/approve.html create mode 100644 internalportal/templates/internalportal/applications/approved_email.txt create mode 100644 internalportal/templates/internalportal/applications/denied_email.txt create mode 100644 internalportal/templates/internalportal/applications/interview_email.txt create mode 100644 internalportal/templates/internalportal/applications/interview_email_form.html create mode 100644 internalportal/templates/internalportal/applications/personalia_box.html create mode 100644 internalportal/templates/internalportal/applications/text_box_copy.html create mode 100644 website/static/website/js/datetimepicker.js create mode 100644 website/templates/website/page_header.html diff --git a/.gitignore b/.gitignore index f8f4416f7..c159d292b 100644 --- a/.gitignore +++ b/.gitignore @@ -18,7 +18,6 @@ profilepictures/ env/ venv/ .vscode/ -static/ **/__pycache__ /static/ diff --git a/applications/admin.py b/applications/admin.py index aa9bd9b8b..cf3f44cc5 100644 --- a/applications/admin.py +++ b/applications/admin.py @@ -22,3 +22,18 @@ class Media: @admin.register(Application) class ApplicationAdmin(BaseApplicationAdmin): inlines = [ApplicationGroupChoiceInline] + list_display = [ + "name", + "email", + "groups", + ] + + def groups(self, obj): + return ", ".join( + [ + group.name + for group in obj.group_choice.order_by( + "applicationgroupchoice__priority" + ) + ] + ) diff --git a/applications/forms.py b/applications/forms.py index 8f83e1ed0..037165159 100644 --- a/applications/forms.py +++ b/applications/forms.py @@ -1,6 +1,9 @@ from django.core.mail import send_mail from django.forms import ModelForm, Textarea, TextInput from django.template.loader import render_to_string +from django.urls import reverse + +from committees.models import Committee from .models import Application, ApplicationGroupChoice @@ -74,4 +77,23 @@ def send_email(self): [self.cleaned_data["email"]], fail_silently=False, ) - pass + + new_application_message = render_to_string( + "applications/new_application_email.txt", + {"applications_url": reverse("internalportal:applications")}, + ) + committee = Committee.objects.filter( + name=self.cleaned_data["group_choice"][0].name + ).first() + if committee: + emails = [ + getattr(committee.main_lead, "email", None), + getattr(committee.second_lead, "email", None), + ] + send_mail( + "[Hackerspace NTNU] Ny søknad!", + new_application_message, + "Hackerspace NTNU", + emails, + fail_silently=False, + ) diff --git a/applications/locale/en/LC_MESSAGES/django.po b/applications/locale/en/LC_MESSAGES/django.po index d52280154..a38247840 100644 --- a/applications/locale/en/LC_MESSAGES/django.po +++ b/applications/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/applications/locale/nb/LC_MESSAGES/django.po b/applications/locale/nb/LC_MESSAGES/django.po index 98ba38667..c5ea688a4 100644 --- a/applications/locale/nb/LC_MESSAGES/django.po +++ b/applications/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/applications/migrations/0020_alter_applicationgroupchoice_options.py b/applications/migrations/0020_alter_applicationgroupchoice_options.py new file mode 100644 index 000000000..2fad25a6e --- /dev/null +++ b/applications/migrations/0020_alter_applicationgroupchoice_options.py @@ -0,0 +1,17 @@ +# Generated by Django 3.2.18 on 2023-11-27 00:53 + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0019_applicationgroup_open_for_applications'), + ] + + operations = [ + migrations.AlterModelOptions( + name='applicationgroupchoice', + options={'ordering': ['priority']}, + ), + ] diff --git a/applications/models.py b/applications/models.py index c32b27fb2..b3d1c97dd 100644 --- a/applications/models.py +++ b/applications/models.py @@ -94,3 +94,6 @@ class ApplicationGroupChoice(models.Model): application = models.ForeignKey(Application, on_delete=models.CASCADE) group = models.ForeignKey(ApplicationGroup, on_delete=models.CASCADE) priority = models.PositiveIntegerField(null=True) + + class Meta: + ordering = ["priority"] diff --git a/applications/templates/applications/new_application_email.txt b/applications/templates/applications/new_application_email.txt new file mode 100644 index 000000000..9dcb29bf4 --- /dev/null +++ b/applications/templates/applications/new_application_email.txt @@ -0,0 +1,22 @@ +Hei, + +Denne mailen blir sendt til deg fordi det har kommet en ny søknad til Hackerspace som har din gruppe på første valg. + +Du finner aktive søknader her: {{ applications_url }} + + +Mvh, +Hackerspace NTNU + +----------------------------------- + + +Hello, + +This email is sent to you because there is a new applicant to Hackerspace with your group as highest priority. + +You can find active applications here: {{ applications_url }} + + +Best regards, +Hackerspace NTNU diff --git a/authentication/views.py b/authentication/views.py index e63ab0b2c..ea9c2be7b 100644 --- a/authentication/views.py +++ b/authentication/views.py @@ -1,4 +1,4 @@ -from django.contrib.auth import logout +from django.contrib.auth import get_user_model, logout from django.shortcuts import redirect from django.urls import reverse from django.views import View @@ -75,3 +75,22 @@ def associate_by_email(backend, details, user=None, *args, **kwargs): prison_user.save() return {"user": alt_users[0], "is_new": False} + + +def get_user_by_stud_or_ntnu_email(email: str): + """Check for the following cases: + + 1. Input email is the same as the user's email + 2. User has a stud.ntnu.no email and input email is ntnu.no + 3. User has a ntnu.no email and input email is stud.ntnu.no + """ + User = get_user_model() + + for query_email in [ + email, + email.split("@")[0] + "@stud.ntnu.no", + email.split("@")[0] + "@ntnu.no", + ]: + user = User.objects.filter(email=query_email).first() + if user: + return user diff --git a/files/locale/en/LC_MESSAGES/django.po b/files/locale/en/LC_MESSAGES/django.po index 69ea64eab..336a2362a 100644 --- a/files/locale/en/LC_MESSAGES/django.po +++ b/files/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/files/locale/nb/LC_MESSAGES/django.po b/files/locale/nb/LC_MESSAGES/django.po index 2e8838a1b..ba8a506d6 100644 --- a/files/locale/nb/LC_MESSAGES/django.po +++ b/files/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/fixtures.json b/fixtures.json index 7958d811a..2bb630853 100644 --- a/fixtures.json +++ b/fixtures.json @@ -635,7 +635,7 @@ "model": "applications.applicationgroup", "pk": 8, "fields": { - "name": "Spill", + "name": "Prosjekt: Spill", "text_main": "Det har i mange år vært interesse for å utvikle spill på Hackerspace og vi har i like mange år holdt på med en spillutviklingsgruppe for å tilfredsstille folket.\r\nDen aktive spillutviklingsgruppen ble ferdig med sitt nyeste prosjekt våren 2022 og skal fortsette morroa med mer spillutvikling.\r\nMålet for prosjektet er å produsere et spill som skal delta på Norwegian game awards. Så gled dere til de gøye, sprø og kaotiske eventyrene som dere vil ha i dette prosjektet!", "text_structure": "", "text_workload": "", diff --git a/internalportal/forms.py b/internalportal/forms.py new file mode 100644 index 000000000..3f4c5928c --- /dev/null +++ b/internalportal/forms.py @@ -0,0 +1,25 @@ +from django.db.models.fields import forms +from django.utils.translation import gettext_lazy as _ + +from news.forms import SplitDateTimeFieldCustom + + +class InterviewEmailForm(forms.Form): + location = forms.CharField( + label=_("Plassering"), + max_length=100, + required=True, + ) + location_link = forms.CharField( + label=_("Lenke til plassering"), + max_length=100, + required=False, + ) + start_time = SplitDateTimeFieldCustom( + label=_("Starttidspunkt"), + required=True, + ) + end_time = SplitDateTimeFieldCustom( + label=_("Sluttidspunkt"), + required=False, + ) diff --git a/internalportal/locale/en/LC_MESSAGES/django.po b/internalportal/locale/en/LC_MESSAGES/django.po new file mode 100644 index 000000000..2b60b44d7 --- /dev/null +++ b/internalportal/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,434 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: internalportal/forms.py:9 +msgid "Plassering" +msgstr "Location" + +#: internalportal/forms.py:14 +msgid "Lenke til plassering" +msgstr "Link to location" + +#: internalportal/forms.py:19 +msgid "Starttidspunkt" +msgstr "Start time" + +#: internalportal/forms.py:23 +msgid "Sluttidspunkt" +msgstr "End time" + +#: internalportal/templates/internalportal/applications/answers.html:5 +msgid "Kunnskap om Hackerspace" +msgstr "Knowledge about Hackerspace" + +#: internalportal/templates/internalportal/applications/answers.html:10 +msgid "Om meg" +msgstr "About me" + +#: internalportal/templates/internalportal/applications/answers.html:15 +msgid "Søknadstekst" +msgstr "Application text" + +#: internalportal/templates/internalportal/applications/answers.html:20 +msgid "Grupper søkt" +msgstr "Groups applied for" + +#: internalportal/templates/internalportal/applications/answers.html:27 +msgid "Andre interesser" +msgstr "Other interests" + +#: internalportal/templates/internalportal/applications/application.html:17 +msgid "Søknadssvar" +msgstr "Application response" + +#: internalportal/templates/internalportal/applications/application.html:30 +msgid "Intervjuprosessen" +msgstr "Interview process" + +#: internalportal/templates/internalportal/applications/application.html:32 +msgid "Les over søknaden" +msgstr "Read through the application" + +#: internalportal/templates/internalportal/applications/application.html:34 +msgid "Send e-post om intervju" +msgstr "Send email about interview" + +#: internalportal/templates/internalportal/applications/application.html:36 +msgid "Hold intervju" +msgstr "Conduct interview" + +#: internalportal/templates/internalportal/applications/application.html:37 +msgid "Gi beskjed om kandidaten ikke er videre i intervjuprosessen" +msgstr "Notify if the candidate is not proceeding in the interview process." + +#: internalportal/templates/internalportal/applications/application.html:39 +msgid "E-post for å avslå" +msgstr "Email to deny" + +#: internalportal/templates/internalportal/applications/application.html:43 +#: internalportal/templates/internalportal/applications/application.html:55 +#: internalportal/templates/internalportal/applications/interview_email_form.html:41 +msgid "Emne" +msgstr "Subject" + +#: internalportal/templates/internalportal/applications/application.html:43 +#: internalportal/templates/internalportal/applications/application.html:55 +msgid "Verv hos Hackerspace" +msgstr "Volunteering at Hackerspace" + +#: internalportal/templates/internalportal/applications/application.html:48 +msgid "Få kandidaten til å logge inn på nettsiden" +msgstr "Have the candidate log in to the website" + +#: internalportal/templates/internalportal/applications/application.html:49 +msgid "" +"Godkjenn kandidaten og send mail at de har kommet inn med HowToHack " +"dokumentet fra Google Drive" +msgstr "" +"Approve the candidate and send an email that they have been accepted with " +"the HowToHack document from Google Drive" + +#: internalportal/templates/internalportal/applications/application.html:51 +msgid "E-post for å godkjenne" +msgstr "Email to approve" + +#: internalportal/templates/internalportal/applications/application.html:60 +msgid "Legg kandidaten inn i kommunikasjonskanaler" +msgstr "Add the candidate to communication channels" + +#: internalportal/templates/internalportal/applications/application.html:67 +#: internalportal/templates/internalportal/applications/applications.html:23 +msgid "Tilbake" +msgstr "Back" + +#: internalportal/templates/internalportal/applications/application.html:68 +#: internalportal/templates/internalportal/applications/approve.html:49 +msgid "Godkjenn" +msgstr "Approve" + +#: internalportal/templates/internalportal/applications/application.html:69 +msgid "Fjern" +msgstr "Remove" + +#: internalportal/templates/internalportal/applications/application.html:71 +#: internalportal/templates/internalportal/applications/application.html:76 +msgid "Send videre" +msgstr "Forward" + +#: internalportal/templates/internalportal/applications/application.html:74 +msgid "Er du sikker på at du vil sende søknaden videre?" +msgstr "Are you sure you want to send the application to the next group?" + +#: internalportal/templates/internalportal/applications/application.html:75 +msgid "Søknaden sendes til" +msgstr "The application is sent to" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:19 +msgid "Bekreft handling" +msgstr "Confirm action" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:20 +msgid "" +"Er du sikker på at du vil slette søknaden? Den er ikke mulig å gjenopprette." +msgstr "" +"Are you sure you want to delete the application? It cannot be recovered." + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:25 +msgid "Ja" +msgstr "Yes" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:28 +msgid "Nei, gå tilbake" +msgstr "No, go back" + +#: internalportal/templates/internalportal/applications/applications.html:6 +msgid "Søknader" +msgstr "Applications" + +#: internalportal/templates/internalportal/applications/applications.html:18 +msgid "Ingen søknader" +msgstr "No applications" + +#: internalportal/templates/internalportal/applications/approve.html:16 +msgid "Godkjenn søknad" +msgstr "Approve application" + +#: internalportal/templates/internalportal/applications/approve.html:20 +#: internalportal/templates/internalportal/applications/personalia_box.html:6 +#: internalportal/templates/internalportal/door-access-member-list.html:10 +msgid "Navn" +msgstr "Name" + +#: internalportal/templates/internalportal/applications/approve.html:23 +msgid "Gruppe" +msgstr "Group" + +#: internalportal/templates/internalportal/applications/approve.html:29 +msgid "For å kunne legge til et nytt medlem må søkerens ntnu e-post benyttes." +msgstr "To add a new member, the applicant's NTNU email must be used." + +#: internalportal/templates/internalportal/applications/approve.html:30 +msgid "Be personen logge inn på nettsiden før godkjenning." +msgstr "Ask the person to log in to the website before approval." + +#: internalportal/templates/internalportal/applications/approve.html:31 +msgid "Legg personen i riktige kommunikasjonskanaler og google drive" +msgstr "Add the person to the correct communication channels and Google Drive" + +#: internalportal/templates/internalportal/applications/approve.html:37 +#: internalportal/templates/internalportal/applications/personalia_box.html:7 +#: internalportal/templates/internalportal/door-access-member-list.html:11 +msgid "Epost" +msgstr "Email" + +#: internalportal/templates/internalportal/applications/approve.html:45 +#: internalportal/templates/internalportal/applications/interview_email_form.html:48 +msgid "Gå tilbake" +msgstr "Go back" + +#: internalportal/templates/internalportal/applications/approved_email.txt:2 +#, python-format +msgid "" +"Hei %(name)s,\n" +"\n" +"Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " +"intervjuet.\n" +"\n" +"Du gjorde et godt inntrykk på intervjuet og vi ønsker å tilby deg medlemskap " +"i Hackerspace NTNU %(application_group)s.\n" +"\n" +"Vi ønsker gjerne at du svarer på denne mailen med å enten akseptere eller " +"avslå tilbudet om medlemskap. \n" +"\n" +"Med vennlig hilsen,\n" +"%(application_group)s" +msgstr "" +" Hi %(name)s,\n" +"\n" +"Thank you for your application to Hackerspace NTNU and for the pleasant " +"interview.\n" +"\n" +"You made a positive impression during the interview, and we would like to " +"offer you membership in Hackerspace NTNU in Hackerspace NTNU " +"%(application_group)s.\n" +"\n" +"We would appreciate it if you could respond to this email by either " +"accepting or declining the membership offer.\n" +"\n" +"Best regards,\n" +"%(application_group)s " + +#: internalportal/templates/internalportal/applications/denied_email.txt:2 +#, python-format +msgid "" +"Hei %(name)s,\n" +"\n" +"Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " +"intervjuet.\n" +"\n" +"Dessverre får du ikke plass i Hackerspace %(application_group)s.\n" +"Jeg ønsker deg lykke til videre med studier.\n" +"\n" +"Med vennlig hilsen,\n" +"%(application_group)s" +msgstr "" +" Hi %(name)s,\n" +"\n" +"Thank you for your application to Hackerspace NTNU and for the pleasant " +"interview.\n" +"\n" +"Unfortunately, you have not been selected for a spot in Hackerspace " +"%(application_group)s.\n" +"I wish you the best of luck with your studies moving forward.\n" +"\n" +"Best regards,\n" +"%(application_group)s " + +#: internalportal/templates/internalportal/applications/interview_email.txt:2 +#, python-format +msgid "" +"Hei %(application_name)s,\n" +"Tusen takk for din søknad hos Hackerspace NTNU!\n" +"\n" +" \n" +"I forbindelse med opptaket hos Hackerspace NTNU, ønsker vi å kalle deg inn " +"til et intervju. Intervjuet er en mulighet for oss til å bli enda bedre " +"kjent med deg før det gjøres sluttvurderinger i opptaket, og en mulighet for " +"deg til å stille spørsmål rundt opptaket, organisasjonen og annet dersom " +"ønskelig.\n" +"\n" +"Foreslått tidspunkt for intervjuet er %(start_time)s i " +msgstr "" +"Hi %(application_name)s,\n" +"Thank you for your application to Hackerspace NTNU!\n" +"\n" +" \n" +"As part of the admission process at Hackerspace NTNU, we would like to " +"invite you to an interview. The interview is an opportunity for us to get to " +"know you better before final evaluations are made in the admission process. " +"It's also a chance for you to ask any questions you may have about the " +"admission, the organization, or anything else if desired.\n" +"\n" +"The proposed time for the interview is %(start_time)s in " + +#: internalportal/templates/internalportal/applications/interview_email.txt:13 +msgid "Med vennlig hilsen" +msgstr "Best regards" + +#: internalportal/templates/internalportal/applications/interview_email_form.html:10 +msgid "E-post for intervju" +msgstr "Email for interview" + +#: internalportal/templates/internalportal/applications/interview_email_form.html:36 +msgid "Lag e-post" +msgstr "Create email" + +#: internalportal/templates/internalportal/applications/interview_email_form.html:41 +msgid "Intervju" +msgstr "Interview" + +#: internalportal/templates/internalportal/applications/personalia_box.html:5 +msgid "Personalia" +msgstr "Personal information" + +#: internalportal/templates/internalportal/applications/personalia_box.html:8 +msgid "Tlf" +msgstr "Phone" + +#: internalportal/templates/internalportal/applications/personalia_box.html:9 +msgid "Studie" +msgstr "Study" + +#: internalportal/templates/internalportal/applications/personalia_box.html:10 +msgid "År" +msgstr "Year" + +#: internalportal/templates/internalportal/applications/personalia_box.html:11 +msgid "Søknad motatt" +msgstr "Application received" + +#: internalportal/templates/internalportal/applications/text_box_copy.html:9 +#: internalportal/templates/internalportal/door-access-member-list.html:6 +msgid "Kopier til utklippstavle" +msgstr "Copy to clipboard" + +#: internalportal/templates/internalportal/door-access-member-list.html:12 +msgid "Tilgang til" +msgstr "Access to" + +#: internalportal/templates/internalportal/door-access-member-list.html:26 +msgid "Ingen aktive medlemmer." +msgstr "No active members." + +#: internalportal/templates/internalportal/internalportal.html:10 +msgid "Internportal" +msgstr "Internal portal" + +#: internalportal/templates/internalportal/internalportal.html:27 +msgid "Siste internnytt" +msgstr "Latest internal news" + +#: internalportal/templates/internalportal/internalportal.html:41 +msgid "Her var det intetnytt" +msgstr "There's no news here" + +#: internalportal/templates/internalportal/internalportal.html:51 +msgid "Siste interne arrangementer" +msgstr "Latest internal events" + +#: internalportal/templates/internalportal/internalportal.html:70 +msgid "Ingen interne arrangementer" +msgstr "No internal events" + +#: internalportal/templates/internalportal/internalportal.html:80 +msgid "Åpne lånesøknader" +msgstr "Open loan applications" + +#: internalportal/templates/internalportal/internalportal.html:93 +msgid "Ingen lånesøknader" +msgstr "No loan applications" + +#: internalportal/templates/internalportal/internalportal.html:108 +msgid "Lånesøknader" +msgstr "Loan applications" + +#: internalportal/templates/internalportal/internalportal.html:117 +msgid "Vaktliste" +msgstr "Shift schedule" + +#: internalportal/templates/internalportal/internalportal.html:126 +msgid "Lager" +msgstr "Storage" + +#: internalportal/templates/internalportal/internalportal.html:135 +msgid "Reservasjoner" +msgstr "Reservations" + +#: internalportal/templates/internalportal/internalportal.html:144 +msgid "Bildegalleri" +msgstr "Image gallery" + +#: internalportal/templates/internalportal/internalportal.html:154 +msgid "Adminpanel" +msgstr "Admin panel" + +#: internalportal/templates/internalportal/internalportal.html:163 +msgid "Medlemsliste for dørtilgang" +msgstr "Member list for door access" + +#: internalportal/templates/internalportal/internalportal.html:176 +msgid "Søkere" +msgstr "Applicants" + +#: internalportal/templates/internalportal/internalportal.html:178 +msgid "venter" +msgstr "waiting" + +#: internalportal/views.py:108 +msgid "Søknad sendt videre til neste gruppe" +msgstr "Application forwarded to the next group" + +#: internalportal/views.py:117 +msgid "Søknaden finnes ikke" +msgstr "The application does not exist" + +#: internalportal/views.py:132 +msgid "Søknaden har ingen flere grupper å gå til" +msgstr "The application has no more groups to go to" + +#: internalportal/views.py:141 +#, python-brace-format +msgid "Gruppen {group_name} finnes ikke. Kontakt administrator." +msgstr "The group {group_name} does not exist. Contact the administrator." + +#: internalportal/views.py:158 +#, python-brace-format +msgid "Gruppen {group} har ingen ledere. Kontakt administrator." +msgstr "" +"The group {group} does not have any leaders. Contact the administrator." + +#: internalportal/views.py:169 +msgid "Søknad sendt videre" +msgstr "Application forwarded" + +#: internalportal/views.py:270 +msgid "Få brukeren til å logge inn med Feide først og bruk søkerens ntnu-mail." +msgstr "" +"Have the user log in with Feide first and use the applicant's NTNU email." diff --git a/internalportal/locale/nb/LC_MESSAGES/django.po b/internalportal/locale/nb/LC_MESSAGES/django.po new file mode 100644 index 000000000..e8b05a68d --- /dev/null +++ b/internalportal/locale/nb/LC_MESSAGES/django.po @@ -0,0 +1,393 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: internalportal/forms.py:9 +msgid "Plassering" +msgstr "" + +#: internalportal/forms.py:14 +msgid "Lenke til plassering" +msgstr "" + +#: internalportal/forms.py:19 +msgid "Starttidspunkt" +msgstr "" + +#: internalportal/forms.py:23 +msgid "Sluttidspunkt" +msgstr "" + +#: internalportal/templates/internalportal/applications/answers.html:5 +msgid "Kunnskap om Hackerspace" +msgstr "" + +#: internalportal/templates/internalportal/applications/answers.html:10 +msgid "Om meg" +msgstr "" + +#: internalportal/templates/internalportal/applications/answers.html:15 +msgid "Søknadstekst" +msgstr "" + +#: internalportal/templates/internalportal/applications/answers.html:20 +msgid "Grupper søkt" +msgstr "" + +#: internalportal/templates/internalportal/applications/answers.html:27 +msgid "Andre interesser" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:17 +msgid "Søknadssvar" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:30 +msgid "Intervjuprosessen" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:32 +msgid "Les over søknaden" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:34 +msgid "Send e-post om intervju" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:36 +msgid "Hold intervju" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:37 +msgid "Gi beskjed om kandidaten ikke er videre i intervjuprosessen" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:39 +msgid "E-post for å avslå" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:43 +#: internalportal/templates/internalportal/applications/application.html:55 +#: internalportal/templates/internalportal/applications/interview_email_form.html:41 +msgid "Emne" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:43 +#: internalportal/templates/internalportal/applications/application.html:55 +msgid "Verv hos Hackerspace" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:48 +msgid "Få kandidaten til å logge inn på nettsiden" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:49 +msgid "" +"Godkjenn kandidaten og send mail at de har kommet inn med HowToHack " +"dokumentet fra Google Drive" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:51 +msgid "E-post for å godkjenne" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:60 +msgid "Legg kandidaten inn i kommunikasjonskanaler" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:67 +#: internalportal/templates/internalportal/applications/applications.html:23 +msgid "Tilbake" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:68 +#: internalportal/templates/internalportal/applications/approve.html:49 +msgid "Godkjenn" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:69 +msgid "Fjern" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:71 +#: internalportal/templates/internalportal/applications/application.html:76 +msgid "Send videre" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:74 +msgid "Er du sikker på at du vil sende søknaden videre?" +msgstr "" + +#: internalportal/templates/internalportal/applications/application.html:75 +msgid "Søknaden sendes til" +msgstr "" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:19 +msgid "Bekreft handling" +msgstr "" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:20 +msgid "" +"Er du sikker på at du vil slette søknaden? Den er ikke mulig å gjenopprette." +msgstr "" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:25 +msgid "Ja" +msgstr "" + +#: internalportal/templates/internalportal/applications/application_confirm_delete.html:28 +msgid "Nei, gå tilbake" +msgstr "" + +#: internalportal/templates/internalportal/applications/applications.html:6 +msgid "Søknader" +msgstr "" + +#: internalportal/templates/internalportal/applications/applications.html:18 +msgid "Ingen søknader" +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:16 +msgid "Godkjenn søknad" +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:20 +#: internalportal/templates/internalportal/applications/personalia_box.html:6 +#: internalportal/templates/internalportal/door-access-member-list.html:10 +msgid "Navn" +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:23 +msgid "Gruppe" +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:29 +msgid "For å kunne legge til et nytt medlem må søkerens ntnu e-post benyttes." +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:30 +msgid "Be personen logge inn på nettsiden før godkjenning." +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:31 +msgid "Legg personen i riktige kommunikasjonskanaler og google drive" +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:37 +#: internalportal/templates/internalportal/applications/personalia_box.html:7 +#: internalportal/templates/internalportal/door-access-member-list.html:11 +msgid "Epost" +msgstr "" + +#: internalportal/templates/internalportal/applications/approve.html:45 +#: internalportal/templates/internalportal/applications/interview_email_form.html:48 +msgid "Gå tilbake" +msgstr "" + +#: internalportal/templates/internalportal/applications/approved_email.txt:2 +#, python-format +msgid "" +"Hei %(name)s,\n" +"\n" +"Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " +"intervjuet.\n" +"\n" +"Du gjorde et godt inntrykk på intervjuet og vi ønsker å tilby deg medlemskap " +"i Hackerspace NTNU %(application_group)s.\n" +"\n" +"Vi ønsker gjerne at du svarer på denne mailen med å enten akseptere eller " +"avslå tilbudet om medlemskap. \n" +"\n" +"Med vennlig hilsen,\n" +"%(application_group)s" +msgstr "" + +#: internalportal/templates/internalportal/applications/denied_email.txt:2 +#, python-format +msgid "" +"Hei %(name)s,\n" +"\n" +"Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige " +"intervjuet.\n" +"\n" +"Dessverre får du ikke plass i Hackerspace %(application_group)s.\n" +"Jeg ønsker deg lykke til videre med studier.\n" +"\n" +"Med vennlig hilsen,\n" +"%(application_group)s" +msgstr "" + +#: internalportal/templates/internalportal/applications/interview_email.txt:2 +#, python-format +msgid "" +"Hei %(application_name)s,\n" +"Tusen takk for din søknad hos Hackerspace NTNU!\n" +"\n" +" \n" +"I forbindelse med opptaket hos Hackerspace NTNU, ønsker vi å kalle deg inn " +"til et intervju. Intervjuet er en mulighet for oss til å bli enda bedre " +"kjent med deg før det gjøres sluttvurderinger i opptaket, og en mulighet for " +"deg til å stille spørsmål rundt opptaket, organisasjonen og annet dersom " +"ønskelig.\n" +"\n" +"Foreslått tidspunkt for intervjuet er %(start_time)s i " +msgstr "" + +#: internalportal/templates/internalportal/applications/interview_email.txt:13 +msgid "Med vennlig hilsen" +msgstr "" + +#: internalportal/templates/internalportal/applications/interview_email_form.html:10 +msgid "E-post for intervju" +msgstr "" + +#: internalportal/templates/internalportal/applications/interview_email_form.html:36 +msgid "Lag e-post" +msgstr "" + +#: internalportal/templates/internalportal/applications/interview_email_form.html:41 +msgid "Intervju" +msgstr "" + +#: internalportal/templates/internalportal/applications/personalia_box.html:5 +msgid "Personalia" +msgstr "" + +#: internalportal/templates/internalportal/applications/personalia_box.html:8 +msgid "Tlf" +msgstr "" + +#: internalportal/templates/internalportal/applications/personalia_box.html:9 +msgid "Studie" +msgstr "" + +#: internalportal/templates/internalportal/applications/personalia_box.html:10 +msgid "År" +msgstr "" + +#: internalportal/templates/internalportal/applications/personalia_box.html:11 +msgid "Søknad motatt" +msgstr "" + +#: internalportal/templates/internalportal/applications/text_box_copy.html:9 +#: internalportal/templates/internalportal/door-access-member-list.html:6 +msgid "Kopier til utklippstavle" +msgstr "" + +#: internalportal/templates/internalportal/door-access-member-list.html:12 +msgid "Tilgang til" +msgstr "" + +#: internalportal/templates/internalportal/door-access-member-list.html:26 +msgid "Ingen aktive medlemmer." +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:10 +msgid "Internportal" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:27 +msgid "Siste internnytt" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:41 +msgid "Her var det intetnytt" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:51 +msgid "Siste interne arrangementer" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:70 +msgid "Ingen interne arrangementer" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:80 +msgid "Åpne lånesøknader" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:93 +msgid "Ingen lånesøknader" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:108 +msgid "Lånesøknader" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:117 +msgid "Vaktliste" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:126 +msgid "Lager" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:135 +msgid "Reservasjoner" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:144 +msgid "Bildegalleri" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:154 +msgid "Adminpanel" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:163 +msgid "Medlemsliste for dørtilgang" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:176 +msgid "Søkere" +msgstr "" + +#: internalportal/templates/internalportal/internalportal.html:178 +msgid "venter" +msgstr "" + +#: internalportal/views.py:108 +msgid "Søknad sendt videre til neste gruppe" +msgstr "" + +#: internalportal/views.py:117 +msgid "Søknaden finnes ikke" +msgstr "" + +#: internalportal/views.py:132 +msgid "Søknaden har ingen flere grupper å gå til" +msgstr "" + +#: internalportal/views.py:141 +#, python-brace-format +msgid "Gruppen {group_name} finnes ikke. Kontakt administrator." +msgstr "" + +#: internalportal/views.py:158 +#, python-brace-format +msgid "Gruppen {group} har ingen ledere. Kontakt administrator." +msgstr "" + +#: internalportal/views.py:169 +msgid "Søknad sendt videre" +msgstr "" + +#: internalportal/views.py:270 +msgid "Få brukeren til å logge inn med Feide først og bruk søkerens ntnu-mail." +msgstr "" diff --git a/internalportal/static/internalportal/css/applications.css b/internalportal/static/internalportal/css/applications.css new file mode 100644 index 000000000..8162455fc --- /dev/null +++ b/internalportal/static/internalportal/css/applications.css @@ -0,0 +1,15 @@ +.application-info { + display: flex; + flex-direction: column; + gap: 1rem; + margin-bottom: 10px; +} + +.application-button-bar { + margin-top: 2rem; + margin-bottom: 2rem; + display: flex; + gap: 4rem; + flex-wrap: wrap; + justify-content: space-around; +} diff --git a/internalportal/templates/internalportal/applications/answers.html b/internalportal/templates/internalportal/applications/answers.html new file mode 100644 index 000000000..7557dc3d3 --- /dev/null +++ b/internalportal/templates/internalportal/applications/answers.html @@ -0,0 +1,31 @@ +{% load i18n %} +
+ +
+
{% trans "Kunnskap om Hackerspace" %}
+

{{ application.knowledge_of_hs }}

+
+ +
+
{% trans "Om meg" %}
+

{{ application.about }}

+
+ +
+
{% trans "Søknadstekst" %}
+

{{ application.application_text }}

+
+ +
+
{% trans "Grupper søkt" %}
+ {% for group_choice in application.applicationgroupchoice_set.all|dictsort:"priority" %} +

{{ forloop.counter }}: {{ group_choice.group.name }}

+ {% endfor %} +
+ +
+
{% trans "Andre interesser" %}
+

{{ application.project_interests }}

+
+ +
diff --git a/internalportal/templates/internalportal/applications/application.html b/internalportal/templates/internalportal/applications/application.html new file mode 100644 index 000000000..6394dfd1f --- /dev/null +++ b/internalportal/templates/internalportal/applications/application.html @@ -0,0 +1,87 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} + {% include "website/page_header.html" with title=application.name %} +
+
+
+ {% include "internalportal/applications/personalia_box.html" with application=application %} +
    +
  • + description{% trans "Søknadssvar" %} + +
    +
    + {% include "internalportal/applications/answers.html" with application=application %} +
    +
    +
  • +
+
+
+
+
+

{% trans "Intervjuprosessen" %}

+
    +
  1. {% trans "Les over søknaden" %}
  2. +
  3. + {% trans "Send e-post om intervju" %} +
  4. +
  5. {% trans "Hold intervju" %}
  6. +
  7. {% trans "Gi beskjed om kandidaten ikke er videre i intervjuprosessen" %}
    + + {% trans "E-post for å avslå" %} + + +
  8. +
  9. {% trans "Få kandidaten til å logge inn på nettsiden" %}
  10. +
  11. {% trans "Godkjenn kandidaten og send mail at de har kommet inn med HowToHack dokumentet fra Google Drive" %}
    + + {% trans "E-post for å godkjenne" %} + + +
  12. +
  13. {% trans "Legg kandidaten inn i kommunikasjonskanaler" %}
  14. +
+
+
+
+
+
+ + + + {% if second_group %} + {% trans "Send videre" %} + + {% endif %} +
+
+ + +{% endblock %} diff --git a/internalportal/templates/internalportal/applications/application_confirm_delete.html b/internalportal/templates/internalportal/applications/application_confirm_delete.html new file mode 100644 index 000000000..945b04f35 --- /dev/null +++ b/internalportal/templates/internalportal/applications/application_confirm_delete.html @@ -0,0 +1,34 @@ +{% extends "website/base.html" %} +{% load i18n %} +{% load static %} + +{% block head %} + +{% endblock %} + +{% block content %} +
+
+
+
+
+
+ {% csrf_token %} +
+ +

{% trans "Bekreft handling" %}

+

{% trans "Er du sikker på at du vil slette søknaden? Den er ikke mulig å gjenopprette." %}

+ + {% include "internalportal/applications/personalia_box.html" with application=application %} + +
+ +
+

+ {% trans "Nei, gå tilbake" %} +
+
+
+
+
+{% endblock content %} diff --git a/internalportal/templates/internalportal/applications/application_list_card.html b/internalportal/templates/internalportal/applications/application_list_card.html new file mode 100644 index 000000000..078efa27f --- /dev/null +++ b/internalportal/templates/internalportal/applications/application_list_card.html @@ -0,0 +1,10 @@ +
+
+
+ {{ application.name }} + {{ application.email }} +

{{ application.year }}. {{ application.study }}

+

{{ application.about }}

+
+
+
diff --git a/internalportal/templates/internalportal/applications/applications.html b/internalportal/templates/internalportal/applications/applications.html new file mode 100644 index 000000000..53514457d --- /dev/null +++ b/internalportal/templates/internalportal/applications/applications.html @@ -0,0 +1,26 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block content %} + {% trans "Søknader" as applications_header %} + {% include "website/page_header.html" with title=applications_header %} +
+
+ +
+ +
+{% endblock %} diff --git a/internalportal/templates/internalportal/applications/approve.html b/internalportal/templates/internalportal/applications/approve.html new file mode 100644 index 000000000..94dcc3ea2 --- /dev/null +++ b/internalportal/templates/internalportal/applications/approve.html @@ -0,0 +1,57 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} +
+
+
+ {% csrf_token %} +
+
+ {% trans "Godkjenn søknad" %} + +
+
+ {% trans "Navn" %}: {{ application.name }} +
+
+ {% trans "Gruppe" %}: {{ group.name }} +
+
+ +
+
+

{% trans "For å kunne legge til et nytt medlem må søkerens ntnu e-post benyttes." %}

+

{% trans "Be personen logge inn på nettsiden før godkjenning." %}

+

{% trans "Legg personen i riktige kommunikasjonskanaler og google drive" %}

+
+
+ +
+
+ + +
+
+ +
+ +
+ +
+
+
+
+
+
+
+{% endblock %} diff --git a/internalportal/templates/internalportal/applications/approved_email.txt b/internalportal/templates/internalportal/applications/approved_email.txt new file mode 100644 index 000000000..820f41814 --- /dev/null +++ b/internalportal/templates/internalportal/applications/approved_email.txt @@ -0,0 +1,10 @@ +{% load i18n %}{% blocktranslate with name=application.name %}Hei {{ name }}, + +Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige intervjuet. + +Du gjorde et godt inntrykk på intervjuet og vi ønsker å tilby deg medlemskap i Hackerspace NTNU {{ application_group }}. + +Vi ønsker gjerne at du svarer på denne mailen med å enten akseptere eller avslå tilbudet om medlemskap. + +Med vennlig hilsen, +{{ application_group }}{% endblocktranslate %} diff --git a/internalportal/templates/internalportal/applications/denied_email.txt b/internalportal/templates/internalportal/applications/denied_email.txt new file mode 100644 index 000000000..f99da8393 --- /dev/null +++ b/internalportal/templates/internalportal/applications/denied_email.txt @@ -0,0 +1,9 @@ +{% load i18n %}{% blocktranslate with name=application.name %}Hei {{ name }}, + +Tusen takk for din søknad hos Hackerspace NTNU og for det trivelige intervjuet. + +Dessverre får du ikke plass i Hackerspace {{ application_group }}. +Jeg ønsker deg lykke til videre med studier. + +Med vennlig hilsen, +{{ application_group }}{% endblocktranslate %} diff --git a/internalportal/templates/internalportal/applications/interview_email.txt b/internalportal/templates/internalportal/applications/interview_email.txt new file mode 100644 index 000000000..00413a9b4 --- /dev/null +++ b/internalportal/templates/internalportal/applications/interview_email.txt @@ -0,0 +1,15 @@ +{% load i18n %}{% blocktranslate with application_name=application.name start_time=interview.start_time %}Hei {{ application_name }}, +Tusen takk for din søknad hos Hackerspace NTNU! + + +I forbindelse med opptaket hos Hackerspace NTNU, ønsker vi å kalle deg inn til et intervju. Intervjuet er en mulighet for oss til å bli enda bedre kjent med deg før det gjøres sluttvurderinger i opptaket, og en mulighet for deg til å stille spørsmål rundt opptaket, organisasjonen og annet dersom ønskelig. + +Foreslått tidspunkt for intervjuet er {{ start_time }} i {% endblocktranslate %}{% if interview.location_link %}{% endif %}{{ interview.location }}{% if interview.location_link %}{% endif %}. + + +Vi ønsker gjerne at du bekrefter at tidspunktet passer, eller eventuelt svarer på mailen med timeplan / tidspunkter som passer bedre. + +{% trans "Med vennlig hilsen" %}, +{{ application_group }} +Hackerspace NTNU + diff --git a/internalportal/templates/internalportal/applications/interview_email_form.html b/internalportal/templates/internalportal/applications/interview_email_form.html new file mode 100644 index 000000000..48bd90b2f --- /dev/null +++ b/internalportal/templates/internalportal/applications/interview_email_form.html @@ -0,0 +1,53 @@ +{% extends "website/base.html" %} +{% load static %} +{% load i18n %} + +{% block head %} + +{% endblock %} + +{% block content %} + {% trans "E-post for intervju" as interview_email_header %} + {% include "website/page_header.html" with title=interview_email_header %} +
+
+
+ {% csrf_token %} +
+
+ location_on + {{ form.location }} + + {{ form.location.errors }} +
+
+ link + {{ form.location_link }} + + {{ form.location_link.errors }} +
+
+ date_range + {{ form.start_time }} + + {{ form.start_time.errors }} +
+
+ +
+ + {% if interview_email %} +
+

{% trans "Emne" %}: [Hackerspace NTNU]: {% trans "Intervju" %}

+ {% include "internalportal/applications/text_box_copy.html" with text=interview_email %} +
+ {% endif %} +
+ +
+ +{% endblock %} diff --git a/internalportal/templates/internalportal/applications/personalia_box.html b/internalportal/templates/internalportal/applications/personalia_box.html new file mode 100644 index 000000000..a621ddd27 --- /dev/null +++ b/internalportal/templates/internalportal/applications/personalia_box.html @@ -0,0 +1,13 @@ +{% load i18n %} + +
+
+
{% trans "Personalia" %}
+

{% trans "Navn" %}: {{ application.name }}

+

{% trans "Epost" %}: {{ application.email }}

+

{% trans "Tlf" %}: {{ application.phone }}

+

{% trans "Studie" %}: {{ application.study }}

+

{% trans "År" %}: {{ application.year }}

+

{% trans "Søknad motatt" %}: {{ application.application_date }}

+
+
diff --git a/internalportal/templates/internalportal/applications/text_box_copy.html b/internalportal/templates/internalportal/applications/text_box_copy.html new file mode 100644 index 000000000..d43b15579 --- /dev/null +++ b/internalportal/templates/internalportal/applications/text_box_copy.html @@ -0,0 +1,17 @@ +{% load i18n %} +
+
+
+ {{ text | safe | linebreaks }} +
+
+ +
+ diff --git a/internalportal/templates/internalportal/internalportal.html b/internalportal/templates/internalportal/internalportal.html index 83fc32c06..adad6188b 100644 --- a/internalportal/templates/internalportal/internalportal.html +++ b/internalportal/templates/internalportal/internalportal.html @@ -168,6 +168,20 @@
{% trans "Medlemsliste for dørtilgang" %}
{% include "internalportal/door-access-member-list.html" with users=door_access_member_list next_year=next_year only %} {% endif %} + + {% if user_is_leader %} + + {% endif %} diff --git a/internalportal/urls.py b/internalportal/urls.py index 1640ce79d..ba45c5638 100644 --- a/internalportal/urls.py +++ b/internalportal/urls.py @@ -6,4 +6,26 @@ urlpatterns = [ path("", views.InternalPortalView.as_view(), name="internalportal"), + path("applications/", views.ApplicationsView.as_view(), name="applications"), + path("applications/", views.ApplicationView.as_view(), name="application"), + path( + "applications/delete/", + views.ApplicationRemoveView.as_view(), + name="delete_application", + ), + path( + "applications/next-group/", + views.ApplicationNextGroupView.as_view(), + name="next_group", + ), + path( + "applications//approve", + views.ApplicationApproveView.as_view(), + name="approve_application", + ), + path( + "applications//interview-email", + views.ApplicationInterviewEmailView.as_view(), + name="interview_email", + ), ] diff --git a/internalportal/views.py b/internalportal/views.py index cdabb0fde..0c04454e1 100644 --- a/internalportal/views.py +++ b/internalportal/views.py @@ -1,9 +1,24 @@ from datetime import datetime, timedelta +from django.contrib import messages from django.contrib.auth import get_user_model -from django.contrib.auth.mixins import PermissionRequiredMixin -from django.views.generic import TemplateView +from django.contrib.auth.mixins import PermissionRequiredMixin, UserPassesTestMixin +from django.contrib.auth.models import Group +from django.contrib.auth.views import FormView, HttpResponseRedirect +from django.core.mail import send_mail +from django.db.models import OuterRef, Q, Subquery +from django.shortcuts import get_object_or_404 +from django.template.loader import render_to_string +from django.urls import reverse, reverse_lazy +from django.utils import timezone +from django.utils.translation import gettext_lazy as _ +from django.views.generic import DeleteView, DetailView, ListView, TemplateView +from django.views.generic.edit import BaseDetailView +from applications.models import Application, ApplicationGroup, ApplicationGroupChoice +from authentication.views import get_user_by_stud_or_ntnu_email +from committees.models import Committee +from internalportal.forms import InterviewEmailForm from inventory.models.item_loan import ItemLoan from news.models import Article, Event @@ -37,5 +52,268 @@ def get_context_data(self, *args, **kwargs): .objects.filter(groups__name="Medlem") .order_by("-date_joined") ) + committee = get_commitee_with_leader(self.request.user) + context["new_applicants_no"] = get_applications_for_committee(committee).count() + context["user_is_leader"] = committee is not None return context + + +class ApplicationsView(PermissionRequiredMixin, UserPassesTestMixin, ListView): + template_name = "internalportal/applications/applications.html" + permission_required = "userprofile.is_active_member" + context_object_name = "applications" + + def test_func(self): + return get_commitee_with_leader(self.request.user) is not None + + def get_queryset(self): + committee = get_commitee_with_leader(self.request.user) + return get_applications_for_committee(committee) + + +class ApplicationView(UserPassesTestMixin, DetailView): + model = Application + template_name = "internalportal/applications/application.html" + context_object_name = "application" + + def test_func(self): + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + groups = self.get_object().applicationgroupchoice_set.all().order_by("priority") + context["second_group"] = groups[1] if groups.count() > 1 else None + email_data = { + "application": self.get_object(), + "application_group": groups.first().group, + "LANGUAGE_CODE": self.request.LANGUAGE_CODE, + } + context["denied_email"] = render_to_string( + "internalportal/applications/denied_email.txt", + email_data, + ) + context["approved_email"] = render_to_string( + "internalportal/applications/approved_email.txt", + email_data, + ) + return context + + +class ApplicationNextGroupView(UserPassesTestMixin, BaseDetailView): + """Send an application to the next group""" + + model = Application + success_url = reverse_lazy("internalportal:applications") + success_message = _("Søknad sendt videre til neste gruppe") + + def test_func(self): + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + + def get(self, request, *args, **kwargs): + application = Application.objects.filter(id=kwargs.get("pk")).first() + if not application: + messages.error(request, _("Søknaden finnes ikke")) + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + new_application_message = render_to_string( + "applications/new_application_email.txt", + { + "applications_url": request.build_absolute_uri( + reverse("internalportal:applications") + ) + }, + ) + next_application_groups = application.applicationgroupchoice_set.order_by( + "priority" + ) + + if next_application_groups.count() < 2: + messages.error(request, _("Søknaden har ingen flere grupper å gå til")) + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + + next_group = next_application_groups[1] + committee = Committee.objects.filter(name=next_group.group.name).first() + + if not committee: + messages.error( + request, + _("Gruppen {group_name} finnes ikke. Kontakt administrator.").format( + group_name=next_group.group.name + ), + ) + return HttpResponseRedirect( + reverse_lazy( + "internalportal:application", kwargs={"pk": application.id} + ) + ) + + emails = [ + getattr(committee.main_lead, "email", None), + getattr(committee.second_lead, "email", None), + ] + if not any(emails): + messages.error( + request, + _("Gruppen {group} har ingen ledere. Kontakt administrator.").format( + group=committee.name + ), + ) + return HttpResponseRedirect( + reverse_lazy( + "internalportal:application", kwargs={"pk": application.id} + ) + ) + + send_mail( + _("Søknad sendt videre"), + new_application_message, + "Hackerspace NTNU", + emails, + fail_silently=False, + ) + + ApplicationGroupChoice.objects.filter(application=application).order_by( + "priority" + ).first().delete() + return HttpResponseRedirect(reverse_lazy("internalportal:applications")) + + +class ApplicationRemoveView(UserPassesTestMixin, DeleteView): + model = Application + template_name = "internalportal/applications/application_confirm_delete.html" + success_url = "/internalportal/applications/" + + def test_func(self): + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + + +class ApplicationInterviewEmailView(UserPassesTestMixin, FormView, DetailView): + form_class = InterviewEmailForm + template_name = "internalportal/applications/interview_email_form.html" + model = Application + + def get_success_url(self): + return reverse_lazy( + "internalportal:interview_email", kwargs={"pk": self.get_object().id} + ) + + def get_context_data(self, **kwargs): + self.object = self.get_object() + context = super().get_context_data(**kwargs) + context["interview_email"] = self.request.session.get("interview_email") + return context + + def get_initial(self): + initial = super().get_initial() + initial["start_time"] = timezone.now() + initial["end_time"] = timezone.now() + timedelta(minutes=20) + return initial + + def test_func(self): + committee = get_commitee_with_leader(self.request.user) + return first_application_group_is_committee(self.get_object(), committee) + + def form_valid(self, form): + application = self.get_object() + interview_email = render_to_string( + "internalportal/applications/interview_email.txt", + { + "interview": form.cleaned_data, + "application": application, + "application_group": ( + application.applicationgroupchoice_set.order_by("priority") + .first() + .group + ), + "LANGUAGE_CODE": self.request.LANGUAGE_CODE, + }, + ) + self.request.session["interview_email"] = interview_email + return super().form_valid(form) + + +class ApplicationApproveView(ApplicationRemoveView): + template_name = "internalportal/applications/approve.html" + + def get_context_data(self, **kwargs): + context = super().get_context_data(**kwargs) + context["group"] = ( + self.get_object() + .applicationgroupchoice_set.order_by("priority") + .first() + .group + ) + return context + + def delete(self, request, *args, **kwargs): + + application = self.get_object() + + email = request.POST.get("email") + if not email: + email = application.email + + group_name = ( + application.applicationgroupchoice_set.order_by("priority") + .first() + .group.name + ) + group = get_object_or_404(Group, name=group_name) + + user = get_user_by_stud_or_ntnu_email(email) + if not user: + messages.error( + request, + _( + "Få brukeren til å logge inn med Feide først " + "og bruk søkerens ntnu-mail." + ), + ) + return HttpResponseRedirect( + reverse_lazy( + "internalportal:approve_application", kwargs={"pk": application.id} + ) + ) + + user.groups.add(group) + user.groups.add(get_object_or_404(Group, name="Medlem")) + user.save() + + # Send mail til søker + + return super().delete(request, *args, **kwargs) + + +def get_commitee_with_leader(user): + query = Q(main_lead=user.id) | Q(second_lead=user.id) + return Committee.objects.filter(query).first() + + +def first_application_group_is_committee(application, committee): + if application is None or committee is None: + return False + return ( + application.applicationgroupchoice_set.order_by("priority").first().group.name + == committee.name + ) + + +def get_applications_for_committee(committee): + if not committee: + return Application.objects.none() + application_group = ApplicationGroup.objects.filter(name=committee.name).first() + + first_group = ( + ApplicationGroupChoice.objects.filter(application=OuterRef("id")) + .order_by("priority") + .values("group")[:1] + ) + + return ( + Application.objects.filter(applicationgroupchoice__group=application_group) + .annotate(first_group=Subquery(first_group)) + .filter(first_group=application_group) + ) diff --git a/inventory/locale/en/LC_MESSAGES/django.po b/inventory/locale/en/LC_MESSAGES/django.po index daacfe51d..7a0648aef 100644 --- a/inventory/locale/en/LC_MESSAGES/django.po +++ b/inventory/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/inventory/locale/nb/LC_MESSAGES/django.po b/inventory/locale/nb/LC_MESSAGES/django.po index 2336378fc..64a0110de 100644 --- a/inventory/locale/nb/LC_MESSAGES/django.po +++ b/inventory/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/news/forms.py b/news/forms.py index 73b86c335..cdd4aac27 100644 --- a/news/forms.py +++ b/news/forms.py @@ -88,6 +88,11 @@ class SplitDateTimeFieldCustom(forms.SplitDateTimeField): "class": "no-autoinit datepicker", } ), + time_attrs=( + { + "class": "no-autoinit timepicker", + } + ), date_format="%Y-%m-%d", time_format="%H:%M", ) diff --git a/news/locale/en/LC_MESSAGES/django.po b/news/locale/en/LC_MESSAGES/django.po index 4a92363e8..53a018f74 100644 --- a/news/locale/en/LC_MESSAGES/django.po +++ b/news/locale/en/LC_MESSAGES/django.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -213,6 +213,7 @@ msgid "Lagre og publiser artikkel" msgstr "Save and publish article" #: news/templates/news/edit_article.html:82 +#: news/templates/news/edit_event.html:245 msgid "Lagre som utkast" msgstr "Save as draft" @@ -236,11 +237,12 @@ msgstr "Skills" msgid "Filer" msgstr "Files" -#: news/templates/news/edit_event.html:223 +#: news/templates/news/edit_event.html:224 msgid "Ferdig" msgstr "Done" -#: news/templates/news/edit_event.html:238 +#: news/templates/news/edit_event.html:239 +#: news/templates/news/edit_event.html:242 msgid "Lagre og publiser arrangement" msgstr "Save and publish event" @@ -379,8 +381,8 @@ msgid "" "Arrangementets påmeldingsfrist er utløpt. Dersom du melder deg av, har du " "ikke mulighet til å melde deg på igjen." msgstr "" -"The registration deadline for the event has expired. If you withdraw your registration, you " -"will not be able to register again." +"The registration deadline for the event has expired. If you withdraw your " +"registration, you will not be able to register again." #: news/templates/news/event.html:201 msgid "Ved å melde deg på dette arrangementet forventes det at du møter opp." diff --git a/news/locale/nb/LC_MESSAGES/django.po b/news/locale/nb/LC_MESSAGES/django.po index 73b816d3f..209cc6229 100644 --- a/news/locale/nb/LC_MESSAGES/django.po +++ b/news/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -217,6 +217,7 @@ msgid "Lagre og publiser artikkel" msgstr "" #: news/templates/news/edit_article.html:82 +#: news/templates/news/edit_event.html:245 msgid "Lagre som utkast" msgstr "" @@ -240,11 +241,12 @@ msgstr "" msgid "Filer" msgstr "" -#: news/templates/news/edit_event.html:223 +#: news/templates/news/edit_event.html:224 msgid "Ferdig" msgstr "" -#: news/templates/news/edit_event.html:238 +#: news/templates/news/edit_event.html:239 +#: news/templates/news/edit_event.html:242 msgid "Lagre og publiser arrangement" msgstr "" diff --git a/news/static/news/js/edit_event.js b/news/static/news/js/edit_event.js index 8dd1b403e..a7932c97f 100644 --- a/news/static/news/js/edit_event.js +++ b/news/static/news/js/edit_event.js @@ -1,49 +1,4 @@ document.addEventListener("DOMContentLoaded", function(event) { - var datepickers = document.querySelectorAll('.datepicker'); - - internationalization = { - months: [ - 'Januar', - 'Februar', - 'Mars', - 'April', - 'Mai', - 'Juni', - 'Juli', - 'August', - 'September', - 'Oktober', - 'November', - 'Desember' - ], - weekdays: [ - 'Søndag', - 'Mandag', - 'Tirsdag', - 'Onsdag', - 'Torsdag', - 'Fredag', - 'Lørdag' - ], - weekdaysShort: [ - 'Søn', - 'Man', - 'Tir', - 'Ons', - 'Tor', - 'Fre', - 'Lør' - ], - weekdaysAbbrev: ['S','M','T','O','T','F','L'] - } - options = { - format: 'yyyy-mm-dd', - firstDay: 1, - i18n: internationalization - } - var instance = M.Datepicker.init(datepickers, options); - - // Vis og gjem deler som relateres til påmeldinger const reg_boxes = document.getElementsByClassName('reg-box'); const reg_check = document.getElementsByName('registration')[0]; diff --git a/news/templates/news/edit_event.html b/news/templates/news/edit_event.html index 91d2c7632..ed447f74a 100644 --- a/news/templates/news/edit_event.html +++ b/news/templates/news/edit_event.html @@ -48,8 +48,7 @@
{% trans "Innhold" %}
{{ form.main_content.errors }} {{ form.main_content }}
-

{% trans "Bare markdown støttes i dette feltet, html blir returnert som plaintext. Bilder - kan legges til ved drag-and-drop." %}

+

{% trans "Bare markdown støttes i dette feltet, html blir returnert som plaintext. Bilder kan legges til ved drag-and-drop." %}

Markdown cheat-sheet

@@ -252,6 +251,7 @@
{% trans "Ferdig" %}
+ -{% endblock content %} \ No newline at end of file +{% endblock content %} diff --git a/projectarchive/locale/en/LC_MESSAGES/django.po b/projectarchive/locale/en/LC_MESSAGES/django.po index 7b1ee2a25..eafb410aa 100644 --- a/projectarchive/locale/en/LC_MESSAGES/django.po +++ b/projectarchive/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/projectarchive/locale/nb/LC_MESSAGES/django.po b/projectarchive/locale/nb/LC_MESSAGES/django.po index a5c5cbc0e..08df77c78 100644 --- a/projectarchive/locale/nb/LC_MESSAGES/django.po +++ b/projectarchive/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/reservations/locale/en/LC_MESSAGES/django.po b/reservations/locale/en/LC_MESSAGES/django.po index 568e0c400..1115cfdf5 100644 --- a/reservations/locale/en/LC_MESSAGES/django.po +++ b/reservations/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/reservations/locale/nb/LC_MESSAGES/django.po b/reservations/locale/nb/LC_MESSAGES/django.po index 1ef7c771f..5d2c822a6 100644 --- a/reservations/locale/nb/LC_MESSAGES/django.po +++ b/reservations/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/userprofile/locale/en/LC_MESSAGES/django.po b/userprofile/locale/en/LC_MESSAGES/django.po index 62b936e31..f61a1fb12 100644 --- a/userprofile/locale/en/LC_MESSAGES/django.po +++ b/userprofile/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/userprofile/locale/nb/LC_MESSAGES/django.po b/userprofile/locale/nb/LC_MESSAGES/django.po index 64c9f17e5..0a4130a23 100644 --- a/userprofile/locale/nb/LC_MESSAGES/django.po +++ b/userprofile/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/watchlist/locale/en/LC_MESSAGES/django.po b/watchlist/locale/en/LC_MESSAGES/django.po index 24328e83f..c66657f08 100644 --- a/watchlist/locale/en/LC_MESSAGES/django.po +++ b/watchlist/locale/en/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/watchlist/locale/nb/LC_MESSAGES/django.po b/watchlist/locale/nb/LC_MESSAGES/django.po index 5eb8ef11b..514e4def7 100644 --- a/watchlist/locale/nb/LC_MESSAGES/django.po +++ b/watchlist/locale/nb/LC_MESSAGES/django.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/website/locale/en/LC_MESSAGES/django.po b/website/locale/en/LC_MESSAGES/django.po index f143875b9..14fcbedf3 100644 --- a/website/locale/en/LC_MESSAGES/django.po +++ b/website/locale/en/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/website/locale/nb/LC_MESSAGES/django.po b/website/locale/nb/LC_MESSAGES/django.po index 479b06dca..93ed282a8 100644 --- a/website/locale/nb/LC_MESSAGES/django.po +++ b/website/locale/nb/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-10-23 17:45+0200\n" +"POT-Creation-Date: 2023-11-27 17:21+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" diff --git a/website/settings.py b/website/settings.py index b50fe10c0..883ecd8cb 100644 --- a/website/settings.py +++ b/website/settings.py @@ -354,7 +354,8 @@ ################################# # Markdownify -MARKDOWNX_MARKDOWNIFY_FUNCTION = "markdownx.utils.markdownify" # Default function that compiles markdown using defined extensions. Using custom function can allow you to pre-process or post-process markdown text. See below for more info. +# Default function that compiles markdown using defined extensions. Using custom function can allow you to pre-process or post-process markdown text. See below for more info. +MARKDOWNX_MARKDOWNIFY_FUNCTION = "markdownx.utils.markdownify" # Markdown extensions MARKDOWNX_MARKDOWN_EXTENSIONS = ( @@ -368,7 +369,8 @@ MARKDOWNX_URLS_PATH = ( "/markdownx/markdownify/" # URL that returns compiled markdown text. ) -MARKDOWNX_UPLOAD_URLS_PATH = "/markdownx/upload/" # URL that accepts file uploads, returns markdown notation of the image. +# URL that accepts file uploads, returns markdown notation of the image. +MARKDOWNX_UPLOAD_URLS_PATH = "/markdownx/upload/" # Media path MARKDOWNX_MEDIA_PATH = datetime.now().strftime( diff --git a/website/static/website/js/datetimepicker.js b/website/static/website/js/datetimepicker.js new file mode 100644 index 000000000..060267a67 --- /dev/null +++ b/website/static/website/js/datetimepicker.js @@ -0,0 +1,53 @@ +document.addEventListener("DOMContentLoaded", function() { + var datepickers = document.querySelectorAll('.datepicker'); + + internationalization = { + months: [ + 'Januar', + 'Februar', + 'Mars', + 'April', + 'Mai', + 'Juni', + 'Juli', + 'August', + 'September', + 'Oktober', + 'November', + 'Desember' + ], + weekdays: [ + 'Søndag', + 'Mandag', + 'Tirsdag', + 'Onsdag', + 'Torsdag', + 'Fredag', + 'Lørdag' + ], + weekdaysShort: [ + 'Søn', + 'Man', + 'Tir', + 'Ons', + 'Tor', + 'Fre', + 'Lør' + ], + weekdaysAbbrev: ['S','M','T','O','T','F','L'] + } + options = { + format: 'yyyy-mm-dd', + firstDay: 1, + i18n: internationalization + } + M.Datepicker.init(datepickers, options); + + + var elems = document.querySelectorAll('.timepicker'); + options = { + twelveHour: false, + format: 'HH:mm', + }; + M.Timepicker.init(elems, options); +}); diff --git a/website/templates/website/page_header.html b/website/templates/website/page_header.html new file mode 100644 index 000000000..1da17f4da --- /dev/null +++ b/website/templates/website/page_header.html @@ -0,0 +1,9 @@ +
+
+
+
+

{{ title }}

+
+
+
+