From 7c6e5ec8253116cda23e9a37e1e27b3f929597ee Mon Sep 17 00:00:00 2001
From: nn2-minh <Nguyen12.Minh@live.uwe.ac.uk>
Date: Sat, 15 Mar 2025 17:37:01 +0700
Subject: [PATCH] Add many things

---
 app/frontend/components/admin/category.py     | 51 ++++++++++++++-----
 app/frontend/components/auth/login.py         |  5 +-
 app/frontend/components/auth/register.py      | 24 +++++++--
 .../components/product/create_product.py      | 27 +++++++---
 app/frontend/components/shop/create_shop.py   |  8 ++-
 app/frontend/components/shop/view_shop.py     | 49 +++++++++++++-----
 app/frontend/main.py                          |  4 +-
 7 files changed, 124 insertions(+), 44 deletions(-)

diff --git a/app/frontend/components/admin/category.py b/app/frontend/components/admin/category.py
index c4d3225..29c239e 100644
--- a/app/frontend/components/admin/category.py
+++ b/app/frontend/components/admin/category.py
@@ -2,10 +2,13 @@ import customtkinter as ctk
 import requests
 from tkinter import messagebox
 
+
 def category_frame(parent, switch_func, API_URL, access_token):
     frame = ctk.CTkFrame(parent)
 
-    ctk.CTkLabel(frame, text="Category Management", font=("Helvetica", 18, "bold")).pack(pady=10)
+    ctk.CTkLabel(
+        frame, text="Category Management", font=("Helvetica", 18, "bold")
+    ).pack(pady=10)
 
     ctk.CTkLabel(frame, text="Category Name:").pack(pady=5)
     entry_name = ctk.CTkEntry(frame)
@@ -24,12 +27,18 @@ def category_frame(parent, switch_func, API_URL, access_token):
             return
 
         try:
-            response = requests.post(f"{API_URL}/category", data={"name": name}, headers=headers)
+            response = requests.post(
+                f"{API_URL}/category", data={"name": name}, headers=headers
+            )
             if response.status_code == 200:
-                messagebox.showinfo("Success", f"Category '{name}' created successfully!")
-                entry_name.delete(0, 'end')
+                messagebox.showinfo(
+                    "Success", f"Category '{name}' created successfully!"
+                )
+                entry_name.delete(0, "end")
             else:
-                messagebox.showerror("Error", response.json().get("detail", "Failed to create category"))
+                messagebox.showerror(
+                    "Error", response.json().get("detail", "Failed to create category")
+                )
         except requests.exceptions.RequestException as e:
             messagebox.showerror("Error", f"Failed to connect to server: {e}")
 
@@ -39,7 +48,9 @@ def category_frame(parent, switch_func, API_URL, access_token):
             if response.status_code == 200:
                 categories = response.json()
                 if categories:
-                    category_list = "\n".join([f"{cat['id']}: {cat['name']}" for cat in categories])
+                    category_list = "\n".join(
+                        [f"{cat['id']}: {cat['name']}" for cat in categories]
+                    )
                     messagebox.showinfo("Categories", category_list)
                 else:
                     messagebox.showinfo("Categories", "No categories available.")
@@ -55,17 +66,25 @@ def category_frame(parent, switch_func, API_URL, access_token):
             messagebox.showwarning("Input Error", "Enter a valid Category ID!")
             return
         if not name:
-            messagebox.showwarning("Input Error", "Category name is required for update!")
+            messagebox.showwarning(
+                "Input Error", "Category name is required for update!"
+            )
             return
 
         try:
-            response = requests.put(f"{API_URL}/category/{category_id}", data={"name": name}, headers=headers)
+            response = requests.put(
+                f"{API_URL}/category/{category_id}",
+                data={"name": name},
+                headers=headers,
+            )
             if response.status_code == 200:
                 messagebox.showinfo("Success", "Category updated successfully!")
-                entry_id.delete(0, 'end')
-                entry_name.delete(0, 'end')
+                entry_id.delete(0, "end")
+                entry_name.delete(0, "end")
             else:
-                messagebox.showerror("Error", response.json().get("detail", "Failed to update category"))
+                messagebox.showerror(
+                    "Error", response.json().get("detail", "Failed to update category")
+                )
         except requests.exceptions.RequestException as e:
             messagebox.showerror("Error", f"Failed to connect to server: {e}")
 
@@ -76,12 +95,16 @@ def category_frame(parent, switch_func, API_URL, access_token):
             return
 
         try:
-            response = requests.delete(f"{API_URL}/category/{category_id}", headers=headers)
+            response = requests.delete(
+                f"{API_URL}/category/{category_id}", headers=headers
+            )
             if response.status_code == 200:
                 messagebox.showinfo("Success", "Category deleted successfully!")
