Source

Target

Commits (16)
Showing with 4557 additions and 429 deletions
+4557 -429
No preview for this file type
from django.contrib import admin
from .models import EditRequest, IncomingEditRequest, Order
# Register your models here.
admin.site.register(EditRequest)
admin.site.register(IncomingEditRequest)
admin.site.register(Order)
\ No newline at end of file
......@@ -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:
......@@ -35,7 +35,7 @@ class RequestForm(forms.ModelForm):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user:
self.fields['storage_item'].queryset = Storage.objects.filter(user=user)
self.fields['storage_item'].queryset = Storage.objects.filter(user=user, file_path__iregex=r'\.(jpg|jpeg|png)$')
......@@ -47,19 +47,48 @@ class OrderForm(forms.ModelForm):
(CHOICE_FILE_UPLOAD, 'Загрузить файл вручную'),
]
# Поле для выбора должности (один вариант)
POSITION_CHOICES = [
('student', 'Студент ВШЭ'),
('professor', 'Преподаватель ВШЭ'),
('worker', 'Сотрудник ВШЭ'),
('other', 'Другое'),
]
position = forms.ChoiceField(choices=POSITION_CHOICES, widget=forms.RadioSelect, label="Ваша должность")
# Поле для целей (несколько вариантов)
PURPOSE_CHOICES = [
('course', 'Курсовая работа'),
('diploma', 'Дипломная работа'),
('project', 'Проект'),
('other', 'Другое'),
]
purpose = forms.MultipleChoiceField(choices=PURPOSE_CHOICES, widget=forms.CheckboxSelectMultiple, label="Цель 3D-печати")
# Поле для текстового ввода цели
additional_purpose = forms.CharField(required=False, widget=forms.Textarea, label="Дополнительно укажите цель 3D-печати")
# Поле для выбора материала (один вариант)
MATERIAL_CHOICES = [
('pla', 'Пластик PLA'),
('abs', 'Пластик ABS'),
('tpu', 'Резина TPU'),
]
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:
model = Order
fields = ['order_parameters'] # Добавьте другие необходимые поля, если нужно
fields = [] # Добавьте другие необходимые поля, если нужно
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
super().__init__(*args, **kwargs)
if user:
self.fields['storage_item'].queryset = Storage.objects.filter(user=user)
self.fields['storage_item'].queryset = Storage.objects.filter(user=user, file_path__iregex=r'\.(obj|stl|step|3mf)$')
......
import os
from django.contrib.auth.models import User
from django.db import models
import threading
import time
from mainapp.utils import upload_file_and_add_task
class Order(models.Model):
order_datetime = models.DateTimeField(auto_now_add=True) # Дата и время создания заказа
......@@ -17,7 +19,7 @@ class EditRequest(models.Model):
req_datetime = models.DateTimeField(auto_now_add=True) # Дата и время создания заказа
user = models.ForeignKey(User, on_delete=models.CASCADE) # Связь с пользователем
req_parameters = models.TextField(default='no parameters') # Параметры заказа
file_path = models.CharField(max_length=255, blank=True, null=True) # Путь к файлу
file_path = models.CharField(max_length=255, blank=True, null=True) # Путь к файлу, отправлен пользователем
req_state = models.CharField(
max_length=50,
default='in_progress',
......@@ -40,10 +42,34 @@ class EditRequest(models.Model):
# Если это новый объект, запускаем фоновую задачу
if is_new:
threading.Thread(target=self.send_request_to_server, args=(), daemon=True).start()
# pass
def send_request_to_server(self):
# Заглушка для отправки данных на сервер
print(f"Начало отправки данных для заявки {self.id}")
print('args: ', "109.71.247.8",
"root",
"s7+DMtcoXC5prR",
self.file_path,
f'DATA_FROM_MAIN_SERVER/{self.user.username}',
self.file_path,
self.req_parameters,
"queue_scripts/venv" )
upload_file_and_add_task(
server_ip="109.71.247.8",
username="root",
password="s7+DMtcoXC5prR",
local_file_path=self.file_path,
remote_dir=f'DATA_FROM_MAIN_SERVER/{self.user.username}',
remote_file_name=os.path.basename(self.file_path),
params=self.req_parameters,
venv_path="queue_scripts/venv", # Путь к виртуальному окружению на внешнем сервере
req_id=self.id
)
time.sleep(5) # Симуляция задержки
print(f"Данные для заявки {self.id} отправлены на сервер.")
......
......@@ -3,11 +3,245 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Создать новую 3D модель</title>
<title>MOVERE | Новая 3D модель</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;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: #121212; /* Цвет в тон страницы */
padding: 30px 20px;
position: fixed;
top: 0;
z-index: 10;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
.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", 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 .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: "Roboto", 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%;
}
.navbar .btns_in_nav {
display: flex;
margin-right: 10%;
}
h1 {
font-family: 'Mulish', Arial, sans-serif;
align-self: flex-start;
/* margin-left: 10%; Сдвиг текста "3D LAB" влево */
}
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;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
flex: 1; /* Занимает оставшееся пространство между навбаром и футером */
width: 80%; /* Ширина контента */
max-width: 1200px;
margin: 15% auto; /* Центрирование контента */
padding-bottom: 20px; /* Отступ от последнего элемента до футера */
padding-top: 15%;
font-family: 'Mulish', Arial, sans-serif;
}
.footer {
width: 100%; /* Футер растягивается на всю ширину */
text-align: center;
/* padding: 10px 20px; Внутренние отступы */
background-color: #121212; /* Цвет фона футера */
color: #888; /* Цвет текста */
font-size: 12px;
margin-top: auto; /* Футер перемещается в самый низ */
margin-bottom: 20px;
}
/* .footer a {
color: #888;
text-decoration: none;
}
.footer a:hover {
color: #FFFFFF;
} */
.card {
background-color: #1E1E1E; /* Фон карточки */
border-radius: 10px; /* Скругленные углы */
padding: 20px; /* Внутренние отступы */
margin-bottom: 20px; /* Отступ между карточками */
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2); /* Легкая тень */
}
.card label {
font-family: 'Mulish', Arial, sans-serif;
font-size: 16px;
color: #FFFFFF; /* Цвет текста */
display: block;
margin-bottom: 10px; /* Отступ от текста до поля */
}
.card input,
/* .card textarea, */
.card select {
width: 100%; /* Растянуть поле на всю ширину карточки */
padding: 10px;
border-radius: 5px;
border: 1px solid #333333; /* Тонкая рамка */
background-color: #121212; /* Фон поля */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px;
}
.card input[type="radio"],
.card input[type="checkbox"] {
width: auto; /* Убираем ширину для радио и чекбоксов */
}
.card legend {
font-size: 16px;
color: #FFFFFF;
margin-bottom: 10px;
font-family: 'Mulish', sans-serif;
}
.card textarea {
width: 98%; /* Заполнение карточки по ширине */
height: 120px; /* Фиксированная высота */
margin: 0 auto; /* Центрирование по горизонтали */
display: block; /* Убирает лишнее пространство вокруг */
padding: 10px;
border-radius: 5px; /* Скругленные углы */
border: 1px solid #333333; /* Рамка */
background-color: #121212; /* Фон */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px; /* Размер текста */
resize: none; /* Запрещаем изменение размера */
}
.card button[type="submit"] {
width: 100%;
padding: 10px;
border: none;
border-radius: 20px;
background-color: #8d53ff;
color: white;
font-size: 16px;
cursor: pointer;
font-family: 'Mulish', sans-serif;
transition: transform 0.2s, background-color 0.2s; /* Анимация */
}
.card button[type="submit"]:hover {
background-color: #9e6dff; /* Легкое осветление */
transform: scale(1.01); /* Увеличение при наведении */
}
.card button[type="submit"]:active {
background-color: #9e6dff; /* Еще большее осветление */
transform: scale(1.01); /* Увеличение при клике */
}
.hidden { display: none; }
</style>
<script>
function validateFileInput(event) {
const fileInput = event.target; // Получаем поле ввода файла
const file = fileInput.files[0]; // Берем первый выбранный файл
if (file) {
const fileName = file.name.toLowerCase(); // Имя файла в нижнем регистре
// Допустимые расширения
const allowedExtensions = ['.jpg', '.jpeg', '.png'];
// Проверка, заканчивается ли имя файла на одно из допустимых расширений
const isValidExtension = allowedExtensions.some(extension => fileName.endsWith(extension));
if (!isValidExtension) {
alert('Допустимы только файлы с расширениями: .jpg, .jpeg, .png !');
fileInput.value = ''; // Очищаем поле
}
}
}
function toggleFields() {
const choice = document.querySelector('input[name="file_choice"]:checked').value;
document.getElementById('storage_fields').style.display = (choice === 'storage') ? 'block' : 'none';
......@@ -23,43 +257,79 @@
</script>
</head>
<body>
<h1>Создать новую 3D модель</h1>
<button onclick="location.href='{% url 'home' %}'">Домой</button>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
<label for="id_req_parameters">Параметры заказа:</label>
<textarea name="req_parameters" cols="40" rows="10" required="" id="id_req_parameters"></textarea>
</p>
<p>
<label>Выбор файла:</label>
<div id="file_choice">
<label for="id_file_choice_0">
<input type="radio" name="file_choice" value="storage" required="" id="id_file_choice_0">
Загрузить из хранилища
</label>
<label for="id_file_choice_1">
<input type="radio" name="file_choice" value="upload" required="" id="id_file_choice_1">
Загрузить файл вручную
</label>
<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="container">
<h1>НОВАЯ 3D МОДЕЛЬ</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<!-- <p>
<label for="id_req_parameters">Параметры заказа:</label>
<textarea name="req_parameters" cols="40" rows="10" required="" id="id_req_parameters"></textarea> -->
<!-- </p> -->
<div class="card">
<label for="id_req_parameters">Комментарии к модели</label>
<textarea name="req_parameters" id="id_req_parameters" placeholder="Введите текст..."></textarea>
</div>
<div class="card">
<label>Выбор файла:</label>
<div id="file_choice">
{{ form.file_choice }}
</div>
</div>
<!-- Поле выбора из хранилища -->
<div class="card hidden" id="storage_fields">
<legend>Выберите файл из хранилища</legend>
{{ form.storage_item }}
</div>
<!-- Поле загрузки файла -->
<div class="card hidden" id="upload_fields">
<legend>Или загрузите файл</legend>
<!-- {{ form.upload_file }} -->
<input type="file" id="upload_file" name="upload_file" onchange="validateFileInput(event)" accept=".jpg,.jpeg,.png">
</div>
<!-- <fieldset id="storage_fields" class="hidden">
<legend>Выберите файл из хранилища</legend>
{{ form.storage_item }}
</fieldset>
<fieldset id="upload_fields" class="hidden">
<legend>Или загрузите файл</legend>
{{ form.upload_file }}
</fieldset> -->
<div class="card">
<button type="submit">
Создать 3D модель
</button>
</div>
</p>
</form>
<fieldset id="storage_fields" class="hidden">
<legend>Выберите файл из хранилища</legend>
{{ form.storage_item }}
</fieldset>
<fieldset id="upload_fields" class="hidden">
<legend>Или загрузите файл</legend>
{{ form.upload_file }}
</fieldset>
</div>
<button type="submit">Создать 3D модель</button>
</form>
<a href="{% url 'view_editrequests' %}">Назад к списку заказов</a>
<div class="footer">(C) MOVERELAB</div>
</body>
</html>
......@@ -3,11 +3,245 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Создать новый заказ</title>
<title>MOVERE | Новая Заявка</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;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: #121212; /* Цвет в тон страницы */
padding: 30px 20px;
position: fixed;
top: 0;
z-index: 10;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
.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", 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 .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%;
}
/* .navbar .btns_in_nav {
display: flex;
margin-right: 10%;
} */
h1 {
font-family: 'Mulish', Arial, sans-serif;
align-self: flex-start;
/* margin-left: 10%; Сдвиг текста "3D LAB" влево */
}
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;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
flex: 1; /* Занимает оставшееся пространство между навбаром и футером */
width: 80%; /* Ширина контента */
max-width: 1200px;
margin: 15% auto; /* Центрирование контента */
padding-bottom: 20px; /* Отступ от последнего элемента до футера */
padding-top: 50%;
}
.footer {
width: 100%; /* Футер растягивается на всю ширину */
text-align: center;
/* padding: 10px 20px; Внутренние отступы */
background-color: #121212; /* Цвет фона футера */
color: #888; /* Цвет текста */
font-size: 12px;
margin-top: auto; /* Футер перемещается в самый низ */
margin-bottom: 20px;
}
/* .footer a {
color: #888;
text-decoration: none;
}
.footer a:hover {
color: #FFFFFF;
} */
.card {
background-color: #1E1E1E; /* Фон карточки */
border-radius: 10px; /* Скругленные углы */
padding: 20px; /* Внутренние отступы */
margin-bottom: 20px; /* Отступ между карточками */
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2); /* Легкая тень */
}
.card label {
font-family: 'Mulish', Arial, sans-serif;
font-size: 16px;
color: #FFFFFF; /* Цвет текста */
display: block;
margin-bottom: 10px; /* Отступ от текста до поля */
}
.card input,
/* .card textarea, */
.card select {
width: 100%; /* Растянуть поле на всю ширину карточки */
padding: 10px;
border-radius: 5px;
border: 1px solid #333333; /* Тонкая рамка */
background-color: #121212; /* Фон поля */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px;
}
.card input[type="radio"],
.card input[type="checkbox"] {
width: auto; /* Убираем ширину для радио и чекбоксов */
}
.card legend {
font-family: 'Mulish', sans-serif;
font-size: 16px;
color: #FFFFFF;
margin-bottom: 10px;
}
.card textarea {
width: 98%; /* Заполнение карточки по ширине */
height: 120px; /* Фиксированная высота */
margin: 0 auto; /* Центрирование по горизонтали */
display: block; /* Убирает лишнее пространство вокруг */
padding: 10px;
border-radius: 5px; /* Скругленные углы */
border: 1px solid #333333; /* Рамка */
background-color: #121212; /* Фон */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px; /* Размер текста */
resize: none; /* Запрещаем изменение размера */
}
.card button[type="submit"] {
width: 100%;
padding: 10px;
border: none;
border-radius: 20px;
background-color: #8d53ff;
color: white;
font-size: 16px;
cursor: pointer;
font-family: 'Mulish', sans-serif;
transition: transform 0.2s, background-color 0.2s; /* Анимация */
}
.card button[type="submit"]:hover {
background-color: #9e6dff; /* Легкое осветление */
transform: scale(1.01); /* Увеличение при наведении */
}
.card button[type="submit"]:active {
background-color: #9e6dff; /* Еще большее осветление */
transform: scale(1.01); /* Увеличение при клике */
}
.hidden { display: none; }
</style>
<script>
function validateFileInput(event) {
const fileInput = event.target; // Получаем поле ввода файла
const file = fileInput.files[0]; // Берем первый выбранный файл
if (file) {
const fileName = file.name.toLowerCase(); // Имя файла в нижнем регистре
// Допустимые расширения
const allowedExtensions = ['.obj', '.stl', '.step', '.3mf'];
// Проверка, заканчивается ли имя файла на одно из допустимых расширений
const isValidExtension = allowedExtensions.some(extension => fileName.endsWith(extension));
if (!isValidExtension) {
alert('Допустимы только файлы с расширениями: .obj, .stl, .step, .3mf!');
fileInput.value = ''; // Очищаем поле
}
}
}
function toggleFields() {
const choice = document.querySelector('input[name="file_choice"]:checked').value;
document.getElementById('storage_fields').style.display = (choice === 'storage') ? 'block' : 'none';
......@@ -23,43 +257,84 @@
</script>
</head>
<body>
<h1>Создать новый заказ</h1>
<button onclick="location.href='{% url 'home' %}'">Домой</button>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<p>
<label for="id_order_parameters">Параметры заказа:</label>
<textarea name="order_parameters" cols="40" rows="10" required="" id="id_order_parameters"></textarea>
</p>
<p>
<label>Выбор файла:</label>
<div id="file_choice">
<label for="id_file_choice_0">
<input type="radio" name="file_choice" value="storage" required="" id="id_file_choice_0">
Загрузить из хранилища
</label>
<label for="id_file_choice_1">
<input type="radio" name="file_choice" value="upload" required="" id="id_file_choice_1">
Загрузить файл вручную
</label>
<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="container">
<h1>НОВАЯ ЗАЯВКА</h1>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<!-- Карточка для должности -->
<div class="card">
<label>Ваша должность:</label>
{{ form.position }}
</div>
<!-- Карточка для цели 3D-печати -->
<div class="card">
<label>Цель 3D-печати:</label>
{{ form.purpose }}
</div>
<!-- Карточка для дополнительной цели -->
<div class="card">
<label for="id_additional_purpose">Дополнительно можно указать цель 3D-печати:</label>
<textarea name="additional_purpose" id="id_additional_purpose" placeholder="Введите текст..."></textarea>
</div>
<!-- Карточка для выбора материала -->
<div class="card">
<label>Выберите материал:</label>
{{ form.material }}
</div>
</p>
<fieldset id="storage_fields" class="hidden">
<legend>Выберите файл из хранилища</legend>
{{ form.storage_item }}
</fieldset>
<!-- Карточка для выбора файла -->
<div class="card">
<label>Выбор файла:</label>
<div id="file_choice">
{{ form.file_choice }}
</div>
</div>
<!-- Поле выбора из хранилища -->
<div class="card hidden" id="storage_fields">
<legend>Выберите файл из хранилища</legend>
{{ form.storage_item }}
</div>
<!-- Поле загрузки файла -->
<div class="card hidden" id="upload_fields">
<legend>Или загрузите файл</legend>
<!-- {{ form.upload_file }} -->
<input type="file" id="upload_file" name="upload_file" onchange="validateFileInput(event)" accept=".obj,.stl,.step,.3mf">
</div>
<!-- Кнопка отправки -->
<div class="card">
<button type="submit">
Создать заявку
</button>
</div>
</form>
</div>
<fieldset id="upload_fields" class="hidden">
<legend>Или загрузите файл</legend>
{{ form.upload_file }}
</fieldset>
<!-- <a href="{% url 'view_orders' %}">Назад к списку заявок</a> -->
<div class="footer">(C) MOVERELAB</div>
<button type="submit">Создать заказ</button>
</form>
<a href="{% url 'view_orders' %}">Назад к списку заказов</a>
</body>
</html>
<!--
......@@ -8,48 +7,16 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Home</title>
{% load static %} Загрузка тега static
<link rel="stylesheet" href="{% static 'mainapp/css/styles.css' %}">
</head>
<body>
<h1>Добро пожаловать!</h1>
{% if is_manager %}
<button onclick="location.href='{% url 'manager_dashboard' %}'">Панель менеджера</button>
{% else %}
<button onclick="location.href='{% url 'view_orders' %}'">Заказы</button>
<button onclick="location.href='{% url 'storage' %}'">Хранилище</button>
<button onclick="location.href='{% url 'view_archive' %}'">Архив</button>
<button onclick="location.href='{% url 'create3d' %}'">Создать 3D!</button>
<button onclick="location.href='{% url 'home' %}'">Домой</button>
{% endif %}
<button onclick="location.href='{% url 'profile' %}'">Профиль</button>
</body>
</html>
-->
<!DOCTYPE html>
<html lang="en">
<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');
a {
text-decoration: none;
}
.navbar {
display: flex;
justify-content: space-between;
......@@ -66,12 +33,14 @@
.navbar .logo {
display: flex; /* Располагает элементы (логотип и текст) в одну строку */
align-items: center; /* Вертикальное выравнивание элементов по центру */
margin-left: 100px;
margin-top: 20px;
/* margin-left: 30px; */
}
.navbar .logo img {
height: 60px; /* Размер логотипа */
margin-right: 10px; /* Отступ между логотипом и текстом */
margin-right: 15px; /* Отступ между логотипом и текстом */
}
.navbar .logo span {
......@@ -81,12 +50,13 @@
white-space: nowrap; /* Запрещает перенос текста на новую строку */
}
.navbar .profile-btn {
background-color: transparent; /* Прозрачный фон */
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; /* Скругленные углы */
......@@ -97,9 +67,35 @@
}
.navbar .profile-btn:hover {
background-color: rgba(255, 255, 255, 0.2); /* Полупрозрачный белый при наведении */
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%;
}
body {
margin: 0;
font-family: "Krona One", serif;
......@@ -123,35 +119,47 @@
display: flex;
gap: 20px;
}
.card {
width: 300px;
height: 400px;
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;
}
position: relative;
width: 300px;
height: 400px;
background-color: #3A3A3A;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
overflow: hidden;
cursor: pointer;
transition: transform 0.3s;
}
.card:hover {
transform: scale(1.05);
}
.card svg {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 80%;
}
.card svg .color-change {
fill: #ffffff; /* Начальный цвет */
transition: fill 0.2s ease; /* Плавное изменение цвета */
}
.card svg .no-change {
fill: none; /* Оставляем как есть */
}
.card:hover svg .color-change {
fill: #8d53ff; /* Цвет при наведении */
}
.card video {
width: 100%;
......@@ -170,11 +178,11 @@
.card .label {
position: relative;
font-family: 'Roboto', Arial, sans-serif;
font-family: 'Mulish', Arial, sans-serif;
color: #FFFFFF;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
font-size: 20px;
font-weight: bold;
margin-bottom: 5px;
text-align: center;
......@@ -182,12 +190,12 @@
}
.card .description {
font-family: 'Roboto', Arial, sans-serif;
font-family: 'Mulish', Arial, sans-serif;
position: relative;
color: #FFFFFF;
color: #c1c1c1;
padding: 5px 10px;
border-radius: 5px;
font-size: 12px;
font-size: 16px;
text-align: center;
margin-bottom: 10px;
z-index: 3;
......@@ -235,38 +243,59 @@
<div class="container">
{% if is_manager %}
<button onclick="location.href='{% url 'manager_dashboard' %}'">Панель менеджера</button>
<div class="card">
<a href="{% url 'manager_dashboard' %}" class="card">
<svg width="250px" height="250px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<path class="color-change" d="M15.2 6l-1.1-0.2c-0.1-0.2-0.1-0.4-0.2-0.6l0.6-0.9 0.5-0.7-2.6-2.6-0.7 0.5-0.9 0.6c-0.2-0.1-0.4-0.1-0.6-0.2l-0.2-1.1-0.2-0.8h-3.6l-0.2 0.8-0.2 1.1c-0.2 0.1-0.4 0.1-0.6 0.2l-0.9-0.6-0.7-0.4-2.5 2.5 0.5 0.7 0.6 0.9c-0.2 0.2-0.2 0.4-0.3 0.6l-1.1 0.2-0.8 0.2v3.6l0.8 0.2 1.1 0.2c0.1 0.2 0.1 0.4 0.2 0.6l-0.6 0.9-0.5 0.7 2.6 2.6 0.7-0.5 0.9-0.6c0.2 0.1 0.4 0.1 0.6 0.2l0.2 1.1 0.2 0.8h3.6l0.2-0.8 0.2-1.1c0.2-0.1 0.4-0.1 0.6-0.2l0.9 0.6 0.7 0.5 2.6-2.6-0.5-0.7-0.6-0.9c0.1-0.2 0.2-0.4 0.2-0.6l1.1-0.2 0.8-0.2v-3.6l-0.8-0.2zM15 9l-1.7 0.3c-0.1 0.5-0.3 1-0.6 1.5l0.9 1.4-1.4 1.4-1.4-0.9c-0.5 0.3-1 0.5-1.5 0.6l-0.3 1.7h-2l-0.3-1.7c-0.5-0.1-1-0.3-1.5-0.6l-1.4 0.9-1.4-1.4 0.9-1.4c-0.3-0.5-0.5-1-0.6-1.5l-1.7-0.3v-2l1.7-0.3c0.1-0.5 0.3-1 0.6-1.5l-1-1.4 1.4-1.4 1.4 0.9c0.5-0.3 1-0.5 1.5-0.6l0.4-1.7h2l0.3 1.7c0.5 0.1 1 0.3 1.5 0.6l1.4-0.9 1.4 1.4-0.9 1.4c0.3 0.5 0.5 1 0.6 1.5l1.7 0.3v2z"></path>
<path class="color-change" d="M8 4.5c-1.9 0-3.5 1.6-3.5 3.5s1.6 3.5 3.5 3.5 3.5-1.6 3.5-3.5c0-1.9-1.6-3.5-3.5-3.5zM8 10.5c-1.4 0-2.5-1.1-2.5-2.5s1.1-2.5 2.5-2.5 2.5 1.1 2.5 2.5c0 1.4-1.1 2.5-2.5 2.5z"></path>
</svg>
<div class="label">ПАНЕЛЬ МЕНЕДЖЕРА</div>
<div class="description">Все заявки на 3D печать и управление ими </div>
</a>
</div>
{% else %}
<a href="{% url 'create_order' %}" class="card">
<img src="{% static 'mainapp/images/tunder.png' %}" alt="Preview">
<video src="{% static 'mainapp/images/purple_tunder.mp4' %}" muted data-playing="false"></video>
<div class="label">НАПЕЧАТАТЬ</div>
<div class="description">Отправить заявку на печать на 3D принтере</div>
</a>
<div class="card">
<a href="{% url 'create_order' %}" class="card">
<svg width="250px" height="250px" viewBox="0 0 256 256" id="Flat" xmlns="http://www.w3.org/2000/svg">
<path class="color-change" d="M226.40723,72.72314c-.0127-.02368-.01856-.04907-.03223-.07251-.00391-.00732-.00977-.01293-.01416-.02026a11.99344,11.99344,0,0,0-4.47754-4.41064l-88-49.5a12.07124,12.07124,0,0,0-11.7666,0l-88,49.5a11.99326,11.99326,0,0,0-4.48389,4.42334c-.00586.01025-.01367.01782-.01953.02783-.01416.02588-.02051.05347-.03418.07959A11.98438,11.98438,0,0,0,28,78.67871v98.64258a12.01534,12.01534,0,0,0,6.1167,10.459l88.00049,49.5a11.97922,11.97922,0,0,0,5.606,1.51343c.085.0061.16553.02686.252.02759h.03613c.1001,0,.19434-.022.293-.0293a11.98372,11.98372,0,0,0,5.5791-1.51172l88-49.5A12.01534,12.01534,0,0,0,228,177.32129V78.67871A11.98919,11.98919,0,0,0,226.40723,72.72314ZM126.03906,25.69238a4.02317,4.02317,0,0,1,3.92188,0l85.91113,48.32471-86.94238,49.39355L40.18945,73.98291Zm-88,155.11524A4.00514,4.00514,0,0,1,36,177.32129V80.80664l88.92822,49.53223-.86865,98.85547Zm179.92188,0-85.90039,48.31909.86816-98.78711L220,80.87305v96.44824A4.00514,4.00514,0,0,1,217.96094,180.80762Z"/>
</svg>
<div class="label">НАПЕЧАТАТЬ</div>
<div class="description">Отправить заявку на печать на 3D принтере</div>
</a>
</div>
<div class="card">
<a href="{% url 'create3d' %}" class="card">
<!-- <img src="{% static 'mainapp/images/store.png' %}" alt="Preview"> -->
<!-- <video src="{% static 'mainapp/images/store.mp4' %}" muted data-playing="false"></video> -->
<svg width="250px" height="250px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="color-change" fill-rule="evenodd" clip-rule="evenodd" d="M12.5 6.00004C12.5 5.31322 12.2163 4.67366 11.7431 4.25578C11.2602 3.82926 10.5847 3.64296 9.87881 3.88387C9.12643 4.14065 8.27977 4.57906 7.61885 5.33233C7.12428 5.89599 6.74984 6.61798 6.58793 7.53045C5.74098 7.65664 5.00843 8.16524 4.47868 8.87157C3.86487 9.68999 3.5 10.7977 3.5 12C3.5 13.2023 3.86487 14.31 4.47868 15.1284C4.99276 15.8139 5.69782 16.3131 6.51308 16.4574C6.50452 16.494 6.5 16.5322 6.5 16.5715C6.5 17.7099 6.9821 18.5424 7.66175 19.1267C8.32466 19.6965 9.1633 20.0221 9.89841 20.212C11.366 20.5912 12.5 19.3418 12.5 18V6.00004ZM7.48691 16.4573C7.49547 16.494 7.5 16.5322 7.5 16.5715C7.5 17.3882 7.83089 17.9534 8.31361 18.3683C8.81308 18.7977 9.48618 19.0727 10.1486 19.2438C10.8199 19.4173 11.5 18.8674 11.5 18V6.00004C11.5 5.58229 11.3265 5.22198 11.0812 5.00533C10.8456 4.79731 10.5413 4.71442 10.2018 4.83027C9.55295 5.05172 8.87946 5.41182 8.37053 5.99186C7.87016 6.56214 7.5 7.37709 7.5 8.57147C7.5 8.84761 7.27614 9.07147 7 9.07147C6.72388 9.07147 6.50003 8.84764 6.5 8.57152C6.04804 8.70228 5.62513 9.00964 5.27868 9.47157C4.80671 10.1009 4.5 10.9932 4.5 12C4.5 13.0068 4.80671 13.8991 5.27868 14.5284C5.75054 15.1576 6.36424 15.5 7 15.5C7.59053 15.5 8.15996 15.2055 8.61676 14.6603C8.79412 14.4487 9.10948 14.4209 9.32114 14.5982C9.53279 14.7756 9.5606 15.091 9.38324 15.3026C8.88463 15.8976 8.23125 16.3255 7.48691 16.4573Z"/>
<path class="color-change" fill-rule="evenodd" clip-rule="evenodd" d="M16.55 11.5H14.5C14.2239 11.5 14 11.7239 14 12C14 12.2761 14.2239 12.5 14.5 12.5H16.55C16.7816 13.6411 17.7905 14.5 19 14.5C20.3807 14.5 21.5 13.3807 21.5 12C21.5 10.6193 20.3807 9.5 19 9.5C17.7905 9.5 16.7816 10.3589 16.55 11.5ZM17.5 11.9963C17.502 11.1695 18.1728 10.5 19 10.5C19.8284 10.5 20.5 11.1716 20.5 12C20.5 12.8284 19.8284 13.5 19 13.5C18.1728 13.5 17.502 12.8305 17.5 12.0037L17.5 12L17.5 11.9963Z"/>
<path class="color-change" fill-rule="evenodd" clip-rule="evenodd" d="M17.3385 16.132C17.7802 15.7388 18.3622 15.5 19 15.5C20.3807 15.5 21.5 16.6193 21.5 18C21.5 19.3807 20.3807 20.5 19 20.5C17.6193 20.5 16.5 19.3807 16.5 18C16.5 17.6162 16.5865 17.2527 16.741 16.9277C16.7227 16.9166 16.7049 16.9042 16.6877 16.8904L14.1877 14.8904C13.972 14.7179 13.9371 14.4033 14.1096 14.1877C14.2821 13.972 14.5967 13.9371 14.8124 14.1096L17.3124 16.1096C17.3214 16.1168 17.3301 16.1243 17.3385 16.132ZM19 16.5C18.1716 16.5 17.5 17.1716 17.5 18C17.5 18.8284 18.1716 19.5 19 19.5C19.8284 19.5 20.5 18.8284 20.5 18C20.5 17.1716 19.8284 16.5 19 16.5Z" />
<path class="color-change" fill-rule="evenodd" clip-rule="evenodd" d="M19 3.5C17.6193 3.5 16.5 4.61929 16.5 6C16.5 6.38376 16.5865 6.74733 16.741 7.07228C16.7227 7.08341 16.7049 7.09584 16.6877 7.10958L14.1877 9.10958C13.972 9.28209 13.9371 9.59674 14.1096 9.81237C14.2821 10.028 14.5967 10.063 14.8124 9.89045L17.3124 7.89045C17.3214 7.88323 17.3301 7.87575 17.3385 7.86804C17.7802 8.26116 18.3622 8.5 19 8.5C20.3807 8.5 21.5 7.38071 21.5 6C21.5 4.61929 20.3807 3.5 19 3.5ZM17.5 6C17.5 5.17157 18.1716 4.5 19 4.5C19.8284 4.5 20.5 5.17157 20.5 6C20.5 6.82843 19.8284 7.5 19 7.5C18.1716 7.5 17.5 6.82843 17.5 6Z" />
</svg>
<div class="label">СОЗДАТЬ</div>
<div class="description">Сгенерировать 3D модель при помощи ИИ</div>
</a>
</div>
<div class="card">
<a href="{% url 'redactor' %}" class="card">
<!-- <img src="{% static 'mainapp/images/store.png' %}" alt="Preview"> -->
<!-- <video src="{% static 'mainapp/images/store.mp4' %}" muted data-playing="false"></video> -->
<svg width="250px" height="250px" viewBox="0 0 1024 1024" xmlns="http://www.w3.org/2000/svg">
<path class="color-change" d="M832 512a32 32 0 1 1 64 0v352a32 32 0 0 1-32 32H160a32 32 0 0 1-32-32V160a32 32 0 0 1 32-32h352a32 32 0 0 1 0 64H192v640h640V512z"/>
<path class="color-change" d="m469.952 554.24 52.8-7.552L847.104 222.4a32 32 0 1 0-45.248-45.248L477.44 501.44l-7.552 52.8zm422.4-422.4a96 96 0 0 1 0 135.808l-331.84 331.84a32 32 0 0 1-18.112 9.088L436.8 623.68a32 32 0 0 1-36.224-36.224l15.104-105.6a32 32 0 0 1 9.024-18.112l331.904-331.84a96 96 0 0 1 135.744 0z"/>
</svg>
<div class="label">РЕДАКТИРОВАТЬ</div>
<div class="description">Редактировать 3D модель прямо в браузере</div>
</a>
</div>
<div class="card">
<a href="{% url 'view_story_and_files' %}" class="card">
<img src="{% static 'mainapp/images/store.png' %}" alt="Preview">
<video src="{% static 'mainapp/images/store.mp4' %}" muted data-playing="false"></video>
<svg width="250px" height="250px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path class="color-change" d="M9.5 2h-6A1.502 1.502 0 0 0 2 3.5v6A1.502 1.502 0 0 0 3.5 11h6A1.502 1.502 0 0 0 11 9.5v-6A1.502 1.502 0 0 0 9.5 2zm.5 7.5a.501.501 0 0 1-.5.5h-6a.501.501 0 0 1-.5-.5v-6a.501.501 0 0 1 .5-.5h6a.501.501 0 0 1 .5.5zM20.5 2h-6A1.502 1.502 0 0 0 13 3.5v6a1.502 1.502 0 0 0 1.5 1.5h6A1.502 1.502 0 0 0 22 9.5v-6A1.502 1.502 0 0 0 20.5 2zm.5 7.5a.501.501 0 0 1-.5.5h-6a.501.501 0 0 1-.5-.5v-6a.501.501 0 0 1 .5-.5h6a.501.501 0 0 1 .5.5zM9.5 13h-6A1.502 1.502 0 0 0 2 14.5v6A1.502 1.502 0 0 0 3.5 22h6a1.502 1.502 0 0 0 1.5-1.5v-6A1.502 1.502 0 0 0 9.5 13zm.5 7.5a.501.501 0 0 1-.5.5h-6a.501.501 0 0 1-.5-.5v-6a.501.501 0 0 1 .5-.5h6a.501.501 0 0 1 .5.5zM20.5 13h-6a1.502 1.502 0 0 0-1.5 1.5v6a1.502 1.502 0 0 0 1.5 1.5h6a1.502 1.502 0 0 0 1.5-1.5v-6a1.502 1.502 0 0 0-1.5-1.5zm.5 7.5a.501.501 0 0 1-.5.5h-6a.501.501 0 0 1-.5-.5v-6a.501.501 0 0 1 .5-.5h6a.501.501 0 0 1 .5.5z"/>
<path class="no-change" fill="none" d="M0 0h24v24H0z"/>
</svg>
<div class="label">ЗАКАЗЫ И ФАЙЛЫ</div>
<div class="description">Список заявок, запросов, файлов</div>
<div class="description">Список заявок, запросов, хранилище и архив </div>
</a>
</div>
......
......@@ -5,28 +5,416 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Панель менеджера</title>
<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: "Mulish", sans-serif;
font-weight: 400;
font-style: normal;
background-color: #121212;
color: #FFFFFF;
display: flex;
flex-direction: column;
align-items: center;
height: 100vh;
word-break: break-all;
}
.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;
word-break: normal;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
th, td {
border: 1px solid #ddd;
padding: 8px;
white-space: nowrap;
.navbar .logo {
display: flex; /* Располагает элементы (логотип и текст) в одну строку */
align-items: center; /* Вертикальное выравнивание элементов по центру */
margin-left: 100px;
margin-top: 20px;
/* margin-left: 30px; */
}
th {
background-color: #f2f2f2;
.navbar .logo img {
height: 60px; /* Размер логотипа */
margin-right: 15px; /* Отступ между логотипом и текстом */
}
th.sortable:hover {
.navbar .logo span {
font-family: "Krona One", serif;
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", 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 .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: "Mulish", sans-serif;
/* font-family: "Krona One", serif; */
text-align: left;
margin-top: 10%;
padding: 0 5%;
}
.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: 'Roboto', 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: 'Roboto', 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); /* Черный фон с небольшой прозрачностью */
}
.modal-content {
background-color: #ad8181;
margin: 15% auto; /* 15% сверху и по центру по горизонтали */
padding: 20px;
border: 1px solid #888;
width: 50%; /* Можете изменить ширину */
}
.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: collapse;
border-spacing: 0;
margin: 10px auto;
border-radius: 10px;
overflow: hidden;
background-color: #1e1e1e;
}
th, td {
width: 20%; /* Устанавливаем одинаковую ширину для всех колонок */
border-bottom: 1px solid #616161;
border-right: 0.5px solid #7b7b7b;
padding: 12px 15px;
color: #f0f0f0;
vertical-align: top; /* Содержимое по верхнему краю */
}
th.sortable a {
text-decoration: none; /* Отменяем подчеркивание ссылок */
color: white; /* Цвет текста ссылок */
}
th:nth-child(1) { width: 5%; }
th:nth-child(2) { width: 12%; }
th:nth-child(3) { width: 15%; }
th:nth-child(4) { width: 19%; }
th:nth-child(5) { width: 19%; }
th:nth-child(6) { width: 10%; }
th:nth-child(7) { width: 10%; }
th:last-child, td:last-child {
border-right: none; /* Убирает правую границу у последней колонки */
width: 20%;
}
th {
background-color: #292929; /* Более темный фон для заголовков */
color: #ffffff; /* Белый цвет текста для заголовков */
}
td {
vertical-align: top; /* Выравнивание содержимого ячейки по верху */
}
.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.5px;
color: white;
border-radius: 8px;
padding: 10px;
text-wrap: wrap;
}
/* .order-card {
margin: 10px;
padding: 10px;
border-radius: 8px;
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.5px;
color: white;
cursor: pointer;
} */
/* Стили для формы */
/* Стили для select элемента */
select {
width: 100%; /* ширина, соответствующая ширине формы */
padding: 8px; /* внутренний отступ */
/* margin-top: 10px; отступ сверху */
border: 1px solid #8d53ff; /* граница */
border-radius: 4px; /* скругленные углы */
display: block; /* блочное отображение */
font-family: "Mulish", sans-serif;
}
button {
background-color: #8d53ff; /* цвет фона */
width: 100%;
border: none; /* без рамки */
border-radius: 4px; /* скругленные углы */
color: white;
font-family: "Mulish", sans-serif;
}
.footer {
font-family: "Krona One", sans-serif;
width: 100%; /* Футер растягивается на всю ширину */
text-align: center;
/* padding: 10px 20px; Внутренние отступы */
background-color: #121212; /* Цвет фона футера */
color: #888; /* Цвет текста */
font-size: 12px;
margin-top: 20px; /* Футер перемещается в самый низ */
margin-bottom: 20px;
}
</style>
</head>
<body>
<h1>Панель менеджера</h1>
<h2>Все заказы</h2>
<button onclick="location.href='{% url 'home' %}'">Домой</button>
<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="storage_home_button" onclick="location.href='{% url 'profile' %}'">Профиль</button>
</div>
</div>
<div class = 'view_orders_h1'>
<h1>>>> СПИСОК ЗАКАЗОВ</h1>
</div>
<table>
<thead>
<tr>
......@@ -37,15 +425,22 @@
<th>Файлы</th>
<th class="sortable"><a href="?sort=order_state">Статус</a></th>
<th>Изменить статус</th>
</tr>
</thead>
<tbody>
{% for order in orders %}
<tr>
<td>{{ order.id }}</td>
<td>{{ order.order_datetime }}</td>
<td>{{ order.order_datetime|date:"Y-m-d" }}</td>
<td>{{ order.user.username }}</td>
<td>{{ order.order_parameters }}</td>
<td>
{% for key, value in order.parsed_params.items%}
<li><strong>{{key}}</strong> : {{value}}</span>
{% endfor %}
</td>
<td>
{% if order.file_basename %}
{{ order.file_basename }}
......@@ -53,7 +448,12 @@
Нет файлов
{% endif %}
</td>
<td>{{ order.order_state }}</td>
<td> {% if order.order_state == 'wait_confirmation' %}
awaiting
{% else %}
{{ order.order_state }}
{% endif %}
</td>
<td>
<form method="post" action="{% url 'manager_dashboard' %}">
{% csrf_token %}
......@@ -77,6 +477,7 @@
</tbody>
</table>
<a href="{% url 'home' %}">Назад на главную</a>
<div class="footer">(C) MOVERELAB</div>
</body>
</html>
......@@ -5,9 +5,178 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Object Viewer</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;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: #121212; /* Цвет в тон страницы */
padding: 30px 20px;
position: fixed;
top: 0;
z-index: 10;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
.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-family: "Krona One", serif;
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", 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 .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: "Roboto", 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%;
}
.navbar2 {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: transparent; /* Цвет в тон страницы */
padding: 30px 20px;
position: fixed;
top: 0;
z-index: 10;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
.navbar2 .logo {
display: flex; /* Располагает элементы (логотип и текст) в одну строку */
align-items: center; /* Вертикальное выравнивание элементов по центру */
margin-left: 100px;
margin-top: 20px;
/* margin-left: 30px; */
}
.navbar2 .logo img {
height: 60px; /* Размер логотипа */
margin-right: 15px; /* Отступ между логотипом и текстом */
}
.navbar2 .logo span {
font-family: "Krona One", serif;
font-size: 20px; /* Размер текста */
font-weight: bold;
color: #121212; /* Цвет текста */
white-space: nowrap; /* Запрещает перенос текста на новую строку */
}
.navbar2 .profile-btn {
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%; */
}
.navbar2 .profile-btn:hover {
background-color: rgb(58, 54, 54); /* Полупрозрачный белый при наведении */
transform: scale(1.1); /* Увеличение кнопки */
}
.navbar2 .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%; */
}
.navbar2 .storage_home_button:hover {
background-color: rgb(58, 54, 54); /* Полупрозрачный белый при наведении */
transform: scale(1.1); /* Увеличение кнопки */
}
.navbar2 .btns_in_nav {
display: flex;
margin-right: 10%;
}
body {
margin: 0;
font-family: Arial, sans-serif;
font-family: "Mulish", sans-serif;
display: flex;
justify-content: center;
align-items: center;
......@@ -47,7 +216,7 @@
}
label {
background-color: rgb(116, 12, 173);
background-color: #8d53ff;
color: white;
padding: 15px 30px;
font-size: 18px;
......@@ -58,7 +227,7 @@
}
label:hover {
background-color: rgb(100, 0, 182);
background-color: #9e6dff;
}
.info-text {
......@@ -70,9 +239,9 @@
#new-file-button {
position: absolute;
bottom: 20px;
right: 20px;
background-color: rgb(116, 12, 173);
bottom: 40px;
left: 100px;
background-color: #8d53ff;
color: white;
padding: 10px 20px;
border-radius: 20px;
......@@ -83,13 +252,13 @@
}
#new-file-button:hover {
background-color: rgb(100, 0, 182);
background-color: #9e6dff;
}
#scale-controls {
position: absolute;
top: 20px;
left: 20px;
top: 180px;
left: 100px;
z-index: 10;
background-color: rgba(255, 255, 255, 0.7);
padding: 10px;
......@@ -108,9 +277,9 @@
#export-button {
position: absolute;
top: 20px;
right: 20px;
background-color: rgb(116, 12, 173);
bottom: 40px;
right: 100px;
background-color: #8d53ff;
color: white;
padding: 10px 20px;
border-radius: 20px;
......@@ -121,43 +290,51 @@
}
#export-button:hover {
background-color: rgb(100, 0, 182);
background-color: #9e6dff;
}
.storage_home_button {
background-color: rgb(45, 42, 42); /* Фон кнопки прозрачный */
font-family: "Krona One", serif;
position: absolute;
border: none;
padding: 1px 1px; /* Отступы внутри кнопки */
top: 7%;
right: 3%;
width: 70px;
font-size: 13px;
font-weight: 700;
color: white; /* Цвет текста */
outline: none; /* Убирает контур при фокусе */
transition: background-color 0.3s;
border-radius: 12px; /* Закругленные углы таблицы */
height: 25px; /* Фиксированная высота */
}
.storage_home_button:hover {
font-family: "Krona One", serif;
background-color: rgb(58, 54, 54); /* Фон кнопки прозрачный */
}
</style>
</head>
<body>
<div class="navbar2">
<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 'profile' %}'">Профиль</button>
<button class="storage_home_button" onclick="location.href='{% url 'home' %}'">Домой</button>
</div>
</div>
<div id="upload-container">
<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 'profile' %}'">Профиль</button>
<button class="storage_home_button" onclick="location.href='{% url 'home' %}'">Домой</button>
</div>
</div>
<label for="upload">Upload 3D Object</label>
<input type="file" id="upload" accept=".stl,.obj">
<p class="info-text">Supported formats: STL, OBJ</p>
<button class="storage_home_button" onclick="location.href='{% url 'home' %}'">Домой</button>
</div>
</div>
<button id="new-file-button">Choose Another File</button>
......@@ -195,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) {
......@@ -303,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);
}
});
......
<h2>Хранилище</h2>
<a href="{% url 'upload_file' %}">Загрузить файл</a>
<button onclick="location.href='{% url 'home' %}'">Домой</button>
{% if items %}
<ul>
{% for item in items %}
<li>
<strong>{{ item.item_name }}</strong>: {{ item.description }} <br>
Дата добавления: {{ item.created_at }}
<a href="{% url 'download_item' item.id %}">Скачать</a>
<form action="{% url 'delete_item' item.id %}" method="POST" style="display:inline;">
{% csrf_token %}
<button type="submit" onclick="return confirm('Вы уверены, что хотите удалить этот элемент?');">Удалить</button>
</form>
</li>
{% endfor %}
</ul>
{% else %}
<p>У вас пока нет элементов в хранилище.</p>
{% endif %}
\ No newline at end of file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MOVERE | Хранилище</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');
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%;
background-color: #121212; /* Цвет в тон страницы */
padding: 30px 20px;
position: fixed;
top: 0;
z-index: 10;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
.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;
}
h2 {
font-size: 32px;
margin-top: 20px;
font-weight: bold;
color: rgb(255, 253, 253);
text-align: center;
}
.buttons-container {
display: flex;
justify-content: flex-start;
gap: 15px;
margin: 20px 0;
/* width: 25%; */
text-align: left;
}
.buttons-container a,
.buttons-container button {
text-decoration: none;
justify-content: flex-start;
padding: 10px 20px;
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%; */
}
.buttons-container a:hover,
.buttons-container button:hover {
background-color: rgb(58, 54, 54);
transform: scale(1.05);
}
ul {
list-style: none;
padding: 0;
width: 90%;
max-width: 800px;
margin: 0 auto;
font-family: "Mulish", serif;
}
li {
background-color: #1E1E1E;
border: 1px solid #333;
border-radius: 8px;
margin-bottom: 10px;
padding: 15px;
display: flex;
flex-direction: column;
gap: 10px;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.2);
font-family: "Mulish", serif;
}
li strong {
font-size: 18px;
color: #eeefee;
}
li span {
color: #ccc;
font-size: 14px;
}
.actions {
display: flex;
gap: 10px;
margin-top: 10px;
}
.actions a,
.actions button {
text-decoration: none;
background-color: #2196F3;
color: white;
padding: 8px 12px;
border: none;
border-radius: 5px;
font-size: 14px;
cursor: pointer;
transition: background-color 0.3s, transform 0.2s;
font-family: "Mulish", serif;
}
.actions a:hover {
background-color: #1B87D3;
}
.actions button {
background-color: #f44336;
}
.actions button:hover {
background-color: #D32F2F;
}
.no-items {
font-size: 18px;
color: #ccc;
text-align: center;
margin-top: 20px;
}
.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;
}
.footer {
width: 100%; /* Футер растягивается на всю ширину */
text-align: center;
/* padding: 10px 20px; Внутренние отступы */
background-color: #121212; /* Цвет фона футера */
color: #888; /* Цвет текста */
font-size: 12px;
margin-top: 60px; /* Футер перемещается в самый низ */
margin-bottom: 20px;
}
</style>
</head>
<body>
<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="buttons-container">
<a href="{% url 'upload_file' %}">+ Загрузить файл</a>
</div>
{% if items %}
<ul>
{% for item in items %}
<li>
<strong>{{ item.item_name }}</strong>
<span>{{ item.description }}</span>
<span>{{ item.basename_filepath }}</span>
<span>Дата добавления: {{ item.created_at|date:"Y-m-d" }}</span>
<div class="actions">
<a href="{% url 'download_item' item.id %}">Скачать</a>
<form action="{% url 'delete_item' item.id %}" method="POST" style="display:inline;">
{% csrf_token %}
<button type="submit" onclick="return confirm('Вы уверены, что хотите удалить этот элемент?');">Удалить</button>
</form>
</div>
</li>
{% endfor %}
</ul>
{% else %}
<p class="no-items">У вас пока нет элементов в хранилище.</p>
{% endif %}
<div class="footer">(C) MOVERELAB</div>
</body>
</html>
<h2>Загрузить файл</h2>
{% if error_message %}
<script type="text/javascript">
alert("{{ error_message }}");
</script>
{% endif %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Загрузить</button>
</form>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>MOVERE | Загрузить файл</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;
justify-content: space-between;
align-items: center;
width: 100%;
background-color: #121212; /* Цвет в тон страницы */
padding: 30px 20px;
position: fixed;
top: 0;
z-index: 10;
/* box-shadow: 0 2px 5px rgba(0, 0, 0, 0.5); */
}
.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", 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 .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%;
}
/* .navbar .btns_in_nav {
display: flex;
margin-right: 10%;
} */
h1 {
font-family: 'Mulish', Arial, sans-serif;
align-self: flex-start;
/* margin-left: 10%; Сдвиг текста "3D LAB" влево */
}
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;
justify-content: center;
height: 100vh;
}
.container {
display: flex;
flex-direction: column;
flex: 1; /* Занимает оставшееся пространство между навбаром и футером */
width: 80%; /* Ширина контента */
max-width: 1200px;
margin: 15% auto; /* Центрирование контента */
padding-bottom: 20px; /* Отступ от последнего элемента до футера */
padding-top: 20%;
}
.footer {
width: 100%; /* Футер растягивается на всю ширину */
text-align: center;
/* padding: 10px 20px; Внутренние отступы */
background-color: #121212; /* Цвет фона футера */
color: #888; /* Цвет текста */
font-size: 12px;
margin-top: auto; /* Футер перемещается в самый низ */
margin-bottom: 20px;
}
/* .footer a {
color: #888;
text-decoration: none;
}
.footer a:hover {
color: #FFFFFF;
} */
.card {
background-color: #1E1E1E; /* Фон карточки */
border-radius: 10px; /* Скругленные углы */
padding: 20px; /* Внутренние отступы */
margin-bottom: 20px; /* Отступ между карточками */
box-shadow: 0px 4px 6px rgba(0, 0, 0, 0.2); /* Легкая тень */
}
.card label {
font-family: 'Mulish', Arial, sans-serif;
font-size: 16px;
color: #FFFFFF; /* Цвет текста */
display: block;
margin-bottom: 10px; /* Отступ от текста до поля */
}
.card input,
/* .card textarea, */
.card select {
width: 98%; /* Растянуть поле на всю ширину карточки */
padding: 10px;
border-radius: 5px;
border: 1px solid #333333; /* Тонкая рамка */
background-color: #121212; /* Фон поля */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px;
}
.card input[type="radio"],
.card input[type="checkbox"] {
width: auto; /* Убираем ширину для радио и чекбоксов */
}
.card legend {
font-family: 'Mulish', sans-serif;
font-size: 16px;
color: #FFFFFF;
margin-bottom: 10px;
}
.card textarea {
width: 98%; /* Заполнение карточки по ширине */
height: 120px; /* Фиксированная высота */
margin: 0 auto; /* Центрирование по горизонтали */
display: block; /* Убирает лишнее пространство вокруг */
padding: 10px;
border-radius: 5px; /* Скругленные углы */
border: 1px solid #333333; /* Рамка */
background-color: #121212; /* Фон */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px; /* Размер текста */
resize: none; /* Запрещаем изменение размера */
}
#id_item_name {
width: 98%; /* Заполнение карточки по ширине */
height: 20px; /* Фиксированная высота */
margin: 0 auto; /* Центрирование по горизонтали */
display: block; /* Убирает лишнее пространство вокруг */
padding: 10px;
border-radius: 5px; /* Скругленные углы */
border: 1px solid #333333; /* Рамка */
background-color: #121212; /* Фон */
color: #FFFFFF; /* Цвет текста */
font-family: 'Mulish', sans-serif;
font-size: 14px; /* Размер текста */
resize: none; /* Запрещаем изменение размера */
}
.card button[type="submit"] {
width: 100%;
padding: 10px;
border: none;
border-radius: 20px;
background-color: rgb(116, 12, 173);
color: white;
font-size: 16px;
cursor: pointer;
font-family: 'Mulish', sans-serif;
transition: transform 0.2s, background-color 0.2s; /* Анимация */
}
.card button[type="submit"]:hover {
background-color: rgb(128, 35, 179); /* Легкое осветление */
transform: scale(1.01); /* Увеличение при наведении */
}
.card button[type="submit"]:active {
background-color: rgba(128, 35, 179); /* Еще большее осветление */
transform: scale(1.01); /* Увеличение при клике */
}
.hidden { display: none; }
</style>
</head>
<body>
<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="container">
<h1>ЗАГРУЗИТЬ НОВЫЙ ФАЙЛ</h1>
{% if error_message %}
<script type="text/javascript">
alert("{{ error_message }}");
</script>
{% endif %}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
<!-- Карточка для дополнительной цели -->
<div class="card">
<label for="id_tem_name">Название</label>
<textarea name="item_name" id="id_item_name" placeholder="Название"></textarea>
</div>
<!-- Карточка для дополнительной цели -->
<div class="card">
<label for="id_description">Описание</label>
<textarea name="description" id="id_description" placeholder="Описание"></textarea>
</div>
<!-- Карточка для выбора файла -->
<div class="card">
<label>Выбор файла:</label>
<div id="file_choice">
{{ form.file }}
</div>
</div>
<!-- Кнопка отправки -->
<div class="card">
<button type="submit">
Загрузить
</button>
</div>
</form>
</div>
<div class="footer">(C) MOVERELAB</div>
</body>
</html>
......@@ -3,62 +3,647 @@
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Архив заказов</title>
<title>MOVERE | Архив</title>
<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%; /*Ширина колонки статуса*/
}
.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);
cursor: pointer;
}
.footer {
width: 100%; /* Футер растягивается на всю ширину */
text-align: center;
/* padding: 10px 20px; Внутренние отступы */
background-color: #121212; /* Цвет фона футера */
color: #888; /* Цвет текста */
font-size: 12px;
margin-top: 5%; /* Футер перемещается в самый низ */
margin-bottom: 5%;
}
</style>
<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 translated;
}
document.addEventListener('DOMContentLoaded', function () {
// Получаем элементы модального окна
const modal = document.getElementById("orderModal");
const closeBtn = modal.querySelector(".close");
const modalContent = modal.querySelector("p");
// Добавляем обработчики событий для каждой карточки
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') || "Неизвестен";
// Парсим параметры
let parsedParameters;
try {
parsedParameters = JSON.parse(orderParameters.replace(/'/g, '"'));
} catch (e) {
console.error("Ошибка парсинга параметров:", e);
parsedParameters = {};
}
// Генерируем HTML для параметров
let parametersHTML = "<ul>";
for (const [key, value] of Object.entries(parsedParameters)) {
parametersHTML += `<li><strong>${key}:</strong> ${value}</li>`;
}
parametersHTML += "</ul>";
// Генерируем HTML содержимое модального окна
modalContent.innerHTML = `
<strong>ID заказа:</strong> ${orderId}<br>
<strong>Дата:</strong> ${orderDate}<br>
<strong>Параметры:</strong> ${parametersHTML}
<strong>Статус:</strong> ${orderStatus}<br>
`;
// Показываем модальное окно
modal.style.display = "block";
});
});
// Закрытие модального окна при клике на кнопку закрытия
closeBtn.addEventListener('click', function () {
modal.style.display = "none";
});
// Закрытие модального окна при клике вне его содержимого
window.addEventListener('click', function (event) {
if (event.target === modal) {
modal.style.display = "none";
}
});
// Закрытие модального окна при нажатии клавиши "Escape"
document.addEventListener('keydown', function (event) {
if (event.key === "Escape") {
modal.style.display = "none";
}
});
});
</script>
</head>
<body>
<h1>Архив заказов</h1>
<a href="{% url 'view_orders' %}" 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 archive_orders_status_list %}
<th class="status-column">
{% if status == 'done' %}Выполнен{% elif status == 'canceled' %}Отменен{% endif %}
</th>
{% endfor %}
</tr>
</thead>
<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 archive_orders_status_list %}
<th class="status-column">
{% if status == 'done' %}
Выполнен
{% elif status == 'canceled' %}
Отменен
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
{% for status, archive_orders in archive_orders_status_list %}
<td class="status-column">
{% if archive_orders %}
<ul>
{% for order in archive_orders %}
<li>
Заказ ID: {{ order.id }} <br>
Дата: {{ order.order_datetime }} <br>
Параметры: {{ order.order_parameters }} <br>
Файл: {% if order.file_basename %}{{ order.file_basename }}{% else %}Нет файла{% endif %}
{% for order, params in archive_orders %}
<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>
<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>
</li>
{% endfor %}
</ul>
{% else %}
Нет архивных заказов
{% endif %}
</td>
{% endfor %}
</tr>
</tbody>
</table>
</div>
<div id="orderModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<p>Здесь будет информация о заказе.</p>
</div>
</div>
<div class="footer">(C) MOVERELAB</div>
</body>
</html>
......@@ -3,33 +3,714 @@
<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>
<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; /* Темнее при наведении */
}
.btn-download {
text-decoration: none;
background-color: #2196F3; /* Синий цвет */
}
.btn-download: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%; /*Ширина колонки статуса*/
}
.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);
cursor: pointer;
}
</style>
<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_progress: "В работе",
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 translated;
}
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');
const downloadUrl = this.getAttribute('data-download-url');
// Генерация HTML параметров
let parametersHTML = '<ul>';
// for (const [key, value] of Object.entries(translatedParameters)) {
// parametersHTML += `<li><strong>${key}:</strong> ${value}</li>`;
// }
parametersHTML += orderParameters
parametersHTML += '</ul>';
const translatedStatus = translations.values[orderStatus] || orderStatus;
// Действия
let actionsHTML = '';
if (orderStatus === 'ready') {
console.log('AAaaaa',downloadUrl )
actionsHTML = `
<div style="margin-top: 20px;">
<a href="${downloadUrl}" class="modal-btn btn-download" target="_blank" rel="noopener noreferrer">Скачать файл</a>
</div>`;
}
// Заполняем содержимое модального окна
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";
}
};
document.addEventListener('keydown', function (event) {
if (event.key === "Escape") {
modal.style.display = "none";
}
});
});
</script>
</head>
<body>
<h1>Список заявок</h1>
<a href="{% url 'create3d' %}" 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>
<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>
<!-- <h1>Список заявок</h1> -->
<!-- <a href="{% url 'create3d' %}" 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> -->
<div class='view_orders_table'>
<table>
<thead>
<tr>
{% for status, _ in orders_status_list %}
<th class="status-column">
{% if status == 'in_progress' %}
В работе
{% elif status == 'ready' %}
Готов
{% elif status == 'error' %}
Ошибка при генерации
{% endif %}
</th>
{% endfor %}
</tr>
</thead>
<tbody>
<tr>
<!-- Ячейка для кнопки "Добавить новый заказ" -->
<td class="status-column">
{% if orders_status_list.0.0 == 'in_progress' %}
<ul>
{% for order in orders_status_list.0.1 %}
<li class="order-card"
data-id="{{ order.id }}"
data-date="{{ order.req_datetime|date:'Y-m-d' }}"
data-parameters="{{ order.req_parameters }}"
data-status="{{ order.req_state}}"
data-download-url="{% url 'download_item_from_nn' order.id %}">
<span style="font-size: 19px;">Запрос {{ order.id }} </span><br>
<span style="font-weight: 300; font-size: 16px; color: gray">{{ order.req_datetime|date:"Y-m-d" }}</span><br>
<br>
<br>
<svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.5 3H12H8C6.34315 3 5 4.34315 5 6V18C5 19.6569 6.34315 21 8 21H12M13.5 3L19 8.625M13.5 3V7.625C13.5 8.17728 13.9477 8.625 14.5 8.625H19M19 8.625V11.8125" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.5 21L17.5 15M17.5 15L20 17.5M17.5 15L15 17.5" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
{% if order.sent_by_user %}{{ order.sent_by_user }}{% else %}{% endif %} <br>
<!-- Полученный файл: {% if order.recieved_from_server %}{{ order.recieved_from_server }}{% else %}Нет файла{% endif %} <br> -->
<!-- {% if order.recieved_from_server %}<a href="{% url 'download_item_from_nn' order.id %}">Скачать</a>{% else %}Нет файла{% endif %} -->
<!-- Отображение статуса заказа -->
<br>
<div>
{% if order.req_state == 'in_progress' %}
<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.req_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.req_state == 'error' %}
<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>
</li>
{% endfor %}
</ul>
{% else %}
{% endif %}
<a href="{% url 'create3d' %}" class="create-order-button">+ Создать новую модель</a>
</td>
<!-- Печать остальных заказов по статусам -->
{% for status, orders in orders_status_list %}
{% if status != 'in_progress' %}
<td class="status-column">
{% if orders %}
<ul>
{% for order in orders %}
<li class="order-card"
data-id="{{ order.id }}"
data-date="{{ order.req_datetime|date:'Y-m-d' }}"
data-parameters="{{ order.req_parameters }}"
data-status="{{ order.req_state}}"
data-download-url="{% url 'download_item_from_nn' order.id %}">
<span style="font-size: 19px;">Запрос {{ order.id }} </span><br>
<span style="font-weight: 300; font-size: 16px; color: gray">{{ order.req_datetime|date:"Y-m-d" }}</span><br>
<br>
<br>
<svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.5 3H12H8C6.34315 3 5 4.34315 5 6V18C5 19.6569 6.34315 21 8 21H12M13.5 3L19 8.625M13.5 3V7.625C13.5 8.17728 13.9477 8.625 14.5 8.625H19M19 8.625V11.8125" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.5 21L17.5 15M17.5 15L20 17.5M17.5 15L15 17.5" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
{% if order.sent_by_user %}{{ order.sent_by_user }}{% else %}Нет файла{% endif %} <br>
{% if order.recieved_from_server %}
<svg width="15px" height="15px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.5 3H12H8C6.34315 3 5 4.34315 5 6V18C5 19.6569 6.34315 21 8 21H12M13.5 3L19 8.625M13.5 3V7.625C13.5 8.17728 13.9477 8.625 14.5 8.625H19M19 8.625V11.8125" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M17.5 15V21M17.5 21L15 18.5M17.5 21L20 18.5" stroke="#ffffff" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
{{ order.recieved_from_server }}
{% else %}{% endif %} <br>
<!-- Отображение статуса заказа -->
<div>
{% if order.req_state == 'in_progress' %}
<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.req_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: green;">Готово</span>
{% elif order.req_state == 'error' %}
<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>
</li>
{% endfor %}
</ul>
{% else %}
{% endif %}
</td>
{% endif %}
{% endfor %}
</tr>
</tbody>
</table>
</div>
<div id="orderModal" class="modal">
<div class="modal-content">
<span class="close">&times;</span>
<p>Здесь будет информация о заказе.</p>
</div>
</div>
<!-- <table>
<thead>
<tr>
{% for status, _ in orders_status_list %}
......@@ -56,11 +737,11 @@
{% for order in orders %}
<li>
Заказ ID: {{ order.id }} <br>
Дата: {{ order.order_datetime }} <br>
Параметры: {{ order.order_parameters }} <br>
Файл: {% if order.file_basename %}{{ order.file_basename }}{% else %}Нет файла{% endif %} <br>
Дата: {{ order.req_datetime }} <br>
Параметры: {{ order.req_parameters }} <br>
Отправленный файл: {% if order.sent_by_user %}{{ order.sent_by_user }}{% else %}Нет файла{% endif %} <br>
Полученный файл: {% if order.recieved_from_server %}{{ order.recieved_from_server }}{% else %}Нет файла{% endif %} <br>
{% if order.recieved_from_server %}<a href="{% url 'download_item_from_nn' order.id %}">Скачать</a>{% else %}Нет файла{% endif %}
</li>
{% endfor %}
</ul>
......@@ -71,6 +752,6 @@
{% endfor %}
</tr>
</tbody>
</table>
</table> -->
</body>
</html>
<!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%; /*Ширина колонки статуса*/
}
.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);
cursor: pointer;
}
</style>
<script>
function confirmCancel(orderId) {
if (confirm('Вы уверены, что хотите отменить этот заказ?')) {
document.getElementById('cancel-form-' + orderId).submit();
<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 translated;
}
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');
let parsedParameters = {};
try {
parsedParameters = JSON.parse(orderParameters.replace(/'/g, '"'));
} catch (e) {
console.error("Ошибка парсинга параметров:", e);
}
// Перевод параметров
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";
}
};
document.addEventListener('keydown', function (event) {
if (event.key === "Escape") {
modal.style.display = "none";
}
});
});
function confirmCancel(orderId) {
if (confirm('Вы уверены, что хотите отменить этот заказ?')) {
document.getElementById('cancel-form-' + orderId).submit();
}
</script>
}
</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>
Параметры: {{ order.order_parameters }} <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">&times;</span>
<p>Здесь будет информация о заказе.</p>
</div>
</div>
</body>
</html>
......@@ -12,7 +12,11 @@
{% 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');
a {
text-decoration: none;
}
.navbar {
display: flex;
......@@ -30,11 +34,14 @@
.navbar .logo {
display: flex; /* Располагает элементы (логотип и текст) в одну строку */
align-items: center; /* Вертикальное выравнивание элементов по центру */
margin-left: 100px;
margin-top: 20px;
/* margin-left: 30px; */
}
.navbar .logo img {
height: 60px; /* Размер логотипа */
margin-right: 10px; /* Отступ между логотипом и текстом */
margin-right: 15px; /* Отступ между логотипом и текстом */
}
.navbar .logo span {
......@@ -43,10 +50,12 @@
color: #FFFFFF; /* Цвет текста */
white-space: nowrap; /* Запрещает перенос текста на новую строку */
}
.navbar .profile-btn {
background-color: transparent; /* Прозрачный фон */
background-color: rgb(45, 42, 42);/* Прозрачный фон */
color: #FFFFFF;
border: 1px solid #4d4d4d; /* Белая рамка */
border: 1px solid #ffffff00; /* Белая рамка */
padding: 15px 30px; /* Увеличенный внутренний отступ */
font-family: "Roboto", sans-serif;
/* font-weight: bold; */
......@@ -54,13 +63,40 @@
border-radius: 20px; /* Скругленные углы */
cursor: pointer;
transition: transform 0.3s, background-color 0.3s, color 0.3s;
/* margin-left: 10%; Отступ справа */
margin-right: 10%; /*Отступ справа */
/* margin-left: 10%; */
}
.navbar .profile-btn:hover {
background-color: rgba(255, 255, 255, 0.2); /* Полупрозрачный белый при наведении */
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: "Roboto", 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%;
}
body {
margin: 0;
font-family: "Krona One", serif;
......@@ -86,33 +122,45 @@
}
.card {
width: 300px;
height: 400px;
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;
}
position: relative;
width: 300px;
height: 400px;
background-color: #3A3A3A;
border-radius: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-end;
overflow: hidden;
cursor: pointer;
transition: transform 0.3s;
}
.card:hover {
transform: scale(1.05);
}
.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 svg {
position: absolute;
top: 20px;
left: 50%;
transform: translateX(-50%);
width: 80%;
height: 80%;
}
.card svg .color-change {
fill: #ffffff; /* Начальный цвет */
transition: fill 0.2s ease; /* Плавное изменение цвета */
}
.card svg .no-change {
fill: none; /* Оставляем как есть */
}
.card:hover svg .color-change {
fill: #8d53ff; /* Цвет при наведении */
}
.card video {
width: 100%;
......@@ -131,11 +179,11 @@
.card .label {
position: relative;
font-family: 'Roboto', Arial, sans-serif;
font-family: 'Mulish', Arial, sans-serif;
color: #FFFFFF;
padding: 5px 10px;
border-radius: 5px;
font-size: 14px;
font-size: 20px;
font-weight: bold;
margin-bottom: 5px;
text-align: center;
......@@ -143,12 +191,12 @@
}
.card .description {
font-family: 'Roboto', Arial, sans-serif;
font-family: 'Mulish', Arial, sans-serif;
position: relative;
color: #FFFFFF;
color: #c1c1c1;
padding: 5px 10px;
border-radius: 5px;
font-size: 12px;
font-size: 16px;
text-align: center;
margin-bottom: 10px;
z-index: 3;
......@@ -198,31 +246,119 @@
<a href="{% url 'view_orders' %}" class="card">
<!-- <img src="{% static 'mainapp/images/tunder.png' %}" alt="Preview"> -->
<!-- <video src="{% static 'mainapp/images/purple_tunder.mp4' %}" muted data-playing="false"></video> -->
<svg height="250px" width="250px" version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 0 470 470" xml:space="preserve">
<!-- <path class="color-change" d="M18 5.498l-5.5-2.26L7 5.499v5.655l-5 2.054v6.443l5.5 2.259 5-2.054 5 2.054 5.5-2.26v-6.442l-5-2.054zm-.5 9.462l-3.432-1.404 3.576-1.468 3.432 1.41zM12 8.127v4.669l-4-1.643V6.492zm1 4.669V8.127l4-1.635v4.661zm-2.068.76L7.5 14.96l-3.576-1.463 3.432-1.41zM8 15.836l4-1.636v4.78l-4 1.642zm8.076-10.047L12.5 7.25 8.924 5.79 12.5 4.32zM3 14.2l4 1.636v4.786L3 18.98zm10 0l4 1.636v4.786l-4-1.642zm5 6.422v-4.786l4-1.636v4.78z"/>
<path class="no-change" fill="none" d="M0 0h24v24H0z"/> -->
<path class="color-change" d="M211.683,151.084c-2.086-3.58-6.679-4.788-10.256-2.705l-51.978,30.281c-3.579,2.085-4.79,6.677-2.705,10.256
c1.394,2.392,3.906,3.726,6.487,3.726c1.282,0,2.581-0.329,3.769-1.021l51.978-30.281
C212.557,159.255,213.768,154.663,211.683,151.084z"/>
<path class="color-change" d="M261.021,161.34l51.978,30.28c1.188,0.691,2.486,1.021,3.769,1.021c2.581,0,5.094-1.334,6.487-3.726
c2.085-3.579,0.874-8.171-2.705-10.256l-51.978-30.28c-3.579-2.084-8.17-0.875-10.256,2.705
C256.231,154.663,257.442,159.255,261.021,161.34z"/>
<path class="color-change" d="M149.551,356.399l51.877,30.223c1.188,0.692,2.486,1.021,3.769,1.021c2.581,0,5.094-1.334,6.487-3.726
c2.085-3.579,0.874-8.171-2.705-10.256l-51.877-30.223c-3.579-2.088-8.17-0.874-10.256,2.705
C144.761,349.723,145.972,354.314,149.551,356.399z"/>
<path class="color-change" d="M465.642,267.424c-0.006-0.597-0.084-1.196-0.235-1.787c-0.019-0.072-0.04-0.142-0.061-0.213
c-0.063-0.218-0.137-0.434-0.221-0.649c-0.029-0.076-0.057-0.151-0.089-0.226c-0.102-0.238-0.217-0.472-0.346-0.703
c-0.018-0.032-0.032-0.067-0.051-0.099c-0.16-0.277-0.323-0.515-0.494-0.745c-0.04-0.054-0.084-0.104-0.126-0.156
c-0.148-0.187-0.303-0.366-0.466-0.536c-0.053-0.055-0.106-0.109-0.161-0.163c-0.185-0.181-0.376-0.352-0.577-0.511
c-0.034-0.027-0.065-0.056-0.099-0.082c-0.243-0.186-0.495-0.356-0.756-0.51c-0.039-0.026-107.888-62.857-107.888-62.857V72.5
c0-0.026-0.005-0.05-0.005-0.076c-0.006-0.597-0.084-1.196-0.235-1.787c-0.019-0.072-0.04-0.142-0.061-0.213
c-0.063-0.218-0.137-0.434-0.221-0.649c-0.029-0.076-0.057-0.151-0.089-0.226c-0.102-0.238-0.217-0.472-0.346-0.703
c-0.018-0.032-0.032-0.067-0.051-0.099c-0.16-0.278-0.323-0.516-0.495-0.746c-0.039-0.052-0.082-0.101-0.122-0.152
c-0.15-0.19-0.307-0.371-0.471-0.542c-0.051-0.053-0.102-0.105-0.155-0.156c-0.188-0.185-0.384-0.36-0.589-0.522
c-0.029-0.023-0.056-0.049-0.086-0.071c-0.245-0.189-0.5-0.36-0.764-0.516C350.349,66.02,238.775,1.02,238.775,1.02
c-2.334-1.359-5.217-1.359-7.551,0l-111.573,65c-0.297,0.178-0.554,0.351-0.801,0.54c-0.027,0.021-0.052,0.044-0.079,0.066
c-0.207,0.164-0.405,0.34-0.595,0.527c-0.052,0.051-0.102,0.102-0.153,0.155c-0.165,0.172-0.322,0.354-0.472,0.544
c-0.04,0.051-0.083,0.099-0.122,0.151c-0.172,0.23-0.335,0.468-0.483,0.722c-0.031,0.056-0.045,0.09-0.063,0.123
c-0.129,0.231-0.244,0.465-0.346,0.703c-0.032,0.074-0.06,0.15-0.089,0.226c-0.084,0.214-0.158,0.43-0.221,0.649
c-0.021,0.071-0.042,0.141-0.06,0.213c-0.152,0.591-0.23,1.19-0.235,1.787c0,0.025-0.005,0.05-0.005,0.076v125.689L8.078,261.02
c-0.3,0.18-0.553,0.35-0.796,0.537c-0.033,0.026-0.064,0.054-0.097,0.08c-0.201,0.16-0.393,0.331-0.578,0.512
c-0.054,0.053-0.108,0.107-0.16,0.162c-0.163,0.17-0.318,0.349-0.466,0.536c-0.042,0.053-0.086,0.103-0.126,0.157
c-0.171,0.229-0.334,0.467-0.482,0.72c-0.031,0.056-0.045,0.09-0.063,0.123c-0.129,0.231-0.244,0.465-0.346,0.703
c-0.032,0.074-0.06,0.15-0.089,0.226c-0.084,0.214-0.158,0.43-0.221,0.649c-0.021,0.071-0.042,0.141-0.06,0.213
c-0.152,0.591-0.23,1.19-0.235,1.787c0,0.025-0.005,0.05-0.005,0.076v130c0,2.669,1.419,5.137,3.725,6.48l111.573,65
c0.021,0.012,0.044,0.02,0.065,0.032c0.268,0.153,0.545,0.293,0.833,0.413c0.28,0.116,0.562,0.208,0.85,0.289
c0.071,0.02,0.143,0.037,0.215,0.055c0.225,0.056,0.454,0.101,0.687,0.136c0.077,0.012,0.152,0.026,0.229,0.035
c0.295,0.035,0.593,0.059,0.897,0.059s0.603-0.023,0.897-0.059c0.077-0.009,0.152-0.023,0.229-0.035
c0.233-0.035,0.462-0.08,0.687-0.136c0.072-0.018,0.144-0.035,0.215-0.055c0.288-0.081,0.57-0.173,0.843-0.286
c0.294-0.122,0.571-0.262,0.839-0.416c0.021-0.012,0.044-0.02,0.065-0.032L235,406.18l107.798,62.801
c0.021,0.012,0.044,0.02,0.065,0.032c0.268,0.153,0.544,0.293,0.832,0.413c0.281,0.116,0.562,0.208,0.849,0.289
c0.072,0.02,0.144,0.038,0.216,0.056c0.225,0.056,0.453,0.101,0.686,0.136c0.077,0.012,0.153,0.026,0.23,0.035
c0.295,0.035,0.593,0.059,0.897,0.059s0.602-0.023,0.897-0.059c0.077-0.009,0.153-0.023,0.23-0.035
c0.232-0.035,0.461-0.08,0.686-0.136c0.072-0.018,0.144-0.035,0.216-0.056c0.287-0.081,0.569-0.173,0.841-0.286
c0.296-0.123,0.572-0.263,0.84-0.416c0.021-0.012,0.044-0.02,0.065-0.032l111.573-65c2.306-1.344,3.725-3.812,3.725-6.48v-130
C465.646,267.474,465.642,267.45,465.642,267.424z M443.247,267.5l-96.674,56.32l-96.674-56.32l96.674-56.32L443.247,267.5z
M130.927,85.549l96.573,56.261v112.64l-96.573-56.261V85.549z M339.073,198.189L242.5,254.451v-112.64l96.573-56.261V198.189z
M227.5,393.189l-96.573,56.262v-112.64l96.573-56.261V393.189z M242.5,280.549l96.573,56.261v112.64L242.5,393.189V280.549z
M235,16.18l96.674,56.32L235,128.82L138.326,72.5L235,16.18z M123.427,211.18l96.674,56.32l-96.674,56.32L26.753,267.5
L123.427,211.18z M19.354,280.549l96.573,56.261v112.64l-96.573-56.262V280.549z M354.073,449.451v-112.64l96.573-56.261v112.64
L354.073,449.451z"/>
<path class="color-change" d="M323.156,346.142c-2.086-3.58-6.678-4.788-10.256-2.705l-51.877,30.223c-3.579,2.085-4.79,6.677-2.705,10.256
c1.394,2.392,3.906,3.726,6.487,3.726c1.282,0,2.581-0.329,3.769-1.021l51.877-30.223
C324.03,354.313,325.241,349.721,323.156,346.142z"/>
<path class="color-change" d="M100.109,346.084c-2.086-3.58-6.679-4.788-10.256-2.705l-51.877,30.223c-3.579,2.085-4.79,6.677-2.705,10.256
c1.394,2.392,3.906,3.726,6.487,3.726c1.282,0,2.581-0.329,3.769-1.021l51.877-30.223
C100.983,354.255,102.194,349.663,100.109,346.084z"/>
<path class="color-change" d="M432.024,373.603l-51.676-30.105c-3.579-2.087-8.171-0.875-10.256,2.705c-2.085,3.579-0.874,8.171,2.705,10.256
l51.676,30.105c1.188,0.692,2.486,1.021,3.769,1.021c2.581,0,5.094-1.334,6.487-3.726
C436.814,380.279,435.604,375.688,432.024,373.603z"/>
</svg>
<div class="label">МОИ ЗАЯВКИ</div>
<div class="description"></div>
</a>
<div class="card">
<a href="{% url 'view_editrequests' %}" class="card">
<!-- <img src="{% static 'mainapp/images/store.png' %}" alt="Preview"> -->
<!-- <video src="{% static 'mainapp/images/store.mp4' %}" muted data-playing="false"></video> -->
<div class="label">МОИ МОДЕЛИ</div>
<div class="description">ИИ</div>
<svg width="800px" height="800px" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path class="color-change" d="M6,19.7439414 C4.25221144,19.1261868 3,17.4593282 3,15.5 L3,8.5 C3,6.01471863 5.01471863,4 7.5,4 L8,4 L8,3.5 C8,2.67157288 8.67157288,2 9.5,2 L14.5,2 C15.3284271,2 16,2.67157288 16,3.5 L16,4 L16.5,4 C18.9852814,4 21,6.01471863 21,8.5 L21,15.5 C21,17.4593282 19.7477886,19.1261868 18,19.7439414 L18,20.5 C18,21.3284271 17.3284271,22 16.5,22 L7.5,22 C6.67157288,22 6,21.3284271 6,20.5 L6,19.7439414 L6,19.7439414 Z M7,19.9725356 L7,20.5 C7,20.7761424 7.22385763,21 7.5,21 L16.5,21 C16.7761424,21 17,20.7761424 17,20.5 L17,19.9725356 C16.8358331,19.9906833 16.6690045,20 16.5,20 L7.5,20 C7.33099545,20 7.16416693,19.9906833 7,19.9725356 L7,19.9725356 Z M9,4 L15,4 L15,3.5 C15,3.22385763 14.7761424,3 14.5,3 L9.5,3 C9.22385763,3 9,3.22385763 9,3.5 L9,4 Z M7.5,5 C5.56700338,5 4,6.56700338 4,8.5 L4,15.5 C4,17.4329966 5.56700338,19 7.5,19 L16.5,19 C18.4329966,19 20,17.4329966 20,15.5 L20,8.5 C20,6.56700338 18.4329966,5 16.5,5 L7.5,5 Z M14.5,10 L15.5,10 C15.7761424,10 16,10.2238576 16,10.5 L16,11.5 C16,11.7761424 15.7761424,12 15.5,12 L14.5,12 C14.2238576,12 14,11.7761424 14,11.5 L14,10.5 C14,10.2238576 14.2238576,10 14.5,10 Z M8.5,10 L9.5,10 C9.77614237,10 10,10.2238576 10,10.5 L10,11.5 C10,11.7761424 9.77614237,12 9.5,12 L8.5,12 C8.22385763,12 8,11.7761424 8,11.5 L8,10.5 C8,10.2238576 8.22385763,10 8.5,10 Z M9.14644661,14.8535534 C8.95118446,14.6582912 8.95118446,14.3417088 9.14644661,14.1464466 C9.34170876,13.9511845 9.65829124,13.9511845 9.85355339,14.1464466 C10.4248566,14.7177498 11.1304821,15 12,15 C12.8695179,15 13.5751434,14.7177498 14.1464466,14.1464466 C14.3417088,13.9511845 14.6582912,13.9511845 14.8535534,14.1464466 C15.0488155,14.3417088 15.0488155,14.6582912 14.8535534,14.8535534 C14.0915232,15.6155836 13.1304821,16 12,16 C10.8695179,16 9.90847678,15.6155836 9.14644661,14.8535534 Z"/>
</svg>
<div class="label">МОИ ГЕНЕРАЦИИ</div>
<div class="description"></div>
</a>
</div>
<div class="card">
<a href="{% url 'view_archive' %}" class="card">
<!-- <img src="{% static 'mainapp/images/store.png' %}" alt="Preview"> -->
<!-- <video src="{% static 'mainapp/images/store.mp4' %}" muted data-playing="false"></video> -->
<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path class="color-change" fill-rule="evenodd" clip-rule="evenodd" d="M5.07868 5.06891C8.87402 1.27893 15.0437 1.31923 18.8622 5.13778C22.6824 8.95797 22.7211 15.1313 18.9262 18.9262C15.1312 22.7211 8.95793 22.6824 5.13774 18.8622C2.87389 16.5984 1.93904 13.5099 2.34047 10.5812C2.39672 10.1708 2.775 9.88377 3.18537 9.94002C3.59575 9.99627 3.88282 10.3745 3.82658 10.7849C3.4866 13.2652 4.27782 15.881 6.1984 17.8016C9.44288 21.0461 14.6664 21.0646 17.8655 17.8655C21.0646 14.6664 21.046 9.44292 17.8015 6.19844C14.5587 2.95561 9.33889 2.93539 6.13935 6.12957L6.88705 6.13333C7.30126 6.13541 7.63535 6.47288 7.63327 6.88709C7.63119 7.3013 7.29372 7.63539 6.87951 7.63331L4.33396 7.62052C3.92269 7.61845 3.58981 7.28556 3.58774 6.8743L3.57495 4.32874C3.57286 3.91454 3.90696 3.57707 4.32117 3.57498C4.73538 3.5729 5.07285 3.907 5.07493 4.32121L5.07868 5.06891ZM11.9999 7.24992C12.4141 7.24992 12.7499 7.58571 12.7499 7.99992V11.6893L15.0302 13.9696C15.3231 14.2625 15.3231 14.7374 15.0302 15.0302C14.7373 15.3231 14.2624 15.3231 13.9696 15.0302L11.2499 12.3106V7.99992C11.2499 7.58571 11.5857 7.24992 11.9999 7.24992Z"/>
</svg>
<div class="label">АРХИВ</div>
<div class="description"></div>
</a>
</div>
<div class="card">
<a href="{% url 'storage' %}" class="card">
<img src="{% static 'mainapp/images/store.png' %}" alt="Preview">
<video src="{% static 'mainapp/images/store.mp4' %}" muted data-playing="false"></video>
<svg version="1.1" id="CLOUD_NETWORK" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px"
y="0px" width="800px" height="800px" viewBox="0 0 1800 1800" enable-background="new 0 0 1800 1800" xml:space="preserve">
<path class="color-change" d="M1635.687,1278.4c-47.769,0-88.294,31.611-101.762,75.016h-145.789v-349.629h73.367
c4.988,0.22,9.674,0.326,14.307,0.326c4.782,0,9.635-0.115,14.817-0.348c0.079-0.005,0.158-0.01,0.237-0.01
c173.133-7.938,308.756-150.018,308.756-323.454c0-134.669-81.956-253.44-205.979-301.697
c-14.456-100.161-63.179-192.209-138.563-260.994c-80.945-73.862-185.92-114.539-295.579-114.539
c-137.799,0-266.188,64.115-349.019,172.916c-45.162-22.9-95.19-34.891-146.321-34.891c-139.064,0-261.005,87.974-305.833,217.184
c-11.335-1.191-22.746-1.793-34.13-1.793C145.642,356.487,0.38,501.749,0.38,680.302c0,178.549,145.262,323.812,323.815,323.812
c5.393,0,10.958-0.146,16.592-0.436c0.875,0.074,1.758,0.109,2.65,0.109h72.515v349.629h-145.79
c-13.467-43.404-53.993-75.016-101.761-75.016c-58.735,0-106.521,47.787-106.521,106.521c0,58.735,47.786,106.521,106.521,106.521
c47.769,0,88.294-31.611,101.761-75.016h177.295c17.401,0,31.506-14.104,31.506-31.506v-381.135h194.534v586.93
c-43.404,13.463-75.016,53.988-75.016,101.762c0,58.735,47.787,106.521,106.521,106.521s106.521-47.786,106.521-106.521
c0-47.773-31.611-88.299-75.016-101.762v-586.93h331.067v586.93c-43.403,13.463-75.016,53.988-75.016,101.762
c0,58.735,47.787,106.521,106.521,106.521c58.735,0,106.522-47.786,106.522-106.521c0-47.773-31.612-88.299-75.016-101.762v-586.93
h194.534v381.135c0,17.401,14.104,31.506,31.506,31.506h177.295c13.468,43.404,53.993,75.016,101.762,75.016
c58.735,0,106.521-47.786,106.521-106.521C1742.208,1326.188,1694.422,1278.4,1635.687,1278.4z M168.401,1428.432
c-23.99,0-43.51-19.52-43.51-43.51s19.52-43.51,43.51-43.51c23.99,0,43.51,19.52,43.51,43.51S192.391,1428.432,168.401,1428.432z
M705.004,1735.988c-23.99,0-43.51-19.52-43.51-43.51s19.52-43.51,43.51-43.51s43.51,19.52,43.51,43.51
S728.994,1735.988,705.004,1735.988z M1099.083,1735.988c-23.989,0-43.509-19.52-43.509-43.51s19.52-43.51,43.509-43.51
c23.99,0,43.51,19.52,43.51,43.51S1123.073,1735.988,1099.083,1735.988z M341.398,940.525c-5.886,0.382-11.674,0.575-17.204,0.575
c-143.807,0-260.803-116.996-260.803-260.799c0-143.807,116.996-260.803,260.803-260.803c16.909,0,33.875,1.644,50.428,4.883
c16.469,3.2,32.53-7.002,36.608-23.247c29.133-116.007,133.14-197.026,252.927-197.026c49.272,0,97.252,13.81,138.753,39.941
c14.479,9.116,33.615,5.006,43.062-9.279c69.877-105.629,187.079-168.687,313.525-168.687c194.314,0,355.039,145.629,373.86,338.749
c1.222,12.531,9.784,23.133,21.783,26.961c108.539,34.626,181.467,134.493,181.467,248.509c0,139.628-109.119,254.017-248.452,260.5
c-0.065,0-0.127,0.005-0.193,0.009c-8.602,0.387-15.744,0.387-24.311,0c-0.479-0.021-0.963-0.035-1.441-0.035H347.895
C345.763,940.468,343.587,940.385,341.398,940.525z M1635.687,1428.432c-23.99,0-43.51-19.52-43.51-43.51s19.52-43.51,43.51-43.51
s43.51,19.52,43.51,43.51S1659.677,1428.432,1635.687,1428.432z"/>
</svg>
<div class="label">ХРАНИЛИЩЕ</div>
<div class="description"></div>
</a>
......
......@@ -19,6 +19,7 @@ urlpatterns = [
path('storage/delete/<int:item_id>/', views.delete_item, name='delete_item'),
path('storage/upload/', views.upload_file, name='upload_file'),
path('storage/download/<int:item_id>/', views.download_item, name='download_item'),
path('view_editrequests/download/<int:item_id>/', views.download_item_from_nn, name='download_item_from_nn'),
path('create_order/', views.create_order, name='create_order'),
path('archive_order/<int:order_id>/', views.archive_order, name='archive_order'),
path('view_archive/', views.view_archive, name='view_archive'),
......@@ -28,6 +29,7 @@ urlpatterns = [
path('cancel_order/<int:order_id>/', views.cancel_order, name='cancel_order'),
path('story-and-files', views.view_story_and_files, name='view_story_and_files'),
path('redactor/', views.redactor, name='redactor'),
path('api/orders/by-username/<str:username>/', views.order_list_by_username_api, name='order_list_by_username_api'),
# path('serve-file/<str:file_name>/', views.serve_file, name='serve_file'),
......
import paramiko
import os
def upload_file_and_add_task(server_ip, username, password, local_file_path, remote_dir, remote_file_name, params, venv_path, req_id):
try:
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(server_ip, username=username, password=password)
print(f"Подключение к {server_ip} установлено.")
# Проверяем и создаём директорию на внешнем сервере
command_check_dir = f"if [ ! -d {remote_dir} ]; then mkdir -p {remote_dir}; fi"
ssh.exec_command(command_check_dir)
print(f"Директория {remote_dir} проверена/создана.")
# Открываем SFTP-соединение
sftp = ssh.open_sftp()
# Загружаем файл
remote_file_path = os.path.join(remote_dir, remote_file_name)
sftp.put(local_file_path, remote_file_path)
print(f"Файл загружен: {remote_file_path}")
sftp.close()
# Команда для активации виртуального окружения и запуска скрипта
add_task_script = "queue_scripts/add_task_to_queue.py" # Укажите путь к скрипту на сервере
command_add_task = (
f"cd {os.path.dirname(add_task_script)} && "
f"source venv/bin/activate && "
f"python3 {os.path.basename(add_task_script)} {req_id} {remote_file_path} \"{params}\""
)
print(f"Запуск команды: {command_add_task}")
# Выполняем команду
stdin, stdout, stderr = ssh.exec_command(command_add_task)
print("STDOUT:", stdout.read().decode('utf-8'))
print("STDERR:", stderr.read().decode('utf-8'))
# Закрываем соединение
ssh.close()
print("Операция завершена.")
except Exception as e:
print(f"Ошибка: {e}")
if __name__ == "__main__":
# Пример использования
upload_file_and_add_task(
server_ip="192.168.1.100",
username="root",
password="password",
local_file_path="/path/to/local/file.txt",
remote_dir="/path/to/remote/directory",
remote_file_name="uploaded_file.txt",
params="--param1=value1 --param2=value2",
venv_path="/path/to/remote/.venv", # Путь к виртуальному окружению на внешнем сервере,
req_id=0
)
......@@ -17,7 +17,7 @@ from rest_framework.response import Response
from rest_framework.decorators import api_view
from .models import Order
from .serializers import OrderSerializer
import ast
......@@ -108,6 +108,32 @@ def download_file(request, file_name):
# response['Content-Disposition'] = f'attachment; filename={os.path.basename(full_path)}'
# return response
from django.contrib.auth.models import User
@csrf_exempt
def order_list_by_username_api(request, username):
# Проверка ключа API
api_key = request.headers.get('Authorization')
if api_key != f"Api-Key {settings.API_KEY}":
return JsonResponse({'error': 'Unauthorized'}, status=403)
if request.method == 'GET':
# Проверка существует ли пользователь с таким именем
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
return JsonResponse({'error': 'User not found'}, status=404)
# Фильтрация заказов по пользователю
orders = Order.objects.filter(user=user)
orders_data = list(orders.values('id', 'order_state')) # Выбирайте нужные поля
return JsonResponse(orders_data, safe=False)
return JsonResponse({'error': 'Method not allowed'}, status=405)
@csrf_exempt
def order_list_api(request):
# Проверка ключа API
......@@ -188,9 +214,14 @@ def home(request):
def make_order(request):
return render(request, 'mainapp/make_order.html')
# @login_required
# def redactor(request):
# return render(request, 'mainapp/redactor.html')
@login_required
def redactor(request):
return render(request, 'mainapp/redactor.html')
# Фильтруем файлы пользователя с допустимыми расширениями
storage_files = Storage.objects.filter(user=request.user, file_path__iregex=r'\.(stl|obj)$')
return render(request, 'mainapp/redactor.html', {'storage_files': storage_files})
@login_required
......@@ -200,10 +231,30 @@ def view_story_and_files(request):
@login_required
def view_archive(request):
user_archive_orders = OrderArchive.objects.filter(user=request.user)
coolpaths = {order.id: order.file_path for order in user_archive_orders}
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
statuses = ['done', 'canceled']
archive_orders_by_status = {status: user_archive_orders.filter(order_state=status) for status in statuses}
new_archive_orders_status_list = create_new_list_for_view(archive_orders_by_status)
archive_orders_status_list = []
for status in statuses:
archive_orders = archive_orders_by_status[status]
......@@ -214,7 +265,10 @@ def view_archive(request):
order.file_basename = []
archive_orders_status_list.append((status, archive_orders))
return render(request, 'mainapp/view_archive.html', {'archive_orders_status_list': archive_orders_status_list})
return render(request, 'mainapp/view_archive.html', {'archive_orders_status_list': new_archive_orders_status_list})
......@@ -235,14 +289,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]
......@@ -254,11 +340,16 @@ 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
@login_required
def create_order(request):
if request.method == 'POST':
......@@ -267,6 +358,17 @@ def create_order(request):
order = form.save(commit=False)
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) # Сохраняем словарь как строку
file_choice = form.cleaned_data.get('file_choice')
if file_choice == OrderForm.CHOICE_FILE_FROM_STORAGE:
......@@ -286,13 +388,14 @@ def create_order(request):
return redirect('view_orders')
else:
form = OrderForm(user=request.user)
return render(request, 'mainapp/create_order.html', {'form': form})
@login_required
def storage(request):
items = Storage.objects.filter(user=request.user)
for item in items:
item.basename_filepath = os.path.basename(item.file_path)
return render(request, 'mainapp/storage.html', {'items': items})
......@@ -309,6 +412,21 @@ def download_item(request, item_id):
else:
# Если файла нет, можно вернуть ошибку или редирект
return redirect('storage')
@login_required
def download_item_from_nn(request, item_id):
item = get_object_or_404(EditRequest, id=item_id, user=request.user)
print('объект: ', item)
print('ищу: ', 'media/' + item.received_file)
# Проверяем, существует ли файл
if os.path.exists('media/' + item.received_file):
# Отправляем файл пользователю для скачивания
print('нашел: ', 'media/' + item.received_file)
return FileResponse(open('media/' + item.received_file, 'rb'), as_attachment=True, filename=os.path.basename(item.received_file))
else:
print('не нашел: ', 'media/' + item.received_file)
# Если файла нет, можно вернуть ошибку или редирект
return redirect('view_editrequests')
@login_required
def delete_item(request, item_id):
......@@ -421,6 +539,11 @@ def logout(request):
@login_required
def manager_dashboard(request):
def parse_params(parametrs):
d = ast.literal_eval(parametrs)
return d
if request.user.groups.filter(name='manager').exists():
if request.method == 'POST':
order_id = request.POST.get('order_id')
......@@ -439,8 +562,14 @@ def manager_dashboard(request):
sort_by = 'order_datetime'
# Получаем все заказы для отображения
orders = Order.objects.all().order_by(sort_by)
for order in orders:
try:
parsed_params = parse_params(order.order_parameters)
order.parsed_params = parsed_params
except:
order.parsed_params = {}
if order.file_path:
order.file_basename = os.path.basename(order.file_path)
else:
......@@ -488,11 +617,16 @@ def view_editrequests(request):
orders = reqs_by_status[status]
for order in orders:
# Извлекаем только basename из файловых путей
if order.file_path:
order.sent_by_user = os.path.basename(order.file_path)
else:
order.sent_by_user = []
if order.received_file:
order.file_basename = os.path.basename(order.received_file)
order.recieved_from_server = os.path.basename(order.received_file)
else:
order.file_basename = []
order.recieved_from_server = []
orders_status_list.append((status, orders))
return render(request, 'mainapp/view_editrequests.html', {'orders_status_list': orders_status_list})
\ No newline at end of file
algorithm.gms
#=========================================================================
* /////////////////////// OPTIMIZATION ///////////////////////
#=========================================================================
* launch optimization logic, passing full sequence of coalition-changing-times
* This will result in a sequence of progressive optimizations,
* one for each %coalitions_t_sequence% time passed
$batinclude "algorithm/optimization_loop" %coalitions_t_sequence%
modules.gms
$set phase %1
$batinclude 'modules/core_time' %2 # Core block to align correctly time epriods
$batinclude 'modules/core_regions' %2 # Regions settings and exogenous data imports
$batinclude 'modules/core_economy' %2 # Core block for economy
$batinclude 'modules/core_emissions' %2 # Core block for emissions
$batinclude 'modules/core_welfare' %2 # Core block for welfare
$batinclude 'modules/cooperation_%cooperation%' %2 # Cooperation setup
$batinclude 'modules/core_algorithm' %2 # Solve settings
$batinclude 'modules/mod_macc' %2 # MAC curves, abatement cost
$batinclude 'modules/mod_land_use' %2 # Land-use HUB
$batinclude 'modules/hub_climate' %2 # Climate HUB
$batinclude 'modules/mod_climate_regional' %2 # Regional climate module
$batinclude 'modules/hub_impact' %2 # Climate Impact HUB
# POLICY
$batinclude 'modules/core_policy' %2 # All policy options
$if set pol_ndc $batinclude 'modules/pol_ndc' %2 # NDC policy module
# Optional Modules
$if set mod_adaptation $batinclude 'modules/mod_adaptation' %2 # Adaptation Module
$if set mod_government $batinclude 'modules/mod_government' %2 # Government Module
$if set mod_labour $batinclude 'modules/mod_labour' %2 # Labour Module
$if set mod_inequality $batinclude 'modules/mod_inequality' %2 # Inequality Module
$if set mod_srm $batinclude 'modules/mod_srm' %2 # Solar Radiation management Module
$if set mod_slr $batinclude 'modules/mod_slr' %2 # Sea level rise Module
$if set mod_natural_capital $batinclude 'modules/mod_natural_capital' %2 # Nature Capital Green Module
$if set mod_emission_pulse $batinclude 'modules/mod_emission_pulse' %2 # Emission Pulse for SCC computation
$if set mod_dac $batinclude 'modules/mod_emi_stor' %2 # Emission storage module
$if set mod_dac $batinclude 'modules/mod_dac' %2 # Negative emissions module