diff --git a/movere_local/mainapp/forms.py b/movere_local/mainapp/forms.py index 5bad2713056992a383da59c46f62bc727da9ba1f..15b265fb5c63fadd08043fcd800774a18b8cd409 100644 --- a/movere_local/mainapp/forms.py +++ b/movere_local/mainapp/forms.py @@ -24,7 +24,7 @@ class RequestForm(forms.ModelForm): ] file_choice = forms.ChoiceField(choices=FILE_CHOICES, widget=forms.RadioSelect) - storage_item = forms.ModelChoiceField(queryset=Storage.objects.none(), required=False) + storage_item = forms.ModelChoiceField(queryset=Storage.objects.none(), required=False, empty_label=None) upload_file = forms.FileField(required=False) class Meta: @@ -77,7 +77,7 @@ class OrderForm(forms.ModelForm): material = forms.ChoiceField(choices=MATERIAL_CHOICES, widget=forms.RadioSelect, label="Выберите материал") file_choice = forms.ChoiceField(choices=FILE_CHOICES, widget=forms.RadioSelect) - storage_item = forms.ModelChoiceField(queryset=Storage.objects.none(), required=False) + storage_item = forms.ModelChoiceField(queryset=Storage.objects.none(), required=False, empty_label=None) upload_file = forms.FileField(required=False) class Meta: diff --git a/movere_local/mainapp/templates/mainapp/create_3d_model.html b/movere_local/mainapp/templates/mainapp/create_3d_model.html index 2b64a6d2781f7163a86e39998f4c62c23d2907e2..db29173f771f4680c0fd279397249462f03d5819 100644 --- a/movere_local/mainapp/templates/mainapp/create_3d_model.html +++ b/movere_local/mainapp/templates/mainapp/create_3d_model.html @@ -8,7 +8,7 @@ {% load static %} @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Krona+One&display=swap'); - + @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&display=swap'); .navbar { display: flex; @@ -44,7 +44,7 @@ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ @@ -89,7 +89,7 @@ h1 { - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', Arial, sans-serif; align-self: flex-start; /* margin-left: 10%; РЎРґРІРёРі текста "3D LAB" влево */ } @@ -120,6 +120,8 @@ margin: 15% auto; /* Центрирование контента */ padding-bottom: 20px; /* Отступ РѕС‚ последнего элемента РґРѕ футера */ padding-top: 15%; + font-family: 'Mulish', Arial, sans-serif; + } .footer { @@ -153,7 +155,7 @@ } .card label { - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', Arial, sans-serif; font-size: 16px; color: #FFFFFF; /* Цвет текста */ display: block; @@ -168,7 +170,7 @@ border: 1px solid #333333; /* Тонкая рамка */ background-color: #121212; /* Фон поля */ color: #FFFFFF; /* Цвет текста */ - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', sans-serif; font-size: 14px; } .card input[type="radio"], @@ -179,8 +181,10 @@ font-size: 16px; color: #FFFFFF; margin-bottom: 10px; + font-family: 'Mulish', sans-serif; } .card textarea { + width: 98%; /* Заполнение карточки РїРѕ ширине */ height: 120px; /* Фиксированная высота */ margin: 0 auto; /* Центрирование РїРѕ горизонтали */ @@ -190,7 +194,7 @@ border: 1px solid #333333; /* Рамка */ background-color: #121212; /* Фон */ color: #FFFFFF; /* Цвет текста */ - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', sans-serif; font-size: 14px; /* Размер текста */ resize: none; /* Запрещаем изменение размера */ } @@ -204,7 +208,7 @@ color: white; font-size: 16px; cursor: pointer; - font-family: 'Roboto', sans-serif; + font-family: 'Mulish', sans-serif; transition: transform 0.2s, background-color 0.2s; /* Анимация */ } diff --git a/movere_local/mainapp/templates/mainapp/create_order.html b/movere_local/mainapp/templates/mainapp/create_order.html index 0af395eb06e53caf8c95663078f7cdd66ff16066..e0fe9e6355fc4f45f333bf027367b75650c4325d 100644 --- a/movere_local/mainapp/templates/mainapp/create_order.html +++ b/movere_local/mainapp/templates/mainapp/create_order.html @@ -8,6 +8,7 @@ {% load static %} @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Krona+One&display=swap'); + @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&display=swap'); .navbar { @@ -44,7 +45,7 @@ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ @@ -62,7 +63,7 @@ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ @@ -89,7 +90,7 @@ h1 { - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', Arial, sans-serif; align-self: flex-start; /* margin-left: 10%; РЎРґРІРёРі текста "3D LAB" влево */ } @@ -153,7 +154,7 @@ } .card label { - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', Arial, sans-serif; font-size: 16px; color: #FFFFFF; /* Цвет текста */ display: block; @@ -168,7 +169,7 @@ border: 1px solid #333333; /* Тонкая рамка */ background-color: #121212; /* Фон поля */ color: #FFFFFF; /* Цвет текста */ - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', sans-serif; font-size: 14px; } .card input[type="radio"], @@ -176,6 +177,7 @@ width: auto; /* Убираем ширину для радио Рё чекбоксов */ } .card legend { + font-family: 'Mulish', sans-serif; font-size: 16px; color: #FFFFFF; margin-bottom: 10px; @@ -190,7 +192,7 @@ border: 1px solid #333333; /* Рамка */ background-color: #121212; /* Фон */ color: #FFFFFF; /* Цвет текста */ - font-family: 'Roboto', Arial, sans-serif; + font-family: 'Mulish', sans-serif; font-size: 14px; /* Размер текста */ resize: none; /* Запрещаем изменение размера */ } @@ -204,7 +206,7 @@ color: white; font-size: 16px; cursor: pointer; - font-family: 'Roboto', sans-serif; + font-family: 'Mulish', sans-serif; transition: transform 0.2s, background-color 0.2s; /* Анимация */ } diff --git a/movere_local/mainapp/templates/mainapp/home.html b/movere_local/mainapp/templates/mainapp/home.html index 9451b4b9f173fe7fc249d3e986d9ad3d4b4eb574..3d3b8f0fabaa9bbfa2137d39d175575ca96db3d0 100644 --- a/movere_local/mainapp/templates/mainapp/home.html +++ b/movere_local/mainapp/templates/mainapp/home.html @@ -43,12 +43,12 @@ <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>Home</title> + <title>MOVERE | Home </title> <style> {% load static %} @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Krona+One&display=swap'); - + @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&display=swap'); .navbar { display: flex; @@ -89,7 +89,7 @@ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ diff --git a/movere_local/mainapp/templates/mainapp/redactor.html b/movere_local/mainapp/templates/mainapp/redactor.html index 98cab20c84c7133929bf9bf9631006ca80b92e1e..400ef6d21aedcc5336df348dada65501de84cfb7 100644 --- a/movere_local/mainapp/templates/mainapp/redactor.html +++ b/movere_local/mainapp/templates/mainapp/redactor.html @@ -8,6 +8,7 @@ {% load static %} @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); @import url('https://fonts.googleapis.com/css2?family=Krona+One&display=swap'); + @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&display=swap'); .navbar { @@ -44,13 +45,14 @@ white-space: nowrap; /* Запрещает перенос текста РЅР° РЅРѕРІСѓСЋ строку */ } + .navbar .profile-btn { background-color: rgb(45, 42, 42);/* Прозрачный фон */ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ @@ -131,7 +133,7 @@ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ @@ -151,7 +153,7 @@ color: #FFFFFF; border: 1px solid #ffffff00; /* Белая рамка */ padding: 15px 30px; /* Увеличенный внутренний отступ */ - font-family: "Roboto", sans-serif; + font-family: "Mulish", sans-serif; /* font-weight: bold; */ font-size: 16px; /* Увеличенный размер шрифта */ border-radius: 20px; /* Скругленные углы */ @@ -174,7 +176,7 @@ body { margin: 0; - font-family: Arial, sans-serif; + font-family: "Mulish", sans-serif; display: flex; justify-content: center; align-items: center; @@ -370,8 +372,7 @@ let object; let isMouseDown = false; let startX, startY; - let rotationX = 0; - let rotationY = 0; + let rotationQuaternion = new THREE.Quaternion(); function clearObject() { if (object) { @@ -478,18 +479,23 @@ }); window.addEventListener('mousemove', event => { - if (isMouseDown && object) { - const deltaX = event.clientX - startX; - const deltaY = event.clientY - startY; + if (isMouseDown && object) { + const deltaX = event.clientX - startX; + const deltaY = event.clientY - startY; + + startX = event.clientX; + startY = event.clientY; + + const quaternionX = new THREE.Quaternion(); + const quaternionY = new THREE.Quaternion(); - rotationX += deltaY * 0.01; - rotationY += deltaX * 0.01; + quaternionX.setFromAxisAngle(new THREE.Vector3(1, 0, 0), deltaY * 0.01); + quaternionY.setFromAxisAngle(new THREE.Vector3(0, 1, 0), deltaX * 0.01); - startX = event.clientX; - startY = event.clientY; + rotationQuaternion.multiplyQuaternions(quaternionY, rotationQuaternion); + rotationQuaternion.multiplyQuaternions(quaternionX, rotationQuaternion); - object.rotation.x = rotationX; - object.rotation.y = rotationY; + object.quaternion.copy(rotationQuaternion); } }); diff --git a/movere_local/mainapp/templates/mainapp/view_orders.html b/movere_local/mainapp/templates/mainapp/view_orders.html index 81e5d25782e6735f94f1496a770a5df2d38fc3ae..3f26e603fa20c207ee325fd9ba7c5564f5796a92 100644 --- a/movere_local/mainapp/templates/mainapp/view_orders.html +++ b/movere_local/mainapp/templates/mainapp/view_orders.html @@ -1,136 +1,774 @@ <!DOCTYPE html> <html lang="en"> <head> + <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> - <title>РњРѕРё заказы</title> + <meta name="csrf-token" content="{{ csrf_token }}"> + <title>MOVERE | РњРѕРё заявки </title> + + <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script> + <script src="https://cdn.jsdelivr.net/npm/three/examples/js/loaders/OBJLoader.js"></script> + <script src="https://cdn.jsdelivr.net/npm/three/examples/js/loaders/STLLoader.js"></script> + + + <style> - table { + + {% load static %} + @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap'); + @import url('https://fonts.googleapis.com/css2?family=Krona+One&display=swap'); + @import url('https://fonts.googleapis.com/css2?family=Mulish:wght@200..1000&display=swap'); + + + body { + margin: 0; + font-family: "Krona One", serif; + font-weight: 400; + font-style: normal; + background-color: #121212; + color: #FFFFFF; + display: flex; + flex-direction: column; + align-items: center; + height: 100vh; + } + + .navbar { + display: flex; + justify-content: space-between; + align-items: center; width: 100%; - border-collapse: collapse; + background-color: #121212; /* Цвет РІ тон страницы */ + padding: 30px 20px; + position: fixed; + top: 0; + z-index: 10; + /* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */ } - th, td { - border: 1px solid #ddd; - padding: 8px; + + .navbar .logo { + display: flex; /* Располагает элементы (логотип Рё текст) РІ РѕРґРЅСѓ строку */ + align-items: center; /* Вертикальное выравнивание элементов РїРѕ центру */ + margin-left: 100px; + margin-top: 20px; + /* margin-left: 30px; */ + } + + .navbar .logo img { + height: 60px; /* Размер логотипа */ + margin-right: 15px; /* Отступ между логотипом Рё текстом */ + } + + .navbar .logo span { + font-size: 20px; /* Размер текста */ + font-weight: bold; + color: #FFFFFF; /* Цвет текста */ + white-space: nowrap; /* Запрещает перенос текста РЅР° РЅРѕРІСѓСЋ строку */ + } + + + .navbar .profile-btn { + background-color: rgb(45, 42, 42);/* Прозрачный фон */ + color: #FFFFFF; + border: 1px solid #ffffff00; /* Белая рамка */ + padding: 15px 30px; /* Увеличенный внутренний отступ */ + font-family: "Mulish"; + /* font-weight: bold; */ + font-size: 16px; /* Увеличенный размер шрифта */ + border-radius: 20px; /* Скругленные углы */ + cursor: pointer; + transition: transform 0.3s, background-color 0.3s, color 0.3s; + margin-right: 10%; /*Отступ справа */ + /* margin-left: 10%; */ + } + + .navbar .profile-btn:hover { + background-color: rgb(58, 54, 54); /* Полупрозрачный белый РїСЂРё наведении */ + transform: scale(1.1); /* Увеличение РєРЅРѕРїРєРё */ + } + + .navbar .storage_home_button { + background-color: rgb(45, 42, 42);/* Прозрачный фон */ + color: #FFFFFF; + border: 1px solid #ffffff00; /* Белая рамка */ + padding: 15px 30px; /* Увеличенный внутренний отступ */ + font-family: "Mulish", sans-serif; + /* font-weight: bold; */ + font-size: 16px; /* Увеличенный размер шрифта */ + border-radius: 20px; /* Скругленные углы */ + cursor: pointer; + transition: transform 0.3s, background-color 0.3s, color 0.3s; + margin-right: 10%; /*Отступ справа */ + /* margin-left: 10%; */ + } + + .navbar .storage_home_button:hover { + background-color: rgb(58, 54, 54); /* Полупрозрачный белый РїСЂРё наведении */ + transform: scale(1.1); /* Увеличение РєРЅРѕРїРєРё */ + } + + + .navbar .btns_in_nav { + display: flex; + margin-right: 10%; + } + + + + .view_orders_h1 { + align-self: flex-start; /* Расположить элемент слева */ + /* margin: 20px; Отступы сверху Рё слева */ + color: rgb(255, 253, 253); + font-size: 20px; + /* font-family: "Krona One", serif; */ text-align: left; + margin-top: 10%; + padding: 0 5%; + font-family: "Mulish", serif; + } + + + .container { + display: flex; + gap: 10px; + } + + + .card { + width: 200px; + height: 300px; + background-color: #3A3A3A; + border-radius: 10px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + overflow: hidden; + position: relative; + cursor: pointer; + transition: transform 0.3s; + } + + .card:hover { + transform: scale(1.05); + } + + .card img { + width: 100%; + height: 100%; + object-fit: cover; + position: absolute; + top: 0; + left: 0; + z-index: 1; + } + + .card video { + width: 100%; + height: 100%; + object-fit: cover; + display: none; + position: absolute; + top: 0; + left: 0; + z-index: 2; + } + + .card video[data-playing="true"] { + display: block; + } + + .card .label { + position: relative; + font-family: 'Mulish', Arial, sans-serif; + color: #FFFFFF; + padding: 5px 10px; + border-radius: 5px; + font-size: 14px; + font-weight: bold; + margin-bottom: 5px; + text-align: center; + z-index: 3; + } + + .card .description { + font-family: 'Mulish', Arial, sans-serif; + position: relative; + color: #FFFFFF; + padding: 5px 10px; + border-radius: 5px; + font-size: 12px; + text-align: center; + margin-bottom: 10px; + z-index: 3; + } + + .home-button { + background-color: transparent; /* Фон РєРЅРѕРїРєРё прозрачный */ + position: absolute; + padding: 1px 1px; /* Отступы внутри РєРЅРѕРїРєРё */ + top: 7%; + right: 3%; + width: 7%; + font-size: 20px; + font-weight: 700; + color: rgb(247, 249, 250); /* Цвет текста */ + border: none; /* Убирает границу */ + outline: none; /* Убирает контур РїСЂРё фокусе */ + } + + .create-order-button { + display: block; + padding: 8px 16px; + background-color: transparent; + color: white; + font-size: 20px; + text-decoration: none; + border-radius: 5px; + text-align: center; + transition: background-color 0.3s; /* Добавляем плавную анимацию */ + z-index: 1000; /* Убедитесь, что РєРЅРѕРїРєР° будет РІРёРґРЅР° над РґСЂСѓРіРёРјРё элементами */ + } + + .create-order-button:hover { + background-color: #4a4646; /* меняем цвет фона РЅР° серый РїСЂРё наведении */ + + } + + .modal { + display: none; /* Скрытое РїРѕ умолчанию */ + position: fixed; /* Фиксийрованное положение */ + z-index: 1; /* Лежит над РґСЂСѓРіРёРјРё элементами */ + left: 0; + top: 0; + width: 100%; /* Полная ширина */ + height: 100%; /* Полная высота */ + overflow: auto; /* Включение прокрутки, если необходимо */ + background-color: rgb(0,0,0); /* Цвет фона */ + background-color: rgba(0,0,0,0.4); /* Черный фон СЃ небольшой прозрачностью */ + border-radius: 20px; + } + + .modal-content { + background-color: #d7d7d7; + color: black; + margin: 15% auto; /* 15% сверху Рё РїРѕ центру РїРѕ горизонтали */ + padding: 20px; + border: 1px solid #888; + width: 50%; /* Можете изменить ширину */ + border-radius: 20px; + font-family: "Mulish", sans-serif; + } + /* Общий стиль для РєРЅРѕРїРѕРє */ +.modal-btn { + display: inline-block; + padding: 10px 20px; + font-size: 16px; + font-family: "Mulish", sans-serif; + font-weight: bold; + color: white; + background-color: #4CAF50; /* Зелёный цвет РїРѕ умолчанию */ + border: none; + border-radius: 8px; + cursor: pointer; + transition: background-color 0.3s, transform 0.2s; +} + +/* РљРЅРѕРїРєР° отмены заказа */ +.cancel-btn { + background-color: #f44336; /* Красный цвет */ +} + +.cancel-btn:hover { + background-color: #d32f2f; /* Темнее РїСЂРё наведении */ +} + +/* РљРЅРѕРїРєР° "Р’ архив" */ +.archive-btn { + background-color: #2196F3; /* РЎРёРЅРёР№ цвет */ +} + +.archive-btn:hover { + background-color: #1976D2; /* Темнее РїСЂРё наведении */ +} + +/* Рффект нажатия */ +.modal-btn:active { + transform: scale(0.95); +} + +/* Модальное РѕРєРЅРѕ: стиль для действий */ +.modal-actions { + margin-top: 20px; + display: flex; + gap: 10px; /* Расстояние между кнопками */ +} + + .close { + color: #aaa; + float: right; + font-size: 28px; + font-weight: bold; + } + + .close:hover, + .close:focus { + color: black; + cursor: pointer; + } + + + + + table { + width: 90%; + table-layout: fixed; /* Фиксированная ширина колонок */ + border-collapse: separate; + border-spacing: 0; + margin: 10px auto; + border-radius: 10px; + overflow: hidden; + background-color: #1e1e1e; + font-family: "Mulish", serif; + font-optical-sizing: auto; + font-weight: 400; + font-style: normal; + } + + th, td { + width: 20%; /* Устанавливаем одинаковую ширину для всех колонок */ + border-bottom: 0.5px solid #606060; + border-right: 0.5px solid #5f5f5f; + padding: 12px 15px; + color: #f0f0f0; + vertical-align: top; /* Содержимое РїРѕ верхнему краю */ } + + + + th:last-child, td:last-child { + border-right: none; /* Убирает правую границу Сѓ последней колонки */ + width: 20%; + } + + th:first-child, td:first-child { + width: 20%; /* Установите ширину первого столбца РїРѕ вашему усмотрению */ + } + th { - background-color: #f2f2f2; + background-color: #292929; /* Более темный фон для заголовков */ + color: #ffffff; /* Белый цвет текста для заголовков */ + } + + td { + vertical-align: top; /* Выравнивание содержимого ячейки РїРѕ верху */ + } + .status-column { - width: 20%; + width: 20%; /*РЁРёСЂРёРЅР° колонки статуса*/ } - </style> - <script> - function confirmCancel(orderId) { - if (confirm('Р’С‹ уверены, что хотите отменить этот заказ?')) { - document.getElementById('cancel-form-' + orderId).submit(); + + .status-column ul { + list-style-type: none; /* Убирает маркеры СЃРїРёСЃРєР° */ + padding: 0; /* Убирает отступ слева, если РѕРЅ есть */ + top: 10px; } + + td .order-card { + margin: 10px; + width: 90%; /* Карточка занимает РІСЃСЋ ширину колонки */ + box-sizing: border-box; /* Включаем padding Рё border РІ расчет ширины */ + /* margin: 0 auto; Центрируем содержимое внутри ячейки */ + background-color: #4a4646; + box-shadow: 0 2px 4px rgba(0,0,0,0.1); + border: 2px solid rgba(255, 255, 255, 0.62); + border-width: 0.0px; + color: white; + border-radius: 8px; + padding: 10px; + text-wrap: wrap; + transition-duration: 0.2s; + + } + td .order-card:hover { + + background-color: #524f4f;/* Полупрозрачный белый РїСЂРё наведении */ + transform: scale(1.05); + + } + + + + + + </style> - - document.addEventListener("DOMContentLoaded", () => { - // Получаем РІСЃРµ элементы СЃ параметрами заказов - const parametersDivs = document.querySelectorAll('[id^="order-parameters-"]'); - // Функция для парсинга строки РІ формате "ключ:значение__ключ:значение" - function parseCustomFormat(customString) { - const result = {}; - const pairs = customString.split('__'); // Разделяем РїРѕ "__" - pairs.forEach((pair) => { - const [key, value] = pair.split(':', 2); // Разделяем РїРѕ первому ":" - if (key) { - result[key.trim()] = value ? value.trim() : ''; // Убираем пробелы Рё обрабатываем отсутствие значения + + +<script> + // Объекты для переводов + const translations = { + keys: { + position: "Должность", + purpose: "Цель 3D-печати", + additional_purpose: "Дополнительная информация", + material: "Материал" + }, + values: { + student: "Студент Р’РЁР", + professor: "Преподаватель Р’РЁР", + worker: "Сотрудник Р’РЁР", + other: "Другое", + course: "Курсовая работа", + diploma: "Дипломная работа", + project: "Проект", + pla: "Пластик PLA", + abs: "Пластик ABS", + tpu: "Резина TPU", + wait_confirmation: "Ожидает подтверждения", + in_work: "Р’ работе", + ready: "Готов", + done: "Получен", + canceled: "Отменен" + } + }; + + // Функция перевода ключей Рё значений + function translateParameters(parameters) { + const translated = {}; + for (const [key, value] of Object.entries(parameters)) { + const translatedKey = translations.keys[key] || key; // Перевод ключа + if (Array.isArray(value)) { + // Если значение — массив, переводим элементы массива + translated[translatedKey] = value.map(item => translations.values[item] || item).join(", "); + } else { + // Переводим одиночное значение + translated[translatedKey] = translations.values[value] || value; } - }); - return result; + } + return translated; } - // Обрабатываем каждый блок СЃ параметрами - parametersDivs.forEach((parametersDiv) => { - const parametersText = parametersDiv.innerText.trim(); + document.addEventListener('DOMContentLoaded', function () { + const modal = document.getElementById("orderModal"); + const closeBtn = document.querySelector(".close"); + const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content'); + + // Открытие модального РѕРєРЅР° РїСЂРё клике РЅР° карточку + document.querySelectorAll('.order-card').forEach(card => { + card.addEventListener('click', function () { + const orderId = this.getAttribute('data-id'); + const orderDate = this.getAttribute('data-date'); + const orderParameters = this.getAttribute('data-parameters'); + const orderStatus = this.getAttribute('data-status'); - try { - // Парсим строку - const parameters = parseCustomFormat(parametersText); + let parsedParameters = {}; + try { + parsedParameters = JSON.parse(orderParameters.replace(/'/g, '"')); + } catch (e) { + console.error("Ошибка парсинга параметров:", e); + } - // Создаем новый форматированный HTML - let formattedHTML = "<strong>Параметры:</strong><br>"; - for (const [key, value] of Object.entries(parameters)) { - formattedHTML += `${key}: ${value}<br>`; + // Перевод параметров + const translatedParameters = translateParameters(parsedParameters); + + // Генерация HTML параметров + let parametersHTML = '<ul>'; + for (const [key, value] of Object.entries(translatedParameters)) { + parametersHTML += `<li><strong>${key}:</strong> ${value}</li>`; + } + parametersHTML += '</ul>'; + + const translatedStatus = translations.values[orderStatus] || orderStatus; + + // Действия + let actionsHTML = ''; + if (orderStatus === 'wait_confirmation') { + actionsHTML = ` + <button class="modal-btn cancel-btn" onclick="confirmCancel(${orderId})">Отменить заказ</button> + <form id="cancel-form-${orderId}" method="post" action="/cancel_order/${orderId}/" style="display: none;"> + <input type="hidden" name="csrfmiddlewaretoken" value="${csrfToken}"> + </form> + `; + } else if (orderStatus === 'done' || orderStatus === 'canceled') { + actionsHTML = ` + <form method="post" action="/archive_order/${orderId}/"> + <input type="hidden" name="csrfmiddlewaretoken" value="${csrfToken}"> + <button class="modal-btn archive-btn" type="submit">Р’ архив</button> + </form> + `; + } + + // Заполняем содержимое модального РѕРєРЅР° + modal.querySelector('p').innerHTML = ` + <strong>ID заказа:</strong> ${orderId}<br> + <strong>Дата:</strong> ${orderDate}<br> + <strong>Параметры:</strong> ${parametersHTML} + <strong>Статус:</strong> ${translatedStatus}<br> + <div class="modal-actions">${actionsHTML}</div> + `; + + modal.style.display = "block"; + }); + }); + + // Закрытие модального РѕРєРЅР° + closeBtn.onclick = function () { + modal.style.display = "none"; + }; + + window.onclick = function (event) { + if (event.target === modal) { + modal.style.display = "none"; } + }; - // Заменяем содержимое блока - parametersDiv.innerHTML = formattedHTML; - } catch (error) { - console.error("Ошибка парсинга параметров:", error); - } + document.addEventListener('keydown', function (event) { + if (event.key === "Escape") { + modal.style.display = "none"; + } + }); }); -}); - </script> + + function confirmCancel(orderId) { + if (confirm('Р’С‹ уверены, что хотите отменить этот заказ?')) { + document.getElementById('cancel-form-' + orderId).submit(); + } + } +</script> + + + + </head> <body> - <h1>РЎРїРёСЃРѕРє заказов</h1> - - <a href="{% url 'create_order' %}" style="display: inline-block; padding: 10px 20px; background-color: #4CAF50; color: white; text-decoration: none; border-radius: 5px;">Создать новый заказ</a> - <button onclick="location.href='{% url 'home' %}'">Домой</button> - - <table> - <thead> - <tr> - {% for status, _ in orders_status_list %} - <th class="status-column"> - {% if status == 'wait_confirmation' %} - Ожидает подтверждения - {% elif status == 'in_work' %} - Отправлен РЅР° печать - {% elif status == 'ready' %} - Готов - {% elif status == 'done' %} - Выполнен - {% elif status == 'canceled' %} - Отменен - {% endif %} - </th> - {% endfor %} - </tr> - </thead> - <tbody> - <tr> - {% for status, orders in orders_status_list %} + + + + <div class="navbar"> + <div class="logo"> + <a href="{% url 'home' %}" style="text-decoration: none; color: inherit; display: flex; align-items: center;"> + <img src="{% static 'mainapp/images/download.png' %}" alt="Logo"> + <span>MOVERELAB</span> + </a> + </div> + <div class="btns_in_nav"> + <button class="profile-btn" onclick="location.href='{% url 'home' %}'">Домой</button> + <button class="profile-btn" onclick="location.href='{% url 'profile' %}'">Профиль</button> + </div> + </div> + + + + + <div class = 'view_orders_h1'> + <h1><span style="font-family: 'Krona One', monospace; font-weight: 400; font-size: 40px;">>>></span> Р—РђРЇР’РљР</h1> + </div> + + <div class='view_orders_table'> + <table> + <thead> + <tr> + {% for status, _ in orders_status_list %} + <th class="status-column"> + {% if status == 'wait_confirmation' %} + Ожидает подтверждения + {% elif status == 'in_work' %} + Отправлен РЅР° печать + {% elif status == 'ready' %} + Готов Рє выдаче + {% elif status == 'done' %} + Выполнен + {% elif status == 'canceled' %} + Отменен + {% endif %} + </th> + {% endfor %} + </tr> + </thead> + <tbody> + <tr> + <!-- Ячейка для РєРЅРѕРїРєРё "Добавить новый заказ" --> <td class="status-column"> - {% if orders %} + {% if orders_status_list.0.0 == 'wait_confirmation' %} <ul> - {% for order in orders %} - <li> - Заказ ID: {{ order.id }} <br> - Дата: {{ order.order_datetime }} <br> - Параметры: <br> - <div id="order-parameters-{{ order.id }}">{{ order.order_parameters }}</div><br> - Файл: {% if order.file_basename %}{{ order.file_basename }}{% else %}Нет файла{% endif %} <br> - - {% if order.order_state == 'wait_confirmation' %} - <!-- РљРЅРѕРїРєР° для отмены заказа СЃ подтверждением --> - <button onclick="confirmCancel({{ order.id }})">Отменить заказ</button> - <form id="cancel-form-{{ order.id }}" method="post" action="{% url 'cancel_order' order.id %}" style="display: none;"> - {% csrf_token %} - </form> - {% elif order.order_state == 'done' or order.order_state == 'canceled' %} - <form method="post" action="{% url 'archive_order' order.id %}"> - {% csrf_token %} - <button type="submit">Р’ архив</button> - </form> + {% for order, params in orders_status_list.0.1 %} + <li class="order-card" + data-id="{{ order.id }}" + data-date="{{ order.order_datetime|date:'Y-m-d' }}" + data-parameters="{{ params }}" + data-status="{{ order.order_state }}"> + + <span style="font-size: 19px;">Номер заказа: {{ order.id }} </span><br> + <span style="font-weight: 300; font-size: 16px; color: gray">{{ order.order_datetime|date:"Y-m-d" }}</span><br> + <!-- Параметры: <br> + {% for param_key, param_value in params.items %} + {% if param_key != 'purpose' %} + {{param_key}}: {{param_value}} <br> + {% else %} + {{param_key}}: {{param_value|join:", "}} {% endif %} - </li> - {% endfor %} + {% endfor %} --> + + <!-- <div id="order-parameters-{{ order.id }}">{{ order.order_parameters }}</div><br> --> + <br> + <br> + + + <svg fill="#ffffff" width="15px" height="15px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <title>file</title> + <path d="M26.731 9.902c-0.005-0.035-0.011-0.066-0.019-0.095l0.001 0.005c-0.031-0.134-0.094-0.249-0.182-0.342l0 0-8-8c-0.092-0.087-0.207-0.15-0.335-0.181l-0.005-0.001c-0.027-0.008-0.059-0.014-0.092-0.019l-0.003-0c-0.026-0.007-0.059-0.014-0.092-0.019l-0.004-0h-12c-0.414 0-0.75 0.336-0.75 0.75v0 28c0 0.414 0.336 0.75 0.75 0.75h20c0.414-0 0.75-0.336 0.75-0.75v0-20c-0.005-0.038-0.012-0.071-0.020-0.103l0.001 0.005zM24.189 9.25h-5.439v-5.439zM6.75 29.25v-26.5h10.5v7.25c0 0.414 0.336 0.75 0.75 0.75h7.25v18.5z"></path> + </svg> + {% if order.file_basename %}{{ order.file_basename }}{% else %}Нет файла{% endif %}<br> + + + + <!-- Отображение статуса заказа --> + <div> + {% if order.order_state == 'wait_confirmation' %} + <svg fill="rgb(58, 174, 231)" width="15px" height="15px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg"> + <path d="M960 112.941c-467.125 0-847.059 379.934-847.059 847.059 0 467.125 379.934 847.059 847.059 847.059 467.125 0 847.059-379.934 847.059-847.059 0-467.125-379.934-847.059-847.059-847.059M960 1920C430.645 1920 0 1489.355 0 960S430.645 0 960 0s960 430.645 960 960-430.645 960-960 960m417.905-575.955L903.552 988.28V395.34h112.941v536.47l429.177 321.77-67.765 90.465Z" fill-rule="evenodd"/> + </svg> + <span style="color: rgb(58, 174, 231);">Ожидает подтверждения</span> + {% elif order.order_state == 'in_work' %} + <svg width="15px" height="15px" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--emojione-monotone" preserveAspectRatio="xMidYMid meet"><path d="M61.287 53.542c-2.649-2.041-9.702-7.678-16.271-14.452c-4.366-4.505-6.223-9.015-9.533-12.429c-2.998-3.092-5.725-4.894-5.725-4.894l-.768.792l-5.188-5.35l2.004-2.067a.912.912 0 0 0 0-1.262l-.414-.427c.002-.002 5.898-7.936 13.353-5.742c.866.257 1.638.694 1.857.471c.298-.306-.837-1.482-1.502-2.162c-9.431-9.65-19.834 1.104-19.839 1.109l-.367-.379a.846.846 0 0 0-1.222 0l-9.239 9.528a.912.912 0 0 0 0 1.262s1.131 1.979-1.835 2.335c-1.194.145-1.942.414-2.366.769a431.18 431.18 0 0 0-1.979 2.009a.912.912 0 0 0 0 1.262l6.914 7.132a.847.847 0 0 0 1.223 0s1.906-1.99 1.947-2.042c.343-.438.605-1.208.743-2.44c.348-3.06 2.264-1.892 2.264-1.892a.846.846 0 0 0 1.224 0l2.004-2.067l5.186 5.349l-.768.793s1.748 2.813 4.746 5.905c3.309 3.413 7.683 5.328 12.05 9.833c6.567 6.774 12.032 14.047 14.014 16.78c.748 1.029.867.934 1.78-.009l2.849-2.938l2.847-2.937c.915-.946 1.009-1.068.011-1.84" fill="rgb(163, 32, 214)"></path><path d="M34.008 22.689a53.27 53.27 0 0 1 2.497 2.408c1.592 1.642 2.924 3.479 4.259 5.44l8.942-8.943A9.938 9.938 0 0 0 61.72 9.584L53.604 17.7l-5.76-1.543l-1.544-5.763l8.114-8.111a9.92 9.92 0 0 0-9.381 2.63a9.932 9.932 0 0 0-2.631 9.38l-8.394 8.396" fill="rgb(163, 32, 214)"></path><path d="M26.489 35.429a53.723 53.723 0 0 1-2.479-2.743l-9.717 9.718a9.926 9.926 0 0 0-9.381 2.629c-3.883 3.88-3.882 10.174 0 14.055a9.934 9.934 0 0 0 14.054 0a9.939 9.939 0 0 0 2.631-9.384l10.004-10.003c-1.84-1.338-3.567-2.679-5.112-4.272M13.483 57.821l-5.761-1.544l-1.543-5.762l4.218-4.215l5.76 1.541l1.543 5.763l-4.217 4.217" fill="rgb(163, 32, 214)"></path></svg> + <span style="color: rgb(163, 32, 214);">Р’ работе</span> + {% elif order.order_state == 'ready' %} + <svg fill="green" width="15px" height="15px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg"> + <path d="M960 112.941c-467.125 0-847.059 379.934-847.059 847.059 0 467.125 379.934 847.059 847.059 847.059 467.125 0 847.059-379.934 847.059-847.059 0-467.125-379.934-847.059-847.059-847.059M960 1920C430.645 1920 0 1489.355 0 960S430.645 0 960 0s960 430.645 960 960-430.645 960-960 960m-107.449-800L759.05 869.491l90.509-90.51 141.524 141.524L1070.91 689.672l90.51 90.509-398.869 398.869Z" fill-rule="evenodd"/> + </svg> + <span style="color: green;">Готов</span> + {% elif order.order_state == 'done' %} + <svg fill="grey" width="15px" height="15px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg"> + <path d="M960 112.941c-467.125 0-847.059 379.934-847.059 847.059 0 467.125 379.934 847.059 847.059 847.059 467.125 0 847.059-379.934 847.059-847.059 0-467.125-379.934-847.059-847.059-847.059M960 1920C430.645 1920 0 1489.355 0 960S430.645 0 960 0s960 430.645 960 960-430.645 960-960 960m113.255-1135.592H846.745v640h226.51v-640Z" fill-rule="evenodd"/> + </svg> + <span style="color: grey;">Получен</span> + {% elif order.order_state == 'canceled' %} + <svg fill="red" width="15px" height="15px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg"> + <path d="M960 112.941c-467.125 0-847.059 379.934-847.059 847.059 0 467.125 379.934 847.059 847.059 847.059 467.125 0 847.059-379.934 847.059-847.059 0-467.125-379.934-847.059-847.059-847.059M960 1920C430.645 1920 0 1489.355 0 960S430.645 0 960 0s960 430.645 960 960-430.645 960-960 960m158.867-1164.91l160.774 160.774-90.509 90.51-160.774-160.774-160.774 160.774-90.51-90.51 160.774-160.774-160.774-160.774 90.51-90.509 160.774 160.774 160.774-160.774 90.509 90.509-160.774 160.774Z" fill-rule="evenodd"/> + </svg> + <span style="color: red;">Отменен</span> + {% endif %} + </div> + + + <!-- РљРЅРѕРїРєР° для отмены заказа СЃ подтверждением --> + <!-- {% if order.order_state == 'wait_confirmation' %} + <button class="delete-btn" onclick="confirmCancel({{ order.id }})">Отменить заказ</button> + <form id="cancel-form-{{ order.id }}" method="post" action="{% url 'cancel_order' order.id %}" style="display: none;"> + {% csrf_token %} + </form> + {% elif order.order_state == 'done' or order.order_state == 'canceled' %} + <form method="post" action="{% url 'archive_order' order.id %}"> + {% csrf_token %} + <button type="submit">Р’ архив</button> + </form> + {% endif %} --> + </li> + {% endfor %} </ul> {% else %} - Нет заказов + {% endif %} + <a href="{% url 'create_order' %}" class="create-order-button">+ Создать новый заказ</a> </td> - {% endfor %} - </tr> - </tbody> - </table> + <!-- Печать остальных заказов РїРѕ статусам --> + {% for status, orders in orders_status_list %} + {% if status != 'wait_confirmation' %} + <td class="status-column"> + {% if orders %} + <ul> + {% for order, params in orders %} + <li class="order-card" + data-id="{{ order.id }}" + data-date="{{ order.order_datetime|date:'Y-m-d' }}" + data-parameters="{{ order.order_parameters }}" + data-status="{{ order.order_state }}"> + <span style="font-size: 19px;">Номер заказа: {{ order.id }} </span><br> + <span style="font-weight: 300; font-size: 16px; color: gray">{{ order.order_datetime|date:"Y-m-d" }}</span><br> + + <!-- Параметры: <br> + {% for param_key, param_value in params.items %} + {% if param_key != 'purpose' %} + {{param_key}}: {{param_value}} <br> + {% else %} + {{param_key}}: {{param_value|join:", "}} + {% endif %} + {% endfor %} --> + <br> + <br> + <svg fill="#ffffff" width="15px" height="15px" viewBox="0 0 32 32" version="1.1" xmlns="http://www.w3.org/2000/svg"> + <title>file</title> + <path d="M26.731 9.902c-0.005-0.035-0.011-0.066-0.019-0.095l0.001 0.005c-0.031-0.134-0.094-0.249-0.182-0.342l0 0-8-8c-0.092-0.087-0.207-0.15-0.335-0.181l-0.005-0.001c-0.027-0.008-0.059-0.014-0.092-0.019l-0.003-0c-0.026-0.007-0.059-0.014-0.092-0.019l-0.004-0h-12c-0.414 0-0.75 0.336-0.75 0.75v0 28c0 0.414 0.336 0.75 0.75 0.75h20c0.414-0 0.75-0.336 0.75-0.75v0-20c-0.005-0.038-0.012-0.071-0.020-0.103l0.001 0.005zM24.189 9.25h-5.439v-5.439zM6.75 29.25v-26.5h10.5v7.25c0 0.414 0.336 0.75 0.75 0.75h7.25v18.5z"></path> + </svg> + {% if order.file_basename %}{{ order.file_basename }}{% else %} Нет файла {% endif %} <br> + + <!-- Отображение статуса заказа --> + <div> + {% if order.order_state == 'wait_confirmation' %} + <svg fill="rgb(58, 174, 231)" width="15px" height="15px" viewBox="0 0 1920 1920" xmlns="http://www.w3.org/2000/svg"> + <path d="M960 112.941c-467.125 0-847.059 379.934-847.059 847.059 0 467.125 379.934 847.059 847.059 847.059 467.125 0 847.059-379.934 847.059-847.059 0-467.125-379.934-847.059-847.059-847.059M960 1920C430.645 1920 0 1489.355 0 960S430.645 0 960 0s960 430.645 960 960-430.645 960-960 960m417.905-575.955L903.552 988.28V395.34h112.941v536.47l429.177 321.77-67.765 90.465Z" fill-rule="evenodd"/> + </svg> + <span style="color: rgb(58, 174, 231);">Ожидает подтверждения</span> + {% elif order.order_state == 'in_work' %} + <svg width="15px" height="15px" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--emojione-monotone" preserveAspectRatio="xMidYMid meet"><path d="M61.287 53.542c-2.649-2.041-9.702-7.678-16.271-14.452c-4.366-4.505-6.223-9.015-9.533-12.429c-2.998-3.092-5.725-4.894-5.725-4.894l-.768.792l-5.188-5.35l2.004-2.067a.912.912 0 0 0 0-1.262l-.414-.427c.002-.002 5.898-7.936 13.353-5.742c.866.257 1.638.694 1.857.471c.298-.306-.837-1.482-1.502-2.162c-9.431-9.65-19.834 1.104-19.839 1.109l-.367-.379a.846.846 0 0 0-1.222 0l-9.239 9.528a.912.912 0 0 0 0 1.262s1.131 1.979-1.835 2.335c-1.194.145-1.942.414-2.366.769a431.18 431.18 0 0 0-1.979 2.009a.912.912 0 0 0 0 1.262l6.914 7.132a.847.847 0 0 0 1.223 0s1.906-1.99 1.947-2.042c.343-.438.605-1.208.743-2.44c.348-3.06 2.264-1.892 2.264-1.892a.846.846 0 0 0 1.224 0l2.004-2.067l5.186 5.349l-.768.793s1.748 2.813 4.746 5.905c3.309 3.413 7.683 5.328 12.05 9.833c6.567 6.774 12.032 14.047 14.014 16.78c.748 1.029.867.934 1.78-.009l2.849-2.938l2.847-2.937c.915-.946 1.009-1.068.011-1.84" fill="rgb(196, 61, 250)"></path><path d="M34.008 22.689a53.27 53.27 0 0 1 2.497 2.408c1.592 1.642 2.924 3.479 4.259 5.44l8.942-8.943A9.938 9.938 0 0 0 61.72 9.584L53.604 17.7l-5.76-1.543l-1.544-5.763l8.114-8.111a9.92 9.92 0 0 0-9.381 2.63a9.932 9.932 0 0 0-2.631 9.38l-8.394 8.396" fill="rgb(196, 61, 250)"></path><path d="M26.489 35.429a53.723 53.723 0 0 1-2.479-2.743l-9.717 9.718a9.926 9.926 0 0 0-9.381 2.629c-3.883 3.88-3.882 10.174 0 14.055a9.934 9.934 0 0 0 14.054 0a9.939 9.939 0 0 0 2.631-9.384l10.004-10.003c-1.84-1.338-3.567-2.679-5.112-4.272M13.483 57.821l-5.761-1.544l-1.543-5.762l4.218-4.215l5.76 1.541l1.543 5.763l-4.217 4.217" fill="rgb(196, 61, 250)"></path></svg> + + <span style="color: rgb(196, 61, 250);">Р’ работе</span> + {% elif order.order_state == 'ready' %} + <svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M8.5 12.5L10.5 14.5L15.5 9.5" stroke="rgb(0, 195, 0)" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> + <path d="M7 3.33782C8.47087 2.48697 10.1786 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 10.1786 2.48697 8.47087 3.33782 7" stroke="rgb(0, 195, 0)" stroke-width="1.5" stroke-linecap="round"/> + </svg> + <span style="color: rgb(0, 195, 0);">Готов</span> + {% elif order.order_state == 'done' %} + <svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path fill-rule="evenodd" clip-rule="evenodd" d="M17.4964 21.9284C17.844 21.7894 18.1491 21.6495 18.4116 21.5176C18.9328 22.4046 19.8969 23 21 23C22.6569 23 24 21.6568 24 20V14C24 12.3431 22.6569 11 21 11C19.5981 11 18.4208 11.9616 18.0917 13.2612C17.8059 13.3614 17.5176 13.4549 17.2253 13.5384C16.3793 13.7801 15.3603 13.9999 14.5 13.9999C13.2254 13.9999 10.942 13.5353 9.62034 13.2364C8.61831 13.0098 7.58908 13.5704 7.25848 14.5622L6.86313 15.7483C5.75472 15.335 4.41275 14.6642 3.47619 14.1674C2.42859 13.6117 1.09699 14.0649 0.644722 15.1956L0.329309 15.9841C0.0210913 16.7546 0.215635 17.6654 0.890813 18.2217C1.66307 18.8581 3.1914 20.0378 5.06434 21.063C6.91913 22.0782 9.21562 22.9999 11.5 22.9999C14.1367 22.9999 16.1374 22.472 17.4964 21.9284ZM20 20C20 20.5523 20.4477 21 21 21C21.5523 21 22 20.5523 22 20V14C22 13.4477 21.5523 13 21 13C20.4477 13 20 13.4477 20 14V20ZM14.5 15.9999C12.9615 15.9999 10.4534 15.4753 9.17918 15.1872C9.17918 15.1872 8.84483 16.1278 8.7959 16.2745L12.6465 17.2776C13.1084 17.3979 13.372 17.8839 13.2211 18.3367C13.0935 18.7194 12.7092 18.9536 12.3114 18.8865C11.0903 18.6805 8.55235 18.2299 7.25848 17.8365C5.51594 17.3066 3.71083 16.5559 2.53894 15.9342C2.53894 15.9342 2.22946 16.6189 2.19506 16.7049C2.92373 17.3031 4.32792 18.3799 6.0246 19.3086C7.76488 20.2611 9.70942 20.9999 11.5 20.9999C15.023 20.9999 17.1768 19.9555 18 19.465V15.3956C16.8681 15.7339 15.6865 15.9999 14.5 15.9999Z" fill="grey"/> + <path d="M12 1C11.4477 1 11 1.44772 11 2V7.58564L9.7071 6.29278C9.3166 5.9024 8.68342 5.9024 8.29292 6.29278C7.90235 6.68341 7.90235 7.31646 8.29292 7.70709L11.292 10.7063C11.6823 11.0965 12.3149 11.0968 12.7055 10.707L15.705 7.71368C16.0955 7.3233 16.0955 6.69 15.705 6.29962C15.3145 5.90899 14.6813 5.90899 14.2908 6.29962L13 7.59034V2C13 1.44772 12.5523 1 12 1Z" fill="grey"/> + </svg> + <span style="color: grey;">Получен</span> + {% elif order.order_state == 'canceled' %} + <svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> + <path d="M16 8L8 16M8.00001 8L16 16M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z" stroke="red" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> + </svg> + <span style="color: red;">Отменен</span> + {% endif %} + </div> + + <!-- {% if order.order_state == 'wait_confirmation' %} + РљРЅРѕРїРєР° для отмены заказа СЃ подтверждением + <button onclick="confirmCancel({{ order.id }})" style="margin-bottom: 20px;" >Отменить заказ</button> + <form id="cancel-form-{{ order.id }}" method="post" action="{% url 'cancel_order' order.id %}" style="display: none;"> + {% csrf_token %} + </form> + {% elif order.order_state == 'done' or order.order_state == 'canceled' %} + <form method="post" action="{% url 'archive_order' order.id %}"> + {% csrf_token %} + <button type="submit">Р’ архив</button> + </form> + {% endif %} --> + </li> + {% endfor %} + </ul> + {% else %} + + {% endif %} + </td> + {% endif %} + {% endfor %} + </tr> + </tbody> + </table> + </div> + + <div id="orderModal" class="modal"> + <div class="modal-content"> + <span class="close">×</span> + <p>Здесь будет информация Рѕ заказе.</p> + </div> + </div> </body> </html> diff --git a/movere_local/mainapp/views.py b/movere_local/mainapp/views.py index cec22819eb8594ea8e572d19da7d3c9d66d7b10c..01ec0ebcc72e339e3cb8ed284cb91eb28510f99e 100644 --- a/movere_local/mainapp/views.py +++ b/movere_local/mainapp/views.py @@ -266,14 +266,46 @@ def archive_order(request, order_id): return redirect('view_orders') +import ast +def parse_params(parametrs): + d = ast.literal_eval(parametrs) + return d @login_required def view_orders(request): user_orders = Order.objects.filter(user=request.user) + coolpaths = {order.id: order.file_path for order in user_orders} + + # Добавляем путь Рє файлу как атрибут каждого заказа + # for order in user_orders: + # order.file_preview_path = coolpaths.get(order.id, "") + # print(f"Order ID: {order.id}, File Path: {order.file_preview_path}") + # print(user_orders[0]) + statuses = ['wait_confirmation', 'in_work', 'ready', 'done', 'canceled'] orders_by_status = {status: user_orders.filter(order_state=status) for status in statuses} + def create_new_list_for_view(orders_by_status): + total = [] + for key, value in orders_by_status.items(): + # print(key, value) + new_list = [] + + for order in value: + try: + order.file_preview_path = coolpaths.get(order.id, "") + parsed_params = parse_params(order.order_parameters) + new_list.append([order, parsed_params]) + except: + new_list.append([order, {}]) + new_str = [key, new_list] + total.append(new_str) + return total + + new_orders_status_list = create_new_list_for_view(orders_by_status) + # print(new_orders_status_list) + orders_status_list = [] for status in statuses: orders = orders_by_status[status] @@ -285,8 +317,12 @@ def view_orders(request): else: order.file_basename = [] orders_status_list.append((status, orders)) - - return render(request, 'mainapp/view_orders.html', {'orders_status_list': orders_status_list}) + # for s in new_orders_status_list: + # print(s[0]) + # for order_batch in s[1]: + # print(order_batch[0].file_preview_path) + # # print(order.file_preview_path) + return render(request, 'mainapp/view_orders.html', {'orders_status_list': new_orders_status_list, 'coolpaths':coolpaths}) from .forms import OrderForm @@ -300,15 +336,15 @@ def create_order(request): order.user = request.user # Объединяем параметры РІ словарь - # order_parameters = { - # "position": form.cleaned_data.get("position"), - # "purpose": form.cleaned_data.get("purpose"), # РЎРїРёСЃРѕРє выбранных целей - # "additional_purpose": form.cleaned_data.get("additional_purpose"), - # "material": form.cleaned_data.get("material"), - # } - longstr = f'position:{form.cleaned_data.get("position")}__purpose:{form.cleaned_data.get("purpose")}__additional_purpose:{form.cleaned_data.get("additional_purpose")}__material:{form.cleaned_data.get("material")}' - order.order_parameters = longstr - # order.order_parameters = str(order_parameters) # Сохраняем словарь как строку + order_parameters = { + "position": form.cleaned_data.get("position"), + "purpose": form.cleaned_data.get("purpose"), # РЎРїРёСЃРѕРє выбранных целей + "additional_purpose": form.cleaned_data.get("additional_purpose"), + "material": form.cleaned_data.get("material"), + } + # longstr = f'position:{form.cleaned_data.get("position")}__purpose:{form.cleaned_data.get("purpose")}__additional_purpose:{form.cleaned_data.get("additional_purpose")}__material:{form.cleaned_data.get("material")}' + # order.order_parameters = longstr + order.order_parameters = str(order_parameters) # Сохраняем словарь как строку file_choice = form.cleaned_data.get('file_choice')