-                entry_id.delete(0, 'end')
+                entry_id.delete(0, "end")
             else:
-                messagebox.showerror("Error", response.json().get("detail", "Failed to delete category"))
+                messagebox.showerror(
+                    "Error", response.json().get("detail", "Failed to delete category")
+                )
         except requests.exceptions.RequestException as e:
             messagebox.showerror("Error", f"Failed to connect to server: {e}")
 
diff --git a/app/frontend/components/auth/login.py b/app/frontend/components/auth/login.py
index b0290cc..64a9f81 100644
--- a/app/frontend/components/auth/login.py
+++ b/app/frontend/components/auth/login.py
@@ -2,6 +2,7 @@ import customtkinter as ctk
 from tkinter import messagebox
 import requests
 
+
 def login_frame(parent, switch_func, API_URL):
     frame = ctk.CTkFrame(parent)
 
@@ -24,7 +25,9 @@ def login_frame(parent, switch_func, API_URL):
                 messagebox.showinfo("Login Successful", f"Welcome back, {email}!")
                 switch_func("create_shop", access_token)
             else:
-                messagebox.showerror("Login Failed", response_data.get("detail", "Invalid credentials"))
+                messagebox.showerror(
+                    "Login Failed", response_data.get("detail", "Invalid credentials")
+                )
         except requests.exceptions.JSONDecodeError:
             messagebox.showerror("Login Failed", "Server returned an invalid response.")
 
diff --git a/app/frontend/components/auth/register.py b/app/frontend/components/auth/register.py
index 64b238b..e098132 100644
--- a/app/frontend/components/auth/register.py
+++ b/app/frontend/components/auth/register.py
@@ -2,6 +2,7 @@ import customtkinter as ctk
 from tkinter import messagebox
 import requests
 
+
 def register_frame(parent, switch_func, API_URL):
     frame = ctk.CTkFrame(parent)
 
@@ -12,7 +13,13 @@ def register_frame(parent, switch_func, API_URL):
         password = entry_password.get()
         confirm_password = entry_confirm_password.get()
 
-        if not username or not email or not phone_number or not password or not confirm_password:
+        if (
+            not username
+            or not email
+            or not phone_number
+            or not password
+            or not confirm_password
+        ):
             messagebox.showwarning("Input Error", "All fields are required!")
             return
 
@@ -22,7 +29,12 @@ def register_frame(parent, switch_func, API_URL):
 
         response = requests.post(
             f"{API_URL}/auth/signup",
-            json={"username": username, "email": email, "phone_number": phone_number, "password": password},
+            json={
+                "username": username,
+                "email": email,
+                "phone_number": phone_number,
+                "password": password,
+            },
         )
 
         try:
@@ -31,9 +43,13 @@ def register_frame(parent, switch_func, API_URL):
                 messagebox.showinfo("Registration Successful", f"Welcome, {username}!")
                 switch_func("login")
             else:
-                messagebox.showerror("Registration Failed", response_data.get("detail", "Unknown error"))
+                messagebox.showerror(
+                    "Registration Failed", response_data.get("detail", "Unknown error")
+                )
         except requests.exceptions.JSONDecodeError:
-            messagebox.showerror("Registration Failed", "Server returned an invalid response.")
+            messagebox.showerror(
+                "Registration Failed", "Server returned an invalid response."
+            )
 
     ctk.CTkLabel(frame, text="Register", font=("Helvetica", 18, "bold")).pack(pady=10)
 
diff --git a/app/frontend/components/product/create_product.py b/app/frontend/components/product/create_product.py
index 2fc5b7a..b95400c 100644
--- a/app/frontend/components/product/create_product.py
+++ b/app/frontend/components/product/create_product.py
@@ -2,10 +2,13 @@ import customtkinter as ctk
 import requests
 from tkinter import messagebox
 
+
 def product_frame(parent, switch_func, API_URL, token):
     frame = ctk.CTkFrame(parent)
 
-    ctk.CTkLabel(frame, text="Product Management", font=("Helvetica", 18, "bold")).pack(pady=10)
+    ctk.CTkLabel(frame, text="Product Management", font=("Helvetica", 18, "bold")).pack(
+        pady=10
+    )
 
     ctk.CTkLabel(frame, text="Product Name:").pack(pady=5)
     entry_name = ctk.CTkEntry(frame)
@@ -32,7 +35,9 @@ def product_frame(parent, switch_func, API_URL, token):
             price = float(price)
             stock = int(stock)
         except ValueError:
