diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/__pycache__/config.cpython-313.pyc b/__pycache__/config.cpython-313.pyc index 700288b..a11615e 100644 Binary files a/__pycache__/config.cpython-313.pyc and b/__pycache__/config.cpython-313.pyc differ diff --git a/assets/settings.png b/assets/settings.png new file mode 100644 index 0000000..10cc589 Binary files /dev/null and b/assets/settings.png differ diff --git a/config.py b/config.py index be71e20..9eb19e0 100644 --- a/config.py +++ b/config.py @@ -1,6 +1,12 @@ -# config.py +# Админ-интерфейс (тёмные цвета) +ADMIN_BACKGROUND_COLOR = "#403d49" +ADMIN_PRIMARY_COLOR = "#ff6347" +ADMIN_BUTTON_COLOR = "#444444" +ADMIN_BUTTON_TEXT_COLOR = "#ffffff" +ADMIN_FONT = ("Comic Sans MS", 25) +ADMIN_BIG_FONT = ("Comic Sans MS", 40) -# Интерфейс +# Интерфейс пользователя BACKGROUND_COLOR = "#f8e1e1" PRIMARY_COLOR = "#ff6347" BUTTON_COLOR = "#87ceeb" @@ -14,3 +20,6 @@ ADMIN_PASSWORD = "admin123" # База данных DATABASE_URL = "sqlite:///database/DogAcademy.db" # Обновлено на правильный путь + +# Иконки +SETTINGS_IMG = "assets/settings.png" diff --git a/database/DogAcademy.db b/database/DogAcademy.db index 3f0c2bb..695b547 100644 Binary files a/database/DogAcademy.db and b/database/DogAcademy.db differ diff --git a/database/__pycache__/db_events.cpython-313.pyc b/database/__pycache__/db_events.cpython-313.pyc index 87f6cf4..b221d76 100644 Binary files a/database/__pycache__/db_events.cpython-313.pyc and b/database/__pycache__/db_events.cpython-313.pyc differ diff --git a/database/__pycache__/db_session.cpython-313.pyc b/database/__pycache__/db_session.cpython-313.pyc index ba13851..d7d1221 100644 Binary files a/database/__pycache__/db_session.cpython-313.pyc and b/database/__pycache__/db_session.cpython-313.pyc differ diff --git a/database/__pycache__/models.cpython-313.pyc b/database/__pycache__/models.cpython-313.pyc index 00ae4eb..9b809a5 100644 Binary files a/database/__pycache__/models.cpython-313.pyc and b/database/__pycache__/models.cpython-313.pyc differ diff --git a/database/db_session.py b/database/db_session.py index 7e8b40e..70b39dc 100644 --- a/database/db_session.py +++ b/database/db_session.py @@ -10,6 +10,7 @@ engine = create_engine(DATABASE_URL, echo=True) # Создание фабрики сессий Session = sessionmaker(bind=engine) +session = Session() def init_db(): """Инициализация базы данных: создание файла и таблиц.""" diff --git a/requirements b/requirements index 5c10195..fb6d71e 100644 --- a/requirements +++ b/requirements @@ -1,2 +1,3 @@ sqlalchemy tk +matplotlib>=3.7.0 diff --git a/src/__pycache__/utils.cpython-313.pyc b/src/__pycache__/utils.cpython-313.pyc new file mode 100644 index 0000000..5416ad6 Binary files /dev/null and b/src/__pycache__/utils.cpython-313.pyc differ diff --git a/src/admin_functions/__pycache__/admin_logging.cpython-313.pyc b/src/admin_functions/__pycache__/admin_logging.cpython-313.pyc new file mode 100644 index 0000000..0a722fc Binary files /dev/null and b/src/admin_functions/__pycache__/admin_logging.cpython-313.pyc differ diff --git a/src/admin_functions/__pycache__/content.cpython-313.pyc b/src/admin_functions/__pycache__/content.cpython-313.pyc new file mode 100644 index 0000000..67ab341 Binary files /dev/null and b/src/admin_functions/__pycache__/content.cpython-313.pyc differ diff --git a/src/admin_functions/__pycache__/db_management.cpython-313.pyc b/src/admin_functions/__pycache__/db_management.cpython-313.pyc new file mode 100644 index 0000000..5ae9899 Binary files /dev/null and b/src/admin_functions/__pycache__/db_management.cpython-313.pyc differ diff --git a/src/admin_functions/__pycache__/knowledge_base.cpython-313.pyc b/src/admin_functions/__pycache__/knowledge_base.cpython-313.pyc new file mode 100644 index 0000000..eb42481 Binary files /dev/null and b/src/admin_functions/__pycache__/knowledge_base.cpython-313.pyc differ diff --git a/src/admin_functions/__pycache__/statistics.cpython-313.pyc b/src/admin_functions/__pycache__/statistics.cpython-313.pyc new file mode 100644 index 0000000..b999857 Binary files /dev/null and b/src/admin_functions/__pycache__/statistics.cpython-313.pyc differ diff --git a/src/admin_functions/admin_logging.py b/src/admin_functions/admin_logging.py new file mode 100644 index 0000000..5a2204b --- /dev/null +++ b/src/admin_functions/admin_logging.py @@ -0,0 +1,32 @@ +import tkinter as tk +from tkinter import ttk +import csv +from src.utils import clear_frame + +def show_logs(frame): + """Отображение логов действий пользователей.""" + clear_frame(frame) + tk.Label(frame, text="Логи действий", font=("Comic Sans MS", 16)).pack() + + table = ttk.Treeview(frame, columns=("Время", "Действие", "Пользователь"), show="headings") + table.heading("Время", text="Время") + table.heading("Действие", text="Действие") + table.heading("Пользователь", text="Пользователь") + table.pack(fill="both", expand=True) + + # Добавьте логи для примера + table.insert("", "end", values=("2024-11-19 12:30", "Добавление вопроса", "admin")) + table.insert("", "end", values=("2024-11-19 13:00", "Удаление пользователя", "moderator")) + + +def export_logs(): + data = [ + ("2024-11-19 12:30", "Добавление вопроса", "admin"), + ("2024-11-19 13:00", "Удаление пользователя", "moderator"), + ] + with open("logs.csv", "w", newline="", encoding="utf-8") as file: + writer = csv.writer(file) + writer.writerow(["Время", "Действие", "Пользователь"]) + writer.writerows(data) + print("Логи успешно экспортированы в logs.csv") + diff --git a/src/admin_functions/content.py b/src/admin_functions/content.py new file mode 100644 index 0000000..281aaa6 --- /dev/null +++ b/src/admin_functions/content.py @@ -0,0 +1,17 @@ +import tkinter as tk +from src.utils import clear_frame + +def manage_levels(frame): + """Создание и настройка уровней.""" + clear_frame(frame) + tk.Label(frame, text="Создание и настройка уровней", font=("Comic Sans MS", 16)).pack() + + # Добавить интерфейс для добавления уровней + + +def manage_dog_params(frame): + """Настройка параметров собаки.""" + clear_frame(frame) + tk.Label(frame, text="Настройка параметров собаки", font=("Comic Sans MS", 16)).pack() + + # Добавить поля для параметров, например, здоровье, голод, сонливость \ No newline at end of file diff --git a/src/admin_functions/db_management.py b/src/admin_functions/db_management.py new file mode 100644 index 0000000..23c9fe0 --- /dev/null +++ b/src/admin_functions/db_management.py @@ -0,0 +1,36 @@ +import tkinter as tk +from tkinter import ttk +from sqlalchemy.orm import sessionmaker +from database.models import Questions +from database.db_session import engine +from src.utils import clear_frame + +Session = sessionmaker(bind=engine) + +def view_tables(): + # Пример функции, которая будет выводить информацию о таблицах + print("Отображаем таблицы базы данных.") + +def edit_users(): + # Код для редактирования пользователей + pass + +def manage_questions(frame): + """Функция для управления вопросами.""" + clear_frame(frame) + + tk.Label(frame, text="Управление вопросами", font=("Comic Sans MS", 16)).pack() + + session = Session() + questions = session.query(Questions).all() + + table = ttk.Treeview(frame, columns=("ID", "Вопрос", "Ответ"), show="headings") + table.heading("ID", text="ID") + table.heading("Вопрос", text="Вопрос") + table.heading("Ответ", text="Ответ") + table.pack(fill="both", expand=True) + + for question in questions: + table.insert("", "end", values=(question.id, question.text, question.answer)) + + session.close() \ No newline at end of file diff --git a/src/admin_functions/knowledge_base.py b/src/admin_functions/knowledge_base.py new file mode 100644 index 0000000..88dadaa --- /dev/null +++ b/src/admin_functions/knowledge_base.py @@ -0,0 +1,50 @@ +from tkinter import ttk +import tkinter as tk +from src.utils import clear_frame + +def add_info(frame): + """Добавление информации о породах собак.""" + clear_frame(frame) + tk.Label(frame, text="Добавление информации", font=("Comic Sans MS", 16)).pack() + + # Реализовать интерфейс для добавления данных + + +def edit_records(frame): + """Редактирование записей в базе знаний.""" + clear_frame(frame) + tk.Label(frame, text="Редактирование записей", font=("Comic Sans MS", 16)).pack() + + # Реализовать интерфейс для редактирования записей + + +def delete_records(frame): + """Удаление записей из базы знаний.""" + clear_frame(frame) + tk.Label(frame, text="Удаление записей", font=("Comic Sans MS", 16)).pack() + + # Реализовать интерфейс для удаления данных + + +def view_knowledge_base(frame): + """Просмотр базы знаний.""" + clear_frame(frame) + tk.Label(frame, text="База знаний", font=("Comic Sans MS", 16)).pack() + + table = ttk.Treeview(frame, columns=("Порода", "Описание"), show="headings") + table.heading("Порода", text="Порода") + table.heading("Описание", text="Описание") + table.pack(fill="both", expand=True) + + # Пример данных + table.insert("", "end", values=("Лабрадор", "Дружелюбная порода")) + table.insert("", "end", values=("Доберман", "Отличный сторож")) + + +def generate_questions(frame): + """Генерация вопросов на основе текстов.""" + clear_frame(frame) + tk.Label(frame, text="Генерация вопросов", font=("Comic Sans MS", 16)).pack() + + # Реализовать генерацию вопросов + diff --git a/src/admin_functions/statistics.py b/src/admin_functions/statistics.py new file mode 100644 index 0000000..adb4ca2 --- /dev/null +++ b/src/admin_functions/statistics.py @@ -0,0 +1,24 @@ +import tkinter as tk +from tkinter import ttk +import matplotlib.pyplot as plt +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg +from src.utils import clear_frame + +def show_statistics(frame): + """Отображение статистики пользователей и уровней.""" + clear_frame(frame) + tk.Label(frame, text="Статистика пользователей", font=("Comic Sans MS", 16)).pack() + + # Пример: график с количеством пользователей + fig, ax = plt.subplots() + ax.bar(["Level 1", "Level 2", "Level 3"], [10, 15, 8]) # Пример данных + ax.set_title("Популярность уровней") + ax.set_xlabel("Уровни") + ax.set_ylabel("Количество прохождений") + + canvas = FigureCanvasTkAgg(fig, master=frame) + canvas.get_tk_widget().pack(fill="both", expand=True) + canvas.draw() + + + diff --git a/src/main.py b/src/main.py index 2fce195..992fe5d 100644 --- a/src/main.py +++ b/src/main.py @@ -1,14 +1,22 @@ from tkinter import Tk +from tkinter import messagebox from src.ui.auth_ui import DogAcademyApp # Изменил на правильный путь from database.db_session import init_db +def on_close(): + """Обработчик закрытия окна.""" + if messagebox.askokcancel("Выход", "Вы действительно хотите выйти?"): + root.destroy() + def main(): """Основной запуск приложения.""" + global root # Инициализируем базу данных init_db() # Запускаем графический интерфейс root = Tk() + root.protocol("WM_DELETE_WINDOW", on_close) app = DogAcademyApp(root) root.mainloop() diff --git a/src/ui/__pycache__/admin_ui.cpython-313.pyc b/src/ui/__pycache__/admin_ui.cpython-313.pyc index 0261396..af8aa7a 100644 Binary files a/src/ui/__pycache__/admin_ui.cpython-313.pyc and b/src/ui/__pycache__/admin_ui.cpython-313.pyc differ diff --git a/src/ui/__pycache__/auth_ui.cpython-313.pyc b/src/ui/__pycache__/auth_ui.cpython-313.pyc index 452c157..3ab9d5c 100644 Binary files a/src/ui/__pycache__/auth_ui.cpython-313.pyc and b/src/ui/__pycache__/auth_ui.cpython-313.pyc differ diff --git a/src/ui/admin_ui.py b/src/ui/admin_ui.py index b94d102..7390bb8 100644 --- a/src/ui/admin_ui.py +++ b/src/ui/admin_ui.py @@ -1,59 +1,163 @@ -# admin_ui.py import tkinter as tk -from config import BACKGROUND_COLOR, PRIMARY_COLOR, BUTTON_COLOR, BUTTON_TEXT_COLOR, FONT +from PIL import Image, ImageTk +from config import SETTINGS_IMG +from src.admin_functions import db_management, admin_logging, statistics, content, knowledge_base +from src.utils import clear_frame # Импортируем общую функцию для очистки фрейма + + +# Конфигурация цветов из config.py +BACKGROUND_COLOR = "#403d49" +TOP_BAR_COLOR = "#383441" +TEXT_COLOR = "#b2acc0" +BUTTON_COLOR = "#403d49" +MENU_COLOR = "#2f2b38" +MENU_OPACITY = 0.9 # Прозрачность меню class AdminApp: def __init__(self, root): self.root = root - self.show_admin_dashboard() + self.root.title("Админ-Панель") + self.root.geometry("1920x1080") + self.root.config(bg=BACKGROUND_COLOR) - def show_admin_dashboard(self): - """Показать интерфейс администратора.""" - self.clear_frame() - self.current_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) - self.current_frame.pack(expand=True) + # Верхняя панель + self.top_bar = tk.Frame(self.root, bg=TOP_BAR_COLOR, height=60) + self.top_bar.pack(side="top", fill="x") - # Заголовок - title = tk.Label( - self.current_frame, - text="Админ-Панель", - bg=BACKGROUND_COLOR, - fg=PRIMARY_COLOR, - font=FONT, + # Кнопка настроек + settings_img = Image.open(SETTINGS_IMG) + settings_img = settings_img.resize((40, 40), Image.Resampling.LANCZOS) + settings_icon = ImageTk.PhotoImage(settings_img) + + self.settings_button = tk.Button( + self.top_bar, + image=settings_icon, + bg=TOP_BAR_COLOR, + activebackground=TOP_BAR_COLOR, + bd=0 ) - title.pack(pady=50) + self.settings_button.image = settings_icon # Сохраняем ссылку на изображение + self.settings_button.pack(side="left", padx=10, pady=10) - # Кнопка для управления вопросами - manage_questions_button = tk.Button( - self.current_frame, - text="Управление вопросами", + # Кнопки навигации + self.create_nav_button("Логирование", admin_logging.show_logs) + self.create_nav_button("Статистика", statistics.show_statistics) + self.create_nav_button("Уведомления", self.show_notifications) + self.create_nav_button("Безопасность", self.show_security) + + # Бургер-меню + self.menu_button = tk.Button( + self.top_bar, + text="☰ Меню", bg=BUTTON_COLOR, - fg=BUTTON_TEXT_COLOR, - font=FONT, - command=self.manage_questions, + fg=TEXT_COLOR, + font=("Comic Sans MS", 14), + activebackground=BUTTON_COLOR, + activeforeground=TEXT_COLOR, + bd=0, + command=self.toggle_menu # Проверьте, что эта команда правильно привязана ) - manage_questions_button.pack(pady=20) + self.menu_button.pack(side="right", padx=10, pady=10) - # Кнопка для управления пользователями - manage_users_button = tk.Button( - self.current_frame, - text="Управление пользователями", + # Основное окно + self.main_frame = tk.Frame(self.root, bg=BACKGROUND_COLOR) + self.main_frame.pack(fill="both", expand=True) + + # Бургер-меню (скрытое по умолчанию) + self.menu_frame = tk.Frame(self.root, bg=MENU_COLOR, width=300) + self.menu_frame.place(x=1620, y=60, width=300, height=1020) # Явно задаём ширину и высоту + self.menu_frame.lower() # Прячем меню + self.menu_visible = False # Добавлен флаг для отслеживания состояния меню + + def toggle_menu(self): + """Показ или скрытие меню.""" + print( + f"Кнопка меню нажата. Меню сейчас {'видимо' if self.menu_visible else 'скрыто'}") # Отладка + if self.menu_visible: # Используем флаг для проверки состояния + print("Скрываем меню") # Отладка + self.menu_frame.lower() # Скрываем меню + self.menu_visible = False + else: + print("Показываем меню") # Отладка + self.menu_frame.lift() # Показываем меню + self.menu_visible = True + self.populate_menu() # Наполнение меню элементами + + def populate_menu(self): + # Очистка меню + for widget in self.menu_frame.winfo_children(): + widget.destroy() + # Создание пунктов меню + self.create_menu_section("Работа с базой данных", [ + ("Редактирование пользователей", db_management.edit_users), + ("Управление вопросами", db_management.manage_questions), + ("Просмотр таблиц", db_management.view_tables), + ]) + self.create_menu_section("Управление игровым контентом", [ + ("Создание и настройка уровней", content.manage_levels), + ("Настройка параметров собаки", content.manage_dog_params), + ]) + self.create_menu_section("Управление интерфейсом пользователя", [ + ("Изменение цветовой схемы, фона и логотипа", self.change_ui_settings), + ("Добавление подсказок в интерфейс", self.manage_ui_tips), + ]) + self.create_menu_section("Работа с базой знаний", [ + ("Добавление информации", knowledge_base.add_info), + ("Редактирование записей", knowledge_base.edit_records), + ("Удаление записей", knowledge_base.delete_records), + ("Просмотр базы знаний", knowledge_base.view_knowledge_base), + ("Генерация вопросов", knowledge_base.generate_questions), + ]) + + def create_menu_section(self, title, items): + section_label = tk.Label(self.menu_frame, text=title, bg=MENU_COLOR, fg=TEXT_COLOR, font=("Comic Sans MS", 14, "bold")) + section_label.pack(anchor="w", padx=10, pady=5) + + for text, command in items: + item_button = tk.Button( + self.menu_frame, + text=text, + bg=BUTTON_COLOR, + fg=TEXT_COLOR, + font=("Comic Sans MS", 12), + activebackground=BUTTON_COLOR, + activeforeground=TEXT_COLOR, + bd=0, + command=lambda: command(self.main_frame) # Вызываем функцию и передаём фрейм + ) + item_button.pack(anchor="w", padx=20, pady=2) + + def create_nav_button(self, text, command): + button = tk.Button( + self.top_bar, + text=text, bg=BUTTON_COLOR, - fg=BUTTON_TEXT_COLOR, - font=FONT, - command=self.manage_users, + fg=TEXT_COLOR, + font=("Comic Sans MS", 14), + activebackground=BUTTON_COLOR, + activeforeground=TEXT_COLOR, + bd=0, + padx=10, + pady=5, + command=lambda: command(self.main_frame) # Вызываем переданную функцию ) - manage_users_button.pack(pady=20) + button.pack(side="left", padx=10, pady=10) - def manage_questions(self): - """Управление вопросами в игре.""" - pass + def manage_ui_tips(self, frame): + # Пример логики для управления подсказками + print("Управление подсказками интерфейса.") + # Код для управления подсказками (например, скрытие или показ подсказок) + tk.Label(frame, text="Здесь будут подсказки для интерфейса", bg=BACKGROUND_COLOR, fg=TEXT_COLOR, font=("Comic Sans MS", 16)).pack() - def manage_users(self): - """Управление пользователями игры.""" - pass + def show_notifications(self, frame): + clear_frame(frame) + tk.Label(frame, text="Здесь будут уведомления", bg=BACKGROUND_COLOR, fg=TEXT_COLOR, font=("Comic Sans MS", 16)).pack() - def clear_frame(self): - """Очистить текущий фрейм.""" - if hasattr(self, 'current_frame') and self.current_frame: - self.current_frame.destroy() + def show_security(self, frame): + clear_frame(frame) + tk.Label(frame, text="Раздел Безопасность", bg=BACKGROUND_COLOR, fg=TEXT_COLOR, font=("Comic Sans MS", 16)).pack() + + def change_ui_settings(self, frame): + clear_frame(frame) + """Метод для изменения цветовой схемы, фона и логотипа""" + print("Изменение UI настроек") # Пока просто тестовый вывод diff --git a/src/utils.py b/src/utils.py new file mode 100644 index 0000000..4250849 --- /dev/null +++ b/src/utils.py @@ -0,0 +1,4 @@ +def clear_frame(frame): + """Удаление всех виджетов из фрейма.""" + for widget in frame.winfo_children(): + widget.destroy()