diff --git a/app/backend/routes/auth.py b/app/backend/routes/auth.py index 3b68f08a8e96dba22fb2c1add89bcc4df9fb7a3b..4d94c797a7faa77e3162a4fea9fb7430ce8b895c 100644 --- a/app/backend/routes/auth.py +++ b/app/backend/routes/auth.py @@ -1,7 +1,7 @@ from fastapi import APIRouter, Depends, HTTPException from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm from backend.models.models import User -from backend.schemas.user import UserCreate, UserLogin +from backend.schemas.user import UserCreate , UserLogin from backend.database import get_session from sqlmodel import Session, select from backend.utils.hashing import hash_password, verify_password @@ -45,28 +45,29 @@ def signup(user_data: UserCreate, session: Session = Depends(get_session)): return {"message": "User created successfully"} -# @router.post("/login") -# def login(user_data: UserLogin, session: Session = Depends(get_session)): -# user = session.exec(select(User).where(User.email == user_data.email)).first() -# if not user or not verify_password(user_data.password, user.password): -# raise HTTPException(status_code=401, detail="Invalid credentials") -# access_token = create_access_token(data={"sub": str(user.id)}) -# return { -# "message": "Login successful", -# "user_id": user.id, -# "access_token": access_token, -# } - - @router.post("/login") -def login( - form_data: OAuth2PasswordRequestForm = Depends(), - session: Session = Depends(get_session), -): - user = session.exec(select(User).where(User.email == form_data.username)).first() - if not user or not verify_password(form_data.password, user.password): +def login(user_data: UserLogin, session: Session = Depends(get_session)): + user = session.exec(select(User).where(User.email == user_data.email)).first() + if not user or not verify_password(user_data.password, user.password): raise HTTPException(status_code=401, detail="Invalid credentials") - access_token = create_access_token(data={"sub": str(user.id)}) + return { + "message": "Login successful", + "user_id": user.id, + "access_token": access_token, + "token_type": "bearer", + } + + +# @router.post("/login") +# def login( +# form_data: OAuth2PasswordRequestForm = Depends(), +# session: Session = Depends(get_session), +# ): +# user = session.exec(select(User).where(User.email == form_data.username)).first() +# if not user or not verify_password(form_data.password, user.password): +# raise HTTPException(status_code=401, detail="Invalid credentials") + +# access_token = create_access_token(data={"sub": str(user.id)}) - return {"access_token": access_token, "token_type": "bearer"} +# return {"access_token": access_token, "token_type": "bearer"} diff --git a/app/frontend/components/create_shop.py b/app/frontend/components/create_shop.py new file mode 100644 index 0000000000000000000000000000000000000000..63d0238c5da638f5a8ff3952984acab641a97d8f --- /dev/null +++ b/app/frontend/components/create_shop.py @@ -0,0 +1,97 @@ +import ttkbootstrap as tb +import ttkbootstrap.constants +from tkinter import messagebox, filedialog +import requests +import os +import json + +def create_shop_frame(parent, switch_func, api_url): + frame = tb.Frame(parent) + + selected_file_path = [None] + + def select_file(): + file_path = filedialog.askopenfilename(title="Select Shop Image") + if file_path: + selected_file_path[0] = file_path + file_label.config(text=os.path.basename(file_path)) + else: + selected_file_path[0] = None + file_label.config(text="No file selected") + + def create_shop(): + name = entry_name.get() + description = entry_description.get() + + if not name: + messagebox.showwarning("Input Error", "Shop name is required!") + return + + url = f"{api_url}/shops" + data = {"name": name, "description": description} + files = {} + + if selected_file_path[0]: + try: + files["file"] = open(selected_file_path[0], "rb") + except Exception as e: + messagebox.showerror("File Error", f"Unable to open file: {str(e)}") + return + + # Read the access token from the file + try: + with open("access_token.json", "r") as token_file: + token_data = json.load(token_file) + access_token = token_data.get("access_token") + except FileNotFoundError: + messagebox.showerror("Token Error", "Access token not found. Please log in.") + return + + headers = {"Authorization": f"Bearer {access_token}"} + print(f"Access Token in create_shop: {access_token}") # Debugging line + + try: + response = requests.post(url, data=data, files=files, headers=headers) + if "file" in files: + files["file"].close() + + response_data = response.json() + if response.status_code == 200: + messagebox.showinfo( + "Shop Created", f"Shop '{name}' created successfully!" + ) + else: + messagebox.showerror( + "Error", response_data.get("detail", "An error occurred") + ) + except Exception as e: + messagebox.showerror("Request Error", str(e)) + + tb.Label(frame, text="Create Shop", font=("Helvetica", 18, "bold")).pack(pady=10) + + tb.Label(frame, text="Shop Name:").pack(pady=5) + entry_name = tb.Entry(frame, bootstyle="info") + entry_name.pack(pady=5) + + tb.Label(frame, text="Description:").pack(pady=5) + entry_description = tb.Entry(frame, bootstyle="info") + entry_description.pack(pady=5) + + tb.Button( + frame, text="Select Image", bootstyle="primary", command=select_file + ).pack(pady=5) + file_label = tb.Label(frame, text="No file selected") + file_label.pack(pady=5) + + tb.Button(frame, text="Create Shop", bootstyle="success", command=create_shop).pack( + pady=15 + ) + + tb.Button( + frame, + text="Back", + bootstyle="link", + command=lambda: switch_func("login"), + ).pack(pady=5) + + return frame \ No newline at end of file diff --git a/app/frontend/components/login.py b/app/frontend/components/login.py index 935ffaf1b47e638371bf47e29edbea7054882875..088e4cad72e63b40ef00dfc4f681a038a16f3f0f 100644 --- a/app/frontend/components/login.py +++ b/app/frontend/components/login.py @@ -1,13 +1,17 @@ import ttkbootstrap as tb import ttkbootstrap.constants from tkinter import messagebox -import requests # Import requests for API communication +import requests +import json +# Global variable to store the access token +access_token = None -def login_frame(parent, switch_func, api_url): # Added api_url parameter +def login_frame(parent, switch_func, api_url): frame = tb.Frame(parent) def login(): + global access_token email = entry_email.get() password = entry_password.get() @@ -15,7 +19,6 @@ def login_frame(parent, switch_func, api_url): # Added api_url parameter messagebox.showwarning("Input Error", "Both fields are required!") return - # Sending login request to backend response = requests.post( f"{api_url}/auth/login", json={"email": email, "password": password} ) @@ -23,8 +26,15 @@ def login_frame(parent, switch_func, api_url): # Added api_url parameter try: response_data = response.json() if response.status_code == 200: + access_token = response_data.get("access_token") + print(f"Access Token: {access_token}") # Debugging line + + # Save the access token to a file + with open("access_token.json", "w") as token_file: + json.dump({"access_token": access_token}, token_file) + messagebox.showinfo("Login Successful", f"Welcome back, {email}!") - # TODO: Implement navigation after login (e.g., open dashboard) + switch_func("create_shop") else: messagebox.showerror( "Login Failed", response_data.get("detail", "Invalid credentials") @@ -52,4 +62,4 @@ def login_frame(parent, switch_func, api_url): # Added api_url parameter command=lambda: switch_func("register"), ).pack() - return frame + return frame \ No newline at end of file diff --git a/app/frontend/components/register.py b/app/frontend/components/register.py index ee85f6c24e173b8970b8edd6ce7b3cfd5f52ed3e..b8aa074c11b1bfcd5a3e7f7e5264692ad1c671aa 100644 --- a/app/frontend/components/register.py +++ b/app/frontend/components/register.py @@ -50,7 +50,7 @@ def register_frame(parent, switch_func, api_url): # Added api_url parameter ) except requests.exceptions.JSONDecodeError: messagebox.showerror( - "Registration Failed", f"Server returned an invalid response." + "Registration Failed", "Server returned an invalid response." ) tb.Label(frame, text="Register", font=("Helvetica", 18, "bold")).pack(pady=10) diff --git a/app/frontend/main.py b/app/frontend/main.py index 5d1dd42c4b5278983067759bcbbe1bbb55de06ce..5fff2ea686d51b8927ed0d1cc4475fc25cb859ed 100644 --- a/app/frontend/main.py +++ b/app/frontend/main.py @@ -1,17 +1,22 @@ import ttkbootstrap as tb from components.login import login_frame from components.register import register_frame +from components.create_shop import ( + create_shop_frame, +) # Import the create_shop frame # Backend API URL API_URL = "http://127.0.0.1:8000" -# Function to switch between login and register +# Function to switch between frames def switch_frame(frame_name): if frame_name == "login": login.tkraise() elif frame_name == "register": register.tkraise() + elif frame_name == "create_shop": + create_shop.tkraise() # Create main window @@ -19,18 +24,17 @@ root = tb.Window(themename="superhero") root.title("Shopping App") root.geometry("900x800") -# Create Frames +# Create Frames inside the main window login = login_frame(root, switch_frame, API_URL) register = register_frame(root, switch_frame, API_URL) +create_shop = create_shop_frame(root, switch_frame, API_URL) -for frame in (login, register): - frame.place(relx=0, rely=0.2, relwidth=1, relheight=1) +# Place all frames responsively within the window. +# Adjust relx, rely, relwidth, and relheight as needed for your layout. +for frame in (login, register, create_shop): + frame.place(relx=0, rely=0.2, relwidth=1, relheight=0.8) - -# Show Login Frame First -switch_frame("login") -# Show Login Frame First +# Show the login frame first switch_frame("login") -# Run the GUI root.mainloop()