-            messagebox.showwarning("Input Error", "Price must be a number and Stock must be an integer.")
+            messagebox.showwarning(
+                "Input Error", "Price must be a number and Stock must be an integer."
+            )
             return
 
         headers = {"Authorization": f"Bearer {token}"}
@@ -42,17 +47,23 @@ def product_frame(parent, switch_func, API_URL, token):
             response = requests.post(f"{API_URL}/products", json=data, headers=headers)
 
             if response.status_code == 200:
-                messagebox.showinfo("Success", f"Product '{name}' created successfully!")
-                entry_name.delete(0, 'end')
-                entry_price.delete(0, 'end')
-                entry_stock.delete(0, 'end')
+                messagebox.showinfo(
+                    "Success", f"Product '{name}' created successfully!"
+                )
+                entry_name.delete(0, "end")
+                entry_price.delete(0, "end")
+                entry_stock.delete(0, "end")
             else:
-                error_message = response.json().get("detail", "Failed to create product")
+                error_message = response.json().get(
+                    "detail", "Failed to create product"
+                )
                 messagebox.showerror("Error", error_message)
         except requests.exceptions.RequestException as e:
             messagebox.showerror("Error", f"Failed to connect to server: {e}")
 
     ctk.CTkButton(frame, text="Create Product", command=create_product).pack(pady=15)
-    ctk.CTkButton(frame, text="Back", command=lambda: switch_func("view_shop")).pack(pady=5)
+    ctk.CTkButton(frame, text="Back", command=lambda: switch_func("view_shop")).pack(
+        pady=5
+    )
 
     return frame
diff --git a/app/frontend/components/shop/create_shop.py b/app/frontend/components/shop/create_shop.py
index d7ac4e3..5319ebe 100644
--- a/app/frontend/components/shop/create_shop.py
+++ b/app/frontend/components/shop/create_shop.py
@@ -63,7 +63,9 @@ def create_shop_frame(parent, switch_func, API_URL, token):
         except Exception as e:
             messagebox.showerror("Request Error", str(e))
 
-    ctk.CTkLabel(frame, text="Create Shop", font=("Helvetica", 18, "bold")).pack(pady=10)
+    ctk.CTkLabel(frame, text="Create Shop", font=("Helvetica", 18, "bold")).pack(
+        pady=10
+    )
 
     ctk.CTkLabel(frame, text="Shop Name:").pack(pady=5)
     entry_name = ctk.CTkEntry(frame, placeholder_text="Enter shop name")
@@ -77,7 +79,9 @@ def create_shop_frame(parent, switch_func, API_URL, token):
     file_label = ctk.CTkLabel(frame, text="No file selected")
     file_label.pack(pady=5)
 
