diff --git a/UI/run.sh b/UI/run.sh new file mode 100644 index 0000000..e4263c3 --- /dev/null +++ b/UI/run.sh @@ -0,0 +1 @@ +flet --web --port 6001 . \ No newline at end of file diff --git a/UI/src/main.py b/UI/src/main.py index 09042eb..565b9a9 100644 --- a/UI/src/main.py +++ b/UI/src/main.py @@ -2,118 +2,10 @@ import flet as ft from flet.core.page import RouteChangeEvent from pages.profile import profile -from requests.board_games import get_sections, get_games +from pages.root import root from requests.auth import login as login_req, registration -def root(page: ft.Page): - def update_games(section): - current_section.value = section - games = get_games(None if section == "Все" else section) - grid.controls.clear() - for game in games: - grid.controls.append( - ft.Column([ - ft.Text(str(game)), - ft.Row([ - ft.IconButton(icon=ft.icons.SHOPPING_CART), - ft.IconButton(icon=ft.icons.FAVORITE), - ]), - ]) - ) - page.update() - - sections = [*get_sections(), "Все"] - - sections_buttons = [ft.Button(section, on_click=lambda e, s=section: update_games(s)) for section in sections] - - games = get_games() - - current_section = ft.Ref[str]() - - grid = ft.GridView( - expand=1, - runs_count=5, - max_extent=200, - child_aspect_ratio=1.0, - spacing=5, - run_spacing=5, - ) - - for game in games: - grid.controls.append( - ft.Column([ - ft.Text(str(game)), - ft.Row([ - ft.IconButton( - icon=ft.Icons.SHOPPING_CART - ), - ft.IconButton( - icon=ft.Icons.FAVORITE - ) - ]) - ]) - ) - - def go_to_login(): - page.route = "/login" - page.update() - - def go_to_register(): - page.route = "/register" - page.update() - - def go_to_profile(): - page.route = "/profile" - page.update() - - def logout(): - page.client_storage.remove("user_id") - page.clean() - root(page) - page.update() - - user_id = page.client_storage.get("user_id") - - page.add( - ft.Row( - [ - ft.Text( - "Весёлые кубики", - color="#59799f", - size=24, - weight=ft.FontWeight.BOLD, - ), - ft.Row([ - ft.Button( - text="Вход", - on_click=lambda e: go_to_login(), - ), - ft.Button( - text="Регистрация", - on_click=lambda e: go_to_register(), - ), - ]) if user_id is None else ft.Row([ - ft.Button( - "Профиль", - on_click=lambda e: go_to_profile() - ), - ft.Button( - text="Выйти", - on_click=lambda e: logout(), - ) - ]) - ], - alignment=ft.MainAxisAlignment.SPACE_BETWEEN, # Adjust alignment if needed - ), - ft.Column( - [ft.Row(sections_buttons, alignment=ft.MainAxisAlignment.CENTER)], - alignment=ft.MainAxisAlignment.START - ), - grid - ) - - def login(page): def close_banner(e): page.close(banner) @@ -268,4 +160,3 @@ def main(page: ft.Page): ft.app(main) - diff --git a/UI/src/models/discount.py b/UI/src/models/discount.py new file mode 100644 index 0000000..dff51c5 --- /dev/null +++ b/UI/src/models/discount.py @@ -0,0 +1,4 @@ +class Discount: + def __init__(self, game_id, discount): + self.game_id = game_id + self.discount = discount diff --git a/UI/src/models/game.py b/UI/src/models/game.py index b5e99a0..7df079d 100644 --- a/UI/src/models/game.py +++ b/UI/src/models/game.py @@ -1,11 +1,18 @@ +import math +import re + + class Game: - def __init__(self, board_game_id, name, genre, publisher, price, count = None): + def __init__(self, board_game_id, name, genre, publisher, price, count = None, discount = None): self.board_game_id = board_game_id self.name = name self.genre = genre self.publisher = publisher self.price = price self.count = count + self.discount = discount def __str__(self): - return f"{self.name}\nЖанр: {self.genre}\nИздатель: {self.publisher}\n{self.price}" + (f"\n{self.count} шт." if self.count is not None else "") + cleaned_string = self.price.replace("\u202f", "")[:-2] + cleaned_string = cleaned_string.replace(",", ".") + return f"{self.name}\nЖанр: {self.genre}\nИздатель: {self.publisher}\n" + (str(self.price) if self.discount is None else f"{math.ceil(float(cleaned_string) * self.discount / 100)} -{self.discount}%") + (f"\n{self.count} шт." if self.count is not None else "") diff --git a/UI/src/pages/profile.py b/UI/src/pages/profile.py index e61c4f3..97a1716 100644 --- a/UI/src/pages/profile.py +++ b/UI/src/pages/profile.py @@ -1,6 +1,7 @@ import flet as ft from requests.auth import get_user +from requests.board_games import get_user_discounts from requests.clients import get_wishlist, get_cart, get_history @@ -17,6 +18,18 @@ def profile(page: ft.Page): cart = get_cart(user.id) history = get_history(user.id) + discounts = get_user_discounts(user.id) + + for game in wishlist: + for d in discounts: + if d.game_id == game.board_game_id: + game.discount = d.discount + + for game in cart: + for d in discounts: + if d.game_id == game.board_game_id: + game.discount = d.discount + page.add(ft.Column([ ft.TextButton("Назад", on_click=back_clicked), ft.Text(f"Здравствуйте, {user.forename} {user.patronymic}!", size=24), diff --git a/UI/src/pages/root.py b/UI/src/pages/root.py new file mode 100644 index 0000000..4393886 --- /dev/null +++ b/UI/src/pages/root.py @@ -0,0 +1,121 @@ +import flet as ft +from requests.board_games import get_sections, get_games, get_user_discounts + + +def root(page: ft.Page): + def update_games(section): + current_section.value = section + games = get_games(None if section == "Все" else section) + grid.controls.clear() + for game in games: + grid.controls.append( + ft.Column([ + ft.Text(str(game)), + ft.Row([ + ft.IconButton(icon=ft.icons.SHOPPING_CART), + ft.IconButton(icon=ft.icons.FAVORITE), + ]), + ]) + ) + page.update() + + sections = [*get_sections(), "Все"] + + sections_buttons = [ft.Button(section, on_click=lambda e, s=section: update_games(s)) for section in sections] + + games = get_games() + + current_section = ft.Ref[str]() + + user_id = page.client_storage.get("user_id"); + + discounts = [] + + if user_id is not None: + discounts = get_user_discounts(user_id) + + grid = ft.GridView( + expand=1, + runs_count=5, + max_extent=200, + child_aspect_ratio=1.0, + spacing=5, + run_spacing=5, + ) + + for game in games: + for d in discounts: + if d.game_id == game.board_game_id: + game.discount = d.discount + + grid.controls.append( + ft.Column([ + ft.Text(str(game)), + ft.Row([ + ft.IconButton( + icon=ft.Icons.SHOPPING_CART + ), + ft.IconButton( + icon=ft.Icons.FAVORITE + ) + ]) + ]) + ) + + def go_to_login(): + page.route = "/login" + page.update() + + def go_to_register(): + page.route = "/register" + page.update() + + def go_to_profile(): + page.route = "/profile" + page.update() + + def logout(): + page.client_storage.remove("user_id") + page.clean() + root(page) + page.update() + + user_id = page.client_storage.get("user_id") + + page.add( + ft.Row( + [ + ft.Text( + "Весёлые кубики", + color="#59799f", + size=24, + weight=ft.FontWeight.BOLD, + ), + ft.Row([ + ft.Button( + text="Вход", + on_click=lambda e: go_to_login(), + ), + ft.Button( + text="Регистрация", + on_click=lambda e: go_to_register(), + ), + ]) if user_id is None else ft.Row([ + ft.Button( + "Профиль", + on_click=lambda e: go_to_profile() + ), + ft.Button( + text="Выйти", + on_click=lambda e: logout(), + ) + ]) + ], + alignment=ft.MainAxisAlignment.SPACE_BETWEEN, # Adjust alignment if needed + ), + ft.Column( + [ft.Row(sections_buttons, alignment=ft.MainAxisAlignment.CENTER)], + alignment=ft.MainAxisAlignment.START + ), + grid + ) \ No newline at end of file diff --git a/UI/src/requests/board_games.py b/UI/src/requests/board_games.py index 5f8a7a3..374e7eb 100644 --- a/UI/src/requests/board_games.py +++ b/UI/src/requests/board_games.py @@ -1,5 +1,6 @@ import psycopg2 +from models.discount import Discount from models.game import Game from requests.connection import get_cursor @@ -32,3 +33,14 @@ def get_games(section = None): res = [Game(game[1], game[2], game[3], game[4], game[5]) for game in cursor.fetchall()] return res + +def get_user_discounts(user_id): + cursor = get_cursor()[0] + + cursor.execute(f""" + select discounts.board_game_id, discounts.amount + from discounts join clients_discounts on discounts.discount_id = clients_discounts.discount + where clients_discounts.client_id = {user_id} + """) + + return [Discount(res[0], res[1]) for res in cursor.fetchall()]