diff --git a/cafe.db b/cafe.db index 050d817..fcac585 100644 Binary files a/cafe.db and b/cafe.db differ diff --git a/project/__pycache__/admin_dashboard.cpython-313.pyc b/project/__pycache__/admin_dashboard.cpython-313.pyc deleted file mode 100644 index 5435bed..0000000 Binary files a/project/__pycache__/admin_dashboard.cpython-313.pyc and /dev/null differ diff --git a/project/__pycache__/admin_menu.cpython-313.pyc b/project/__pycache__/admin_menu.cpython-313.pyc new file mode 100644 index 0000000..e2e6777 Binary files /dev/null and b/project/__pycache__/admin_menu.cpython-313.pyc differ diff --git a/project/__pycache__/database.cpython-313.pyc b/project/__pycache__/database.cpython-313.pyc index 30a0d09..5712a62 100644 Binary files a/project/__pycache__/database.cpython-313.pyc and b/project/__pycache__/database.cpython-313.pyc differ diff --git a/project/__pycache__/kasir.cpython-313.pyc b/project/__pycache__/kasir.cpython-313.pyc new file mode 100644 index 0000000..58b88b1 Binary files /dev/null and b/project/__pycache__/kasir.cpython-313.pyc differ diff --git a/project/__pycache__/kasir_dashboard.cpython-313.pyc b/project/__pycache__/kasir_dashboard.cpython-313.pyc deleted file mode 100644 index e1ca0aa..0000000 Binary files a/project/__pycache__/kasir_dashboard.cpython-313.pyc and /dev/null differ diff --git a/project/__pycache__/pembeli_menu.cpython-313.pyc b/project/__pycache__/pembeli_menu.cpython-313.pyc index 88746e1..cbaca1c 100644 Binary files a/project/__pycache__/pembeli_menu.cpython-313.pyc and b/project/__pycache__/pembeli_menu.cpython-313.pyc differ diff --git a/project/__pycache__/pemilik.cpython-313.pyc b/project/__pycache__/pemilik.cpython-313.pyc new file mode 100644 index 0000000..1333135 Binary files /dev/null and b/project/__pycache__/pemilik.cpython-313.pyc differ diff --git a/project/__pycache__/pemilik_dashboard.cpython-313.pyc b/project/__pycache__/pemilik_dashboard.cpython-313.pyc deleted file mode 100644 index 17b5c3f..0000000 Binary files a/project/__pycache__/pemilik_dashboard.cpython-313.pyc and /dev/null differ diff --git a/project/__pycache__/waiter_dashboard.cpython-313.pyc b/project/__pycache__/waiter_dashboard.cpython-313.pyc index 6596aeb..02bd477 100644 Binary files a/project/__pycache__/waiter_dashboard.cpython-313.pyc and b/project/__pycache__/waiter_dashboard.cpython-313.pyc differ diff --git a/project/admin_dashboard.py b/project/admin_dashboard.py deleted file mode 100644 index 26d8710..0000000 --- a/project/admin_dashboard.py +++ /dev/null @@ -1,7 +0,0 @@ -import tkinter as tk - -class AdminDashboard(tk.Frame): - def __init__(self, parent, controller): - super().__init__(parent) - tk.Label(self, text="ADMIN DASHBOARD", font=("Arial", 20, "bold")).pack(pady=20) - tk.Button(self, text="Logout", command=lambda: controller.show_frame("Login")).pack() diff --git a/project/admin_menu.py b/project/admin_menu.py new file mode 100644 index 0000000..af6b83c --- /dev/null +++ b/project/admin_menu.py @@ -0,0 +1,40 @@ +import tkinter as tk +from database import connect +from tkinter import messagebox + +class AdminMenu: + def __init__(self, root): + self.root = root + self.frame = tk.Frame(root) + self.frame.pack() + + tk.Label( + self.frame, + text="ADMIN - KELOLA MENU", + font=("Arial", 18, "bold") + ).pack(pady=10) + + self.nama = tk.Entry(self.frame) + self.harga = tk.Entry(self.frame) + self.gambar = tk.Entry(self.frame) + + for label, entry in [ + ("Nama Menu", self.nama), + ("Harga", self.harga), + ("Path Gambar", self.gambar) + ]: + tk.Label(self.frame, text=label).pack() + entry.pack() + + tk.Button(self.frame, text="Tambah Menu", command=self.tambah).pack(pady=5) + + def tambah(self): + db = connect() + cur = db.cursor() + cur.execute( + "INSERT INTO menu(nama,harga,gambar) VALUES (?,?,?)", + (self.nama.get(), self.harga.get(), self.gambar.get()) + ) + db.commit() + db.close() + messagebox.showinfo("Sukses", "Menu berhasil ditambahkan") diff --git a/project/database.py b/project/database.py index 3836f4e..2bbf052 100644 --- a/project/database.py +++ b/project/database.py @@ -7,9 +7,8 @@ def setup_database(): db = connect() cur = db.cursor() - # Table users cur.execute(""" - CREATE TABLE IF NOT EXISTS users ( + CREATE TABLE IF NOT EXISTS users( id INTEGER PRIMARY KEY AUTOINCREMENT, username TEXT, password TEXT, @@ -17,28 +16,44 @@ def setup_database(): ) """) - # Table menu (buat nanti) cur.execute(""" - CREATE TABLE IF NOT EXISTS menu ( + CREATE TABLE IF NOT EXISTS menu( id INTEGER PRIMARY KEY AUTOINCREMENT, nama TEXT, - kategori TEXT, harga REAL, - stok INTEGER + gambar TEXT + ) + """) + + cur.execute(""" + CREATE TABLE IF NOT EXISTS orders( + id INTEGER PRIMARY KEY AUTOINCREMENT, + nama TEXT, + harga REAL + ) + """) + + cur.execute(""" + CREATE TABLE IF NOT EXISTS pembayaran( + id INTEGER PRIMARY KEY AUTOINCREMENT, + order_id INTEGER, + total REAL ) """) - # Tambah user default cur.execute("SELECT COUNT(*) FROM users") if cur.fetchone()[0] == 0: users = [ - ("admin", "admin", "admin"), - ("kasir", "kasir", "kasir"), - ("waiter", "waiter", "waiter"), - ("pembeli", "pembeli", "pembeli"), - ("pemilik", "pemilik", "pemilik cafe") + ("admin","admin","admin"), + ("kasir","kasir","kasir"), + ("pembeli","pembeli","pembeli"), + ("pemilik","pemilik","pemilik"), + ("waiter","waiter","waiter") ] - cur.executemany("INSERT INTO users(username,password,role) VALUES (?,?,?)", users) + cur.executemany( + "INSERT INTO users(username,password,role) VALUES (?,?,?)", + users + ) db.commit() db.close() diff --git a/project/kasir.py b/project/kasir.py new file mode 100644 index 0000000..5f9c45d --- /dev/null +++ b/project/kasir.py @@ -0,0 +1,76 @@ +import tkinter as tk +from tkinter import messagebox +from database import connect + +class KasirPage: + def __init__(self, parent, controller): + self.parent = parent + self.controller = controller + self.frame = tk.Frame(parent) + self.frame.pack(fill="both", expand=True) + + tk.Label(self.frame, text="KASIR PAGE", font=("Arial", 18, "bold")).pack(pady=10) + + # Tombol Logout + tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5) + + # Listbox untuk menampilkan order + tk.Label(self.frame, text="Daftar Order:", font=("Arial", 12, "bold")).pack(pady=5) + self.listbox = tk.Listbox(self.frame, width=50, height=10) + self.listbox.pack(pady=5) + + # Tombol bayar + tk.Button(self.frame, text="Bayar", bg="#d1e7dd", command=self.bayar).pack(pady=5) + + self.load_orders() # Load order dari database saat awal + + def load_orders(self): + self.listbox.delete(0, tk.END) + db = connect() + cur = db.cursor() + cur.execute("SELECT id, nama, harga FROM orders") + self.data = cur.fetchall() + db.close() + + for order in self.data: + self.listbox.insert(tk.END, f"ID {order[0]}: {order[1]} - Rp {order[2]:,}") + + def bayar(self): + idx = self.listbox.curselection() + if not idx: + messagebox.showwarning("Pilih Order", "Pilih order yang ingin dibayar!") + return + + order = self.data[idx[0]] + order_id, nama, total = order + + # Simpan pembayaran di database (opsional, bisa buat tabel pembayaran) + db = connect() + cur = db.cursor() + cur.execute("INSERT INTO pembayaran VALUES (NULL, ?, ?)", (order_id, total)) + cur.execute("DELETE FROM orders WHERE id=?", (order_id,)) + db.commit() + db.close() + + # Tampilkan struk + self.tampil_struk(order_id, nama, total) + + # Update listbox + self.load_orders() + + def tampil_struk(self, order_id, nama, total): + win = tk.Toplevel(self.frame) + win.title("Struk Pembayaran") + + tk.Label(win, text="STRUK PEMBAYARAN", font=("Arial",14,"bold")).pack(pady=5) + tk.Label(win, text=f"Order ID : {order_id}").pack() + tk.Label(win, text=f"Nama Menu: {nama}").pack() + tk.Label(win, text=f"Total : Rp {total:,}").pack() + tk.Label(win, text="Terima kasih 🙏").pack(pady=10) + tk.Button(win, text="Tutup", command=win.destroy).pack(pady=5) + + def logout(self): + self.frame.destroy() + from main import LoginScreen + LoginScreen(self.parent) + diff --git a/project/kasir_dashboard.py b/project/kasir_dashboard.py deleted file mode 100644 index bd10ca7..0000000 --- a/project/kasir_dashboard.py +++ /dev/null @@ -1,7 +0,0 @@ -import tkinter as tk - -class KasirDashboard(tk.Frame): - def __init__(self, parent, controller): - super().__init__(parent) - tk.Label(self, text="KASIR DASHBOARD", font=("Arial", 20, "bold")).pack(pady=20) - tk.Button(self, text="Logout", command=lambda: controller.show_frame("Login")).pack() diff --git a/project/login.py b/project/login.py new file mode 100644 index 0000000..86798c0 --- /dev/null +++ b/project/login.py @@ -0,0 +1,46 @@ +import tkinter as tk +from tkinter import messagebox +from database import connect +from admin_menu import AdminMenu +from pembeli_menu import PembeliMenu +from kasir import KasirPage +from pemilik import PemilikPage + +class LoginPage: + def __init__(self, root): + self.root = root + self.frame = tk.Frame(root) + self.frame.pack(expand=True) + + tk.Label(self.frame, text="LOGIN CAFE", font=("Arial",20,"bold")).pack(pady=10) + + self.user = tk.Entry(self.frame) + self.passw = tk.Entry(self.frame, show="*") + self.user.pack() + self.passw.pack() + + tk.Button(self.frame, text="Login", command=self.login).pack(pady=5) + + def login(self): + db = connect() + cur = db.cursor() + cur.execute("SELECT role FROM users WHERE username=? AND password=?", + (self.user.get(), self.passw.get())) + res = cur.fetchone() + db.close() + + if not res: + messagebox.showerror("Error","Login gagal") + return + + self.frame.destroy() + role = res[0] + + if role=="admin": + AdminMenu(self.root) + elif role=="pembeli": + PembeliMenu(self.root) + elif role=="kasir": + KasirPage(self.root) + elif role=="pemilik": + PemilikPage(self.root) diff --git a/project/main.py b/project/main.py index 78b340c..23cb139 100644 --- a/project/main.py +++ b/project/main.py @@ -1,61 +1,27 @@ import tkinter as tk -from tkinter import messagebox from database import setup_database, connect - -from admin_dashboard import AdminDashboard -from kasir_dashboard import KasirDashboard -from waiter_dashboard import WaiterDashboard from pembeli_menu import PembeliMenu -from pemilik_dashboard import PemilikDashboard +from kasir import KasirPage +from pemilik import PemilikPage +from admin_menu import AdminMenu +from waiter_dashboard import WaiterDashboard +from tkinter import messagebox +# --- Login Screen --- +class LoginScreen: + def __init__(self, root): + self.root = root + self.frame = tk.Frame(root) + self.frame.pack(fill="both", expand=True) -class App(tk.Tk): - def __init__(self): - super().__init__() - self.title("Sistem Cafe") - self.geometry("500x400") - - self.container = tk.Frame(self) - self.container.pack(fill="both", expand=True) - - self.frames = {} - - # Register screens - for name, FrameClass in { - "Login": LoginScreen, - "Admin": AdminDashboard, - "Kasir": KasirDashboard, - "Waiter": WaiterDashboard, - "Pembeli": PembeliMenu, - "Pemilik": PemilikDashboard - }.items(): - frame = FrameClass(self.container, self) - self.frames[name] = frame - frame.grid(row=0, column=0, sticky="nsew") - - self.show_frame("Login") - - def show_frame(self, name): - frame = self.frames[name] - frame.tkraise() - - -class LoginScreen(tk.Frame): - def __init__(self, parent, controller): - super().__init__(parent) - self.controller = controller - - tk.Label(self, text="LOGIN SISTEM CAFE", font=("Arial", 20, "bold")).pack(pady=20) - - tk.Label(self, text="Username").pack() - self.username_entry = tk.Entry(self, width=30) + tk.Label(self.frame,text="LOGIN SISTEM CAFE", font=("Arial",18,"bold")).pack(pady=20) + tk.Label(self.frame,text="Username").pack() + self.username_entry = tk.Entry(self.frame) self.username_entry.pack() - - tk.Label(self, text="Password").pack() - self.password_entry = tk.Entry(self, width=30, show="*") - self.password_entry.pack() - - tk.Button(self, text="Login", width=20, command=self.login).pack(pady=15) + tk.Label(self.frame,text="Password").pack() + self.password_entry = tk.Entry(self.frame, show="*") + self.password_entry.pack(pady=5) + tk.Button(self.frame,text="Login", bg="#cfe2ff", command=self.login).pack(pady=10) def login(self): username = self.username_entry.get() @@ -63,32 +29,43 @@ class LoginScreen(tk.Frame): db = connect() cur = db.cursor() - - cur.execute("SELECT role FROM users WHERE username=? AND password=?", (username, password)) + cur.execute("SELECT role FROM users WHERE username=? AND password=?", (username,password)) result = cur.fetchone() + db.close() if result: role = result[0] + self.frame.destroy() + if role=="pembeli": + PembeliMenu(self.root) + + elif role=="kasir": + KasirPage(self.root, self.root) + + elif role=="pemilik": + PemilikPage(self.root, self.root) + + elif role == "admin": + AdminMenu(self.root) - if role == "admin": - self.controller.show_frame("Admin") - elif role == "kasir": - self.controller.show_frame("Kasir") elif role == "waiter": - self.controller.show_frame("Waiter") - elif role == "pembeli": - self.controller.show_frame("Pembeli") - elif role == "pemilik cafe": - self.controller.show_frame("Pemilik") + WaiterDashboard(self.root) + else: + messagebox.showerror("Error","Role tidak dikenali") else: - messagebox.showerror("Error", "Username atau password salah") + messagebox.showerror("Error","Username / Password salah") - db.close() +# --- App --- +class App(tk.Tk): + def __init__(self): + super().__init__() + self.title("Sistem Cafe") + self.geometry("700x600") - -# RUN PROGRAM -if __name__ == "__main__": +# --- Run Program --- +if __name__=="__main__": setup_database() app = App() + LoginScreen(app) app.mainloop() diff --git a/project/pembeli_menu.py b/project/pembeli_menu.py index 6a8e161..c57f2bf 100644 --- a/project/pembeli_menu.py +++ b/project/pembeli_menu.py @@ -1,7 +1,91 @@ import tkinter as tk +from PIL import Image, ImageTk +from database import connect +from tkinter import messagebox + +class PembeliMenu: + def __init__(self, parent): + self.parent = parent + self.frame = tk.Frame(parent) + self.frame.pack(fill="both", expand=True) + + + self.cart = [] # Simpan tuple (nama, harga) + self.images = [] # Simpan reference gambar agar tidak dihapus GC + + # --- Judul Halaman --- + tk.Label(self.frame, text="MENU PEMBELI", font=("Arial", 18, "bold")).pack(pady=10) + + # --- Tombol Logout --- + tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5) + + # --- Frame Menu --- + self.menu_frame = tk.Frame(self.frame) + self.menu_frame.pack(pady=10) + + self.load_menu() # Load menu dari database + + # --- Daftar Pesanan --- + tk.Label(self.frame, text="Daftar Pesanan:", font=("Arial", 12, "bold")).pack(pady=5) + self.listbox = tk.Listbox(self.frame, width=50, height=6) + self.listbox.pack() + + # --- Total --- + self.total_lbl = tk.Label(self.frame, text="Total: Rp 0", font=("Arial", 12, "bold")) + self.total_lbl.pack(pady=5) + + # --- Tombol Checkout --- + tk.Button(self.frame, text="Checkout", bg="#d1e7dd", command=self.checkout).pack(pady=5) + + def load_menu(self): + db = connect() + cur = db.cursor() + cur.execute("SELECT nama, harga, gambar FROM menu") + data = cur.fetchall() + db.close() + + for i, (nama, harga, gambar) in enumerate(data): + f = tk.Frame(self.menu_frame, bd=2, relief="ridge") + f.grid(row=i//3, column=i%3, padx=10, pady=10) + + try: + img = Image.open(gambar).resize((120, 90)) + photo = ImageTk.PhotoImage(img) + self.images.append(photo) + tk.Label(f, image=photo).pack() + except FileNotFoundError: + tk.Label(f, text="No Image").pack() + + tk.Label(f, text=nama).pack() + tk.Label(f, text=f"Rp {harga:,}").pack() + tk.Button(f, text="Pesan", bg="#cfe2ff", + command=lambda n=nama, h=harga: self.add(n, h)).pack(pady=3) + + def add(self, nama, harga): + self.cart.append((nama, harga)) + self.listbox.insert(tk.END, f"{nama} - Rp {harga:,}") + total = sum(h for _, h in self.cart) + self.total_lbl.config(text=f"Total: Rp {total:,}") + + def checkout(self): + if not self.cart: + messagebox.showwarning("Pesan Kosong", "Belum ada pesanan!") + return + + db = connect() + cur = db.cursor() + for nama, harga in self.cart: + cur.execute("INSERT INTO orders VALUES (NULL, ?, ?)", (nama, harga)) + db.commit() + db.close() + + messagebox.showinfo("Sukses", "Pesanan dikirim ke kasir") + self.cart.clear() + self.listbox.delete(0, tk.END) + self.total_lbl.config(text="Total: Rp 0") + + def logout(self): + self.frame.destroy() + from main import LoginScreen + LoginScreen(self.parent) -class PembeliMenu(tk.Frame): - def __init__(self, parent, controller): - super().__init__(parent) - tk.Label(self, text="MENU PEMBELI", font=("Arial", 20, "bold")).pack(pady=20) - tk.Button(self, text="Logout", command=lambda: controller.show_frame("Login")).pack() diff --git a/project/pemilik.py b/project/pemilik.py new file mode 100644 index 0000000..7d1007c --- /dev/null +++ b/project/pemilik.py @@ -0,0 +1,40 @@ +import tkinter as tk +from database import connect + +class PemilikPage: + def __init__(self, parent, controller): + self.parent = parent + self.controller = controller + self.frame = tk.Frame(parent) + self.frame.pack(fill="both", expand=True) + + tk.Label(self.frame, text="LAPORAN PENJUALAN", font=("Arial", 18, "bold")).pack(pady=10) + + # Label untuk total penjualan + self.total_lbl = tk.Label(self.frame, text="Total Penjualan: Rp 0", font=("Arial", 14, "bold")) + self.total_lbl.pack(pady=5) + + # Tombol Refresh + tk.Button(self.frame, text="Refresh", bg="#cfe2ff", command=self.load).pack(pady=5) + + # Tombol Logout + tk.Button(self.frame, text="Logout", bg="#f9e79f", command=self.logout).pack(pady=5) + + # Load data awal + self.load() + + def load(self): + db = connect() + cur = db.cursor() + # Jumlahkan semua total pembayaran dari tabel pembayaran + cur.execute("SELECT SUM(total) FROM pembayaran") + total = cur.fetchone()[0] or 0 + db.close() + + self.total_lbl.config(text=f"Total Penjualan: Rp {total:,}") + + def logout(self): + self.frame.destroy() + from main import LoginScreen + LoginScreen(self.parent) + diff --git a/project/pemilik_dashboard.py b/project/pemilik_dashboard.py deleted file mode 100644 index aa445e7..0000000 --- a/project/pemilik_dashboard.py +++ /dev/null @@ -1,7 +0,0 @@ -import tkinter as tk - -class PemilikDashboard(tk.Frame): - def __init__(self, parent, controller): - super().__init__(parent) - tk.Label(self, text="PEMILIK CAFE DASHBOARD", font=("Arial", 20, "bold")).pack(pady=20) - tk.Button(self, text="Logout", command=lambda: controller.show_frame("Login")).pack() diff --git a/project/project.css b/project/project.css index e4cb90d..459fde1 100644 --- a/project/project.css +++ b/project/project.css @@ -1,8 +1,10 @@ project/ │ main.py │ database.py -│ admin_dashboard.py -│ kasir_dashboard.py -│ waiter_dashboard.py │ pembeli_menu.py -│ pemilik_dashboard.py +│ kasir_page.py +│ pemilik_page.py +│ mie ayam.webp +│ mie kuah.webp +│ es teh.webp +│ jus jeruk.webp \ No newline at end of file diff --git a/project/waiter_dashboard.py b/project/waiter_dashboard.py index 0a5549a..a325494 100644 --- a/project/waiter_dashboard.py +++ b/project/waiter_dashboard.py @@ -1,7 +1,17 @@ import tkinter as tk -class WaiterDashboard(tk.Frame): - def __init__(self, parent, controller): - super().__init__(parent) - tk.Label(self, text="WAITER DASHBOARD", font=("Arial", 20, "bold")).pack(pady=20) - tk.Button(self, text="Logout", command=lambda: controller.show_frame("Login")).pack() +class WaiterDashboard: + def __init__(self, parent): + self.parent = parent + self.frame = tk.Frame(parent) + self.frame.pack(fill="both", expand=True) + + tk.Label(self.frame, text="WAITER", font=("Arial", 20, "bold")).pack(pady=20) + tk.Label(self.frame, text="(Input pesanan manual)").pack() + + tk.Button(self.frame, text="Logout", command=self.logout).pack(pady=10) + + def logout(self): + self.frame.destroy() + from main import LoginScreen + LoginScreen(self.parent)