diff --git a/osinaweb/db.sqlite3 b/osinaweb/db.sqlite3 index e1deaf01..ff81c433 100644 Binary files a/osinaweb/db.sqlite3 and b/osinaweb/db.sqlite3 differ diff --git a/osinaweb/input.css b/osinaweb/input.css index 601daba1..08626b60 100644 --- a/osinaweb/input.css +++ b/osinaweb/input.css @@ -2,6 +2,22 @@ @tailwind components; @tailwind utilities; +.fixedSideHeader::-webkit-scrollbar { + width: 5px; + /* Width of the entire scrollbar */ + +} + +.fixedSideHeader::-webkit-scrollbar-thumb { + background: #7B8894; + /* Color of the scroll thumb */ +} + +.fixedSideHeader::-webkit-scrollbar-track { + background: #5a5a5a3c; + /* Color of the scrollbar track */ +} + /* FOR THE IFRAME TO TAKE 95% OF WIDTH ON SMALL SCREEN SIZES */ @media screen and (max-width: 798px) { diff --git a/osinaweb/osinacore/__pycache__/forms.cpython-311.pyc b/osinaweb/osinacore/__pycache__/forms.cpython-311.pyc index 30bf420c..35fbcffa 100644 Binary files a/osinaweb/osinacore/__pycache__/forms.cpython-311.pyc and b/osinaweb/osinacore/__pycache__/forms.cpython-311.pyc differ diff --git a/osinaweb/osinacore/__pycache__/models.cpython-311.pyc b/osinaweb/osinacore/__pycache__/models.cpython-311.pyc index e5a8228b..58161853 100644 Binary files a/osinaweb/osinacore/__pycache__/models.cpython-311.pyc and b/osinaweb/osinacore/__pycache__/models.cpython-311.pyc differ diff --git a/osinaweb/osinacore/__pycache__/views.cpython-311.pyc b/osinaweb/osinacore/__pycache__/views.cpython-311.pyc index 19de9950..e74394c9 100644 Binary files a/osinaweb/osinacore/__pycache__/views.cpython-311.pyc and b/osinaweb/osinacore/__pycache__/views.cpython-311.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0021_alter_customerprofile_business_and_more.cpython-311.pyc b/osinaweb/osinacore/migrations/__pycache__/0021_alter_customerprofile_business_and_more.cpython-311.pyc new file mode 100644 index 00000000..96fe2b56 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0021_alter_customerprofile_business_and_more.cpython-311.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0022_customerprofile_customer_id.cpython-311.pyc b/osinaweb/osinacore/migrations/__pycache__/0022_customerprofile_customer_id.cpython-311.pyc new file mode 100644 index 00000000..7ed65dd1 Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0022_customerprofile_customer_id.cpython-311.pyc differ diff --git a/osinaweb/osinacore/migrations/__pycache__/0023_task_assigned_to.cpython-311.pyc b/osinaweb/osinacore/migrations/__pycache__/0023_task_assigned_to.cpython-311.pyc new file mode 100644 index 00000000..bec5f55c Binary files /dev/null and b/osinaweb/osinacore/migrations/__pycache__/0023_task_assigned_to.cpython-311.pyc differ diff --git a/osinaweb/osinacore/views.py b/osinaweb/osinacore/views.py index 5f71adad..67dc5fa7 100644 --- a/osinaweb/osinacore/views.py +++ b/osinaweb/osinacore/views.py @@ -6,7 +6,7 @@ from django.contrib import messages from .forms import * from django.utils import timezone from django.urls import reverse - +from django.http import HttpResponse # Pages views @@ -198,6 +198,40 @@ def businessdetails(request): } return render(request, 'business-details.html', context) +@login_required +def businesses(request): + context = { + + } + return render(request, 'businesses.html', context) + +@login_required +def adduser(request): + + context = { + + + } + return render(request, 'add-user.html', context) + +@login_required +def userdetails(request): + + context = { + + + } + return render(request, 'user-details.html', context) + +@login_required +def users(request): + + context = { + + + } + return render(request, 'users.html', context) + @@ -275,28 +309,30 @@ def update_status_modal(request, *args, **kwargs): #Save Functions - - @login_required def save_note(request): if request.method == 'POST': text = request.POST.get('note_text') - color= request.POST.get('note_color') + color = request.POST.get('note_color') user = request.user date = timezone.now() note = Note( - text = text, - color = color, - user = user, - date = date, + text=text, + color=color, + user=user, + date=date, ) note.save() + # Reload the parent page + return HttpResponse('') - return render(request, 'addnote-modal.html') + + + @login_required def save_project(request): if request.method == 'POST': diff --git a/osinaweb/osinaweb/__pycache__/urls.cpython-311.pyc b/osinaweb/osinaweb/__pycache__/urls.cpython-311.pyc index 9ac6e985..50a3d3a4 100644 Binary files a/osinaweb/osinaweb/__pycache__/urls.cpython-311.pyc and b/osinaweb/osinaweb/__pycache__/urls.cpython-311.pyc differ diff --git a/osinaweb/osinaweb/urls.py b/osinaweb/osinaweb/urls.py index 09e4ff39..905ba1b0 100644 --- a/osinaweb/osinaweb/urls.py +++ b/osinaweb/osinaweb/urls.py @@ -31,6 +31,10 @@ urlpatterns = [ path('customerdetails//', views.customerdetails, name='customerdetails'), path('addbusiness/', views.addbusiness, name='addbusiness'), path('businessdetails/', views.businessdetails, name='businessdetails'), + path('businesses/', views.businesses, name='businesses'), + path('adduser/', views.adduser, name='adduser'), + path('userdetails/', views.userdetails, name='userdetails'), + path('users/', views.users, name='users'), path('projectdetails//', views.detailed_project, name='detailed-project'), path('createproject/', views.create_project, name='createproject'), path('createepic//', views.create_epic, name='createepic'), diff --git a/osinaweb/static/dist/output.css b/osinaweb/static/dist/output.css index 7e074e91..db16ba17 100644 --- a/osinaweb/static/dist/output.css +++ b/osinaweb/static/dist/output.css @@ -743,10 +743,18 @@ video { margin-top: 1.5rem; } +.mt-\[-63px\] { + margin-top: -63px; +} + .mt-\[5\%\] { margin-top: 5%; } +.mt-\[50px\] { + margin-top: 50px; +} + .block { display: block; } @@ -848,6 +856,10 @@ video { width: 100px; } +.w-\[120px\] { + width: 120px; +} + .w-\[14\%\] { width: 14%; } @@ -932,6 +944,10 @@ video { width: 380px; } +.w-\[40\%\] { + width: 40%; +} + .w-\[40px\] { width: 40px; } @@ -964,6 +980,10 @@ video { width: 55%; } +.w-\[55px\] { + width: 55px; +} + .w-\[60px\] { width: 60px; } @@ -1121,6 +1141,10 @@ video { overflow-x: auto; } +.overflow-y-auto { + overflow-y: auto; +} + .rounded-full { border-radius: 9999px; } @@ -1243,6 +1267,11 @@ video { border-color: rgb(255 255 255 / var(--tw-border-opacity)); } +.border-yellow-500 { + --tw-border-opacity: 1; + border-color: rgb(234 179 8 / var(--tw-border-opacity)); +} + .bg-black { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); @@ -1698,6 +1727,21 @@ video { transition-duration: 300ms; } +.fixedSideHeader::-webkit-scrollbar { + width: 5px; + /* Width of the entire scrollbar */ +} + +.fixedSideHeader::-webkit-scrollbar-thumb { + background: #7B8894; + /* Color of the scroll thumb */ +} + +.fixedSideHeader::-webkit-scrollbar-track { + background: #5a5a5a3c; + /* Color of the scrollbar track */ +} + /* FOR THE IFRAME TO TAKE 95% OF WIDTH ON SMALL SCREEN SIZES */ @media screen and (max-width: 798px) { @@ -1736,11 +1780,21 @@ video { background-color: rgb(255 255 255 / var(--tw-bg-opacity)); } +.hover\:bg-yellow-500:hover { + --tw-bg-opacity: 1; + background-color: rgb(234 179 8 / var(--tw-bg-opacity)); +} + .hover\:text-blue-500:hover { --tw-text-opacity: 1; color: rgb(59 130 246 / var(--tw-text-opacity)); } +.hover\:text-gray-500:hover { + --tw-text-opacity: 1; + color: rgb(107 114 128 / var(--tw-text-opacity)); +} + .hover\:text-red-500:hover { --tw-text-opacity: 1; color: rgb(239 68 68 / var(--tw-text-opacity)); diff --git a/osinaweb/static/js/pop-modals.js b/osinaweb/static/js/pop-modals.js index 2efbf722..266177e5 100644 --- a/osinaweb/static/js/pop-modals.js +++ b/osinaweb/static/js/pop-modals.js @@ -1,192 +1,68 @@ document.addEventListener("DOMContentLoaded", function () { - // Function to open the modal - function openModal(url) { - const modalContainer = document.getElementById("popUpModal"); + function openModalWithDimensions(url, width, height) { + const modalUrl = url; + openModal(modalUrl); - //Get the iframe element const iframe = document.getElementById("popupModalFrame"); + iframe.style.height = height; + iframe.style.width = width; + } - //Get the body element + function openModal(url) { + const modalContainer = document.getElementById("popUpModal"); + const iframe = document.getElementById("popupModalFrame"); const body = document.body; - //Disable scrolling body.style.overflow = "hidden"; - - //Set the URL of the iframe to load the external content iframe.src = url; - - //Display the modal modalContainer.style.display = "flex"; } - //Function to close the modal function closeModal() { const modalContainer = document.getElementById("popUpModal"); - const iframe = document.getElementById("popupModalFrame"); - - //Clear the URL to stop loading the content - iframe.src = ""; - const body = document.body; - //Enable scrolling + iframe.src = ""; body.style.overflow = "auto"; - - //Hide the modal modalContainer.style.display = "none"; } + function addButtonClickListener(buttonId, width, height) { + const button = document.getElementById(buttonId); + if (button) { + button.addEventListener("click", () => { + const modalUrl = button.getAttribute("data-modal-url"); + openModalWithDimensions(modalUrl, width, height); + }); + } + } - const closeButton = document.getElementById("closeModalButton"); + // Add button click listeners with dimensions + addButtonClickListener("addStatusButton", "450px", "200px"); + addButtonClickListener("addNoteButton", "400px", "225px"); + addButtonClickListener("addFileButton", "500px", "320px"); + addButtonClickListener("addCredentialsButton", "500px", "300px"); + addButtonClickListener("updateStatusButton", "fit-content", "160px"); + addButtonClickListener("showPointsButton", "600px", "450px"); + addButtonClickListener("addPointButton", "500px", "225px"); + addButtonClickListener("timelineButton", "600px", "450px"); + addButtonClickListener("addTimeButton", "300px", "270px"); + addButtonClickListener("deleteTaskButton", "fit-content", "130px"); + const closeButton = document.getElementById("closeModalButton"); closeButton.addEventListener("click", () => { closeModal(); }); const modalContainer = document.getElementById("popUpModal"); - // Event listener to trigger the modal when clicking outside of it window.addEventListener("click", function (event) { if (event.target === modalContainer) { closeModal(); } }); - //ADD STATUS MODAL - const addStatusButton = document.getElementById("addStatusButton"); - - addStatusButton.addEventListener("click", () => { - const modalUrl = addStatusButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "200px" - iframe.style.width = "450px" - }); - - //ADD NOTE MODAL - const addNoteButton = document.getElementById("addNoteButton"); - - addNoteButton.addEventListener("click", () => { - // Retrieve the URL from the data attribute - const modalUrl = addNoteButton.getAttribute("data-modal-url"); - - // Open the modal with the retrieved URL - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "225px" - iframe.style.width = "400px" - }); - - //ADD FILE MODAL (in the inner project page) - const addFileButton = document.getElementById("addFileButton"); - - addFileButton.addEventListener("click", () => { - const modalUrl = addFileButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "320px" - iframe.style.width = "500px" - }); - - - //ADD CREDENTIALS MODAL (in the inner project page) - const addCredentialsButton = document.getElementById("addCredentialsButton"); - - addCredentialsButton.addEventListener("click", () => { - const modalUrl = addCredentialsButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "300px" - iframe.style.width = "500px" - }); - - - //SHOW TASK MODALS - //Show the update status modal - const updateStatusButton = document.getElementById("updateStatusButton"); - - updateStatusButton.addEventListener("click", () => { - const modalUrl = updateStatusButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "160px" - iframe.style.width = "fit-content" - }); - - - //Show the show points modal - const showPointsButton = document.getElementById("showPointsButton"); - - showPointsButton.addEventListener("click", () => { - const modalUrl = showPointsButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "450px" - iframe.style.width = "600px" - }); - - //Show the add point modal - const addPointButton = document.getElementById("addPointButton"); - - addPointButton.addEventListener("click", () => { - const modalUrl = addPointButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "225px" - iframe.style.width = "500px" - }); - - //Show the Timeline modal - const timelineButton = document.getElementById("timelineButton"); - - timelineButton.addEventListener("click", () => { - const modalUrl = timelineButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "450px" - iframe.style.width = "600px" - }); - - //Show the add timeline modal - const addTimeButton = document.getElementById("addTimeButton"); - - addTimeButton.addEventListener("click", () => { - const modalUrl = addTimeButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "270px" - iframe.style.width = "300px" - }); - - //Show the delete task modal - const deleteTaskButton = document.getElementById("deleteTaskButton"); - - deleteTaskButton.addEventListener("click", () => { - const modalUrl = deleteTaskButton.getAttribute("data-modal-url"); - - openModal(modalUrl); - - const iframe = document.getElementById("popupModalFrame"); - iframe.style.height = "130px" - iframe.style.width = "fit-content" - }); - -}); \ No newline at end of file + // TO RELOAD THE TOP WINDOW AFTER ADDING + // window.top.location.reload(); +}); diff --git a/osinaweb/templates/add-business.html b/osinaweb/templates/add-business.html index b4b3a18c..639bc57a 100644 --- a/osinaweb/templates/add-business.html +++ b/osinaweb/templates/add-business.html @@ -2,8 +2,6 @@ {%load static%} {% block content %} - -

diff --git a/osinaweb/templates/add-customer.html b/osinaweb/templates/add-customer.html index 1d959630..f26a809a 100644 --- a/osinaweb/templates/add-customer.html +++ b/osinaweb/templates/add-customer.html @@ -2,7 +2,6 @@ {%load static%} {% block content %} -
@@ -58,6 +57,13 @@ Select Business

+
+ + + + + +
+
+ + Upload + Profile Picture + + +
+
+ + + + + + + + + + + + +
+ +
+
+ +
+
+ + + + + + + +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/templates/addstatus-modal.html b/osinaweb/templates/addstatus-modal.html index 4a0e907c..93eaf429 100644 --- a/osinaweb/templates/addstatus-modal.html +++ b/osinaweb/templates/addstatus-modal.html @@ -2,6 +2,7 @@ + @@ -15,21 +16,49 @@

Add Status

- +
- +
- +

Add Status To Task

- + + + +
+ \ No newline at end of file diff --git a/osinaweb/templates/business-details.html b/osinaweb/templates/business-details.html index 22901635..a6c79409 100644 --- a/osinaweb/templates/business-details.html +++ b/osinaweb/templates/business-details.html @@ -53,13 +53,13 @@ - -
- + +
+
-
-
- +
+
+

Emile Ellye - Ositcom

@@ -75,8 +75,8 @@
-

Name: Ositcom

+

Name: Ositcom +

@@ -85,8 +85,8 @@
-

VAT: Checked

+

VAT: Checked +

@@ -108,12 +108,22 @@

Business Type: Association

+ +
+

Related Customer: + + Emile Elliye + +

+
+
+ -
+

USERS ACTIVITY

-
+
diff --git a/osinaweb/templates/businesses.html b/osinaweb/templates/businesses.html new file mode 100644 index 00000000..529f5e46 --- /dev/null +++ b/osinaweb/templates/businesses.html @@ -0,0 +1,273 @@ +{% extends "main.html" %} +{%load static%} +{% block title %}My Projects{% endblock %} +{% block content %} + +
+
+
+
+

Recent Note:

+

Send an Email to Salim.

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

Businesses

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

Name

+
+
+

Business Type

+
+
+

Financial number

+
+
+

Actions

+
+
+ + +
+ +
+
+

HII

+
+
+

Non-profit

+
+
+

2022

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

USERS ACTIVITY

+
+ + + +
+
+
+
+
+ user profile +
+
+

Nataly

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+
+
+ user profile +
+
+

Salim

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+
+
+ user profile +
+
+

Emile

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + +
+ + + + + + +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/templates/create-project.html b/osinaweb/templates/create-project.html index 0f361959..c6aa816d 100644 --- a/osinaweb/templates/create-project.html +++ b/osinaweb/templates/create-project.html @@ -2,8 +2,6 @@ {%load static%} {% block content %} - -

diff --git a/osinaweb/templates/create-task.html b/osinaweb/templates/create-task.html index cad9074e..5edeb807 100644 --- a/osinaweb/templates/create-task.html +++ b/osinaweb/templates/create-task.html @@ -9,47 +9,58 @@

Create Task

- +
- - - - - - - - - + + + +
- +
- +
- + - +
-
- +
+
{% if customer.status == 'Active' %}
@@ -197,9 +197,9 @@
-
+

USERS ACTIVITY

-
+
diff --git a/osinaweb/templates/customers.html b/osinaweb/templates/customers.html index 12cab0f5..e618d322 100644 --- a/osinaweb/templates/customers.html +++ b/osinaweb/templates/customers.html @@ -53,14 +53,14 @@
- -
- + +
+

Customers

- +
@@ -163,10 +163,9 @@
-
+

USERS ACTIVITY

-
- +
diff --git a/osinaweb/templates/index.html b/osinaweb/templates/index.html index db87be09..6303130b 100644 --- a/osinaweb/templates/index.html +++ b/osinaweb/templates/index.html @@ -7,7 +7,7 @@

Recent Note:

-

Send an Email to Salim.

+

--

+ class="w-[120px] px-2 py-1 bg-transparent border border-yellow-500 rounded-md text-yellow-500 hover:bg-yellow-500 hover:text-white">Working + On
@@ -34,9 +37,12 @@

Fix the LaylNhar Header

-
+
+ class="w-[120px] px-2 py-1 bg-transparent border border-blue-500 rounded-md text-blue-500 hover:bg-blue-500 hover:text-white">Complete +
@@ -48,8 +54,8 @@ cumque ex amet! Sequi aliquid quos ullam, sapiente iste impedit explicabo?

- +
diff --git a/osinaweb/templates/task-details.html b/osinaweb/templates/task-details.html index 489ebfde..060da761 100644 --- a/osinaweb/templates/task-details.html +++ b/osinaweb/templates/task-details.html @@ -272,7 +272,7 @@
-
+
@@ -502,9 +502,9 @@
-
+

USERS ACTIVITY

-
+
diff --git a/osinaweb/templates/tasks.html b/osinaweb/templates/tasks.html index 427dfb99..4d009c5f 100644 --- a/osinaweb/templates/tasks.html +++ b/osinaweb/templates/tasks.html @@ -52,9 +52,9 @@
- -
- + +
+

My Tasks

@@ -287,9 +287,9 @@
-
+

USERS ACTIVITY

-
+
diff --git a/osinaweb/templates/user-details.html b/osinaweb/templates/user-details.html new file mode 100644 index 00000000..014f75bd --- /dev/null +++ b/osinaweb/templates/user-details.html @@ -0,0 +1,250 @@ +{% extends "main.html" %} +{%load static%} +{% block title %}My Projects{% endblock %} +{% block content %} + +
+
+
+
+

Recent Note:

+

Send an Email to Salim.

+
+
+ + +
+
+ + + +
+
+ + +
+ + +
+
+
+
+ user-image +
+
+

Nataly

+
+
+
+ + +
+
+
+
+

Username: Nataly

+
+ +
+

Password: -- +

+
+ +
+

Group: Group + 1

+
+ +
+

First Name: Nataly

+
+ +
+

Last Name: Nataly

+
+ +
+

Email: nataly.aw@ositcom.net

+
+ +
+
+ + +
+

USERS ACTIVITY

+
+ + +
+
+
+
+
+ user profile +
+
+

Nataly

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+
+
+ user profile +
+
+

Salim

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+
+
+ user profile +
+
+

Emile

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ +
+
+
+
+ + + + +
+ + + + + + + + + +{% endblock content %} \ No newline at end of file diff --git a/osinaweb/templates/users.html b/osinaweb/templates/users.html new file mode 100644 index 00000000..09ff19ce --- /dev/null +++ b/osinaweb/templates/users.html @@ -0,0 +1,266 @@ +{% extends "main.html" %} +{%load static%} +{% block title %}My Projects{% endblock %} +{% block content %} + +
+
+
+
+

Recent Note:

+

Send an Email to Salim.

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

Users

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

Username

+
+
+

Group

+
+
+ Actions +
+
+ + +
+ +
+
+

Nataly.aw

+
+
+

Group 1

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

USERS ACTIVITY

+
+ + + +
+
+
+
+
+ user profile +
+
+

Nataly

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+
+
+ user profile +
+
+

Salim

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+
+
+ user profile +
+
+

Emile

+

11:30 AM

+
+
+
+ +
+
+ + +
+

Closed - Create the Osina home page

+
+ + +
+ + +
+
+
+ + +
+
+
+ +
+ + + + + +
+ + + + + + +{% endblock content %} \ No newline at end of file