From 3b82c77f3492b861e97f843c77f9daf5d7648452 Mon Sep 17 00:00:00 2001
From: nn2-minh <Nguyen12.Minh@live.uwe.ac.uk>
Date: Wed, 2 Apr 2025 23:54:11 +0700
Subject: [PATCH] Modified the front end of the app

---
 app/backend/routes/shop.py                    |  13 +-
 app/frontend/components/auth/login.py         | 137 ++++--
 app/frontend/components/auth/register.py      | 237 ++++++++---
 app/frontend/components/dashboard.py          | 398 +++++++++++-------
 .../components/product/view_product.py        | 180 ++++++++
 app/frontend/components/shop/create_shop.py   | 293 +++++++++----
 app/frontend/components/shop/view_shop.py     | 332 ++++++++++++---
 app/frontend/components/user_details.py       | 304 ++++++-------
 app/frontend/components/user_orders.py        | 347 ++++++++-------
 app/frontend/main.py                          |   4 +-
 10 files changed, 1551 insertions(+), 694 deletions(-)
 create mode 100644 app/frontend/components/product/view_product.py

diff --git a/app/backend/routes/shop.py b/app/backend/routes/shop.py
index d5a651a..a545b83 100644
--- a/app/backend/routes/shop.py
+++ b/app/backend/routes/shop.py
@@ -1,7 +1,7 @@
 from fastapi import APIRouter, Depends, HTTPException, UploadFile, File, Form
 from sqlmodel import Session, func
 from geopy.geocoders import Nominatim
-from backend.models.models import Shop, User, Order
+from backend.models.models import Shop, User, Order, Product
 from backend.schemas.shop import ShopRead
 from backend.database import get_session
 from backend.routes.auth import get_current_user
@@ -81,12 +81,19 @@ def get_all_shops(order: str = "desc", session: Session = Depends(get_session)):
     return shops
 
 
-@router.get("/get/{shop_id}", response_model=ShopRead)
+@router.get("/get/{shop_id}", response_model=dict)
 def read_shop(shop_id: int, session: Session = Depends(get_session)):
     shop = session.get(Shop, shop_id)
     if not shop:
         raise HTTPException(status_code=404, detail="Shop not found")
-    return shop
+    
+    # Query products related to the shop
+    products = session.query(Product).filter(Product.shop_id == shop_id).all()
+    
+    return {
+        "shop": shop,
+        "products": products
+    }
 
 
 @router.put("/put/{shop_id}", response_model=ShopRead)
diff --git a/app/frontend/components/auth/login.py b/app/frontend/components/auth/login.py
index bc8da11..f44c06f 100644
--- a/app/frontend/components/auth/login.py
+++ b/app/frontend/components/auth/login.py
@@ -4,26 +4,44 @@ from tkinter import messagebox
 from PIL import Image
 from utils.api_requests import login_api
 
+SHOPPING = "#00c1ff"
+DARK_BG = "#1f1f1f"
+CARD_BG = "#2b2b2b"
 
 def login_frame(parent, switch_func, API_URL):
-    # Overall container
-    container = ctk.CTkFrame(parent, fg_color="#F3F4F6")  # Light gray background
+    # Overall container with dark background
+    container = ctk.CTkFrame(parent, fg_color=DARK_BG)
     container.grid_columnconfigure(0, weight=1)
     container.grid_columnconfigure(1, weight=1)
     container.grid_rowconfigure(0, weight=1)
 
     # Left image frame
-    left_frame = ctk.CTkFrame(container, fg_color="transparent")
-    left_frame.grid(row=0, column=0, sticky="nsew")
+    left_frame = ctk.CTkFrame(container, fg_color=CARD_BG, corner_radius=15)
+    left_frame.grid(row=0, column=0, sticky="nsew", padx=(20, 10), pady=20)
 
-    image_path = os.path.abspath("app/static/front_end_img/login.jpg")
-    img = ctk.CTkImage(light_image=Image.open(image_path), size=(800, 800))
-    image_label = ctk.CTkLabel(left_frame, image=img, text="")
-    image_label.place(relwidth=1, relheight=1)
+    # App branding
+    brand_frame = ctk.CTkFrame(left_frame, fg_color="transparent")
+    brand_frame.place(relx=0.5, rely=0.5, anchor="center")
+
+    app_name = ctk.CTkLabel(
+        brand_frame,
+        text="Shopping App",
+        font=("Helvetica", 40, "bold"),
+        text_color=SHOPPING
+    )
+    app_name.pack()
+
+    app_slogan = ctk.CTkLabel(
+        brand_frame,
+        text="Your One-Stop Shopping Destination",
+        font=("Helvetica", 16),
+        text_color="white"
+    )
+    app_slogan.pack(pady=(10, 30))
 
     # Right login frame
-    right_frame = ctk.CTkFrame(container, fg_color="white", corner_radius=20)
-    right_frame.grid(row=0, column=1, sticky="nsew", padx=50, pady=100)
+    right_frame = ctk.CTkFrame(container, fg_color=CARD_BG, corner_radius=15)
+    right_frame.grid(row=0, column=1, sticky="nsew", padx=(10, 20), pady=20)
     right_frame.grid_columnconfigure(0, weight=1)
 
     # Login Function
@@ -46,56 +64,103 @@ def login_frame(parent, switch_func, API_URL):
                 "Login Failed", response_data.get("detail", "Invalid credentials")
             )
 
+    # Login form container
+    form_frame = ctk.CTkFrame(right_frame, fg_color="transparent")
+    form_frame.place(relx=0.5, rely=0.5, anchor="center")
+
     # Title
     ctk.CTkLabel(
-        right_frame,
-        text="Login",
-        font=ctk.CTkFont("Helvetica", size=26, weight="bold"),
-        text_color="#111827",
-    ).pack(pady=(20, 10))
+        form_frame,
+        text="Welcome Back",
+        font=("Helvetica", 32, "bold"),
+        text_color=SHOPPING
+    ).pack(pady=(0, 10))
+
+    ctk.CTkLabel(
+        form_frame,
+        text="Sign in to your account",
+        font=("Helvetica", 14),
+        text_color="gray"
+    ).pack(pady=(0, 20))
 
     # Email
+    email_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    email_frame.pack(fill="x", pady=(0, 15))
+
     ctk.CTkLabel(
-        right_frame, text="Email", font=("Helvetica", 14), text_color="#374151"
-    ).pack(pady=(10, 5))
+        email_frame,
+        text="Email",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
+
     entry_email = ctk.CTkEntry(
-        right_frame, height=40, corner_radius=10, placeholder_text="Enter your email"
+        email_frame,
+        height=40,
+        corner_radius=8,
+        placeholder_text="Enter your email",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_email.pack(pady=5, padx=20, fill="x")
+    entry_email.pack(fill="x", pady=(5, 0))
 
     # Password
+    password_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    password_frame.pack(fill="x", pady=(0, 20))
+
     ctk.CTkLabel(
-        right_frame, text="Password", font=("Helvetica", 14), text_color="#374151"
-    ).pack(pady=(10, 5))
+        password_frame,
+        text="Password",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
+
     entry_password = ctk.CTkEntry(
-        right_frame,
+        password_frame,
         height=40,
         show="*",
-        corner_radius=10,
+        corner_radius=8,
         placeholder_text="Enter your password",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_password.pack(pady=5, padx=20, fill="x")
+    entry_password.pack(fill="x", pady=(5, 0))
 
     # Login Button
     ctk.CTkButton(
-        right_frame,
-        text="Login",
+        form_frame,
+        text="Sign In",
         command=login,
-        corner_radius=10,
+        corner_radius=8,
         height=45,
-        font=("Helvetica", 14),
-        fg_color="#2563EB",
-        hover_color="#1E40AF",
-    ).pack(pady=20, padx=20, fill="x")
+        font=("Helvetica", 14, "bold"),
+        fg_color=SHOPPING,
+        hover_color="#0096ff",
+    ).pack(fill="x", pady=(0, 15))
 
     # Register Redirect
+    register_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    register_frame.pack(fill="x")
+
+    ctk.CTkLabel(
+        register_frame,
+        text="Don't have an account?",
+        font=("Helvetica", 12),
+        text_color="gray"
+    ).pack(side="left", padx=(0, 5))
+
     ctk.CTkButton(
-        right_frame,
-        text="Don't have an account? Register",
+        register_frame,
+        text="Register",
         command=lambda: switch_func("register"),
         fg_color="transparent",
-        hover_color="#E5E7EB",
-        text_color="#2563EB",
-    ).pack(pady=(5, 20))
+        hover_color="#3b3b3b",
+        text_color=SHOPPING,
+        font=("Helvetica", 12, "bold"),
+        width=70,
+        height=25
+    ).pack(side="left")
 
     return container
diff --git a/app/frontend/components/auth/register.py b/app/frontend/components/auth/register.py
index 5f92659..6677b2f 100644
--- a/app/frontend/components/auth/register.py
+++ b/app/frontend/components/auth/register.py
@@ -1,19 +1,45 @@
 import customtkinter as ctk
 from tkinter import messagebox
-from utils.api_requests import register_api  # Import the API function
+from utils.api_requests import register_api
 
+SHOPPING = "#00c1ff"
+DARK_BG = "#1f1f1f"
+CARD_BG = "#2b2b2b"
 
 def register_frame(parent, switch_func, API_URL):
-    # Create a full-window container with a light gray background
-    container = ctk.CTkFrame(parent, fg_color="#F3F4F6")
-    container.pack(expand=True, fill="both")
-
-    # Center the register panel (the white card) in the middle of the container.
-    # Width and height are set to ensure a consistent size.
-    register_panel = ctk.CTkFrame(
-        container, fg_color="white", corner_radius=20, width=400, height=500
+    # Create a full-window container with dark background
+    container = ctk.CTkFrame(parent, fg_color=DARK_BG)
+    container.grid_columnconfigure(0, weight=1)
+    container.grid_columnconfigure(1, weight=1)
+    container.grid_rowconfigure(0, weight=1)
+
+    # Left branding frame
+    left_frame = ctk.CTkFrame(container, fg_color=CARD_BG, corner_radius=15)
+    left_frame.grid(row=0, column=0, sticky="nsew", padx=(20, 10), pady=20)
+
+    # App branding
+    brand_frame = ctk.CTkFrame(left_frame, fg_color="transparent")
+    brand_frame.place(relx=0.5, rely=0.5, anchor="center")
+
+    app_name = ctk.CTkLabel(
+        brand_frame,
+        text="Shopping App",
+        font=("Helvetica", 40, "bold"),
+        text_color=SHOPPING
     )
-    register_panel.place(relx=0.5, rely=0.5, anchor="center")
+    app_name.pack()
+
+    app_slogan = ctk.CTkLabel(
+        brand_frame,
+        text="Join Our Shopping Community",
+        font=("Helvetica", 16),
+        text_color="white"
+    )
+    app_slogan.pack(pady=(10, 30))
+
+    # Right register frame
+    right_frame = ctk.CTkFrame(container, fg_color=CARD_BG, corner_radius=15)
+    right_frame.grid(row=0, column=1, sticky="nsew", padx=(10, 20), pady=20)
 
     def register():
         username = entry_username.get()
@@ -22,13 +48,7 @@ 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 all([username, email, phone_number, password, confirm_password]):
             messagebox.showwarning("Input Error", "All fields are required!")
             return
 
@@ -36,7 +56,6 @@ def register_frame(parent, switch_func, API_URL):
             messagebox.showerror("Password Error", "Passwords do not match!")
             return
 
-        # Call the API function from register_api.py
         status_code, response_data = register_api(
             username, email, phone_number, password, API_URL
         )
@@ -49,82 +68,170 @@ def register_frame(parent, switch_func, API_URL):
                 "Registration Failed", response_data.get("detail", "Unknown error")
             )
 
