Files
api-copp/web/designer.py
2026-04-06 12:15:09 +05:00

345 lines
17 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import flet as ft
# Глобальный масштаб интерфейса. 1.0 = 100%, 1.7 = 170%.
# Меняйте только эту константу, чтобы масштабировать весь UI.
SCALE: float = 1.7
def s(v: int | float) -> int:
"""Применяет SCALE к любому размеру: шрифтам, отступам, ицих."""
return round(v * SCALE)
class clolors:
background = "#C0DE9E"
laer1 = "#FFEAB7"
laer2 = "#D9F1F4"
laer3 = "#D2EA32"
ferst = "#85C446"
class CastomText(ft.Text):
def __init__(self, text, size=14, color=clolors.ferst, weight=ft.FontWeight.NORMAL):
super().__init__(
value=text,
color=color,
size=s(size),
weight=weight,
max_lines=99,
)
class CastomTextField_input(ft.TextField):
def __init__(self, on_change=None, on_submit=None, label="Ваше имя", hint_text="Введите текст...", prefix_icon=None, suffix_icon=None, **kwargs):
super().__init__(
label=label,
hint_text=hint_text,
filled=True, # заливка фона
bgcolor=clolors.ferst, # цвет заливки
border_color=clolors.laer2, # цвет границы
border_radius=s(12), # скругление углов
label_style=ft.TextStyle(
color=clolors.laer3,
size=s(14),
weight=ft.FontWeight.BOLD,
),
hint_style=ft.TextStyle(
color=clolors.laer1,
size=s(14),
italic=True,
),
text_style=ft.TextStyle(
color=clolors.laer3,
size=s(16),
),
content_padding=ft.padding.symmetric(horizontal=s(12), vertical=s(14)),
prefix_icon=prefix_icon,
suffix_icon=suffix_icon,
on_change=on_change,
on_submit=on_submit,
**kwargs,
)
class CastomButton(ft.Button):
def __init__(self, text, on_click):
super().__init__(
content=text,
style=ft.ButtonStyle(
color=clolors.ferst,
bgcolor=clolors.laer1,
text_style=ft.TextStyle(
size=s(14)
),
padding=ft.padding.symmetric(horizontal=s(16), vertical=s(10)),
),
on_click=on_click
)
class CastomIconButton(ft.Button):
"""Кнопка с иконкой и текстом."""
def __init__(self, text, icon, on_click):
super().__init__(
content=ft.Row(
spacing=s(8),
tight=True,
controls=[
ft.Icon(icon, color=clolors.ferst, size=s(18)),
ft.Text(text, color=clolors.ferst, size=s(14)),
],
),
style=ft.ButtonStyle(
color=clolors.ferst,
bgcolor=clolors.laer2,
text_style=ft.TextStyle(size=s(14)),
padding=ft.padding.symmetric(horizontal=s(16), vertical=s(10)),
),
on_click=on_click,
)
class CastomDropdown(ft.Dropdown):
def __init__(self, label="", hint_text="", options=None, on_change=None):
super().__init__(
label=label,
hint_text=hint_text,
options=options or [],
filled=True,
fill_color=clolors.laer3,
color=clolors.ferst,
border_color=clolors.laer2,
border_radius=s(12),
focused_border_color=clolors.laer1,
label_style=ft.TextStyle(
color=clolors.ferst,
size=s(14),
weight=ft.FontWeight.BOLD,
),
hint_style=ft.TextStyle(
color=clolors.laer1,
size=s(14),
italic=True,
),
text_style=ft.TextStyle(
color=clolors.ferst,
size=s(16),
),
menu_style=ft.MenuStyle(
bgcolor=clolors.laer3,
),
)
if on_change is not None:
self.on_select = on_change
class CastomSwitch(ft.Switch):
def __init__(self, label, on_change):
super().__init__(
label=label,
label_text_style=ft.TextStyle(size=s(12), color=clolors.ferst),
active_color=clolors.ferst,
active_track_color=clolors.laer1,
inactive_thumb_color=clolors.laer2,
inactive_track_color=clolors.laer3,
on_change=on_change
)
class AlterDiaalogApproval(ft.AlertDialog):
def __init__(self, on_accept=None):
self._on_accept = on_accept
self.switch_approval = CastomSwitch(
label="Я согласен с условиями пользовательского соглашения",
on_change=self.switch_changed
)
self.button_approval = CastomButton(
text="Принять",
on_click=self.accept
)
self.button_approval.disabled = True
super().__init__(
bgcolor=clolors.laer3,
title=ft.Text(
"Пользовательское соглашение",
color=clolors.ferst,
size=s(16),
weight=ft.FontWeight.BOLD,
),
content=ft.Container(
width=s(350),
height=s(400),
content=ft.Column(
scroll=ft.ScrollMode.AUTO,
expand=True,
controls=[
ft.Markdown(
"""
# ПОЛЬЗОВАТЕЛЬСКОЕ СОГЛАШЕНИЕ
## 1. ОБЩИЕ ПОЛОЖЕНИЯ
Настоящее Пользовательское соглашение (далее — «Соглашение») регулирует отношения между администрацией сайта https://copp74.ru (далее — «Сайт», «Мы», «Администрация») и пользователем (далее — «Пользователь», «Вы»).
Используя Сайт, Вы автоматически соглашаетесь со всеми условиями настоящего Соглашения. Если Вы не согласны с этими условиями, пожалуйста, не используйте Сайт.
## 2. ОПИСАНИЕ САЙТА
Сайт https://copp74.ru представляет собой онлайн-платформу для прохождения тестов и проверки знаний. Основная функция Сайта — предоставление Пользователям возможности проходить различные тесты и получать результаты.
## 3. РЕГИСТРАЦИЯ И ЛИЧНЫЕ ДАННЫЕ
### 3.1 Регистрация
Для использования Сайта Пользователь должен зарегистрироваться и указать следующую информацию:
- Фамилию
- Имя
- Учебное заведение (образовательную организацию)
### 3.2 Назначение личных данных
Указанные фамилия, имя и учебное заведение используются исключительно для:
- Идентификации Пользователя в системе
- Отображения результатов тестирования
- Ведения статистики прохождения тестов
- Организации пользователей по учебным заведениям для аналитики
- Внутреннего анализа и улучшения качества тестирования
### 3.3 Защита личных данных
**Мы гарантируем, что Ваши персональные данные (фамилия, имя и информация об учебном заведении):**
- Не будут переданы третьим лицам или организациям без Вашего согласия
- Не будут использованы в коммерческих целях
- Не будут распространяться без Вашего согласия
- Хранятся в защищенной базе данных
Данные будут удалены в соответствии с законодательством Российской Федерации по защите персональных данных при закрытии аккаунта или по запросу Пользователя.
## 4. ПРАВА И ОБЯЗАННОСТИ ПОЛЬЗОВАТЕЛЯ
### 4.1 Права Пользователя
Пользователь имеет право:
- Проходить тесты, размещенные на Сайте
- Получать результаты своего тестирования
- Запросить удаление своего аккаунта и данных
- Обратиться в поддержку по вопросам использования Сайта
- Получить информацию о том, как его данные обрабатываются
### 4.2 Обязанности Пользователя
Пользователь обязуется:
- Предоставлять достоверную информацию при регистрации
- Указывать корректное название учебного заведения
- Не использовать Сайт в противоправных целях
- Не пытаться получить несанкционированный доступ к системам Сайта
- Не воспроизводить, не копировать и не распространять содержимое Сайта без разрешения
- Соблюдать все применимые законы Российской Федерации
## 5. ОГРАНИЧЕНИЕ ОТВЕТСТВЕННОСТИ
### 5.1 Предоставление Сайта «Как есть»
Сайт предоставляется в режиме «как есть» без каких-либо явных или подразумеваемых гарантий. Администрация не гарантирует:
- Непрерывную работу Сайта
- Отсутствие ошибок в тестах или результатах
- Соответствие Сайта конкретным целям Пользователя
### 5.2 Ограничение ответственности
В максимальной степени, допускаемой законодательством Российской Федерации, Администрация не несет ответственность за:
- Убытки, возникшие в результате использования или невозможности использования Сайта
- Технические сбои, потерю данных
- Ущерб, причиненный прямо или косвенно в связи с использованием Сайта
## 6. ИНТЕЛЛЕКТУАЛЬНАЯ СОБСТВЕННОСТЬ
Все содержимое Сайта, включая тесты, вопросы, задания, дизайн, логотипы и тексты, защищено авторским правом и законами об интеллектуальной собственности Российской Федерации. Пользователь не имеет права использовать это содержимое в коммерческих целях без письменного разрешения Администрации.
## 7. ИЗМЕНЕНИЕ СОГЛАШЕНИЯ
Администрация оставляет за собой право изменять условия настоящего Соглашения в любое время. Изменения вступают в силе с момента их публикации на Сайте. Продолжение использования Сайта после публикации изменений означает согласие Пользователя с новыми условиями.
## 8. ПРЕКРАЩЕНИЕ ДОСТУПА
Администрация может заблокировать доступ Пользователя к Сайту без предварительного уведомления, если:
- Пользователь нарушает условия настоящего Соглашения
- Пользователь использует Сайт в противоправных целях
- Пользователь предоставил поддельную информацию при регистрации
## 9. КОНФИДЕНЦИАЛЬНОСТЬ
Пожалуйста, ознакомьтесь с нашей Политикой конфиденциальности, которая описывает, как мы обращаемся с Вашими личными данными и какие меры безопасности мы применяем.
## 10. ПРИМЕНИМОЕ ПРАВО
Настоящее Соглашение регулируется законодательством Российской Федерации. Все споры, возникающие в связи с Соглашением, подлежат разрешению в судах Российской Федерации.
## 11. КОНТАКТНАЯ ИНФОРМАЦИЯ
Если у Вас есть вопросы по данному Соглашению или функционированию Сайта https://copp74.ru, свяжитесь с нами через форму обратной связи на Сайте.
## 12. ЗАКЛЮЧИТЕЛЬНЫЕ ПОЛОЖЕНИЯ
Если какая-либо часть настоящего Соглашения будет признана недействительной, остальные положения остаются в полной силе.
Пользователь подтверждает, что прочитал, понял и согласен со всеми условиями настоящего Соглашения перед использованием Сайта.
**Дата последнего обновления:** 19.03.2026
---
*Соглашение соответствует законодательству Российской Федерации, включая Федеральный закон «О защите персональных данных» и Федеральный закон «О защите прав потребителей».*
""",
expand=True,
md_style_sheet=ft.MarkdownStyleSheet(
p_text_style=ft.TextStyle(color=clolors.ferst, size=s(12)),
h1_text_style=ft.TextStyle(color=clolors.ferst, size=s(18), weight=ft.FontWeight.BOLD),
h2_text_style=ft.TextStyle(color=clolors.ferst, size=s(15), weight=ft.FontWeight.BOLD),
h3_text_style=ft.TextStyle(color=clolors.laer1, size=s(13), weight=ft.FontWeight.BOLD),
a_text_style=ft.TextStyle(color=clolors.laer1),
),
)
]
),
),
actions=[
ft.Column(
width=s(350),
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
controls=[
ft.Row(
expand=True,
alignment=ft.MainAxisAlignment.START,
controls=[
ft.Container(
width=s(330),
content=self.switch_approval,
),
]
),
ft.Row(
expand=True,
alignment=ft.MainAxisAlignment.CENTER,
controls=[
self.button_approval,
]
)
]
)
],
actions_alignment=ft.MainAxisAlignment.CENTER,
)
def switch_changed(self, e):
#self.switch_approval.value = not e.control.value
self.button_approval.disabled = not e.control.value
self.update()
def accept(self, e):
self.open = False
self.page.update()
if self._on_accept:
self._on_accept()
else:
self.page.run_task(self.page.push_route, "/reg")