-    ctk.CTkButton(frame, text="Create Shop", fg_color="green", command=create_shop).pack(pady=15)
+    ctk.CTkButton(
+        frame, text="Create Shop", fg_color="green", command=create_shop
+    ).pack(pady=15)
 
     ctk.CTkButton(
         frame,
diff --git a/app/frontend/components/shop/view_shop.py b/app/frontend/components/shop/view_shop.py
index 2c10314..a5b9141 100644
--- a/app/frontend/components/shop/view_shop.py
+++ b/app/frontend/components/shop/view_shop.py
@@ -4,6 +4,7 @@ from tkinter import messagebox
 from PIL import Image, ImageTk
 import io
 
+
 def view_shop_frame(parent, switch_func, API_URL, token):
     frame = ctk.CTkFrame(parent)
 
@@ -12,10 +13,14 @@ def view_shop_frame(parent, switch_func, API_URL, token):
     title_label.pack(pady=10)
 
     # Shop Details
-    shop_name_label = ctk.CTkLabel(frame, text="Shop Name: ", font=("Helvetica", 14, "bold"))
+    shop_name_label = ctk.CTkLabel(
+        frame, text="Shop Name: ", font=("Helvetica", 14, "bold")
+    )
     shop_name_label.pack(pady=5)
-    
-    shop_description_label = ctk.CTkLabel(frame, text="Description: ", font=("Helvetica", 12))
+
+    shop_description_label = ctk.CTkLabel(
+        frame, text="Description: ", font=("Helvetica", 12)
+    )
     shop_description_label.pack(pady=5)
 
     shop_image_label = ctk.CTkLabel(frame, text="")  # Placeholder for shop image
@@ -26,14 +31,18 @@ def view_shop_frame(parent, switch_func, API_URL, token):
     product_list_frame.pack(fill="both", expand=True, padx=10, pady=10)
 
     def fetch_shop_data():
-        """ Fetch the shop created by the logged-in user """
+        """Fetch the shop created by the logged-in user"""
         headers = {"Authorization": f"Bearer {token}"}
         try:
-            response = requests.get(f"{API_URL}/shops/my-shop", headers=headers)  # Adjust the endpoint as needed
+            response = requests.get(
+                f"{API_URL}/shops/my-shop", headers=headers
+            )  # Adjust the endpoint as needed
             if response.status_code == 200:
                 shop_data = response.json()
                 shop_name_label.configure(text=f"Shop Name: {shop_data['name']}")
-                shop_description_label.configure(text=f"Description: {shop_data.get('description', 'No description')}")
+                shop_description_label.configure(
+                    text=f"Description: {shop_data.get('description', 'No description')}"
+                )
 
                 # Load and display shop image if available
                 if "image_url" in shop_data and shop_data["image_url"]:
@@ -47,7 +56,7 @@ def view_shop_frame(parent, switch_func, API_URL, token):
                         shop_image_label.image = img_tk
                     except Exception:
                         pass
-                
+
                 fetch_products(shop_data["id"])  # Fetch products for this shop
             else:
                 messagebox.showerror("Error", "Failed to fetch shop details.")
@@ -55,10 +64,12 @@ def view_shop_frame(parent, switch_func, API_URL, token):
             messagebox.showerror("Error", f"Request error: {e}")
 
     def fetch_products(shop_id):
-        """ Fetch products that belong to the user's shop """
+        """Fetch products that belong to the user's shop"""
         headers = {"Authorization": f"Bearer {token}"}
         try:
-            response = requests.get(f"{API_URL}/products?shop_id={shop_id}", headers=headers)
+            response = requests.get(
+                f"{API_URL}/products?shop_id={shop_id}", headers=headers
+            )
             if response.status_code == 200:
                 products = response.json()
                 display_products(products)
@@ -68,12 +79,14 @@ def view_shop_frame(parent, switch_func, API_URL, token):
             messagebox.showerror("Error", f"Request error: {e}")
 
     def display_products(products):
-        """ Display the list of products in the shop """
+        """Display the list of products in the shop"""
         for widget in product_list_frame.winfo_children():
             widget.destroy()
 
         if not products:
-            ctk.CTkLabel(product_list_frame, text="No products found.", font=("Helvetica", 12)).pack(pady=10)
+            ctk.CTkLabel(
+                product_list_frame, text="No products found.", font=("Helvetica", 12)
+            ).pack(pady=10)
             return
 
         for product in products:
@@ -102,15 +115,23 @@ def view_shop_frame(parent, switch_func, API_URL, token):
             details_frame = ctk.CTkFrame(product_frame)
             details_frame.pack(side="left", fill="x", expand=True, padx=10)
 
-            ctk.CTkLabel(details_frame, text=product["name"], font=("Helvetica", 12, "bold")).pack(anchor="w")
-            ctk.CTkLabel(details_frame, text=f"Price: ${product['price']:.2f}", font=("Helvetica", 12)).pack(anchor="w")
+            ctk.CTkLabel(
+                details_frame, text=product["name"], font=("Helvetica", 12, "bold")
+            ).pack(anchor="w")
+            ctk.CTkLabel(
+                details_frame,
+                text=f"Price: ${product['price']:.2f}",
+                font=("Helvetica", 12),
+            ).pack(anchor="w")
 
     # Refresh Data Button
     refresh_button = ctk.CTkButton(frame, text="Refresh", command=fetch_shop_data)
     refresh_button.pack(pady=10)
 
     # Back Button
-    back_button = ctk.CTkButton(frame, text="Back", command=lambda: switch_func("login"))
+    back_button = ctk.CTkButton(
+        frame, text="Back", command=lambda: switch_func("login")
+    )
     back_button.pack(pady=10)
 
     # Fetch shop data on load
diff --git a/app/frontend/main.py b/app/frontend/main.py
index cc8b927..2b14d6b 100644
--- a/app/frontend/main.py
+++ b/app/frontend/main.py
@@ -12,6 +12,7 @@ API_URL = "http://127.0.0.1:8000"
 # Global variable to store the access token
 access_token = None
 
+
 # Function to switch between frames
 def switch_frame(frame_name, token=None):
     global access_token
@@ -20,6 +21,7 @@ def switch_frame(frame_name, token=None):
 
     frames.get(frame_name, login).tkraise()  # Default to login if frame_name is invalid
 
+
 # Create main window
 ctk.set_appearance_mode("dark")  # Light, Dark, or System
 ctk.set_default_color_theme("blue")
@@ -43,7 +45,7 @@ frames = {
     "create_shop": create_shop,
     "create_product": product,
     "category": category,
-    "view_shop": view_shop
+    "view_shop": view_shop,
 }
 
 # Place all frames responsively
-- 
GitLab