-    # Title for the registration form
+    # Register form container
+    form_frame = ctk.CTkFrame(right_frame, fg_color="transparent")
+    form_frame.place(relx=0.5, rely=0.5, anchor="center")
+
+    # Title
     ctk.CTkLabel(
-        register_panel,
+        form_frame,
         text="Create Account",
-        font=ctk.CTkFont("Helvetica", size=26, weight="bold"),
-        text_color="#111827",
-    ).pack(pady=(20, 10))
+        font=("Helvetica", 32, "bold"),
+        text_color=SHOPPING
+    ).pack(pady=(0, 10))
+
+    ctk.CTkLabel(
+        form_frame,
+        text="Fill in your details to register",
+        font=("Helvetica", 14),
+        text_color="gray"
+    ).pack(pady=(0, 20))
+
+    # Username
+    username_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    username_frame.pack(fill="x", pady=(0, 15))
+
+    ctk.CTkLabel(
+        username_frame,
+        text="Username",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
 
-    # Username Entry
     entry_username = ctk.CTkEntry(
-        register_panel,
-        placeholder_text="Username",
+        username_frame,
         height=40,
-        corner_radius=10,
-        width=250,
+        corner_radius=8,
+        placeholder_text="Enter your username",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_username.pack(pady=10, padx=20, fill="x")
+    entry_username.pack(fill="x", pady=(5, 0))
+
+    # Email
+    email_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    email_frame.pack(fill="x", pady=(0, 15))
+
+    ctk.CTkLabel(
+        email_frame,
+        text="Email",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
 
-    # Email Entry
     entry_email = ctk.CTkEntry(
-        register_panel, placeholder_text="Email", height=40, corner_radius=10, width=250
+        email_frame,
+        height=40,
+        corner_radius=8,
+        placeholder_text="Enter your email",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_email.pack(pady=10, padx=20, fill="x")
+    entry_email.pack(fill="x", pady=(5, 0))
+
+    # Phone
+    phone_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    phone_frame.pack(fill="x", pady=(0, 15))
+
+    ctk.CTkLabel(
+        phone_frame,
+        text="Phone Number",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
 
-    # Phone Number Entry
     entry_phone = ctk.CTkEntry(
-        register_panel,
-        placeholder_text="Phone Number",
+        phone_frame,
         height=40,
-        corner_radius=10,
-        width=250,
+        corner_radius=8,
+        placeholder_text="Enter your phone number",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_phone.pack(pady=10, padx=20, fill="x")
+    entry_phone.pack(fill="x", pady=(5, 0))
+
+    # Password
+    password_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    password_frame.pack(fill="x", pady=(0, 15))
+
+    ctk.CTkLabel(
+        password_frame,
+        text="Password",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
 
-    # Password Entry
     entry_password = ctk.CTkEntry(
-        register_panel,
-        placeholder_text="Password",
-        show="*",
+        password_frame,
         height=40,
-        corner_radius=10,
-        width=250,
+        corner_radius=8,
+        show="*",
+        placeholder_text="Enter your password",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_password.pack(pady=10, padx=20, fill="x")
+    entry_password.pack(fill="x", pady=(5, 0))
+
+    # Confirm Password
+    confirm_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    confirm_frame.pack(fill="x", pady=(0, 20))
+
+    ctk.CTkLabel(
+        confirm_frame,
+        text="Confirm Password",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
 
-    # Confirm Password Entry
     entry_confirm_password = ctk.CTkEntry(
-        register_panel,
-        placeholder_text="Confirm Password",
-        show="*",
+        confirm_frame,
         height=40,
-        corner_radius=10,
-        width=250,
+        corner_radius=8,
+        show="*",
+        placeholder_text="Confirm your password",
+        fg_color="#3b3b3b",
+        border_color=SHOPPING,
+        text_color="white"
     )
-    entry_confirm_password.pack(pady=10, padx=20, fill="x")
+    entry_confirm_password.pack(fill="x", pady=(5, 0))
 
     # Register Button
     ctk.CTkButton(
-        register_panel,
-        text="Register",
+        form_frame,
+        text="Create Account",
         command=register,
-        corner_radius=10,
+        corner_radius=8,
         height=45,
-        font=("Helvetica", 14),
-        fg_color="#2563EB",
-        hover_color="#1E40AF",
-    ).pack(pady=20, padx=20, fill="x")
+        font=("Helvetica", 14, "bold"),
+        fg_color=SHOPPING,
+        hover_color="#0096ff",
+    ).pack(fill="x", pady=(0, 15))
+
+    # Login Redirect
+    login_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+    login_frame.pack(fill="x")
+
+    ctk.CTkLabel(
+        login_frame,
+        text="Already have an account?",
+        font=("Helvetica", 12),
+        text_color="gray"
+    ).pack(side="left", padx=(0, 5))
 
-    # Link to Login Page
     ctk.CTkButton(
-        register_panel,
-        text="Already have an account? Login",
+        login_frame,
+        text="Sign In",
         command=lambda: switch_func("login"),
         fg_color="transparent",
-        hover_color="#E5E7EB",
-        text_color="#2563EB",
-    ).pack(pady=(5, 20))
+        hover_color="#3b3b3b",
+        text_color=SHOPPING,
+        font=("Helvetica", 12, "bold"),
+        width=70,
+        height=25
+    ).pack(side="left")
 
     return container
diff --git a/app/frontend/components/dashboard.py b/app/frontend/components/dashboard.py
index fe5a880..b4bc80b 100644
--- a/app/frontend/components/dashboard.py
+++ b/app/frontend/components/dashboard.py
@@ -3,9 +3,13 @@ import requests
 from PIL import Image, ImageTk
 from tkinter import messagebox
 import io
+# import time
+# import threading
 
 SHOPPING = "#00c1ff"
-BACKEND_HOST = "http://127.0.0.1:8000"  # Adjust if needed
+DARK_BG = "#1f1f1f"
+CARD_BG = "#2b2b2b"
+BACKEND_HOST = "http://127.0.0.1:8000"
 
 
 def fix_url(url):
@@ -18,38 +22,79 @@ def fix_url(url):
     # If the URL starts with "app/static/", remove that part.
     prefix = "app/static/"
     if url.startswith(prefix):
-        url = url[len(prefix) :]
+        url = url[len(prefix):]
     # Prepend the public URL
     return f"{BACKEND_HOST}/static/{url}"
 
 
 def dashboard_frame(parent, switch_func, API_URL, token):
-    """
-    Main dashboard UI:
-      - Header (top bar) with logo, search, user, cart
-      - Middle area with horizontal scroll of top shops
-      - Bottom area with grid layout of recommended products
-    """
-    frame = ctk.CTkFrame(parent, fg_color="transparent")
-
-    # ------------- HEADER (Top Bar) -------------
-    header_frame = ctk.CTkFrame(frame, fg_color=SHOPPING)
-    header_frame.place(relx=0, rely=0, relwidth=1, relheight=0.1)
-
-    # App Logo (Left)
-    logo_label = ctk.CTkLabel(
-        header_frame,
-        text="Shopping App",
+    frame = ctk.CTkFrame(parent, fg_color=DARK_BG)
+
+    # ------------- LEFT SIDEBAR -------------
+    sidebar = ctk.CTkFrame(frame, fg_color=CARD_BG, width=60)
+    sidebar.pack(side="left", fill="y")
+    sidebar.pack_propagate(False)
+
+    # Dashboard Icon
+    dashboard_icon = ctk.CTkButton(
+        sidebar,
+        text="🏠",
+        font=("Helvetica", 20),
+        fg_color="transparent",
         text_color="white",
-        font=("Helvetica", 20, "bold"),
+        hover_color="#3b3b3b",
+        width=40,
+        height=40,
+        command=lambda: switch_func("dashboard")
+    )
+    dashboard_icon.pack(pady=(20, 10))
+
+    # User Icon
+    user_icon = ctk.CTkButton(
+        sidebar,
+        text="πŸ‘€",
+        font=("Helvetica", 20),
+        fg_color="transparent",
+        text_color="white",
+        hover_color="#3b3b3b",
+        width=40,
+        height=40,
+        command=lambda: switch_func("user_details")
     )
-    logo_label.place(relx=0.01, rely=0.1, relwidth=0.15, relheight=0.8)
+    user_icon.pack(pady=10)
+
+    # Cart Icon
+    cart_icon = ctk.CTkButton(
+        sidebar,
+        text="πŸ›’",
+        font=("Helvetica", 20),
+        fg_color="transparent",
+        text_color="white",
+        hover_color="#3b3b3b",
+        width=40,
+        height=40,
+        command=lambda: switch_func("user_orders")
+    )
+    cart_icon.pack(pady=10)
+
+    # ------------- MAIN CONTENT -------------
+    main_content = ctk.CTkFrame(frame, fg_color="transparent")
+    main_content.pack(side="left", fill="both", expand=True)
+
+    # Search bar at top
+    search_frame = ctk.CTkFrame(main_content, fg_color=CARD_BG, height=60)
+    search_frame.pack(fill="x", padx=20, pady=10)
+    search_frame.pack_propagate(False)
 
-    # Search bar (Center)
     search_entry = ctk.CTkEntry(
-        header_frame, placeholder_text="Search in Shop...", height=30
+        search_frame,
+        placeholder_text="Search for shops and products...",
+        height=35,
+        fg_color="#3b3b3b",
+        text_color="white",
+        placeholder_text_color="#888888"
     )
-    search_entry.place(relx=0.25, rely=0.25, relwidth=0.45, relheight=0.5)
+    search_entry.pack(side="left", fill="x", expand=True, padx=(20, 10), pady=12)
 
     def perform_search():
         """Call an endpoint to search products by keyword."""
@@ -65,7 +110,7 @@ def dashboard_frame(parent, switch_func, API_URL, token):
             )
             if resp.status_code == 200:
                 products = resp.json()
-                display_products(products, bottom_products_frame)
+                display_products(products, products_frame)
             else:
                 messagebox.showerror(
                     "Error", f"Search failed. Status code: {resp.status_code}"
@@ -74,181 +119,210 @@ def dashboard_frame(parent, switch_func, API_URL, token):
             messagebox.showerror("Error", f"Request error: {e}")
 
     search_button = ctk.CTkButton(
-        header_frame,
+        search_frame,
         text="Search",
-        fg_color="white",
-        text_color="black",
-        command=perform_search,
-    )
-    search_button.place(relx=0.71, rely=0.25, relwidth=0.08, relheight=0.5)
-
-    # ------------- USER & CART ICONS (Top-Right) -------------
-    def open_user_details():
-        switch_func("user_details")
-
-    def open_cart_details():
-        switch_func("user_orders")
-
-    user_button = ctk.CTkButton(
-        header_frame,
-        text="User",
-        fg_color="white",
-        text_color="black",
-        command=open_user_details,
-    )
-    user_button.place(relx=0.82, rely=0.25, relwidth=0.08, relheight=0.5)
-
-    cart_button = ctk.CTkButton(
-        header_frame,
-        text="Cart",
-        fg_color="white",
-        text_color="black",
-        command=open_cart_details,
-    )
-    cart_button.place(relx=0.91, rely=0.25, relwidth=0.08, relheight=0.5)
-
-    # ------------- MIDDLE (Featured/Top Shops) -------------
-    middle_frame = ctk.CTkFrame(frame, fg_color="transparent")
-    middle_frame.place(relx=0, rely=0.1, relwidth=1, relheight=0.25)
-
-    featured_label = ctk.CTkLabel(
-        middle_frame, text="TOP SHOP", font=("Helvetica", 16, "bold")
-    )
-    featured_label.pack(pady=5)
-
-    top_shops_frame = ctk.CTkScrollableFrame(
-        middle_frame, fg_color="transparent", width=750, height=150
+        fg_color=SHOPPING,
+        text_color="white",
+        width=100,
+        height=35,
+        command=perform_search
     )
-    top_shops_frame.pack(fill="both", expand=True, padx=10, pady=5)
-
-    def create_shop_card(parent, shop_data):
-        """
-        Create a card for a shop with its image on top and name below.
-        """
-        card = ctk.CTkFrame(
-            parent, corner_radius=5, fg_color="#2b2b2b", width=100, height=130
-        )
-        card.pack_propagate(False)
+    search_button.pack(side="right", padx=20)
+
+    # Featured Shops Carousel
+    carousel_frame = ctk.CTkFrame(main_content, fg_color=CARD_BG, height=300)
+    carousel_frame.pack(fill="x", padx=20, pady=10)
+    carousel_frame.pack_propagate(False)
+
+    # Carousel content
+    carousel_content = ctk.CTkFrame(carousel_frame, fg_color="transparent")
+    carousel_content.pack(fill="both", expand=True, padx=20, pady=20)
+
+    featured_shops = []
+    current_shop_index = 0
+
+    def create_shop_slide(shop_data):
+        slide = ctk.CTkFrame(carousel_content, fg_color="transparent")
+        
+        # Shop Image
+        image_frame = ctk.CTkFrame(slide, fg_color="transparent", width=400, height=200)
+        image_frame.pack(side="left", padx=20)
+        image_frame.pack_propagate(False)
+        
+        image_label = ctk.CTkLabel(image_frame, text="")
+        image_label.pack(expand=True)
 
-        image_label = ctk.CTkLabel(card, text="")
-        image_label.pack(pady=5)
-
-        # Use "image_url" as returned by the backend, then fix it if needed.
         image_url = shop_data.get("image_url")
         if image_url:
             fixed_url = fix_url(image_url)
-            print(f"[DEBUG] Fetching shop image from: {fixed_url}")
             try:
                 resp = requests.get(fixed_url)
-                print(f"[DEBUG] Status code for shop image: {resp.status_code}")
                 if resp.status_code == 200:
-                    pil_img = Image.open(io.BytesIO(resp.content)).resize((60, 60))
+                    pil_img = Image.open(io.BytesIO(resp.content)).resize((380, 180))
                     tk_img = ImageTk.PhotoImage(pil_img)
                     image_label.configure(image=tk_img, text="")
                     image_label.image = tk_img
-                else:
-                    print(
-                        f"[DEBUG] Failed to fetch shop image. Status: {resp.status_code}"
-                    )
             except Exception as e:
                 print(f"[DEBUG] Shop image error: {e}")
-        else:
-            print(f"[DEBUG] No 'image_url' found for shop: {shop_data.get('name')}")
 
-        name_text = shop_data.get("name", "No Name")
-        name_label = ctk.CTkLabel(
-            card, text=name_text, font=("Helvetica", 11, "bold"), wraplength=90
+        # Shop Details
+        details_frame = ctk.CTkFrame(slide, fg_color="transparent")
+        details_frame.pack(side="left", fill="both", expand=True, padx=20)
+
+        shop_name = ctk.CTkLabel(
+            details_frame,
+            text=shop_data.get("name", "Shop Name"),
+            font=("Helvetica", 24, "bold"),
+            text_color=SHOPPING
+        )
+        shop_name.pack(anchor="w", pady=(0, 10))
+
+        shop_desc = ctk.CTkLabel(
+            details_frame,
+            text=shop_data.get("description", "No description available."),
+            font=("Helvetica", 14),
+            text_color="white",
+            wraplength=400,
+            justify="left"
+        )
+        shop_desc.pack(anchor="w", pady=5)
+
+        visit_button = ctk.CTkButton(
+            details_frame,
+            text="Visit Shop β†’",
+            fg_color=SHOPPING,
+            text_color="white",
+            command=lambda: switch_func("view_shop", shop_data.get("id")),
+            width=120,
+            height=35
         )
-        name_label.pack()
+        visit_button.pack(anchor="w", pady=20)
 
-        return card
+        return slide
 
-    def display_shops(shops, container):
-        for widget in container.winfo_children():
+    def update_carousel():
+        nonlocal current_shop_index
+        if not featured_shops:
+            return
+
+        # Clear current content
+        for widget in carousel_content.winfo_children():
             widget.destroy()
 
-        if not shops:
-            ctk.CTkLabel(container, text="No shops found.").pack(pady=10)
-            return
+        # Create and show current slide
+        current_slide = create_shop_slide(featured_shops[current_shop_index])
+        current_slide.pack(fill="both", expand=True)
 
-        inner_frame = ctk.CTkFrame(container, fg_color="transparent")
-        inner_frame.pack(side="top", fill="both", expand=True)
+        # Update dots
+        update_carousel_dots()
 
-        for shop in shops:
-            shop_card = create_shop_card(inner_frame, shop)
-            shop_card.pack(side="left", padx=5, pady=5)
+        # Schedule next slide
+        current_shop_index = (current_shop_index + 1) % len(featured_shops)
+        carousel_content.after(5000, update_carousel)
 
-    # ------------- BOTTOM (Products) -------------
-    bottom_frame = ctk.CTkFrame(frame, fg_color="transparent")
-    bottom_frame.place(relx=0, rely=0.35, relwidth=1, relheight=0.65)
+    # Carousel navigation dots
+    dots_frame = ctk.CTkFrame(carousel_frame, fg_color="transparent", height=30)
+    dots_frame.pack(side="bottom", fill="x", pady=10)
 
-    recommend_label = ctk.CTkLabel(
-        bottom_frame, text="TODAY'S RECOMMENDATIONS", font=("Helvetica", 16, "bold")
+    def update_carousel_dots():
+        for widget in dots_frame.winfo_children():
+            widget.destroy()
+
+        for i in range(len(featured_shops)):
+            color = SHOPPING if i == current_shop_index else "gray"
+            dot = ctk.CTkLabel(
+                dots_frame,
+                text="●",
+                text_color=color,
+                font=("Helvetica", 16)
+            )
+            dot.pack(side="left", padx=2)
+
+    # Products Section
+    products_section = ctk.CTkFrame(main_content, fg_color="transparent")
+    products_section.pack(fill="both", expand=True, padx=20, pady=10)
+
+    products_header = ctk.CTkFrame(products_section, fg_color="transparent")
+    products_header.pack(fill="x", pady=(0, 10))
+
+    products_title = ctk.CTkLabel(
+        products_header,
+        text="Featured Products",
+        font=("Helvetica", 20, "bold"),
+        text_color="white"
     )
-    recommend_label.pack(pady=5)
+    products_title.pack(side="left")
 
-    bottom_products_frame = ctk.CTkScrollableFrame(
-        bottom_frame, fg_color="transparent", width=750, height=300
+    products_frame = ctk.CTkScrollableFrame(
+        products_section,
+        fg_color="transparent",
+        height=400
     )
-    bottom_products_frame.pack(fill="both", expand=True, padx=10, pady=5)
+    products_frame.pack(fill="both", expand=True)
 
     def create_product_card(parent, product_data):
-        card_width = 130
-        card_height = 210
         card = ctk.CTkFrame(
             parent,
-            corner_radius=5,
-            fg_color="#2b2b2b",
-            width=card_width,
-            height=card_height,
+            fg_color=CARD_BG,
+            corner_radius=10,
+            width=200,
+            height=280
         )
         card.pack_propagate(False)
 
-        image_label = ctk.CTkLabel(card, text="")
-        image_label.pack(pady=5)
+        # Product Image
+        image_frame = ctk.CTkFrame(card, fg_color="transparent", height=150)
+        image_frame.pack(fill="x", padx=10, pady=10)
+        image_frame.pack_propagate(False)
+
+        image_label = ctk.CTkLabel(image_frame, text="")
+        image_label.pack(expand=True)
 
         product_images = product_data.get("images", [])
         if product_images:
             img_url = product_images[0].get("image_url")
             if img_url:
                 fixed_url = fix_url(img_url)
-                print(f"[DEBUG] Fetching product image from: {fixed_url}")
                 try:
                     resp = requests.get(fixed_url)
-                    print(f"[DEBUG] Status code for product image: {resp.status_code}")
                     if resp.status_code == 200:
-                        pil_img = Image.open(io.BytesIO(resp.content)).resize((70, 70))
+                        pil_img = Image.open(io.BytesIO(resp.content)).resize((120, 120))
                         tk_img = ImageTk.PhotoImage(pil_img)
                         image_label.configure(image=tk_img, text="")
                         image_label.image = tk_img
-                    else:
-                        print(
-                            f"[DEBUG] Failed to fetch product image. Status: {resp.status_code}"
-                        )
                 except Exception as e:
                     print(f"[DEBUG] Product image error: {e}")
-        else:
-            print(f"[DEBUG] No images found for product: {product_data.get('name')}")
 
-        name_text = product_data.get("name", "No Name")
+        # Product Details
+        details_frame = ctk.CTkFrame(card, fg_color="transparent")
+        details_frame.pack(fill="both", expand=True, padx=10, pady=(0, 10))
+
         name_label = ctk.CTkLabel(
-            card,
-            text=name_text,
-            font=("Helvetica", 11, "bold"),
-            wraplength=120,
-            anchor="center",
-            justify="center",
+            details_frame,
+            text=product_data.get("name", "No Name"),
+            font=("Helvetica", 14, "bold"),
+            wraplength=180,
+            justify="left"
         )
-        name_label.pack(padx=5, pady=3)
+        name_label.pack(anchor="w")
 
-        price_val = product_data.get("price", 0.0)
         price_label = ctk.CTkLabel(
-            card,
-            text=f"β‚« {price_val:,.1f}",
-            font=("Helvetica", 10, "bold"),
-            text_color="#ff4242",
+            details_frame,
+            text=f"β‚« {product_data.get('price', 0.0):,.1f}",
+            font=("Helvetica", 14, "bold"),
+            text_color="#ff4242"
+        )
+        price_label.pack(anchor="w", pady=5)
+
+        view_button = ctk.CTkButton(
+            details_frame,
+            text="View Details",
+            command=lambda: switch_func("view_product", product_data),
+            fg_color=SHOPPING,
+            text_color="white",
+            height=30
         )
-        price_label.pack(side="bottom", pady=5)
+        view_button.pack(side="bottom", pady=5)
 
         return card
 
@@ -257,26 +331,42 @@ def dashboard_frame(parent, switch_func, API_URL, token):
             widget.destroy()
 
         if not products:
-            ctk.CTkLabel(container, text="No products found.").pack(pady=10)
+            no_products_label = ctk.CTkLabel(
+                container,
+                text="No products available.",
+                font=("Helvetica", 14),
+                text_color="gray"
+            )
+            no_products_label.pack(pady=20)
             return
 
         grid_frame = ctk.CTkFrame(container, fg_color="transparent")
         grid_frame.pack(fill="both", expand=True)
 
-        columns = 7  # 7 products per row
-        for idx, product in enumerate(products):
-            row = idx // columns
-            col = idx % columns
+        max_cols = 4
+        row = 0
+        col = 0
+
+        for product in products:
             product_card = create_product_card(grid_frame, product)
-            product_card.grid(row=row, column=col, padx=5, pady=5)
+            product_card.grid(row=row, column=col, padx=10, pady=10, sticky="nsew")
+            
+            col += 1
+            if col >= max_cols:
+                col = 0
+                row += 1
+
+        for i in range(max_cols):
+            grid_frame.grid_columnconfigure(i, weight=1)
 
     def fetch_featured_shops():
         headers = {"Authorization": f"Bearer {token}"}
         try:
             resp = requests.get(f"{API_URL}/shops/list", headers=headers)
             if resp.status_code == 200:
-                shops = resp.json()
-                display_shops(shops[:100], top_shops_frame)
+                nonlocal featured_shops
+                featured_shops = resp.json()[:5]  # Get top 5 shops for carousel
+                update_carousel()
             else:
                 messagebox.showerror(
                     "Error",
@@ -291,7 +381,7 @@ def dashboard_frame(parent, switch_func, API_URL, token):
             resp = requests.get(f"{API_URL}/product/list", headers=headers)
             if resp.status_code == 200:
                 products = resp.json()
-                display_products(products[:20], bottom_products_frame)
+                display_products(products[:12], products_frame)  # Show top 12 products
             else:
                 messagebox.showerror(
                     "Error",
diff --git a/app/frontend/components/product/view_product.py b/app/frontend/components/product/view_product.py
new file mode 100644
index 0000000..5fdca7d
--- /dev/null
+++ b/app/frontend/components/product/view_product.py
@@ -0,0 +1,180 @@
+import customtkinter as ctk
+import requests
+from PIL import Image, ImageTk
+from tkinter import messagebox
+import io
+
+BACKEND_HOST = "http://127.0.0.1:8000"  # Adjust if needed
+
+
+def fix_url(url):
+    """
+    Fix the URL to ensure it points to the correct static file location.
+    """
+    if url.startswith("http"):
+        return url
+    return f"{BACKEND_HOST}/static/{url}"
+
+
+def view_shop_frame(parent, switch_func, API_URL, token, shop_id):
+    """
+    CustomTkinter-based frame to display shop details and products.
+    """
+    frame = ctk.CTkFrame(parent, fg_color="transparent")
+
+    # Fetch shop details and products from the backend
+    headers = {"Authorization": f"Bearer {token}"}
+    try:
+        response = requests.get(f"{API_URL}/shops/get/{shop_id}", headers=headers)
+        if response.status_code == 200:
+            data = response.json()
+            shop_data = data.get("shop", {})
+            products = data.get("products", [])
+        else:
+            messagebox.showerror("Error", f"Failed to fetch shop data. Status: {response.status_code}")
+            return frame
+    except Exception as e:
+        messagebox.showerror("Error", f"Request error: {e}")
+        return frame
+
+    # ------------- TOP LAYER (Shop Image and Details) -------------
+    top_layer = ctk.CTkFrame(frame, fg_color="transparent")
+    top_layer.place(relx=0, rely=0, relwidth=1, relheight=0.4)
+
+    # Shop Image
+    shop_image_label = ctk.CTkLabel(top_layer, text="")
+    shop_image_label.place(relx=0.05, rely=0.1, relwidth=0.3, relheight=0.8)
+
+    shop_image_url = shop_data.get("image_url")
+    if shop_image_url:
+        fixed_url = fix_url(shop_image_url)
+        try:
+            resp = requests.get(fixed_url)
+            if resp.status_code == 200:
+                pil_img = Image.open(io.BytesIO(resp.content)).resize((200, 200))
+                tk_img = ImageTk.PhotoImage(pil_img)
+                shop_image_label.configure(image=tk_img, text="")
+                shop_image_label.image = tk_img
+        except Exception as e:
+            print(f"[DEBUG] Failed to load shop image: {e}")
+
+    # Shop Details
+    shop_details_frame = ctk.CTkFrame(top_layer, fg_color="transparent")
+    shop_details_frame.place(relx=0.4, rely=0.1, relwidth=0.55, relheight=0.8)
+
+    shop_name_label = ctk.CTkLabel(
+        shop_details_frame,
+        text=shop_data.get("name", "Shop Name"),
+        font=("Helvetica", 20, "bold"),
+    )
+    shop_name_label.pack(pady=10)
+
+    shop_description_label = ctk.CTkLabel(
+        shop_details_frame,
+        text=shop_data.get("description", "No description available."),
+        font=("Helvetica", 14),
+        wraplength=400,
+        justify="left",
+    )
+    shop_description_label.pack(pady=5)
+
+    shop_address_label = ctk.CTkLabel(
+        shop_details_frame,
+        text=f"Address: {shop_data.get('address', 'No address provided')}",
+        font=("Helvetica", 12),
+    )
+    shop_address_label.pack(pady=5)
+
+    # ------------- BOTTOM LAYER (Products) -------------
+    bottom_layer = ctk.CTkFrame(frame, fg_color="transparent")
+    bottom_layer.place(relx=0, rely=0.4, relwidth=1, relheight=0.6)
+
+    products_label = ctk.CTkLabel(
+        bottom_layer, text="Products", font=("Helvetica", 16, "bold")
+    )
+    products_label.pack(pady=10)
+
+    products_frame = ctk.CTkScrollableFrame(
+        bottom_layer, fg_color="transparent", width=750, height=300
+    )
+    products_frame.pack(fill="both", expand=True, padx=10, pady=5)
+
+    def create_product_card(parent, product_data):
+        card_width = 130
+        card_height = 210
+        card = ctk.CTkFrame(
+            parent,
+            corner_radius=5,
+            fg_color="#2b2b2b",
+            width=card_width,
+            height=card_height,
+        )
+        card.pack_propagate(False)
+
+        image_label = ctk.CTkLabel(card, text="")
+        image_label.pack(pady=5)
+
+        product_images = product_data.get("images", [])
+        if product_images:
+            img_url = product_images[0].get("image_url")
+            if img_url:
+                fixed_url = fix_url(img_url)
+                try:
+                    resp = requests.get(fixed_url)
+                    if resp.status_code == 200:
+                        pil_img = Image.open(io.BytesIO(resp.content)).resize((70, 70))
+                        tk_img = ImageTk.PhotoImage(pil_img)
+                        image_label.configure(image=tk_img, text="")
+                        image_label.image = tk_img
+                except Exception as e:
+                    print(f"[DEBUG] Product image error: {e}")
+
+        name_text = product_data.get("name", "No Name")
+        name_label = ctk.CTkLabel(
+            card,
+            text=name_text,
+            font=("Helvetica", 11, "bold"),
+            wraplength=120,
+            anchor="center",
+            justify="center",
+        )
+        name_label.pack(padx=5, pady=3)
+
+        price_val = product_data.get("price", 0.0)
+        price_label = ctk.CTkLabel(
+            card,
+            text=f"β‚« {price_val:,.1f}",
+            font=("Helvetica", 10, "bold"),
+            text_color="#ff4242",
+        )
+        price_label.pack(side="bottom", pady=5)
+
+        # Bind click event on card and its children.
+        def on_click(event, product=product_data):
+            switch_func("view_product", product)
+
+        card.bind("<Button-1>", on_click)
+        return card
+
+    def display_products(products, container):
+        for widget in container.winfo_children():
+            widget.destroy()
+
+        if not products:
+            ctk.CTkLabel(container, text="No products found.").pack(pady=10)
+            return
+
+        grid_frame = ctk.CTkFrame(container, fg_color="transparent")
+        grid_frame.pack(fill="both", expand=True)
+
+        columns = 5  # 5 products per row
+        for idx, product in enumerate(products):
+            row = idx // columns
+            col = idx % columns
+            product_card = create_product_card(grid_frame, product)
+            product_card.grid(row=row, column=col, padx=5, pady=5)
+
+    # Display products
+    display_products(products, products_frame)
+
+    return frame
\ No newline at end of file
diff --git a/app/frontend/components/shop/create_shop.py b/app/frontend/components/shop/create_shop.py
index 7417248..6d5a991 100644
--- a/app/frontend/components/shop/create_shop.py
+++ b/app/frontend/components/shop/create_shop.py
@@ -1,93 +1,240 @@
 import customtkinter as ctk
-from tkinter import filedialog, messagebox
 import requests
-import os
+from PIL import Image, ImageTk
+from tkinter import messagebox, filedialog
+# import io
+
+SHOPPING = "#00c1ff"
+DARK_BG = "#1f1f1f"
+CARD_BG = "#2b2b2b"
 
 def create_shop_frame(parent, switch_func, API_URL, token):
     """
-    Frame for a user to create a shop.
-    This version stores the token in the frame and provides an update_token method.
+    Create shop page with a modern dark theme and improved layout.
     """
-    frame = ctk.CTkFrame(parent)
-    
-    # Store the initial token in the frame
-    frame.token = token
-
-    # Define an update_token method so the global token can be propagated.
-    def update_token(new_token):
-        frame.token = new_token
-    frame.update_token = update_token
-
-    title = ctk.CTkLabel(frame, text="Create Your Shop", font=("Helvetica", 18, "bold"))
-    title.pack(pady=10)
-
-    button_label = ctk.CTkLabel(frame, text="Back to Dashboard", text_color="blue", cursor="hand2")
-    button_label.pack(pady=5)
-    button_label.bind("<Button-1>", lambda e: switch_func("dashboard", token))
-    # Shop Name Field
-    shop_name_label = ctk.CTkLabel(frame, text="Shop Name:")
-    shop_name_label.pack(pady=5)
-    shop_name_entry = ctk.CTkEntry(frame, width=300)
-    shop_name_entry.pack(pady=5)
-
-    # Address Field (using a default for demonstration)
-    address_label = ctk.CTkLabel(frame, text="Address:")
-    address_label.pack(pady=5)
-    address_entry = ctk.CTkEntry(frame, width=300)
-    address_entry.pack(pady=5)
-
-    # Shop Image Upload
-    image_path = ctk.StringVar(value="No file selected")
-    def browse_image():
-        filename = filedialog.askopenfilename(
-            title="Select Shop Image", 
-            filetypes=[("Image Files", "*.png;*.jpg;*.jpeg;*.gif")]
+    # Main container frame
+    frame = ctk.CTkFrame(parent, fg_color=DARK_BG)
+
+    # --- TOP BAR ---
+    top_bar = ctk.CTkFrame(frame, fg_color=SHOPPING, height=50)
+    top_bar.pack(fill="x", side="top")
+
+    top_label = ctk.CTkLabel(
+        top_bar, 
+        text="Create Shop", 
+        text_color="white", 
+        font=("Helvetica", 20, "bold")
+    )
+    top_label.pack(side="left", padx=25)
+
+    def go_back():
+        switch_func("dashboard")
+
+    back_button = ctk.CTkButton(
+        top_bar,
+        text="← Back",
+        fg_color="transparent",
+        text_color="white",
+        hover_color="#0096ff",
+        command=go_back,
+        width=80,
+        height=35,
+        font=("Helvetica", 14)
+    )
+    back_button.pack(side="right", padx=20, pady=7)
+
+    # --- MAIN SECTION: Sidebar + Content ---
+    main_section = ctk.CTkFrame(frame, fg_color="transparent")
+    main_section.pack(fill="both", expand=True)
+
+    # LEFT SIDEBAR
+    sidebar_frame = ctk.CTkFrame(main_section, width=250, fg_color=CARD_BG, corner_radius=15)
+    sidebar_frame.pack(side="left", fill="y", padx=20, pady=20)
+    sidebar_frame.pack_propagate(False)
+
+    sidebar_title = ctk.CTkLabel(
+        sidebar_frame, 
+        text="Menu", 
+        font=("Helvetica", 18, "bold"), 
+        text_color=SHOPPING
+    )
+    sidebar_title.pack(pady=(20, 10))
+
+    def create_nav_button(text, command=None, is_active=False):
+        return ctk.CTkButton(
+            sidebar_frame,
+            text=text,
+            fg_color="transparent",
+            text_color="white",
+            hover_color="#3b3b3b",
+            command=command,
+            height=40,
+            font=("Helvetica", 14),
+            state="disabled" if is_active else "normal"
         )
-        if filename:
-            image_path.set(filename)
-    browse_button = ctk.CTkButton(frame, text="Browse Image", command=browse_image)
-    browse_button.pack(pady=5)
-    image_label = ctk.CTkLabel(frame, textvariable=image_path)
-    image_label.pack(pady=5)
-
-    def submit_shop():
-        # Use the token stored in the frame
-        current_token = frame.token
-        if not current_token:
-            messagebox.showerror("Error", "No access token found. Please log in again.")
-            return
 
-        name = shop_name_entry.get().strip()
-        address = address_entry.get().strip()
-        if not name or not address:
-            messagebox.showerror("Error", "Please fill all fields.")
+    nav_dashboard = create_nav_button("Dashboard", go_back)
+    nav_dashboard.pack(fill="x", padx=15, pady=5)
+
+    def open_profile():
+        switch_func("user_details")
+
+    nav_profile = create_nav_button("My Profile", open_profile)
+    nav_profile.pack(fill="x", padx=15, pady=5)
+
+    nav_orders = create_nav_button("My Orders", lambda: switch_func("user_orders"))
+    nav_orders.pack(fill="x", padx=15, pady=5)
+
+    become_owner = create_nav_button("Become Shop Owner", is_active=True)
+    become_owner.pack(fill="x", padx=15, pady=5)
+
+    # RIGHT CONTENT (Create Shop Form)
+    content_frame = ctk.CTkFrame(main_section, fg_color=CARD_BG, corner_radius=15)
+    content_frame.pack(side="left", fill="both", expand=True, padx=(0, 20), pady=20)
+
+    # Header
+    header_frame = ctk.CTkFrame(content_frame, fg_color="transparent")
+    header_frame.pack(fill="x", padx=30, pady=20)
+
+    title_label = ctk.CTkLabel(
+        header_frame,
+        text="Create Your Shop",
+        font=("Helvetica", 24, "bold"),
+        text_color=SHOPPING
+    )
+    title_label.pack(anchor="w")
+
+    subtitle_label = ctk.CTkLabel(
+        header_frame,
+        text="Fill in your shop details to get started",
+        font=("Helvetica", 14),
+        text_color="gray"
+    )
+    subtitle_label.pack(anchor="w", pady=(5, 0))
+
+    # Main Content
+    main_content = ctk.CTkFrame(content_frame, fg_color="transparent")
+    main_content.pack(fill="both", expand=True, padx=30, pady=(0, 20))
+
+    # LEFT FORM
+    form_frame = ctk.CTkFrame(main_content, fg_color="transparent")
+    form_frame.pack(side="left", fill="both", expand=True, padx=(0, 20))
+
+    def create_form_field(label_text, placeholder_text):
+        field_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+        field_frame.pack(fill="x", pady=(0, 15))
+
+        label = ctk.CTkLabel(
+            field_frame,
+            text=label_text,
+            font=("Helvetica", 14),
+            text_color="white"
+        )
+        label.pack(anchor="w")
+
+        entry = ctk.CTkEntry(
+            field_frame,
+            height=40,
+            corner_radius=8,
+            placeholder_text=placeholder_text,
+            fg_color="#3b3b3b",
+            border_color=SHOPPING,
+            text_color="white"
+        )
+        entry.pack(fill="x", pady=(5, 0))
+        return entry
+
+    shop_name_entry = create_form_field("Shop Name", "Enter your shop name...")
+    shop_description_entry = create_form_field("Shop Description", "Enter your shop description...")
+    shop_address_entry = create_form_field("Shop Address", "Enter your shop address...")
+
+    # RIGHT PICTURE SECTION
+    pic_frame = ctk.CTkFrame(main_content, fg_color="transparent")
+    pic_frame.pack(side="left", fill="both", expand=True)
+
+    pic_label = ctk.CTkLabel(
+        pic_frame,
+        text="Shop Logo",
+        font=("Helvetica", 18, "bold"),
+        text_color=SHOPPING
+    )
+    pic_label.pack(anchor="w", pady=(0, 10))
+
+    photo_frame = ctk.CTkFrame(pic_frame, fg_color="#3b3b3b", corner_radius=10)
+    photo_frame.pack(fill="x", pady=(0, 20))
+
+    photo_label = ctk.CTkLabel(
+        photo_frame,
+        text="No image",
+        text_color="gray",
+        font=("Helvetica", 14)
+    )
+    photo_label.pack(pady=20)
+
+    def choose_photo():
+        file_path = filedialog.askopenfilename(
+            title="Choose a Shop Logo",
+            filetypes=[("Image Files", "*.png *.jpg *.jpeg *.gif")],
+        )
+        if file_path:
+            try:
+                pil_img = Image.open(file_path).resize((150, 150))
+                tk_img = ImageTk.PhotoImage(pil_img)
+                photo_label.configure(image=tk_img, text="")
+                photo_label.image = tk_img
+            except Exception as e:
+                print(f"Image load error: {e}")
+                messagebox.showerror("Error", "Cannot load the image.")
+
+    change_photo_button = ctk.CTkButton(
+        pic_frame,
+        text="Choose Image",
+        command=choose_photo,
+        corner_radius=8,
+        height=40,
+        font=("Helvetica", 14),
+        fg_color=SHOPPING,
+        hover_color="#0096ff",
+    )
+    change_photo_button.pack(fill="x")
+
+    # Create Shop Button
+    def create_shop():
+        shop_name = shop_name_entry.get().strip()
+        shop_description = shop_description_entry.get().strip()
+        shop_address = shop_address_entry.get().strip()
+
+        if not all([shop_name, shop_description, shop_address]):
+            messagebox.showwarning("Input Error", "All fields are required!")
             return
 
-        data = {
-            "name": name,
-            "address": address,
-            "description": "Default shop description"
+        headers = {"Authorization": f"Bearer {token}"}
+        payload = {
+            "name": shop_name,
+            "description": shop_description,
+            "address": shop_address,
         }
-        files = {}
-        if os.path.isfile(image_path.get()):
-            files["file"] = open(image_path.get(), "rb")
-        headers = {"Authorization": f"Bearer {current_token}"}
-        print("Creating shop with token:", current_token)
+
         try:
-            resp = requests.post(f"{API_URL}/shops/create", data=data, files=files, headers=headers)
+            resp = requests.post(f"{API_URL}/shops/create", headers=headers, json=payload)
             if resp.status_code == 200:
-                shop = resp.json()
                 messagebox.showinfo("Success", "Shop created successfully!")
-                switch_func("create_product", shop)  # Pass the shop data to the view shop frame
+                switch_func("dashboard")
             else:
-                messagebox.showerror("Error", f"Failed to create shop. Status: {resp.status_code}\n{resp.text}")
+                messagebox.showerror("Error", "Failed to create shop.")
         except Exception as e:
             messagebox.showerror("Error", f"Request error: {e}")
-        finally:
-            if files:
-                files["file"].close()
 
-    submit_button = ctk.CTkButton(frame, text="Create Shop", command=submit_shop)
-    submit_button.pack(pady=10)
+    create_button = ctk.CTkButton(
+        form_frame,
+        text="Create Shop",
+        command=create_shop,
+        corner_radius=8,
+        height=45,
+        font=("Helvetica", 14, "bold"),
+        fg_color=SHOPPING,
+        hover_color="#0096ff",
+    )
+    create_button.pack(fill="x", pady=(20, 0))
 
     return frame
diff --git a/app/frontend/components/shop/view_shop.py b/app/frontend/components/shop/view_shop.py
index 8840001..2c951fa 100644
--- a/app/frontend/components/shop/view_shop.py
+++ b/app/frontend/components/shop/view_shop.py
@@ -4,72 +4,276 @@ from PIL import Image, ImageTk
 from tkinter import messagebox
 import io
 
-def view_shop_frame(parent, switch_func, shop_data, token, API_URL):
+SHOPPING = "#00c1ff"  # Adding theme color
+BACKEND_HOST = "http://127.0.0.1:8000"  # Adjust if needed
+
+
+def fix_url(url):
+    """
+    Fix the URL to ensure it points to the correct static file location.
+    """
+    if url.startswith("http"):
+        return url
+    # If the URL starts with "app/static/", remove that part
+    prefix = "app/static/"
+    if url.startswith(prefix):
+        url = url[len(prefix):]
+    return f"{BACKEND_HOST}/static/{url}"
+
+
+def view_shop_frame(parent, switch_func, API_URL, token, shop_id):
     """
-    Frame to display the owner’s shop.
-    If shop_data is None, display a message that no shop has been created.
-    Otherwise, display the shop's details and its products.
+    CustomTkinter-based frame to display shop details and products.
     """
-    frame = ctk.CTkFrame(parent)
-
-    # If shop_data is None, show a message and a button to create a shop.
-    if shop_data is None:
-        msg = ctk.CTkLabel(frame, text="No shop created yet.", font=("Helvetica", 16, "bold"))
-        msg.pack(pady=20)
-        create_button = ctk.CTkButton(frame, text="Create Shop", command=lambda: switch_func("create_shop"))
-        create_button.pack(pady=10)
-        return frame
-
-    # Otherwise, proceed normally.
-    shop_name = shop_data.get("name", "No Name")
-    shop_image_url = shop_data.get("image_url", "")
-
-    # Header: Shop Image and Name
-    header_frame = ctk.CTkFrame(frame)
-    header_frame.pack(pady=10, fill="x")
-
-    image_label = ctk.CTkLabel(header_frame, text="")
-    image_label.pack(side="left", padx=10)
-    try:
-        resp = requests.get(shop_image_url)
-        if resp.status_code == 200:
-            pil_img = Image.open(io.BytesIO(resp.content)).resize((80, 80))
-            tk_img = ImageTk.PhotoImage(pil_img)
-            image_label.configure(image=tk_img, text="")
-            image_label.image = tk_img
-    except Exception as e:
-        print("Error loading shop image:", e)
-    name_label = ctk.CTkLabel(header_frame, text=shop_name, font=("Helvetica", 16, "bold"))
-    name_label.pack(side="left", padx=10)
-
-    # Button to create a new product
-    def goto_create_product():
-        switch_func("create_product", shop_data)
-    create_prod_button = ctk.CTkButton(frame, text="Add New Product", command=goto_create_product)
-    create_prod_button.pack(pady=10)
-
-    # Products list
-    products_frame = ctk.CTkScrollableFrame(frame, width=750, height=300)
-    products_frame.pack(padx=10, pady=10, fill="both", expand=True)
-
-    headers = {"Authorization": f"Bearer {token}"}
-    try:
-        resp = requests.get(f"{API_URL}/product/list?shop_id={shop_data.get('id')}", headers=headers)
-        if resp.status_code == 200:
-            products = resp.json()
-            if products:
-                for product in products:
-                    prod_frame = ctk.CTkFrame(products_frame, fg_color="#2b2b2b", corner_radius=5)
-                    prod_frame.pack(padx=5, pady=5, fill="x")
-                    prod_name = product.get("name", "No Name")
-                    prod_label = ctk.CTkLabel(prod_frame, text=prod_name, font=("Helvetica", 12, "bold"))
-                    prod_label.pack(side="left", padx=10)
-                    # Optionally, add more product details here
+    # Main frame
+    main_frame = ctk.CTkFrame(parent, fg_color="transparent")
+    main_frame.pack(fill="both", expand=True)
+
+    # Create a container frame for content that can be refreshed
+    container_frame = ctk.CTkFrame(main_frame, fg_color="transparent")
+    container_frame.pack(fill="both", expand=True)
+
+    def refresh_data(new_shop_id=None, new_token=None):
+        """Refresh the shop view with new data"""
+        nonlocal token, shop_id
+        if new_token:
+            token = new_token
+        if new_shop_id:
+            shop_id = new_shop_id
+
+        # Clear the container
+        for widget in container_frame.winfo_children():
+            widget.destroy()
+
+        if not shop_id:
+            print("[DEBUG] No shop ID provided")
+            no_shop_label = ctk.CTkLabel(
+                container_frame,
+                text="No shop selected",
+                font=("Helvetica", 16)
+            )
+            no_shop_label.pack(pady=20)
+            return
+
+        # Back button at the top
+        back_button = ctk.CTkButton(
+            container_frame,
+            text="← Back to Dashboard",
+            command=lambda: switch_func("dashboard"),
+            fg_color=SHOPPING,
+            text_color="white",
+            width=150
+        )
+        back_button.pack(anchor="nw", padx=20, pady=10)
+
+        # Create a scrollable frame for all content
+        content_frame = ctk.CTkScrollableFrame(container_frame, fg_color="transparent")
+        content_frame.pack(fill="both", expand=True, padx=20, pady=10)
+
+        # Fetch shop details and products from the backend
+        headers = {"Authorization": f"Bearer {token}"}
+        try:
+            print(f"[DEBUG] Fetching shop data for ID: {shop_id}")
+            response = requests.get(f"{API_URL}/shops/get/{shop_id}", headers=headers)
+            print(f"[DEBUG] Response status: {response.status_code}")
+            
+            if response.status_code == 200:
+                data = response.json()
+                shop_data = data.get("shop", {})
+                products = data.get("products", [])
+                print(f"[DEBUG] Shop data: {shop_data}")
+                print(f"[DEBUG] Number of products: {len(products)}")
             else:
-                ctk.CTkLabel(products_frame, text="No products found.").pack(pady=10)
+                print(f"[DEBUG] Error response: {response.text}")
+                messagebox.showerror("Error", f"Failed to fetch shop data. Status: {response.status_code}")
+                return
+        except Exception as e:
+            print(f"[DEBUG] Error fetching shop data: {e}")
+            messagebox.showerror("Error", f"Request error: {e}")
+            return
+
+        # Shop Header Section
+        shop_header = ctk.CTkFrame(content_frame, fg_color="#2b2b2b", corner_radius=10)
+        shop_header.pack(fill="x", padx=10, pady=10)
+
+        # Shop Image and Details in header
+        header_left = ctk.CTkFrame(shop_header, fg_color="transparent")
+        header_left.pack(side="left", padx=20, pady=20)
+
+        shop_image_label = ctk.CTkLabel(header_left, text="")
+        shop_image_label.pack(pady=5)
+
+        # Load shop image
+        shop_image_url = shop_data.get("image_url")
+        if shop_image_url:
+            fixed_url = fix_url(shop_image_url)
+            try:
+                print(f"[DEBUG] Loading shop image from: {fixed_url}")
+                resp = requests.get(fixed_url)
+                if resp.status_code == 200:
+                    pil_img = Image.open(io.BytesIO(resp.content)).resize((150, 150))
+                    tk_img = ImageTk.PhotoImage(pil_img)
+                    shop_image_label.configure(image=tk_img, text="")
+                    shop_image_label.image = tk_img
+                else:
+                    print(f"[DEBUG] Failed to load shop image. Status: {resp.status_code}")
+            except Exception as e:
+                print(f"[DEBUG] Shop image error: {e}")
+
+        # Shop Details
+        header_right = ctk.CTkFrame(shop_header, fg_color="transparent")
+        header_right.pack(side="left", fill="both", expand=True, padx=20, pady=20)
+
+        shop_name = ctk.CTkLabel(
+            header_right,
+            text=shop_data.get("name", "Shop Name"),
+            font=("Helvetica", 24, "bold"),
+            text_color=SHOPPING
+        )
+        shop_name.pack(anchor="w")
+
+        shop_description = ctk.CTkLabel(
+            header_right,
+            text=shop_data.get("description", "No description available."),
+            font=("Helvetica", 14),
+            wraplength=500,
+            justify="left"
+        )
+        shop_description.pack(anchor="w", pady=10)
+
+        shop_address = ctk.CTkLabel(
+            header_right,
+            text=f"πŸ“ {shop_data.get('address', 'No address provided')}",
+            font=("Helvetica", 12),
+            justify="left"
+        )
+        shop_address.pack(anchor="w")
+
+        # Products Section
+        products_section = ctk.CTkFrame(content_frame, fg_color="transparent")
+        products_section.pack(fill="both", expand=True, padx=10, pady=10)
+
+        # Products Header
+        products_header = ctk.CTkFrame(products_section, fg_color="transparent")
+        products_header.pack(fill="x", pady=10)
+
+        products_title = ctk.CTkLabel(
+            products_header,
+            text="Products",
+            font=("Helvetica", 20, "bold"),
+            text_color=SHOPPING
+        )
+        products_title.pack(side="left")
+
+        products_count = ctk.CTkLabel(
+            products_header,
+            text=f"({len(products)} items)",
+            font=("Helvetica", 14)
+        )
+        products_count.pack(side="left", padx=10)
+
+        # Products Grid
+        products_grid = ctk.CTkFrame(products_section, fg_color="transparent")
+        products_grid.pack(fill="both", expand=True)
+
+        def create_product_card(parent, product_data):
+            card = ctk.CTkFrame(
+                parent,
+                fg_color="#2b2b2b",
+                corner_radius=10,
+                width=200,
+                height=280
+            )
+            card.pack_propagate(False)
+
+            # Product Image
+            image_frame = ctk.CTkFrame(card, fg_color="transparent", height=150)
+            image_frame.pack(fill="x", padx=10, pady=10)
+            image_frame.pack_propagate(False)
+
+            image_label = ctk.CTkLabel(image_frame, text="")
+            image_label.pack(expand=True)
+
+            # Load product image
+            product_images = product_data.get("images", [])
+            if product_images:
+                img_url = product_images[0].get("image_url")
+                if img_url:
+                    fixed_url = fix_url(img_url)
+                    try:
+                        resp = requests.get(fixed_url)
+                        if resp.status_code == 200:
+                            pil_img = Image.open(io.BytesIO(resp.content)).resize((120, 120))
+                            tk_img = ImageTk.PhotoImage(pil_img)
+                            image_label.configure(image=tk_img, text="")
+                            image_label.image = tk_img
+                    except Exception as e:
+                        print(f"[DEBUG] Product image error: {e}")
+
+            # Product Details
+            details_frame = ctk.CTkFrame(card, fg_color="transparent")
+            details_frame.pack(fill="both", expand=True, padx=10, pady=(0, 10))
+
+            name_label = ctk.CTkLabel(
+                details_frame,
+                text=product_data.get("name", "No Name"),
+                font=("Helvetica", 14, "bold"),
+                wraplength=180,
+                justify="left"
+            )
+            name_label.pack(anchor="w")
+
+            price_label = ctk.CTkLabel(
+                details_frame,
+                text=f"β‚« {product_data.get('price', 0.0):,.1f}",
+                font=("Helvetica", 14, "bold"),
+                text_color="#ff4242"
+            )
+            price_label.pack(anchor="w", pady=5)
+
+            # View Product Button
+            view_button = ctk.CTkButton(
+                details_frame,
+                text="View Details",
+                command=lambda p=product_data: switch_func("view_product", p),
+                fg_color=SHOPPING,
+                text_color="white",
+                height=30
+            )
+            view_button.pack(side="bottom", pady=5)
+
+            return card
+
+        if not products:
+            no_products_label = ctk.CTkLabel(
+                products_grid,
+                text="No products available in this shop.",
+                font=("Helvetica", 14),
+                text_color="gray"
+            )
+            no_products_label.pack(pady=20)
         else:
-            messagebox.showerror("Error", f"Failed to fetch products. Status: {resp.status_code}")
-    except Exception as e:
-        messagebox.showerror("Error", f"Request error: {e}")
+            row = 0
+            col = 0
+            max_cols = 4  # Number of products per row
+
+            for product in products:
+                product_card = create_product_card(products_grid, product)
+                product_card.grid(row=row, column=col, padx=10, pady=10, sticky="nsew")
+                
+                col += 1
+                if col >= max_cols:
+                    col = 0
+                    row += 1
+
+            # Configure grid columns to be equal width
+            for i in range(max_cols):
+                products_grid.grid_columnconfigure(i, weight=1)
+
+    # Add the refresh_data method to the frame
+    main_frame.refresh_data = refresh_data
+
+    # Initial load with empty shop_id
+    refresh_data()
 
-    return frame
+    return main_frame
\ No newline at end of file
diff --git a/app/frontend/components/user_details.py b/app/frontend/components/user_details.py
index c22431a..7adf510 100644
--- a/app/frontend/components/user_details.py
+++ b/app/frontend/components/user_details.py
@@ -5,175 +5,175 @@ from tkinter import messagebox, filedialog
 import io
 
 SHOPPING = "#00c1ff"
+DARK_BG = "#1f1f1f"
+CARD_BG = "#2b2b2b"
 
 
 def user_details_frame(parent, switch_func, API_URL, token):
     """
-    User details page with a "Become Shop Owner" button.
-    When clicked, it calls switch_func("create_shop") to navigate to shop creation.
+    User details page with a modern dark theme and improved layout.
     """
     # Main container frame
-    frame = ctk.CTkFrame(parent, fg_color="transparent")
+    frame = ctk.CTkFrame(parent, fg_color=DARK_BG)
 
     # --- TOP BAR ---
-    top_bar = ctk.CTkFrame(frame, fg_color=SHOPPING, height=40)
+    top_bar = ctk.CTkFrame(frame, fg_color=SHOPPING, height=50)
     top_bar.pack(fill="x", side="top")
 
     top_label = ctk.CTkLabel(
-        top_bar, text="My Profile", text_color="white", font=("Helvetica", 16, "bold")
+        top_bar, 
+        text="My Profile", 
+        text_color="white", 
+        font=("Helvetica", 20, "bold")
     )
-    top_label.pack(side="left", padx=21)
+    top_label.pack(side="left", padx=25)
 
     def go_back():
         switch_func("dashboard")
 
     back_button = ctk.CTkButton(
         top_bar,
-        text="Back",
-        fg_color="white",
-        text_color="black",
+        text="← Back",
+        fg_color="transparent",
+        text_color="white",
+        hover_color="#0096ff",
         command=go_back,
-        width=60,
-        height=30,
+        width=80,
+        height=35,
+        font=("Helvetica", 14)
     )
-    back_button.pack(side="right", padx=20, pady=5)
+    back_button.pack(side="right", padx=20, pady=7)
 
     # --- MAIN SECTION: Sidebar + Content ---
     main_section = ctk.CTkFrame(frame, fg_color="transparent")
     main_section.pack(fill="both", expand=True)
 
     # LEFT SIDEBAR
-    sidebar_frame = ctk.CTkFrame(main_section, width=200, fg_color="#2b2b2b")
-    sidebar_frame.pack(side="left", fill="y")
+    sidebar_frame = ctk.CTkFrame(main_section, width=250, fg_color=CARD_BG, corner_radius=15)
+    sidebar_frame.pack(side="left", fill="y", padx=20, pady=20)
+    sidebar_frame.pack_propagate(False)
+
     sidebar_title = ctk.CTkLabel(
-        sidebar_frame, text="Menu", font=("Helvetica", 14, "bold"), text_color="white"
-    )
-    sidebar_title.pack(pady=(10, 5))
-    nav_dashboard = ctk.CTkButton(
-        sidebar_frame,
-        text="Dashboard",
-        fg_color="#2b2b2b",
-        text_color="white",
-        hover_color="#3b3b3b",
-        command=go_back,
-    )
-    nav_dashboard.pack(fill="x", padx=10, pady=5)
-    nav_profile = ctk.CTkButton(
-        sidebar_frame,
-        text="My Profile",
-        fg_color="#3b3b3b",
-        text_color="white",
-        hover_color="#3b3b3b",
-        state="disabled",
+        sidebar_frame, 
+        text="Menu", 
+        font=("Helvetica", 18, "bold"), 
+        text_color=SHOPPING
     )
-    nav_profile.pack(fill="x", padx=10, pady=5)
-    nav_orders = ctk.CTkButton(
-        sidebar_frame,
-        text="My Orders",
-        fg_color="#2b2b2b",
-        text_color="white",
-        hover_color="#3b3b3b",
-        command=lambda: switch_func("user_orders"),
-    )
-    nav_orders.pack(fill="x", padx=10, pady=5)
-    # NEW: Become Shop Owner button
-    become_owner = ctk.CTkButton(
-        sidebar_frame,
-        text="Become Shop Owner",
-        fg_color="#2b2b2b",
-        text_color="white",
-        hover_color="#3b3b3b",
-        command=lambda: switch_func("create_shop"),
-    )
-    become_owner.pack(fill="x", padx=10, pady=5)
+    sidebar_title.pack(pady=(20, 10))
+
+    def create_nav_button(text, command=None, is_active=False):
+        return ctk.CTkButton(
+            sidebar_frame,
+            text=text,
+            fg_color="transparent",
+            text_color="white",
+            hover_color="#3b3b3b",
+            command=command,
+            height=40,
+            font=("Helvetica", 14),
+            state="disabled" if is_active else "normal"
+        )
+
+    nav_dashboard = create_nav_button("Dashboard", go_back)
+    nav_dashboard.pack(fill="x", padx=15, pady=5)
+
+    nav_profile = create_nav_button("My Profile", is_active=True)
+    nav_profile.pack(fill="x", padx=15, pady=5)
+
+    nav_orders = create_nav_button("My Orders", lambda: switch_func("user_orders"))
+    nav_orders.pack(fill="x", padx=15, pady=5)
+
+    become_owner = create_nav_button("Become Shop Owner", lambda: switch_func("create_shop"))
+    become_owner.pack(fill="x", padx=15, pady=5)
 
     # RIGHT CONTENT (User Details Form)
-    content_frame = ctk.CTkFrame(main_section, fg_color="transparent")
-    content_frame.pack(side="left", fill="both", expand=True, padx=20, pady=20)
+    content_frame = ctk.CTkFrame(main_section, fg_color=CARD_BG, corner_radius=15)
+    content_frame.pack(side="left", fill="both", expand=True, padx=(0, 20), pady=20)
+
+    # Header
+    header_frame = ctk.CTkFrame(content_frame, fg_color="transparent")
+    header_frame.pack(fill="x", padx=30, pady=20)
+
     title_label = ctk.CTkLabel(
-        content_frame,
-        text="My Profile",
-        font=("Helvetica", 18, "bold"),
-        text_color="white",
+        header_frame,
+        text="Profile Information",
+        font=("Helvetica", 24, "bold"),
+        text_color=SHOPPING
     )
-    title_label.pack(anchor="w", pady=(0, 5))
+    title_label.pack(anchor="w")
+
     subtitle_label = ctk.CTkLabel(
-        content_frame,
+        header_frame,
         text="Manage your profile information to keep your account secure",
-        font=("Helvetica", 12),
-        text_color="#cccccc",
+        font=("Helvetica", 14),
+        text_color="gray"
     )
-    subtitle_label.pack(anchor="w", pady=(0, 15))
+    subtitle_label.pack(anchor="w", pady=(5, 0))
 
-    right_main = ctk.CTkFrame(content_frame, fg_color="transparent")
-    right_main.pack(fill="both", expand=True)
+    # Main Content
+    main_content = ctk.CTkFrame(content_frame, fg_color="transparent")
+    main_content.pack(fill="both", expand=True, padx=30, pady=(0, 20))
 
     # LEFT FORM
-    form_frame = ctk.CTkFrame(right_main, fg_color="transparent")
+    form_frame = ctk.CTkFrame(main_content, fg_color="transparent")
     form_frame.pack(side="left", fill="both", expand=True, padx=(0, 20))
-    # Username
-    username_label = ctk.CTkLabel(
-        form_frame, text="Username", font=("Helvetica", 12), text_color="white"
-    )
-    username_label.pack(anchor="w")
-    username_entry = ctk.CTkEntry(form_frame, placeholder_text="Enter your username...")
-    username_entry.pack(anchor="w", pady=(0, 10))
-    # Name
-    name_label = ctk.CTkLabel(
-        form_frame, text="Name", font=("Helvetica", 12), text_color="white"
-    )
-    name_label.pack(anchor="w")
-    name_entry = ctk.CTkEntry(form_frame, placeholder_text="Enter your name...")
-    name_entry.pack(anchor="w", pady=(0, 10))
-    # Email
-    email_label = ctk.CTkLabel(
-        form_frame, text="Email", font=("Helvetica", 12), text_color="white"
-    )
-    email_label.pack(anchor="w")
-    email_entry = ctk.CTkEntry(form_frame, placeholder_text="Enter your email...")
-    email_entry.pack(anchor="w", pady=(0, 10))
-    # Phone
-    phone_label = ctk.CTkLabel(
-        form_frame, text="Phone", font=("Helvetica", 12), text_color="white"
-    )
-    phone_label.pack(anchor="w")
-    phone_entry = ctk.CTkEntry(form_frame, placeholder_text="Enter your phone...")
-    phone_entry.pack(anchor="w", pady=(0, 10))
-    # Gender
-    gender_label = ctk.CTkLabel(
-        form_frame, text="Gender", font=("Helvetica", 12), text_color="white"
-    )
-    gender_label.pack(anchor="w", pady=(10, 0))
-    gender_var = ctk.StringVar(value="Male")
+
+    def create_form_field(label_text, placeholder_text):
+        field_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
+        field_frame.pack(fill="x", pady=(0, 15))
+
+        label = ctk.CTkLabel(
+            field_frame,
+            text=label_text,
+            font=("Helvetica", 14),
+            text_color="white"
+        )
+        label.pack(anchor="w")
+
+        entry = ctk.CTkEntry(
+            field_frame,
+            height=40,
+            corner_radius=8,
+            placeholder_text=placeholder_text,
+            fg_color="#3b3b3b",
+            border_color=SHOPPING,
+            text_color="white"
+        )
+        entry.pack(fill="x", pady=(5, 0))
+        return entry
+
+    username_entry = create_form_field("Username", "Enter your username...")
+    name_entry = create_form_field("Name", "Enter your name...")
+    email_entry = create_form_field("Email", "Enter your email...")
+    phone_entry = create_form_field("Phone", "Enter your phone number...")
+
+    # Gender Selection
     gender_frame = ctk.CTkFrame(form_frame, fg_color="transparent")
-    gender_frame.pack(anchor="w", pady=5)
-    male_radio = ctk.CTkRadioButton(
-        gender_frame, text="Male", variable=gender_var, value="Male", text_color="white"
-    )
-    female_radio = ctk.CTkRadioButton(
-        gender_frame,
-        text="Female",
-        variable=gender_var,
-        value="Female",
-        text_color="white",
-    )
-    other_radio = ctk.CTkRadioButton(
+    gender_frame.pack(fill="x", pady=(0, 15))
+
+    ctk.CTkLabel(
         gender_frame,
-        text="Other",
-        variable=gender_var,
-        value="Other",
-        text_color="white",
-    )
-    male_radio.pack(side="left", padx=5)
-    female_radio.pack(side="left", padx=5)
-    other_radio.pack(side="left", padx=5)
-    # Birthday
-    birthday_label = ctk.CTkLabel(
-        form_frame, text="Date of Birth", font=("Helvetica", 12), text_color="white"
-    )
-    birthday_label.pack(anchor="w", pady=(10, 0))
-    birthday_entry = ctk.CTkEntry(form_frame, placeholder_text="dd/mm/yyyy")
-    birthday_entry.pack(anchor="w", pady=(0, 10))
+        text="Gender",
+        font=("Helvetica", 14),
+        text_color="white"
+    ).pack(anchor="w")
+
+    gender_var = ctk.StringVar(value="Male")
+    gender_options = ctk.CTkFrame(gender_frame, fg_color="transparent")
+    gender_options.pack(fill="x", pady=(5, 0))
+
+    for gender in ["Male", "Female", "Other"]:
+        ctk.CTkRadioButton(
+            gender_options,
+            text=gender,
+            variable=gender_var,
+            value=gender,
+            text_color="white",
+            fg_color=SHOPPING,
+            hover_color="#0096ff"
+        ).pack(side="left", padx=(0, 20))
+
+    birthday_entry = create_form_field("Date of Birth", "dd/mm/yyyy")
 
     # Save Button
     def save_profile():
@@ -197,26 +197,38 @@ def user_details_frame(parent, switch_func, API_URL, token):
 
     save_button = ctk.CTkButton(
         form_frame,
-        text="Save",
-        fg_color=SHOPPING,
-        text_color="white",
+        text="Save Changes",
         command=save_profile,
-        width=80,
+        corner_radius=8,
+        height=45,
+        font=("Helvetica", 14, "bold"),
+        fg_color=SHOPPING,
+        hover_color="#0096ff",
     )
-    save_button.pack(anchor="w", pady=(20, 10))
+    save_button.pack(fill="x", pady=(20, 0))
 
     # RIGHT PICTURE SECTION
-    pic_frame = ctk.CTkFrame(right_main, fg_color="transparent")
+    pic_frame = ctk.CTkFrame(main_content, fg_color="transparent")
     pic_frame.pack(side="left", fill="both", expand=True)
+
     pic_label = ctk.CTkLabel(
         pic_frame,
         text="Profile Picture",
-        font=("Helvetica", 12, "bold"),
-        text_color="white",
+        font=("Helvetica", 18, "bold"),
+        text_color=SHOPPING
     )
     pic_label.pack(anchor="w", pady=(0, 10))
-    photo_label = ctk.CTkLabel(pic_frame, text="No image", text_color="white")
-    photo_label.pack(anchor="w", pady=(0, 10))
+
+    photo_frame = ctk.CTkFrame(pic_frame, fg_color="#3b3b3b", corner_radius=10)
+    photo_frame.pack(fill="x", pady=(0, 20))
+
+    photo_label = ctk.CTkLabel(
+        photo_frame,
+        text="No image",
+        text_color="gray",
+        font=("Helvetica", 14)
+    )
+    photo_label.pack(pady=20)
 
     def choose_photo():
         file_path = filedialog.askopenfilename(
@@ -225,7 +237,7 @@ def user_details_frame(parent, switch_func, API_URL, token):
         )
         if file_path:
             try:
-                pil_img = Image.open(file_path).resize((100, 100))
+                pil_img = Image.open(file_path).resize((150, 150))
                 tk_img = ImageTk.PhotoImage(pil_img)
                 photo_label.configure(image=tk_img, text="")
                 photo_label.image = tk_img
@@ -236,12 +248,14 @@ def user_details_frame(parent, switch_func, API_URL, token):
     change_photo_button = ctk.CTkButton(
         pic_frame,
         text="Choose Image",
-        fg_color="white",
-        text_color="black",
         command=choose_photo,
-        width=80,
+        corner_radius=8,
+        height=40,
+        font=("Helvetica", 14),
+        fg_color=SHOPPING,
+        hover_color="#0096ff",
     )
-    change_photo_button.pack(anchor="w")
+    change_photo_button.pack(fill="x")
 
     def fetch_user_info():
         headers = {"Authorization": f"Bearer {token}"}
@@ -265,9 +279,7 @@ def user_details_frame(parent, switch_func, API_URL, token):
                     try:
                         resp_pic = requests.get(pic_url)
                         if resp_pic.status_code == 200:
-                            pil_img = Image.open(io.BytesIO(resp_pic.content)).resize(
-                                (100, 100)
-                            )
+                            pil_img = Image.open(io.BytesIO(resp_pic.content)).resize((150, 150))
                             tk_img = ImageTk.PhotoImage(pil_img)
                             photo_label.configure(image=tk_img, text="")
                             photo_label.image = tk_img
diff --git a/app/frontend/components/user_orders.py b/app/frontend/components/user_orders.py
index 6d72df8..cbb83ea 100644
--- a/app/frontend/components/user_orders.py
+++ b/app/frontend/components/user_orders.py
@@ -5,111 +5,220 @@ from tkinter import messagebox
 import io
 
 SHOPPING = "#00c1ff"
+DARK_BG = "#1f1f1f"
+CARD_BG = "#2b2b2b"
 
 
 def user_orders_frame(parent, switch_func, API_URL, token):
     """
-    A two-column user orders page that displays the products the user has purchased
-    along with associated shop details. The layout and color scheme match your dashboard.
+    A modern user orders page that displays the products the user has purchased
+    along with associated shop details.
     """
-
-    # Main container frame with transparent background
-    frame = ctk.CTkFrame(parent, fg_color="transparent")
+    # Main container frame with dark background
+    frame = ctk.CTkFrame(parent, fg_color=DARK_BG)
 
     # ----------------- TOP BAR -----------------
-    top_bar = ctk.CTkFrame(frame, fg_color=SHOPPING, height=40)
+    top_bar = ctk.CTkFrame(frame, fg_color=SHOPPING, height=50)
     top_bar.pack(fill="x", side="top")
 
     top_label = ctk.CTkLabel(
-        top_bar, text="My Orders", text_color="white", font=("Helvetica", 16, "bold")
+        top_bar, 
+        text="My Orders", 
+        text_color="white", 
+        font=("Helvetica", 20, "bold")
     )
-    top_label.pack(side="left", padx=20)
+    top_label.pack(side="left", padx=25)
 
     def go_back():
         switch_func("dashboard")
 
     back_button = ctk.CTkButton(
         top_bar,
-        text="Back",
-        fg_color="white",
-        text_color="black",
+        text="← Back",
+        fg_color="transparent",
+        text_color="white",
+        hover_color="#0096ff",
         command=go_back,
-        width=60,
-        height=30,
+        width=80,
+        height=35,
+        font=("Helvetica", 14)
     )
-    back_button.pack(side="right", padx=20, pady=5)
+    back_button.pack(side="right", padx=20, pady=7)
 
     # ----------------- MAIN SECTION (Sidebar + Content) -----------------
     main_section = ctk.CTkFrame(frame, fg_color="transparent")
     main_section.pack(fill="both", expand=True)
 
     # ----------------- LEFT SIDEBAR -----------------
-    sidebar_frame = ctk.CTkFrame(main_section, width=200, fg_color="#2b2b2b")
-    sidebar_frame.pack(side="left", fill="y")
+    sidebar_frame = ctk.CTkFrame(main_section, width=250, fg_color=CARD_BG, corner_radius=15)
+    sidebar_frame.pack(side="left", fill="y", padx=20, pady=20)
+    sidebar_frame.pack_propagate(False)
 
     sidebar_title = ctk.CTkLabel(
-        sidebar_frame, text="Menu", font=("Helvetica", 14, "bold"), text_color="white"
+        sidebar_frame, 
+        text="Menu", 
+        font=("Helvetica", 18, "bold"), 
+        text_color=SHOPPING
     )
-    sidebar_title.pack(pady=(10, 5))
+    sidebar_title.pack(pady=(20, 10))
+
+    def create_nav_button(text, command=None, is_active=False):
+        return ctk.CTkButton(
+            sidebar_frame,
+            text=text,
+            fg_color="transparent",
+            text_color="white",
+            hover_color="#3b3b3b",
+            command=command,
+            height=40,
+            font=("Helvetica", 14),
+            state="disabled" if is_active else "normal"
+        )
+
+    nav_dashboard = create_nav_button("Dashboard", go_back)
+    nav_dashboard.pack(fill="x", padx=15, pady=5)
 
     def open_profile():
         switch_func("user_details")
 
-    nav_dashboard = ctk.CTkButton(
-        sidebar_frame,
-        text="Dashboard",
-        fg_color="#2b2b2b",
-        text_color="white",
-        hover_color="#3b3b3b",
-        command=go_back,
-    )
-    nav_dashboard.pack(fill="x", padx=10, pady=5)
+    nav_profile = create_nav_button("My Profile", open_profile)
+    nav_profile.pack(fill="x", padx=15, pady=5)
 
-    nav_profile = ctk.CTkButton(
-        sidebar_frame,
-        text="My Profile",
-        fg_color="#2b2b2b",
-        text_color="white",
-        hover_color="#3b3b3b",
-        command=open_profile,
-    )
-    nav_profile.pack(fill="x", padx=10, pady=5)
-
-    nav_orders = ctk.CTkButton(
-        sidebar_frame,
-        text="My Orders",
-        fg_color="#3b3b3b",  # Active/selected state
-        text_color="white",
-        hover_color="#3b3b3b",
-        state="disabled",
-    )
-    nav_orders.pack(fill="x", padx=10, pady=5)
+    nav_orders = create_nav_button("My Orders", is_active=True)
+    nav_orders.pack(fill="x", padx=15, pady=5)
 
     # ----------------- RIGHT CONTENT (Orders List) -----------------
-    content_frame = ctk.CTkFrame(main_section, fg_color="transparent")
-    content_frame.pack(side="left", fill="both", expand=True, padx=20, pady=20)
+    content_frame = ctk.CTkFrame(main_section, fg_color=CARD_BG, corner_radius=15)
+    content_frame.pack(side="left", fill="both", expand=True, padx=(0, 20), pady=20)
+
+    # Header
+    header_frame = ctk.CTkFrame(content_frame, fg_color="transparent")
+    header_frame.pack(fill="x", padx=30, pady=20)
 
     main_title_label = ctk.CTkLabel(
-        content_frame,
-        text="Your Orders",
-        font=("Helvetica", 18, "bold"),
-        text_color="white",
+        header_frame,
+        text="Order History",
+        font=("Helvetica", 24, "bold"),
+        text_color=SHOPPING
     )
-    main_title_label.pack(anchor="w", pady=(0, 5))
+    main_title_label.pack(anchor="w")
 
     subtitle_label = ctk.CTkLabel(
-        content_frame,
-        text="Review the products you have purchased.",
-        font=("Helvetica", 12),
-        text_color="#cccccc",
+        header_frame,
+        text="Review the products you have purchased",
+        font=("Helvetica", 14),
+        text_color="gray"
+    )
+    subtitle_label.pack(anchor="w", pady=(5, 0))
+
+    # Orders List Container
+    orders_list_frame = ctk.CTkScrollableFrame(
+        content_frame, 
+        fg_color="transparent",
+        corner_radius=0
     )
-    subtitle_label.pack(anchor="w", pady=(0, 15))
+    orders_list_frame.pack(fill="both", expand=True, padx=30, pady=(0, 20))
+
+    def create_order_card(order_data):
+        product = order_data.get("product", {})
+        order_date = order_data.get("order_date", "Unknown Date")
+
+        card = ctk.CTkFrame(orders_list_frame, fg_color="#3b3b3b", corner_radius=10)
+        card.pack(fill="x", pady=5)
+
+        # Left: Product image
+        image_frame = ctk.CTkFrame(card, fg_color="transparent", width=100, height=100)
+        image_frame.pack(side="left", padx=15, pady=15)
+        image_frame.pack_propagate(False)
+
+        image_label = ctk.CTkLabel(image_frame, text="")
+        image_label.pack(expand=True)
+
+        if product.get("images"):
+            try:
+                img_url = product["images"][0]["image_url"]
+                img_resp = requests.get(img_url)
+                if img_resp.status_code == 200:
+                    pil_img = Image.open(io.BytesIO(img_resp.content)).resize((80, 80))
+                    tk_img = ImageTk.PhotoImage(pil_img)
+                    image_label.configure(image=tk_img, text="")
+                    image_label.image = tk_img
+            except Exception as ex:
+                print(f"Product image error: {ex}")
+
+        # Right: Order details
+        info_frame = ctk.CTkFrame(card, fg_color="transparent")
+        info_frame.pack(side="left", fill="both", expand=True, padx=15, pady=15)
+
+        # Product Name
+        ctk.CTkLabel(
+            info_frame,
+            text=product.get("name", "No Name"),
+            font=("Helvetica", 16, "bold"),
+            text_color="white"
+        ).pack(anchor="w")
+
+        # Price and Date
+        price = product.get("price", 0.0)
+        ctk.CTkLabel(
+            info_frame,
+            text=f"β‚« {price:,.1f}",
+            font=("Helvetica", 14),
+            text_color=SHOPPING
+        ).pack(anchor="w", pady=(5, 0))
+
+        ctk.CTkLabel(
+            info_frame,
+            text=f"Ordered on: {order_date}",
+            font=("Helvetica", 12),
+            text_color="gray"
+        ).pack(anchor="w", pady=(5, 0))
+
+        # Shop Name
+        shop_id = product.get("shop_id")
+        shop_name_label = ctk.CTkLabel(
+            info_frame,
+            text="Shop: Loading...",
+            font=("Helvetica", 12),
+            text_color="gray"
+        )
+        shop_name_label.pack(anchor="w", pady=(5, 0))
+
+        def fetch_shop_and_update_label(sid, label_widget):
+            headers = {"Authorization": f"Bearer {token}"}
+            try:
+                sresp = requests.get(f"{API_URL}/shop/get/{sid}", headers=headers)
+                if sresp.status_code == 200:
+                    shop_data = sresp.json()
+                    label_widget.configure(
+                        text=f"Shop: {shop_data.get('name', 'No Shop Name')}"
+                    )
+                else:
+                    label_widget.configure(text="Shop: Not found")
+            except Exception:
+                label_widget.configure(text="Shop: Error fetching")
+
+        fetch_shop_and_update_label(shop_id, shop_name_label)
+
+        # View Order Button
+        def view_order():
+            messagebox.showinfo(
+                "Order Details", 
+                f"View details for order of {product.get('name')}"
+            )
 
-    # A frame to hold the list of orders
-    orders_list_frame = ctk.CTkFrame(content_frame, fg_color="transparent")
-    orders_list_frame.pack(fill="both", expand=True)
+        view_button = ctk.CTkButton(
+            info_frame,
+            text="View Order",
+            command=view_order,
+            corner_radius=8,
+            height=35,
+            font=("Helvetica", 12),
+            fg_color=SHOPPING,
+            hover_color="#0096ff",
+        )
+        view_button.pack(anchor="e", pady=(10, 0))
 
-    # ----------- Functions to fetch and display orders -----------
     def fetch_orders():
         """
         Fetch the list of user orders from the API.
@@ -118,110 +227,46 @@ def user_orders_frame(parent, switch_func, API_URL, token):
         try:
             resp = requests.get(f"{API_URL}/orders/list", headers=headers)
             if resp.status_code == 200:
-                orders = resp.json()  # Expect a list of order dicts
-                display_orders(orders, orders_list_frame)
+                orders = resp.json()
+                display_orders(orders)
             else:
                 messagebox.showerror("Error", "Failed to fetch orders.")
         except Exception as ex:
             messagebox.showerror("Error", f"Request error: {ex}")
 
-    def display_orders(orders, container):
+    def display_orders(orders):
         """
         Display each order with product and shop details.
         """
         # Clear previous content
-        for widget in container.winfo_children():
+        for widget in orders_list_frame.winfo_children():
             widget.destroy()
 
         if not orders:
-            ctk.CTkLabel(container, text="No orders found.", text_color="white").pack(
-                pady=10
-            )
-            return
+            no_orders_frame = ctk.CTkFrame(orders_list_frame, fg_color="transparent")
+            no_orders_frame.pack(expand=True, pady=20)
 
-        for order in orders:
-            # Assume each order dict includes a 'product' dict and an 'order_date'
-            product = order.get("product", {})
-            order_date = order.get("order_date", "Unknown Date")
-
-            order_frame = ctk.CTkFrame(container, corner_radius=5, fg_color="#2b2b2b")
-            order_frame.pack(fill="x", padx=5, pady=5)
-
-            # Left: Product image
-            image_label = ctk.CTkLabel(order_frame, text="")
-            image_label.pack(side="left", padx=5, pady=5)
-            if product.get("images"):
-                try:
-                    img_url = product["images"][0]["image_url"]
-                    img_resp = requests.get(img_url)
-                    if img_resp.status_code == 200:
-                        pil_img = Image.open(io.BytesIO(img_resp.content)).resize(
-                            (60, 60)
-                        )
-                        tk_img = ImageTk.PhotoImage(pil_img)
-                        image_label.configure(image=tk_img, text="")
-                        image_label.image = tk_img
-                except Exception as ex:
-                    print(f"Product image error: {ex}")
-
-            # Right: Order details and shop info
-            info_frame = ctk.CTkFrame(order_frame, fg_color="transparent")
-            info_frame.pack(side="left", fill="both", expand=True, padx=10)
-
-            # Product Name
-            ctk.CTkLabel(
-                info_frame,
-                text=product.get("name", "No Name"),
-                font=("Helvetica", 13, "bold"),
-                text_color="white",
-            ).pack(anchor="w")
-
-            # Price (and order date)
-            price = product.get("price", 0.0)
-            ctk.CTkLabel(
-                info_frame, text=f"Price: {price:.2f}", text_color="#cccccc"
-            ).pack(anchor="w")
             ctk.CTkLabel(
-                info_frame, text=f"Ordered on: {order_date}", text_color="#cccccc"
-            ).pack(anchor="w")
-
-            # Shop Name
-            shop_id = product.get("shop_id")
-            shop_name_label = ctk.CTkLabel(
-                info_frame, text="Shop: Loading...", text_color="#cccccc"
-            )
-            shop_name_label.pack(anchor="w")
-
-            def fetch_shop_and_update_label(sid, label_widget):
-                headers = {"Authorization": f"Bearer {token}"}
-                try:
-                    sresp = requests.get(f"{API_URL}/shop/get/{sid}", headers=headers)
-                    if sresp.status_code == 200:
-                        shop_data = sresp.json()
-                        label_widget.configure(
-                            text=f"Shop: {shop_data.get('name', 'No Shop Name')}"
-                        )
-                    else:
-                        label_widget.configure(text="Shop: Not found")
-                except Exception:
-                    label_widget.configure(text="Shop: Error fetching")
-
-            fetch_shop_and_update_label(shop_id, shop_name_label)
-
-            # "View Order" button (placeholder action)
-            def view_order():
-                messagebox.showinfo(
-                    "Order Details", f"View details for order of {product.get('name')}"
-                )
-
-            view_button = ctk.CTkButton(
-                info_frame,
-                text="View Order",
+                no_orders_frame,
+                text="No orders found",
+                font=("Helvetica", 16),
+                text_color="gray"
+            ).pack()
+
+            ctk.CTkButton(
+                no_orders_frame,
+                text="Start Shopping",
+                command=go_back,
+                corner_radius=8,
+                height=40,
+                font=("Helvetica", 14),
                 fg_color=SHOPPING,
-                text_color="white",
-                command=view_order,
-            )
-            view_button.pack(anchor="e", pady=(5, 0))
+                hover_color="#0096ff",
+            ).pack(pady=(20, 0))
+            return
+
+        for order in orders:
+            create_order_card(order)
 
     # Fetch orders when the frame loads
     fetch_orders()
diff --git a/app/frontend/main.py b/app/frontend/main.py
index 145c151..e53b707 100644
--- a/app/frontend/main.py
+++ b/app/frontend/main.py
@@ -48,8 +48,8 @@ register = register_frame(root, switch_frame, API_URL)
 create_shop = create_shop_frame(
     root, switch_frame, API_URL, access_token
 )  # Accepts token
-# Pass a placeholder (None) for shop_data in view_shop_frame
-view_shop = view_shop_frame(root, switch_frame, None, access_token, API_URL)
+# Fix the parameter order for view_shop_frame
+view_shop = view_shop_frame(root, switch_frame, API_URL, access_token, None)  # Pass shop_id as None initially
 product = create_product_frame(root, switch_frame, API_URL, access_token)
 category = category_frame(root, switch_frame, API_URL, access_token)
 dashboard = dashboard_frame(root, switch_frame, API_URL, access_token)
-- 
GitLab