Created
January 16, 2026 20:21
-
-
Save ravsau/3bde2f8b4790f7b0a729d5463de0eab9 to your computer and use it in GitHub Desktop.
example driving app
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import tkinter as tk | |
| from tkinter import ttk, messagebox | |
| import sqlite3 | |
| # ========================== | |
| # DATABASE SETUP | |
| # ========================== | |
| conn = sqlite3.connect("driving_course.db") | |
| cursor = conn.cursor() | |
| # Create tables | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS users ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| name TEXT NOT NULL, | |
| username TEXT UNIQUE NOT NULL, | |
| password TEXT NOT NULL, | |
| security_code TEXT NOT NULL | |
| ) | |
| """) | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS admins ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| name TEXT NOT NULL, | |
| username TEXT UNIQUE NOT NULL, | |
| password TEXT NOT NULL, | |
| security_code TEXT NOT NULL | |
| ) | |
| """) | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS courses ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| vehicle TEXT NOT NULL, | |
| package TEXT NOT NULL, | |
| price REAL NOT NULL | |
| ) | |
| """) | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS enrollments ( | |
| id INTEGER PRIMARY KEY AUTOINCREMENT, | |
| user_id INTEGER NOT NULL, | |
| course_id INTEGER NOT NULL, | |
| enrollment_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | |
| FOREIGN KEY (user_id) REFERENCES users(id), | |
| FOREIGN KEY (course_id) REFERENCES courses(id) | |
| ) | |
| """) | |
| conn.commit() | |
| # ========================== | |
| # GLOBAL VARIABLES | |
| # ========================== | |
| ADMIN_SECRET_CODE = "1234" # Fixed 4-digit admin code for admin registration | |
| VEHICLE_CATEGORIES = ["Car", "Van", "Scooter", "Bike"] | |
| COURSE_PACKAGES = ["7 Days", "15 Days", "30 Days"] | |
| current_user_id = None | |
| current_user_name = None | |
| # ========================== | |
| # MAIN WINDOW | |
| # ========================== | |
| root = tk.Tk() | |
| root.title("Driving Course Registration System") | |
| root.geometry("900x600") | |
| root.configure(bg="#f0f0f0") | |
| # ========================== | |
| # STYLING | |
| # ========================== | |
| style = ttk.Style() | |
| style.configure("Title.TLabel", font=("Arial", 24, "bold")) | |
| style.configure("Subtitle.TLabel", font=("Arial", 14)) | |
| style.configure("TButton", font=("Arial", 11), padding=5) | |
| # ========================== | |
| # UTILITY FUNCTIONS | |
| # ========================== | |
| def clear_window(): | |
| """Clear all widgets from the main window.""" | |
| for widget in root.winfo_children(): | |
| widget.destroy() | |
| def create_centered_frame(parent): | |
| """Create a centered frame for forms.""" | |
| frame = ttk.Frame(parent) | |
| frame.place(relx=0.5, rely=0.5, anchor="center") | |
| return frame | |
| def create_form_entry(parent, label_text, show=None): | |
| """Create a label and entry pair.""" | |
| ttk.Label(parent, text=label_text).pack(anchor="w", pady=(10, 2)) | |
| entry = ttk.Entry(parent, width=30, show=show) | |
| entry.pack(fill="x") | |
| return entry | |
| # ========================== | |
| # LOGIN PAGE | |
| # ========================== | |
| def login_page(): | |
| """Display the login page.""" | |
| clear_window() | |
| frame = create_centered_frame(root) | |
| # Title | |
| ttk.Label(frame, text="Driving Course Registration", style="Title.TLabel").pack(pady=(0, 5)) | |
| ttk.Label(frame, text="Login to your account", style="Subtitle.TLabel").pack(pady=(0, 20)) | |
| # Username | |
| username_entry = create_form_entry(frame, "Username") | |
| # Password | |
| password_entry = create_form_entry(frame, "Password", show="*") | |
| # Role selection | |
| ttk.Label(frame, text="Login as:").pack(anchor="w", pady=(15, 5)) | |
| role_var = tk.StringVar(value="user") | |
| role_frame = ttk.Frame(frame) | |
| role_frame.pack(fill="x") | |
| ttk.Radiobutton(role_frame, text="User", variable=role_var, value="user").pack(side="left", padx=(0, 20)) | |
| ttk.Radiobutton(role_frame, text="Admin", variable=role_var, value="admin").pack(side="left") | |
| def login(): | |
| """Handle login authentication.""" | |
| global current_user_id, current_user_name | |
| username = username_entry.get().strip() | |
| password = password_entry.get() | |
| role = role_var.get() | |
| if not username or not password: | |
| messagebox.showerror("Error", "Please fill in all fields") | |
| return | |
| if role == "user": | |
| cursor.execute("SELECT id, name FROM users WHERE username=? AND password=?", | |
| (username, password)) | |
| result = cursor.fetchone() | |
| if result: | |
| current_user_id = result[0] | |
| current_user_name = result[1] | |
| user_dashboard() | |
| else: | |
| messagebox.showerror("Error", "Invalid username or password") | |
| else: | |
| cursor.execute("SELECT id, name FROM admins WHERE username=? AND password=?", | |
| (username, password)) | |
| result = cursor.fetchone() | |
| if result: | |
| current_user_id = result[0] | |
| current_user_name = result[1] | |
| admin_dashboard() | |
| else: | |
| messagebox.showerror("Error", "Invalid admin credentials") | |
| # Buttons | |
| ttk.Button(frame, text="Login", command=login, width=20).pack(pady=(20, 5)) | |
| ttk.Button(frame, text="Sign Up", command=signup_page, width=20).pack(pady=5) | |
| ttk.Button(frame, text="Forgot Password?", command=forgot_password_page, width=20).pack(pady=5) | |
| # ========================== | |
| # SIGNUP PAGE | |
| # ========================== | |
| def signup_page(): | |
| """Display the signup page.""" | |
| clear_window() | |
| frame = create_centered_frame(root) | |
| # Title | |
| ttk.Label(frame, text="Create Account", style="Title.TLabel").pack(pady=(0, 20)) | |
| # Full Name | |
| name_entry = create_form_entry(frame, "Full Name") | |
| # Username | |
| username_entry = create_form_entry(frame, "Username") | |
| # Password | |
| password_entry = create_form_entry(frame, "Password", show="*") | |
| # Confirm Password | |
| confirm_password_entry = create_form_entry(frame, "Confirm Password", show="*") | |
| # Security Code | |
| ttk.Label(frame, text="4-Digit Security Code (for password recovery)").pack(anchor="w", pady=(10, 2)) | |
| security_entry = ttk.Entry(frame, width=30, show="*") | |
| security_entry.pack(fill="x") | |
| # Role selection | |
| ttk.Label(frame, text="Register as:").pack(anchor="w", pady=(15, 5)) | |
| role_var = tk.StringVar(value="user") | |
| role_frame = ttk.Frame(frame) | |
| role_frame.pack(fill="x") | |
| ttk.Radiobutton(role_frame, text="User", variable=role_var, value="user").pack(side="left", padx=(0, 20)) | |
| ttk.Radiobutton(role_frame, text="Admin", variable=role_var, value="admin").pack(side="left") | |
| # Admin Code (only for admin registration) | |
| ttk.Label(frame, text="Admin Secret Code (required for admin registration)").pack(anchor="w", pady=(10, 2)) | |
| admin_code_entry = ttk.Entry(frame, width=30, show="*") | |
| admin_code_entry.pack(fill="x") | |
| def signup(): | |
| """Handle user/admin registration.""" | |
| name = name_entry.get().strip() | |
| username = username_entry.get().strip() | |
| password = password_entry.get() | |
| confirm_password = confirm_password_entry.get() | |
| security_code = security_entry.get().strip() | |
| role = role_var.get() | |
| admin_code = admin_code_entry.get().strip() | |
| # Validation | |
| if not name or not username or not password or not security_code: | |
| messagebox.showerror("Error", "Please fill in all required fields") | |
| return | |
| if password != confirm_password: | |
| messagebox.showerror("Error", "Passwords do not match") | |
| return | |
| if not security_code.isdigit() or len(security_code) != 4: | |
| messagebox.showerror("Error", "Security code must be exactly 4 digits") | |
| return | |
| if len(password) < 4: | |
| messagebox.showerror("Error", "Password must be at least 4 characters") | |
| return | |
| try: | |
| if role == "user": | |
| cursor.execute( | |
| "INSERT INTO users (name, username, password, security_code) VALUES (?, ?, ?, ?)", | |
| (name, username, password, security_code) | |
| ) | |
| else: | |
| # Validate admin secret code | |
| if admin_code != ADMIN_SECRET_CODE: | |
| messagebox.showerror("Error", "Invalid Admin Secret Code") | |
| return | |
| cursor.execute( | |
| "INSERT INTO admins (name, username, password, security_code) VALUES (?, ?, ?, ?)", | |
| (name, username, password, security_code) | |
| ) | |
| conn.commit() | |
| messagebox.showinfo("Success", "Account created successfully!") | |
| login_page() | |
| except sqlite3.IntegrityError: | |
| messagebox.showerror("Error", "Username already exists. Please choose another.") | |
| # Buttons | |
| ttk.Button(frame, text="Create Account", command=signup, width=20).pack(pady=(20, 5)) | |
| ttk.Button(frame, text="Back to Login", command=login_page, width=20).pack(pady=5) | |
| # ========================== | |
| # FORGOT PASSWORD PAGE | |
| # ========================== | |
| def forgot_password_page(): | |
| """Display the forgot password page.""" | |
| clear_window() | |
| frame = create_centered_frame(root) | |
| # Title | |
| ttk.Label(frame, text="Reset Password", style="Title.TLabel").pack(pady=(0, 10)) | |
| ttk.Label(frame, text="Enter your details to reset password", style="Subtitle.TLabel").pack(pady=(0, 20)) | |
| # Username | |
| username_entry = create_form_entry(frame, "Username") | |
| # Security Code | |
| security_entry = create_form_entry(frame, "4-Digit Security Code", show="*") | |
| # Role selection | |
| ttk.Label(frame, text="Account type:").pack(anchor="w", pady=(15, 5)) | |
| role_var = tk.StringVar(value="user") | |
| role_frame = ttk.Frame(frame) | |
| role_frame.pack(fill="x") | |
| ttk.Radiobutton(role_frame, text="User", variable=role_var, value="user").pack(side="left", padx=(0, 20)) | |
| ttk.Radiobutton(role_frame, text="Admin", variable=role_var, value="admin").pack(side="left") | |
| # New Password | |
| new_password_entry = create_form_entry(frame, "New Password", show="*") | |
| # Confirm New Password | |
| confirm_password_entry = create_form_entry(frame, "Confirm New Password", show="*") | |
| def reset_password(): | |
| """Handle password reset.""" | |
| username = username_entry.get().strip() | |
| security_code = security_entry.get().strip() | |
| new_password = new_password_entry.get() | |
| confirm_password = confirm_password_entry.get() | |
| role = role_var.get() | |
| # Validation | |
| if not username or not security_code or not new_password: | |
| messagebox.showerror("Error", "Please fill in all fields") | |
| return | |
| if new_password != confirm_password: | |
| messagebox.showerror("Error", "Passwords do not match") | |
| return | |
| if len(new_password) < 4: | |
| messagebox.showerror("Error", "Password must be at least 4 characters") | |
| return | |
| # Check credentials and update password | |
| table = "users" if role == "user" else "admins" | |
| cursor.execute(f"SELECT id FROM {table} WHERE username=? AND security_code=?", | |
| (username, security_code)) | |
| result = cursor.fetchone() | |
| if result: | |
| cursor.execute(f"UPDATE {table} SET password=? WHERE username=?", | |
| (new_password, username)) | |
| conn.commit() | |
| messagebox.showinfo("Success", "Password updated successfully!") | |
| login_page() | |
| else: | |
| messagebox.showerror("Error", "Invalid username or security code") | |
| # Buttons | |
| ttk.Button(frame, text="Reset Password", command=reset_password, width=20).pack(pady=(20, 5)) | |
| ttk.Button(frame, text="Back to Login", command=login_page, width=20).pack(pady=5) | |
| # ========================== | |
| # USER DASHBOARD | |
| # ========================== | |
| def user_dashboard(): | |
| """Display the user dashboard.""" | |
| clear_window() | |
| # Main container | |
| main_frame = ttk.Frame(root) | |
| main_frame.pack(fill="both", expand=True) | |
| # Sidebar | |
| sidebar = ttk.Frame(main_frame, width=200) | |
| sidebar.pack(side="left", fill="y", padx=10, pady=10) | |
| sidebar.pack_propagate(False) | |
| # Welcome message | |
| ttk.Label(sidebar, text=f"Welcome,", font=("Arial", 10)).pack(anchor="w") | |
| ttk.Label(sidebar, text=f"{current_user_name}", font=("Arial", 14, "bold")).pack(anchor="w", pady=(0, 20)) | |
| # Navigation buttons | |
| ttk.Button(sidebar, text="Dashboard", command=show_user_dashboard, width=18).pack(pady=5) | |
| ttk.Button(sidebar, text="My Courses", command=show_my_courses, width=18).pack(pady=5) | |
| ttk.Button(sidebar, text="Profile", command=show_profile, width=18).pack(pady=5) | |
| # Spacer | |
| ttk.Frame(sidebar).pack(expand=True) | |
| # Logout button at bottom | |
| ttk.Button(sidebar, text="Logout", command=logout, width=18).pack(pady=10) | |
| # Content area | |
| global content_frame | |
| content_frame = ttk.Frame(main_frame) | |
| content_frame.pack(side="right", fill="both", expand=True, padx=10, pady=10) | |
| # Show dashboard by default | |
| show_user_dashboard() | |
| def show_user_dashboard(): | |
| """Show the main dashboard with course filters.""" | |
| for widget in content_frame.winfo_children(): | |
| widget.destroy() | |
| # Title | |
| ttk.Label(content_frame, text="Available Courses", style="Title.TLabel").pack(pady=(0, 20)) | |
| # Filter section | |
| filter_frame = ttk.LabelFrame(content_frame, text="Filter Courses", padding=10) | |
| filter_frame.pack(fill="x", pady=(0, 20)) | |
| # Vehicle filter | |
| vehicle_frame = ttk.Frame(filter_frame) | |
| vehicle_frame.pack(fill="x", pady=5) | |
| ttk.Label(vehicle_frame, text="Vehicle Category:", width=15).pack(side="left") | |
| vehicle_var = tk.StringVar() | |
| vehicle_combo = ttk.Combobox(vehicle_frame, textvariable=vehicle_var, values=VEHICLE_CATEGORIES, width=20, state="readonly") | |
| vehicle_combo.pack(side="left", padx=10) | |
| # Package filter | |
| package_frame = ttk.Frame(filter_frame) | |
| package_frame.pack(fill="x", pady=5) | |
| ttk.Label(package_frame, text="Course Package:", width=15).pack(side="left") | |
| package_var = tk.StringVar() | |
| package_combo = ttk.Combobox(package_frame, textvariable=package_var, values=COURSE_PACKAGES, width=20, state="readonly") | |
| package_combo.pack(side="left", padx=10) | |
| # Course list | |
| ttk.Label(content_frame, text="Course List:", font=("Arial", 12, "bold")).pack(anchor="w") | |
| # Treeview for courses | |
| columns = ("ID", "Vehicle", "Package", "Price") | |
| course_tree = ttk.Treeview(content_frame, columns=columns, show="headings", height=10) | |
| course_tree.heading("ID", text="ID") | |
| course_tree.heading("Vehicle", text="Vehicle") | |
| course_tree.heading("Package", text="Package") | |
| course_tree.heading("Price", text="Price (Rs.)") | |
| course_tree.column("ID", width=50) | |
| course_tree.column("Vehicle", width=150) | |
| course_tree.column("Package", width=150) | |
| course_tree.column("Price", width=100) | |
| course_tree.pack(fill="both", expand=True, pady=10) | |
| # Scrollbar | |
| scrollbar = ttk.Scrollbar(content_frame, orient="vertical", command=course_tree.yview) | |
| course_tree.configure(yscrollcommand=scrollbar.set) | |
| def load_courses(): | |
| """Load all courses into the treeview.""" | |
| course_tree.delete(*course_tree.get_children()) | |
| cursor.execute("SELECT id, vehicle, package, price FROM courses") | |
| for row in cursor.fetchall(): | |
| course_tree.insert("", "end", values=(row[0], row[1], row[2], f"Rs. {row[3]}")) | |
| def filter_courses(): | |
| """Filter courses based on selected criteria.""" | |
| course_tree.delete(*course_tree.get_children()) | |
| vehicle = vehicle_var.get() | |
| package = package_var.get() | |
| query = "SELECT id, vehicle, package, price FROM courses WHERE 1=1" | |
| params = [] | |
| if vehicle: | |
| query += " AND vehicle=?" | |
| params.append(vehicle) | |
| if package: | |
| query += " AND package=?" | |
| params.append(package) | |
| cursor.execute(query, params) | |
| for row in cursor.fetchall(): | |
| course_tree.insert("", "end", values=(row[0], row[1], row[2], f"Rs. {row[3]}")) | |
| def enroll_course(): | |
| """Enroll in the selected course.""" | |
| selected = course_tree.selection() | |
| if not selected: | |
| messagebox.showwarning("Warning", "Please select a course to enroll") | |
| return | |
| item = course_tree.item(selected[0]) | |
| course_id = item['values'][0] | |
| # Check if already enrolled | |
| cursor.execute("SELECT id FROM enrollments WHERE user_id=? AND course_id=?", | |
| (current_user_id, course_id)) | |
| if cursor.fetchone(): | |
| messagebox.showinfo("Info", "You are already enrolled in this course") | |
| return | |
| cursor.execute("INSERT INTO enrollments (user_id, course_id) VALUES (?, ?)", | |
| (current_user_id, course_id)) | |
| conn.commit() | |
| messagebox.showinfo("Success", "Successfully enrolled in the course!") | |
| # Buttons | |
| button_frame = ttk.Frame(content_frame) | |
| button_frame.pack(fill="x", pady=10) | |
| ttk.Button(button_frame, text="Show All", command=load_courses).pack(side="left", padx=5) | |
| ttk.Button(button_frame, text="Apply Filter", command=filter_courses).pack(side="left", padx=5) | |
| ttk.Button(button_frame, text="Enroll in Course", command=enroll_course).pack(side="left", padx=5) | |
| # Load all courses initially | |
| load_courses() | |
| def show_my_courses(): | |
| """Show user's enrolled courses.""" | |
| for widget in content_frame.winfo_children(): | |
| widget.destroy() | |
| ttk.Label(content_frame, text="My Enrolled Courses", style="Title.TLabel").pack(pady=(0, 20)) | |
| # Treeview for enrolled courses | |
| columns = ("Vehicle", "Package", "Price", "Enrolled On") | |
| enrolled_tree = ttk.Treeview(content_frame, columns=columns, show="headings", height=15) | |
| enrolled_tree.heading("Vehicle", text="Vehicle") | |
| enrolled_tree.heading("Package", text="Package") | |
| enrolled_tree.heading("Price", text="Price (Rs.)") | |
| enrolled_tree.heading("Enrolled On", text="Enrolled On") | |
| enrolled_tree.column("Vehicle", width=150) | |
| enrolled_tree.column("Package", width=150) | |
| enrolled_tree.column("Price", width=100) | |
| enrolled_tree.column("Enrolled On", width=150) | |
| enrolled_tree.pack(fill="both", expand=True, pady=10) | |
| # Load enrolled courses | |
| cursor.execute(""" | |
| SELECT c.vehicle, c.package, c.price, e.enrollment_date | |
| FROM courses c | |
| JOIN enrollments e ON c.id = e.course_id | |
| WHERE e.user_id = ? | |
| """, (current_user_id,)) | |
| for row in cursor.fetchall(): | |
| enrolled_tree.insert("", "end", values=(row[0], row[1], f"Rs. {row[2]}", row[3] or "N/A")) | |
| # Check if no courses | |
| if not enrolled_tree.get_children(): | |
| ttk.Label(content_frame, text="You haven't enrolled in any courses yet.", | |
| font=("Arial", 12)).pack(pady=20) | |
| def show_profile(): | |
| """Show user profile.""" | |
| for widget in content_frame.winfo_children(): | |
| widget.destroy() | |
| ttk.Label(content_frame, text="My Profile", style="Title.TLabel").pack(pady=(0, 30)) | |
| # Get user info | |
| cursor.execute("SELECT name, username FROM users WHERE id=?", (current_user_id,)) | |
| user = cursor.fetchone() | |
| profile_frame = ttk.LabelFrame(content_frame, text="Profile Information", padding=20) | |
| profile_frame.pack(fill="x", padx=50) | |
| ttk.Label(profile_frame, text="Full Name:", font=("Arial", 11, "bold")).pack(anchor="w") | |
| ttk.Label(profile_frame, text=user[0], font=("Arial", 11)).pack(anchor="w", pady=(0, 15)) | |
| ttk.Label(profile_frame, text="Username:", font=("Arial", 11, "bold")).pack(anchor="w") | |
| ttk.Label(profile_frame, text=user[1], font=("Arial", 11)).pack(anchor="w", pady=(0, 15)) | |
| # Count enrolled courses | |
| cursor.execute("SELECT COUNT(*) FROM enrollments WHERE user_id=?", (current_user_id,)) | |
| course_count = cursor.fetchone()[0] | |
| ttk.Label(profile_frame, text="Enrolled Courses:", font=("Arial", 11, "bold")).pack(anchor="w") | |
| ttk.Label(profile_frame, text=str(course_count), font=("Arial", 11)).pack(anchor="w") | |
| def logout(): | |
| """Logout and return to login page.""" | |
| global current_user_id, current_user_name | |
| current_user_id = None | |
| current_user_name = None | |
| login_page() | |
| # ========================== | |
| # ADMIN DASHBOARD | |
| # ========================== | |
| def admin_dashboard(): | |
| """Display the admin dashboard.""" | |
| clear_window() | |
| # Main container | |
| main_frame = ttk.Frame(root) | |
| main_frame.pack(fill="both", expand=True) | |
| # Sidebar | |
| sidebar = ttk.Frame(main_frame, width=200) | |
| sidebar.pack(side="left", fill="y", padx=10, pady=10) | |
| sidebar.pack_propagate(False) | |
| # Welcome message | |
| ttk.Label(sidebar, text="Admin Panel", font=("Arial", 14, "bold")).pack(anchor="w", pady=(0, 20)) | |
| ttk.Label(sidebar, text=f"Welcome, {current_user_name}", font=("Arial", 10)).pack(anchor="w", pady=(0, 20)) | |
| # Navigation buttons | |
| ttk.Button(sidebar, text="Manage Courses", command=show_manage_courses, width=18).pack(pady=5) | |
| ttk.Button(sidebar, text="View Enrollments", command=show_enrollments, width=18).pack(pady=5) | |
| ttk.Button(sidebar, text="View Users", command=show_users, width=18).pack(pady=5) | |
| # Spacer | |
| ttk.Frame(sidebar).pack(expand=True) | |
| # Logout button at bottom | |
| ttk.Button(sidebar, text="Logout", command=logout, width=18).pack(pady=10) | |
| # Content area | |
| global admin_content_frame | |
| admin_content_frame = ttk.Frame(main_frame) | |
| admin_content_frame.pack(side="right", fill="both", expand=True, padx=10, pady=10) | |
| # Show manage courses by default | |
| show_manage_courses() | |
| def show_manage_courses(): | |
| """Show course management interface.""" | |
| for widget in admin_content_frame.winfo_children(): | |
| widget.destroy() | |
| ttk.Label(admin_content_frame, text="Manage Courses", style="Title.TLabel").pack(pady=(0, 20)) | |
| # Add course section | |
| add_frame = ttk.LabelFrame(admin_content_frame, text="Add New Course", padding=10) | |
| add_frame.pack(fill="x", pady=(0, 20)) | |
| # Vehicle | |
| vehicle_frame = ttk.Frame(add_frame) | |
| vehicle_frame.pack(fill="x", pady=5) | |
| ttk.Label(vehicle_frame, text="Vehicle:", width=10).pack(side="left") | |
| vehicle_var = tk.StringVar() | |
| vehicle_combo = ttk.Combobox(vehicle_frame, textvariable=vehicle_var, values=VEHICLE_CATEGORIES, width=20, state="readonly") | |
| vehicle_combo.pack(side="left", padx=10) | |
| # Package | |
| package_frame = ttk.Frame(add_frame) | |
| package_frame.pack(fill="x", pady=5) | |
| ttk.Label(package_frame, text="Package:", width=10).pack(side="left") | |
| package_var = tk.StringVar() | |
| package_combo = ttk.Combobox(package_frame, textvariable=package_var, values=COURSE_PACKAGES, width=20, state="readonly") | |
| package_combo.pack(side="left", padx=10) | |
| # Price | |
| price_frame = ttk.Frame(add_frame) | |
| price_frame.pack(fill="x", pady=5) | |
| ttk.Label(price_frame, text="Price (Rs.):", width=10).pack(side="left") | |
| price_entry = ttk.Entry(price_frame, width=22) | |
| price_entry.pack(side="left", padx=10) | |
| # Course list | |
| ttk.Label(admin_content_frame, text="Existing Courses:", font=("Arial", 12, "bold")).pack(anchor="w") | |
| columns = ("ID", "Vehicle", "Package", "Price") | |
| course_tree = ttk.Treeview(admin_content_frame, columns=columns, show="headings", height=10) | |
| course_tree.heading("ID", text="ID") | |
| course_tree.heading("Vehicle", text="Vehicle") | |
| course_tree.heading("Package", text="Package") | |
| course_tree.heading("Price", text="Price (Rs.)") | |
| course_tree.column("ID", width=50) | |
| course_tree.column("Vehicle", width=150) | |
| course_tree.column("Package", width=150) | |
| course_tree.column("Price", width=100) | |
| course_tree.pack(fill="both", expand=True, pady=10) | |
| def load_courses(): | |
| """Load all courses.""" | |
| course_tree.delete(*course_tree.get_children()) | |
| cursor.execute("SELECT id, vehicle, package, price FROM courses") | |
| for row in cursor.fetchall(): | |
| course_tree.insert("", "end", values=(row[0], row[1], row[2], f"Rs. {row[3]}")) | |
| def add_course(): | |
| """Add a new course.""" | |
| vehicle = vehicle_var.get() | |
| package = package_var.get() | |
| price = price_entry.get().strip() | |
| if not vehicle or not package or not price: | |
| messagebox.showerror("Error", "Please fill in all fields") | |
| return | |
| try: | |
| price_float = float(price) | |
| if price_float <= 0: | |
| raise ValueError("Price must be positive") | |
| except ValueError: | |
| messagebox.showerror("Error", "Please enter a valid price") | |
| return | |
| cursor.execute("INSERT INTO courses (vehicle, package, price) VALUES (?, ?, ?)", | |
| (vehicle, package, price_float)) | |
| conn.commit() | |
| messagebox.showinfo("Success", "Course added successfully!") | |
| # Clear fields | |
| vehicle_combo.set("") | |
| package_combo.set("") | |
| price_entry.delete(0, tk.END) | |
| load_courses() | |
| def delete_course(): | |
| """Delete selected course.""" | |
| selected = course_tree.selection() | |
| if not selected: | |
| messagebox.showwarning("Warning", "Please select a course to delete") | |
| return | |
| if messagebox.askyesno("Confirm", "Are you sure you want to delete this course?"): | |
| item = course_tree.item(selected[0]) | |
| course_id = item['values'][0] | |
| cursor.execute("DELETE FROM enrollments WHERE course_id=?", (course_id,)) | |
| cursor.execute("DELETE FROM courses WHERE id=?", (course_id,)) | |
| conn.commit() | |
| load_courses() | |
| messagebox.showinfo("Success", "Course deleted successfully!") | |
| # Buttons | |
| button_frame = ttk.Frame(add_frame) | |
| button_frame.pack(fill="x", pady=10) | |
| ttk.Button(button_frame, text="Add Course", command=add_course).pack(side="left", padx=5) | |
| delete_frame = ttk.Frame(admin_content_frame) | |
| delete_frame.pack(fill="x") | |
| ttk.Button(delete_frame, text="Delete Selected Course", command=delete_course).pack(side="left") | |
| load_courses() | |
| def show_enrollments(): | |
| """Show all enrollments.""" | |
| for widget in admin_content_frame.winfo_children(): | |
| widget.destroy() | |
| ttk.Label(admin_content_frame, text="All Enrollments", style="Title.TLabel").pack(pady=(0, 20)) | |
| columns = ("User", "Course", "Package", "Enrolled On") | |
| enroll_tree = ttk.Treeview(admin_content_frame, columns=columns, show="headings", height=15) | |
| enroll_tree.heading("User", text="User") | |
| enroll_tree.heading("Course", text="Course") | |
| enroll_tree.heading("Package", text="Package") | |
| enroll_tree.heading("Enrolled On", text="Enrolled On") | |
| enroll_tree.column("User", width=150) | |
| enroll_tree.column("Course", width=150) | |
| enroll_tree.column("Package", width=100) | |
| enroll_tree.column("Enrolled On", width=150) | |
| enroll_tree.pack(fill="both", expand=True, pady=10) | |
| cursor.execute(""" | |
| SELECT u.name, c.vehicle, c.package, e.enrollment_date | |
| FROM enrollments e | |
| JOIN users u ON e.user_id = u.id | |
| JOIN courses c ON e.course_id = c.id | |
| ORDER BY e.enrollment_date DESC | |
| """) | |
| for row in cursor.fetchall(): | |
| enroll_tree.insert("", "end", values=(row[0], row[1], row[2], row[3] or "N/A")) | |
| def show_users(): | |
| """Show all registered users.""" | |
| for widget in admin_content_frame.winfo_children(): | |
| widget.destroy() | |
| ttk.Label(admin_content_frame, text="Registered Users", style="Title.TLabel").pack(pady=(0, 20)) | |
| columns = ("ID", "Name", "Username", "Courses Enrolled") | |
| user_tree = ttk.Treeview(admin_content_frame, columns=columns, show="headings", height=15) | |
| user_tree.heading("ID", text="ID") | |
| user_tree.heading("Name", text="Name") | |
| user_tree.heading("Username", text="Username") | |
| user_tree.heading("Courses Enrolled", text="Courses Enrolled") | |
| user_tree.column("ID", width=50) | |
| user_tree.column("Name", width=150) | |
| user_tree.column("Username", width=150) | |
| user_tree.column("Courses Enrolled", width=100) | |
| user_tree.pack(fill="both", expand=True, pady=10) | |
| cursor.execute(""" | |
| SELECT u.id, u.name, u.username, COUNT(e.id) as course_count | |
| FROM users u | |
| LEFT JOIN enrollments e ON u.id = e.user_id | |
| GROUP BY u.id | |
| """) | |
| for row in cursor.fetchall(): | |
| user_tree.insert("", "end", values=(row[0], row[1], row[2], row[3])) | |
| # ========================== | |
| # START APPLICATION | |
| # ========================== | |
| if __name__ == "__main__": | |
| login_page() | |
| root.mainloop() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment