This commit is contained in:
Nathan 2025-12-07 22:04:26 +07:00
commit 1a5d12f76f
22 changed files with 385 additions and 116 deletions

BIN
cafe.db

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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()

40
project/admin_menu.py Normal file
View File

@ -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")

View File

@ -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()

76
project/kasir.py Normal file
View File

@ -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)

View File

@ -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()

46
project/login.py Normal file
View File

@ -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)

View File

@ -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()

View File

@ -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()

40
project/pemilik.py Normal file
View File

@ -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)

View File

@ -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()

View File

@ -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

View File

@ -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)