Styling Totoro

This commit is contained in:
Jevinca Marvella 2025-12-14 17:45:41 +07:00
parent 61547a4012
commit 673a693020
2 changed files with 262 additions and 49 deletions

BIN
img/totoro_logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

311
main.py
View File

@ -12,6 +12,24 @@ import tkinter as tk
from tkinter import ttk, messagebox, filedialog, simpledialog
from PIL import Image, ImageTk
# ========================================
# UI STYLING - TOTORO THEME COLORS
# ========================================
COLORS = {
'bg_main': '#F5F5DC', # Beige/Krem lembut (background utama)
'bg_secondary': '#FFFFFF', # Putih untuk cards
'primary': '#8FBFA8', # Hijau Totoro (medium)
'primary_dark': '#6B9080', # Hijau tua
'accent': '#A8D5BA', # Hijau pastel lembut
'brown': '#8B7355', # Coklat kayu
'text_dark': '#3D3D3D', # Text gelap
'text_light': '#666666', # Text abu-abu
'success': '#6B9080', # Hijau untuk success
'warning': '#D4A574', # Coklat muda untuk warning
'danger': '#C9797A', # Merah lembut untuk danger
'border': '#D4C5B9', # Border coklat muda
}
USERS_CSV = "users.csv"
MENU_CSV = "menu.csv"
PROMO_CSV = "promo.csv"
@ -793,7 +811,7 @@ def report_get_monthly_summary(year=None, month=None, method_filter=None):
def report_export_to_text(report_data, report_type='daily'):
"""Export laporan ke format text"""
text = "=" * 70 + "\n"
text += "LAPORAN PENJUALAN CAFE TOTORO MANIA\n"
text += "LAPORAN PENJUALAN CAFÉ TOTORO \n"
text += "=" * 70 + "\n\n"
if report_type == 'daily':
@ -1101,52 +1119,196 @@ def meja_get(nomor_meja):
class App:
def __init__(self, root):
self.root = root
self.root.title("Cafe Totoro Mania")
self.root.title("Totoro Cafe")
self.session = None
self.img_cache = {}
self.setup_ui()
def setup_ui(self):
self.root.geometry("1000x650")
self.root.resizable(False, False)
self.login_frame()
# UI STYLING - Window setup dengan tema Totoro
self.root.geometry("1200x750")
self.root.resizable(True, True) # Bisa maximize
self.root.configure(bg=COLORS['bg_main'])
# UI STYLING - Custom styles untuk tema Totoro
style = ttk.Style()
style.configure("Accent.TButton", font=("Arial", 11, "bold"))
style.configure("TButton", padding=6) # Padding tombol lebih besar
style.theme_use('clam')
# Background colors
style.configure(".", background=COLORS['bg_main'], foreground=COLORS['text_dark'])
# Frame styles
style.configure("TFrame", background=COLORS['bg_main'])
style.configure("TLabelframe", background=COLORS['bg_main'], bordercolor=COLORS['border'])
style.configure("TLabelframe.Label", background=COLORS['bg_main'], foreground=COLORS['brown'], font=("Arial", 10, "bold"))
# Button styles
style.configure("TButton",
background=COLORS['primary'],
foreground="white",
borderwidth=0,
focuscolor='none',
font=("Arial", 10),
padding=10)
style.map("TButton",
background=[('active', COLORS['primary_dark']), ('pressed', COLORS['primary_dark'])],
foreground=[('active', 'white')])
style.configure("Accent.TButton",
background=COLORS['brown'],
foreground="white",
font=("Arial", 11, "bold"),
padding=12)
style.map("Accent.TButton",
background=[('active', '#6B5D48'), ('pressed', '#6B5D48')])
# Label styles
style.configure("TLabel", background=COLORS['bg_main'], foreground=COLORS['text_dark'], font=("Arial", 10))
# Entry styles
style.configure("TEntry", fieldbackground="white", bordercolor=COLORS['border'])
# Treeview styles
style.configure("Treeview",
background="white",
foreground=COLORS['text_dark'],
fieldbackground="white",
borderwidth=0,
font=("Arial", 9))
style.configure("Treeview.Heading",
background=COLORS['primary'],
foreground="white",
font=("Arial", 10, "bold"))
style.map("Treeview.Heading",
background=[('active', COLORS['primary_dark'])])
# Notebook (tabs) styles
style.configure("TNotebook", background=COLORS['bg_main'], borderwidth=0)
style.configure("TNotebook.Tab",
background=COLORS['accent'],
foreground=COLORS['text_dark'],
padding=[20, 10],
font=("Arial", 10))
style.map("TNotebook.Tab",
background=[('selected', COLORS['primary'])],
foreground=[('selected', 'white')],
expand=[('selected', [1, 1, 1, 0])])
self.login_frame()
def login_frame(self):
for w in self.root.winfo_children():
w.destroy()
frame = ttk.Frame(self.root, padding=20)
frame.pack(expand=True)
ttk.Label(frame, text="Login Duluu...", font=("Arial", 24)).grid(row=0, column=0, columnspan=2, pady=10)
ttk.Label(frame, text="Username:").grid(row=1, column=0, sticky='e', pady=5)
self.username_var = tk.StringVar()
ttk.Entry(frame, textvariable=self.username_var, width=30).grid(row=1, column=1, pady=5)
ttk.Label(frame, text="Password:").grid(row=2, column=0, sticky='e', pady=5)
self.password_var = tk.StringVar()
ttk.Entry(frame, textvariable=self.password_var, show="*", width=30).grid(row=2, column=1, pady=5)
# TAMBAHAN: Input nama pembeli (untuk role pembeli)
ttk.Label(frame, text="Nama Lengkap:", font=("Arial", 9)).grid(row=3, column=0, sticky='e', pady=5)
# UI STYLING - Main container dengan background Totoro
main_container = tk.Frame(self.root, bg=COLORS['bg_main'])
main_container.pack(fill='both', expand=True)
# UI STYLING - Center frame untuk login card
center_frame = tk.Frame(main_container, bg=COLORS['bg_main'])
center_frame.place(relx=0.5, rely=0.5, anchor='center')
# UI STYLING - Login card dengan shadow effect
card = tk.Frame(center_frame, bg='white', relief='flat', borderwidth=0)
card.pack(padx=20, pady=20)
# UI STYLING - Header dengan tema Totoro
header_frame = tk.Frame(card, bg=COLORS['primary'], height=100)
header_frame.pack(fill='x', pady=(0, 30))
# UI STYLING - Logo Totoro di atas card
try:
totoro_img = Image.open("img/totoro_logo.png")
totoro_img = totoro_img.resize((100, 100), Image.Resampling.LANCZOS)
totoro_photo = ImageTk.PhotoImage(totoro_img)
self.totoro_logo = totoro_photo
img_label = tk.Label(card, image=totoro_photo, bg='white')
img_label.pack(pady=(20, 10))
except:
# Fallback jika gambar tidak ditemukan
tk.Label(card, text="🌿", font=("Arial", 48), bg='white').pack(pady=(20, 10))
tk.Label(header_frame,
text="🌿 TOTORO CAFÉ 🌿",
font=("Arial", 24, "bold"),
bg=COLORS['primary'],
fg='white').pack(pady=20)
tk.Label(header_frame,
text="Selamat Datang di Sistem Manajemen Cafe",
font=("Arial", 10),
bg=COLORS['primary'],
fg='white').pack(pady=(0, 10))
# UI STYLING - Form container
form_frame = tk.Frame(card, bg='white')
form_frame.pack(padx=50, pady=20)
# Username
tk.Label(form_frame, text="Username:", font=("Arial", 11), bg='white', fg=COLORS['text_dark']).grid(row=0, column=0, sticky='w', pady=(10, 5))
self.username_var = tk.StringVar()
username_entry = tk.Entry(form_frame, textvariable=self.username_var, width=35, font=("Arial", 11), relief='solid', borderwidth=1)
username_entry.grid(row=1, column=0, pady=(0, 15), ipady=8)
# Password
tk.Label(form_frame, text="Password:", font=("Arial", 11), bg='white', fg=COLORS['text_dark']).grid(row=2, column=0, sticky='w', pady=(10, 5))
self.password_var = tk.StringVar()
password_entry = tk.Entry(form_frame, textvariable=self.password_var, show="", width=35, font=("Arial", 11), relief='solid', borderwidth=1)
password_entry.grid(row=3, column=0, pady=(0, 15), ipady=8)
# UI STYLING - Info untuk pembeli
info_frame = tk.Frame(form_frame, bg='#FFF9E6', relief='solid', borderwidth=1)
info_frame.grid(row=4, column=0, pady=15, sticky='ew')
tk.Label(info_frame, text=" Khusus untuk Pembeli", font=("Arial", 9, "bold"), bg='#FFF9E6', fg=COLORS['brown']).pack(anchor='w', padx=10, pady=(10, 5))
# Nama Lengkap
tk.Label(form_frame, text="Nama Lengkap:", font=("Arial", 10), bg='white', fg=COLORS['text_light']).grid(row=5, column=0, sticky='w', pady=(5, 3))
self.customer_name_var = tk.StringVar()
customer_entry = ttk.Entry(frame, textvariable=self.customer_name_var, width=30)
customer_entry.grid(row=3, column=1, pady=5)
ttk.Label(frame, text="(Khusus untuk Pembeli)", font=("Arial", 7), foreground='gray').grid(row=4, column=1, sticky='w')
# TAMBAHAN BARU: Input nomor meja (untuk role pembeli)
ttk.Label(frame, text="Nomor Meja:", font=("Arial", 9)).grid(row=5, column=0, sticky='e', pady=5)
customer_entry = tk.Entry(form_frame, textvariable=self.customer_name_var, width=35, font=("Arial", 10), relief='solid', borderwidth=1)
customer_entry.grid(row=6, column=0, pady=(0, 10), ipady=6)
# Nomor Meja
tk.Label(form_frame, text="Nomor Meja (1-10):", font=("Arial", 10), bg='white', fg=COLORS['text_light']).grid(row=7, column=0, sticky='w', pady=(5, 3))
self.customer_meja_var = tk.StringVar()
meja_entry = ttk.Entry(frame, textvariable=self.customer_meja_var, width=30)
meja_entry.grid(row=5, column=1, pady=5)
ttk.Label(frame, text="(Khusus untuk Pembeli - Meja 1-10)", font=("Arial", 7), foreground='gray').grid(row=6, column=1, sticky='w')
meja_entry = tk.Entry(form_frame, textvariable=self.customer_meja_var, width=35, font=("Arial", 10), relief='solid', borderwidth=1)
meja_entry.grid(row=8, column=0, pady=(0, 20), ipady=6)
# UI STYLING - Login button dengan style Totoro
login_btn = tk.Button(form_frame,
text="🌿 LOGIN",
command=self.handle_login,
bg=COLORS['primary'],
fg='white',
font=("Arial", 12, "bold"),
relief='flat',
cursor='hand2',
width=30,
height=2)
login_btn.grid(row=9, column=0, pady=(10, 20))
# Hover effect untuk button
def on_enter(e):
login_btn['background'] = COLORS['primary_dark']
def on_leave(e):
login_btn['background'] = COLORS['primary']
login_btn.bind("<Enter>", on_enter)
login_btn.bind("<Leave>", on_leave)
# UI STYLING - Footer
footer_frame = tk.Frame(card, bg='white')
footer_frame.pack(fill='x', pady=(0, 20))
tk.Label(footer_frame,
text="© 2025 Café Totoro - Proyek UAS Informatika",
font=("Arial", 8),
bg='white',
fg=COLORS['text_light']).pack()
ttk.Button(frame, text="Login", command=self.handle_login).grid(row=7, column=0, columnspan=2, pady=12)
def handle_login(self):
u = self.username_var.get().strip()
@ -1230,23 +1392,74 @@ class App:
def dashboard_frame(self):
for w in self.root.winfo_children():
w.destroy()
top = ttk.Frame(self.root)
# UI STYLING - Header dashboard dengan tema Totoro
top = tk.Frame(self.root, bg=COLORS['primary'], height=60)
top.pack(fill='x')
# Text untuk header
if self.session['role'] in ['pembeli', 'user'] and 'customer_name' in self.session:
header_text = f"👤 {self.session['customer_name']} | User: {self.session['username']} | Role: {self.session['role']}"
else:
header_text = f"User: {self.session['username']} | Role: {self.session['role']}"
# Left side - User info
left_info = tk.Frame(top, bg=COLORS['primary'])
left_info.pack(side='left', padx=20, pady=10)
ttk.Label(
top,
text=header_text,
font=("Arial", 12)
).pack(side='left', padx=10, pady=6)
ttk.Button(top, text="Logout", command=self.logout).pack(side='right', padx=10)
main = ttk.Notebook(self.root)
main.pack(fill='both', expand=True, padx=10, pady=8)
# UI STYLING - Logo kecil di header
try:
totoro_header = Image.open("img/totoro_logo.png")
totoro_header = totoro_header.resize((40, 40), Image.Resampling.LANCZOS)
totoro_header_photo = ImageTk.PhotoImage(totoro_header)
self.totoro_header_logo = totoro_header_photo
tk.Label(top, image=totoro_header_photo, bg=COLORS['primary']).pack(side='left', padx=(20, 5))
except:
tk.Label(top, text="🌿", font=("Arial", 24), bg=COLORS['primary']).pack(side='left', padx=(20, 5))
if self.session['role'] in ['pembeli', 'user'] and 'customer_name' in self.session:
header_text = f"👤 {self.session['customer_name']}"
subtext = f"Meja {self.session.get('nomor_meja', '-')}{self.session['role'].title()}"
else:
header_text = f"👤 {self.session['username']}"
subtext = f"Role: {self.session['role'].title()}"
tk.Label(left_info,
text=header_text,
font=("Arial", 13, "bold"),
bg=COLORS['primary'],
fg='white').pack(anchor='w')
tk.Label(left_info,
text=subtext,
font=("Arial", 9),
bg=COLORS['primary'],
fg='white').pack(anchor='w')
# Right side - Logout button
logout_btn = tk.Button(top,
text="🚪 Logout",
command=self.logout,
bg=COLORS['brown'],
fg='white',
font=("Arial", 10, "bold"),
relief='flat',
cursor='hand2',
padx=20,
pady=8)
logout_btn.pack(side='right', padx=20, pady=10)
# Hover effect
def on_enter(e):
logout_btn['background'] = '#6B5D48'
def on_leave(e):
logout_btn['background'] = COLORS['brown']
logout_btn.bind("<Enter>", on_enter)
logout_btn.bind("<Leave>", on_leave)
# UI STYLING - Container untuk tabs
tab_container = tk.Frame(self.root, bg=COLORS['bg_main'])
tab_container.pack(fill='both', expand=True, padx=15, pady=10)
main = ttk.Notebook(tab_container)
main.pack(fill='both', expand=True)
self.tab_menu_manage = ttk.Frame(main)
self.tab_menu_view = ttk.Frame(main)
self.tab_promo = ttk.Frame(main)
@ -4328,8 +4541,8 @@ class App:
# Build struk string
struk = "═════════════════════════════════════════\n"
struk += " CAFE TOTORO MANIA\n"
struk += " Jl. Raya Kampus No. 123, Surabaya\n"
struk += " TOTORO CAFE\n"
struk += " Jl. Raya Totoro No. 123, Surabaya\n"
struk += " Telp: 031-123456\n"
struk += "═════════════════════════════════════════\n\n"
struk += f"No. Struk : STR-{tid}-{datetime.now().strftime('%Y%m%d')}\n"