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>
......@@ -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
)
This diff is collapsed.
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%
This diff is collapsed.