import tkinter as tk from tkinter import messagebox, ttk from PIL import Image, ImageTk import sqlite3 import datetime import os # ================= DATABASE CONNECT ================= def connect(): return sqlite3.connect("cafe.db") # ================= PEMBELI MENU ================= class PembeliMenu: def __init__(self, parent): self.parent = parent self.frame = tk.Frame(parent) self.frame.pack(fill="both", expand=True) self.cart = [] self.images = [] # ================= HEADER ================= header = tk.Frame(self.frame) header.pack(fill="x", padx=20, pady=10) tk.Label( header, text="SELAMAT DATANG", font=("Arial", 18, "bold") ).pack(side="left") tk.Button( header, text="⬅ Logout", bg="#f8d7da", font=("Arial", 10, "bold"), command=self.logout ).pack(side="right") # ================= INPUT DATA ================= info_frame = tk.Frame(self.frame, bd=2, relief="groove", padx=10, pady=10) info_frame.pack(pady=5) tk.Label(info_frame, text="Nama Anda:").grid(row=0, column=0, sticky="e") self.entry_nama = tk.Entry(info_frame) self.entry_nama.grid(row=0, column=1, padx=5) tk.Label(info_frame, text="Pilih Meja:").grid(row=0, column=2, sticky="e") self.meja_var = tk.StringVar() self.combo_meja = ttk.Combobox( info_frame, textvariable=self.meja_var, state="readonly", width=5 ) self.combo_meja.grid(row=0, column=3, padx=5) tk.Button(info_frame, text="🔄", command=self.refresh_available_tables).grid(row=0, column=4, padx=2) self.refresh_available_tables() # ================= CONTENT 2 KOLOM ================= content = tk.Frame(self.frame) content.pack(fill="both", expand=True, padx=20, pady=10) content.grid_columnconfigure(0, weight=3) content.grid_columnconfigure(1, weight=1) # ================= MENU (KIRI) ================= self.menu_frame = tk.Frame(content) self.menu_frame.grid(row=0, column=0, sticky="nw") self.load_menu() # ================= KERANJANG (KANAN) ================= cart_frame = tk.LabelFrame( content, text="Keranjang Pesanan", font=("Arial", 11, "bold"), padx=10, pady=10 ) cart_frame.grid(row=0, column=1, sticky="ne") self.listbox = tk.Listbox(cart_frame, width=35, height=10, font=("Courier", 10)) self.listbox.pack(pady=5) tk.Button(cart_frame, text="➖ Kurangi / Hapus Item", fg="red", command=self.kurangi_item_cart).pack(pady=5) self.total_lbl = tk.Label(cart_frame, text="Total: Rp 0", font=("Arial", 12, "bold")) self.total_lbl.pack(pady=5) tk.Button(cart_frame, text="✅ KIRIM PESANAN", bg="#d1e7dd", font=("Arial", 11, "bold"), command=self.checkout).pack(pady=10) # ================= MEJA ================= def refresh_available_tables(self): total_meja = [str(i) for i in range(1, 11)] db = connect() cur = db.cursor() cur.execute("SELECT DISTINCT meja_id FROM transaksi WHERE status != 'Selesai'") terisi = [str(row[0]) for row in cur.fetchall()] db.close() tersedia = [m for m in total_meja if m not in terisi] self.combo_meja['values'] = tersedia if tersedia else ["Penuh"] self.combo_meja.set(tersedia[0] if tersedia else "Penuh") # ================= MENU ================= def load_menu(self): db = connect() cur = db.cursor() cur.execute("SELECT nama, harga, gambar FROM menu") data = cur.fetchall() db.close() columns = 4 for i, (nama, harga, gambar) in enumerate(data): row, col = divmod(i, columns) card = tk.Frame(self.menu_frame, width=180, height=220, bd=2, relief="ridge") card.grid(row=row, column=col, padx=10, pady=10) card.grid_propagate(False) try: filename = os.path.basename(gambar) if gambar else None img_path = os.path.join("aset", filename) if filename else None if img_path and os.path.exists(img_path): img = Image.open(img_path).resize((140, 90)) photo = ImageTk.PhotoImage(img) self.images.append(photo) tk.Label(card, image=photo).pack(pady=5) else: tk.Label(card, text="[No Image]", height=6).pack() except Exception: tk.Label(card, text="Error Img", height=6).pack() tk.Label(card, text=nama, font=("Arial", 10, "bold"), wraplength=160).pack() tk.Label(card, text=f"Rp {harga:,.0f}").pack(pady=2) tk.Button(card, text="Tambah", bg="#cfe2ff", command=lambda n=nama, h=harga: self.add_to_cart(n, h)).pack(pady=5) # ================= CART ================= def add_to_cart(self, nama, harga): for item in self.cart: if item['nama'] == nama: item['qty'] += 1 item['subtotal'] = item['qty'] * harga self.refresh_cart() return self.cart.append({'nama': nama, 'harga_satuan': harga, 'qty': 1, 'subtotal': harga}) self.refresh_cart() def kurangi_item_cart(self): if not self.listbox.curselection(): return idx = self.listbox.curselection()[0] item = self.cart[idx] item['qty'] -= 1 if item['qty'] <= 0: self.cart.pop(idx) else: item['subtotal'] = item['qty'] * item['harga_satuan'] self.refresh_cart() def refresh_cart(self): self.listbox.delete(0, tk.END) total = 0 for item in self.cart: self.listbox.insert(tk.END, f"{item['nama']} (x{item['qty']}) - Rp {item['subtotal']:,.0f}") total += item['subtotal'] self.total_lbl.config(text=f"Total: Rp {total:,.0f}") # ================= CHECKOUT ================= def checkout(self): if not self.entry_nama.get() or not self.cart: messagebox.showwarning("Error", "Data belum lengkap") return total = sum(item['subtotal'] for item in self.cart) tanggal = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S") db = connect() cur = db.cursor() cur.execute("INSERT INTO transaksi (tanggal, total, meja_id, status) VALUES (?, ?, ?, ?)", (tanggal, total, self.combo_meja.get(), "Pending")) db.commit() db.close() messagebox.showinfo("Berhasil", "Pesanan berhasil dikirim") self.cart.clear() self.refresh_cart() def logout(self): self.frame.destroy() from main import LoginScreen LoginScreen(self.parent) # ================= RUN ================= if __name__ == '__main__': root = tk.Tk() root.title("Sistem Cafe Python") root.geometry("1200x700") PembeliMenu(root) root.mainloop()