diff --git a/SQL/InventoryDB.sql b/SQL/InventoryDB.sql index f041e03..364734c 100644 --- a/SQL/InventoryDB.sql +++ b/SQL/InventoryDB.sql @@ -1,4 +1,4 @@ -CREATE DATABASE IF NOT EXISTS `inventory` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */; +CREATE DATABASE IF NOT EXISTS `inventory` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */; USE `inventory`; -- MySQL dump 10.13 Distrib 8.0.25, for Win64 (x86_64) -- @@ -28,7 +28,7 @@ CREATE TABLE `currentstock` ( `productcode` varchar(45) NOT NULL, `quantity` int NOT NULL, PRIMARY KEY (`productcode`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -55,7 +55,7 @@ CREATE TABLE `customers` ( `location` varchar(45) NOT NULL, `phone` varchar(45) NOT NULL, PRIMARY KEY (`cid`) -) ENGINE=InnoDB AUTO_INCREMENT=307 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=307 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -84,7 +84,7 @@ CREATE TABLE `products` ( `brand` varchar(45) NOT NULL, PRIMARY KEY (`pid`), UNIQUE KEY `productcode_UNIQUE` (`productcode`) -) ENGINE=InnoDB AUTO_INCREMENT=130 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=130 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -112,7 +112,7 @@ CREATE TABLE `purchaseinfo` ( `quantity` int NOT NULL, `totalcost` double NOT NULL, PRIMARY KEY (`purchaseID`) -) ENGINE=InnoDB AUTO_INCREMENT=1012 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=1012 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -141,7 +141,7 @@ CREATE TABLE `salesinfo` ( `revenue` double NOT NULL, `soldby` varchar(45) NOT NULL, PRIMARY KEY (`salesid`) -) ENGINE=InnoDB AUTO_INCREMENT=2013 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=2013 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -168,7 +168,7 @@ CREATE TABLE `suppliers` ( `location` varchar(45) NOT NULL, `mobile` varchar(10) NOT NULL, PRIMARY KEY (`sid`) -) ENGINE=InnoDB AUTO_INCREMENT=409 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=409 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -192,7 +192,7 @@ CREATE TABLE `userlogs` ( `username` varchar(45) NOT NULL, `in_time` varchar(45) NOT NULL, `out_time` varchar(45) NOT NULL -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- @@ -221,7 +221,7 @@ CREATE TABLE `users` ( `password` varchar(200) NOT NULL, `usertype` varchar(45) NOT NULL, PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; +) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci; /*!40101 SET character_set_client = @saved_cs_client */; -- diff --git a/src/com/inventory/DAO/CustomerDAO.class b/src/com/inventory/DAO/CustomerDAO.class new file mode 100644 index 0000000..c16fb4f Binary files /dev/null and b/src/com/inventory/DAO/CustomerDAO.class differ diff --git a/src/com/inventory/DAO/DeliveryDAO$DeliveryDetail.class b/src/com/inventory/DAO/DeliveryDAO$DeliveryDetail.class new file mode 100644 index 0000000..d1856e6 Binary files /dev/null and b/src/com/inventory/DAO/DeliveryDAO$DeliveryDetail.class differ diff --git a/src/com/inventory/DAO/DeliveryDAO.class b/src/com/inventory/DAO/DeliveryDAO.class new file mode 100644 index 0000000..6a0d461 Binary files /dev/null and b/src/com/inventory/DAO/DeliveryDAO.class differ diff --git a/src/com/inventory/DAO/DeliveryDAO.java b/src/com/inventory/DAO/DeliveryDAO.java new file mode 100644 index 0000000..cf13d88 --- /dev/null +++ b/src/com/inventory/DAO/DeliveryDAO.java @@ -0,0 +1,208 @@ +package com.inventory.DAO; + +import com.inventory.Database.ConnectionFactory; +import java.sql.*; +import java.util.ArrayList; + +/** + * DAO for Delivery records. + */ +public class DeliveryDAO { + + private Connection conn; + + // --- Inner class to hold delivery details --- + public static class DeliveryDetail { + private int deliveryId; + private Date deliveryDate; + private String customerName; + private String productName; + private String agentName; + private String status; + private String signatureNotes; + + public DeliveryDetail(int deliveryId, Date deliveryDate, String customerName, + String productName, String agentName, String status, + String signatureNotes) { + this.deliveryId = deliveryId; + this.deliveryDate = deliveryDate; + this.customerName = customerName; + this.productName = productName; + this.agentName = agentName; + this.status = status; + this.signatureNotes = signatureNotes; + } + + public Object[] toArray() { + return new Object[]{ + deliveryId, + deliveryDate, + customerName, + productName, + agentName, + status, + (signatureNotes != null && !signatureNotes.isEmpty()) ? signatureNotes : "N/A" + }; + } + } + + public DeliveryDAO() { + conn = new ConnectionFactory().getConn(); + } + + // --- Load ALL deliveries (ADMIN view) --- + public ArrayList getAllDeliveryDetails() { + ArrayList deliveryList = new ArrayList<>(); + + String query = "SELECT d.delivery_id, d.delivery_date, d.customer_name, " + + "p.productname, u.name AS agent_name, d.delivery_status, d.customer_signature " + + "FROM delivery d " + + "INNER JOIN products p ON d.inventory_id = p.pid " + + "INNER JOIN users u ON d.user_id = u.id"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + while (rs.next()) { + DeliveryDetail detail = new DeliveryDetail( + rs.getInt("delivery_id"), + rs.getDate("delivery_date"), + rs.getString("customer_name"), + rs.getString("productname"), + rs.getString("agent_name"), + rs.getString("delivery_status"), + rs.getString("customer_signature") + ); + deliveryList.add(detail); + } + + } catch (SQLException e) { + System.err.println("Error loading all deliveries: " + e.getMessage()); + } + + return deliveryList; + } + + // --- Load deliveries for specific delivery agent --- + public ArrayList getDeliveriesByAgentId(int agentId) { + ArrayList deliveryList = new ArrayList<>(); + + String query = "SELECT d.delivery_id, d.delivery_date, d.customer_name, " + + "p.productname, u.name AS agent_name, d.delivery_status, d.customer_signature " + + "FROM delivery d " + + "INNER JOIN products p ON d.inventory_id = p.pid " + + "INNER JOIN users u ON d.user_id = u.id " + + "WHERE d.user_id = ?"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + ps.setInt(1, agentId); + + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + DeliveryDetail detail = new DeliveryDetail( + rs.getInt("delivery_id"), + rs.getDate("delivery_date"), + rs.getString("customer_name"), + rs.getString("productname"), + rs.getString("agent_name"), + rs.getString("delivery_status"), + rs.getString("customer_signature") + ); + deliveryList.add(detail); + } + } + + } catch (SQLException e) { + System.err.println("Error loading agent deliveries: " + e.getMessage()); + } + + return deliveryList; + } + + // --- Add new delivery --- + public boolean addDelivery(int inventoryId, int agentId, String customerName, Date deliveryDate) { + String query = "INSERT INTO delivery (inventory_id, user_id, delivery_date, delivery_status, customer_name, customer_signature) " + + "VALUES (?, ?, ?, 'Pending', ?, NULL)"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + ps.setInt(1, inventoryId); + ps.setInt(2, agentId); + ps.setDate(3, deliveryDate); + ps.setString(4, customerName); + + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + System.err.println("Error adding delivery: " + e.getMessage()); + return false; + } + } + + // --- Update delivery status --- + public boolean updateDeliveryStatus(int deliveryId, String newStatus, String signature) { + String query = "UPDATE delivery SET delivery_status = ?, customer_signature = ? WHERE delivery_id = ?"; + + try (PreparedStatement ps = conn.prepareStatement(query)) { + + ps.setString(1, newStatus); + ps.setString(2, (signature == null || signature.isEmpty()) ? null : signature); + ps.setInt(3, deliveryId); + + return ps.executeUpdate() > 0; + + } catch (SQLException e) { + System.err.println("Error updating delivery status: " + e.getMessage()); + return false; + } + } + + // --- Get count of pending deliveries for daily summary --- + public int getPendingDeliveriesCount() { + String query = "SELECT COUNT(*) FROM delivery WHERE delivery_status IN ('Pending', 'In Transit')"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + if (rs.next()) { + return rs.getInt(1); + } + + } catch (SQLException e) { + System.err.println("Error counting pending deliveries: " + e.getMessage()); + } + + return 0; + } + + // --- Get list of pending deliveries for details view --- + public ArrayList getPendingDeliveriesList() { + ArrayList list = new ArrayList<>(); + String query = "SELECT d.delivery_id, d.delivery_date, d.customer_name, p.productname, u.name AS agent_name, d.delivery_status " + + "FROM delivery d " + + "INNER JOIN products p ON d.inventory_id = p.pid " + + "INNER JOIN users u ON d.user_id = u.id " + + "WHERE d.delivery_status IN ('Pending', 'In Transit')"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + while (rs.next()) { + String item = String.format("ID: %d | Date: %s | Product: %s | Customer: %s | Agent: %s | Status: %s", + rs.getInt("delivery_id"), + rs.getDate("delivery_date"), + rs.getString("productname"), + rs.getString("customer_name"), + rs.getString("agent_name"), + rs.getString("delivery_status")); + list.add(item); + } + + } catch (SQLException e) { + System.err.println("Error loading pending deliveries list: " + e.getMessage()); + } + + return list; + } +} diff --git a/src/com/inventory/DAO/ProductDAO.class b/src/com/inventory/DAO/ProductDAO.class new file mode 100644 index 0000000..70f7afd Binary files /dev/null and b/src/com/inventory/DAO/ProductDAO.class differ diff --git a/src/com/inventory/DAO/ProductDAO.java b/src/com/inventory/DAO/ProductDAO.java index 0a33f2e..3c2f1ec 100644 --- a/src/com/inventory/DAO/ProductDAO.java +++ b/src/com/inventory/DAO/ProductDAO.java @@ -11,6 +11,8 @@ import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Vector; @@ -29,6 +31,34 @@ public class ProductDAO { Statement statement2 = null; ResultSet resultSet = null; + +public List getLowStockProducts() { + List lowStockList = new ArrayList<>(); + + String sql = "SELECT c.productcode, c.quantity, p.productname " + + "FROM currentstock c JOIN products p ON c.productcode = p.productcode " + + "WHERE c.quantity < 20"; + + // PreparedStatement ps = conn.prepareStatement(query); + // ResultSet rs = ps.executeQuery(); + + try (Connection conn = ConnectionFactory.getConnection(); + PreparedStatement stmt = conn.prepareStatement(sql); + ResultSet rs = stmt.executeQuery()) { + + while (rs.next()) { + String pname = rs.getString("productname"); + int qty = rs.getInt("quantity"); + lowStockList.add(pname + " (Qty: " + qty + ")"); + } + + } catch (Exception e) { + e.printStackTrace(); + } + + return lowStockList; +} + public ProductDAO() { try { conn = new ConnectionFactory().getConn(); @@ -340,6 +370,25 @@ public void deleteProductDAO(String code) { public void deletePurchaseDAO(int ID){ try { + // 1. Get product code and quantity before deleting + String getQuery = "SELECT productcode, quantity FROM purchaseinfo WHERE purchaseID=?"; + prepStatement = conn.prepareStatement(getQuery); + prepStatement.setInt(1, ID); + resultSet = prepStatement.executeQuery(); + + if (resultSet.next()) { + String prodCode = resultSet.getString("productcode"); + int quantity = resultSet.getInt("quantity"); + + // 2. Decrease stock (Reverse the purchase) + String stockQuery = "UPDATE currentstock SET quantity=quantity-? WHERE productcode=?"; + PreparedStatement stockStmt = conn.prepareStatement(stockQuery); + stockStmt.setInt(1, quantity); + stockStmt.setString(2, prodCode); + stockStmt.executeUpdate(); + } + + // 3. Delete the transaction String query = "DELETE FROM purchaseinfo WHERE purchaseID=?"; prepStatement = conn.prepareStatement(query); prepStatement.setInt(1, ID); @@ -354,6 +403,25 @@ public void deletePurchaseDAO(int ID){ public void deleteSaleDAO(int ID) { try { + // 1. Get product code and quantity before deleting + String getQuery = "SELECT productcode, quantity FROM salesinfo WHERE salesID=?"; + prepStatement = conn.prepareStatement(getQuery); + prepStatement.setInt(1, ID); + resultSet = prepStatement.executeQuery(); + + if (resultSet.next()) { + String prodCode = resultSet.getString("productcode"); + int quantity = resultSet.getInt("quantity"); + + // 2. Increase stock (Reverse the sale) + String stockQuery = "UPDATE currentstock SET quantity=quantity+? WHERE productcode=?"; + PreparedStatement stockStmt = conn.prepareStatement(stockQuery); + stockStmt.setInt(1, quantity); + stockStmt.setString(2, prodCode); + stockStmt.executeUpdate(); + } + + // 3. Delete the transaction String query = "DELETE FROM salesinfo WHERE salesID=?"; prepStatement = conn.prepareStatement(query); prepStatement.setInt(1, ID); @@ -411,27 +479,30 @@ public ResultSet getQueryResult() { } // Purchase table data set retrieval - public ResultSet getPurchaseInfo() { - try { - String query = "SELECT PurchaseID,purchaseinfo.ProductCode,ProductName,Quantity,Totalcost " + - "FROM purchaseinfo INNER JOIN products " + - "ON products.productcode=purchaseinfo.productcode ORDER BY purchaseid;"; - resultSet = statement.executeQuery(query); - } catch (SQLException throwables) { - throwables.printStackTrace(); - } - return resultSet; + public ResultSet getPurchaseInfo() { + try { + String query = + "SELECT p.PurchaseID, p.ProductCode, pr.ProductName, p.Quantity, p.Totalcost " + + "FROM purchaseinfo p " + + "INNER JOIN products pr ON pr.productcode = p.productcode " + + "ORDER BY p.PurchaseID"; + + resultSet = statement.executeQuery(query); + + } catch (SQLException throwables) { + throwables.printStackTrace(); } + return resultSet; +} + // Stock table data set retrieval public ResultSet getCurrentStockInfo() { try { - String query = """ - SELECT currentstock.ProductCode,products.ProductName, - currentstock.Quantity,products.CostPrice,products.SellPrice - FROM currentstock INNER JOIN products - ON currentstock.productcode=products.productcode; - """; + String query = "SELECT currentstock.ProductCode,products.ProductName," + + "currentstock.Quantity,products.CostPrice,products.SellPrice " + + "FROM currentstock INNER JOIN products " + + "ON currentstock.productcode=products.productcode;"; resultSet = statement.executeQuery(query); } catch (SQLException throwables) { throwables.printStackTrace(); @@ -442,14 +513,12 @@ public ResultSet getCurrentStockInfo() { // Sales table data set retrieval public ResultSet getSalesInfo() { try { - String query = """ - SELECT salesid,salesinfo.productcode,productname, - salesinfo.quantity,revenue,users.name AS Sold_by - FROM salesinfo INNER JOIN products - ON salesinfo.productcode=products.productcode - INNER JOIN users - ON salesinfo.soldby=users.username; - """; + String query = "SELECT salesid,salesinfo.productcode,productname," + + "salesinfo.quantity,revenue,users.name AS Sold_by " + + "FROM salesinfo INNER JOIN products " + + "ON salesinfo.productcode=products.productcode " + + "INNER JOIN users " + + "ON salesinfo.soldby=users.username;"; resultSet = statement.executeQuery(query); } catch (SQLException throwables) { throwables.printStackTrace(); diff --git a/src/com/inventory/DAO/ReportDAO.java b/src/com/inventory/DAO/ReportDAO.java new file mode 100644 index 0000000..defd1be --- /dev/null +++ b/src/com/inventory/DAO/ReportDAO.java @@ -0,0 +1,166 @@ +package com.inventory.DAO; + +import com.inventory.Database.ConnectionFactory; +import java.sql.*; + +/** + * DAO for generating summary reports and statistics. + */ +public class ReportDAO { + + private Connection conn; + + public ReportDAO() { + conn = new ConnectionFactory().getConn(); + } + + /** + * Get count of new consignments (purchases) added today. + * @return count of purchases from today + */ + public int getTodayConsignmentsCount() { + String query = "SELECT COUNT(*) FROM purchaseinfo WHERE DATE(date) = CURDATE()"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + if (rs.next()) { + return rs.getInt(1); + } + + } catch (SQLException e) { + System.err.println("Error counting today's consignments: " + e.getMessage()); + } + + return 0; + } + + /** + * Get list of new consignments (purchases) added today. + * @return list of strings describing today's purchases + */ + public java.util.List getTodayConsignmentsList() { + java.util.List list = new java.util.ArrayList<>(); + String query = "SELECT p.PurchaseID, pr.ProductName, p.Quantity, p.Totalcost, s.fullname " + + "FROM purchaseinfo p " + + "INNER JOIN products pr ON p.productcode = pr.productcode " + + "INNER JOIN suppliers s ON p.suppliercode = s.suppliercode " + + "WHERE DATE(p.date) = CURDATE()"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + while (rs.next()) { + String item = String.format("ID: %d | Product: %s | Qty: %d | Cost: %.2f | Supplier: %s", + rs.getInt("PurchaseID"), + rs.getString("ProductName"), + rs.getInt("Quantity"), + rs.getDouble("Totalcost"), + rs.getString("fullname")); + list.add(item); + } + + } catch (SQLException e) { + System.err.println("Error listing today's consignments: " + e.getMessage()); + } + + return list; + } + + /** + * Get count of deliveries added today. + * @return count of deliveries from today + */ + public int getTodayDeliveriesCount() { + String query = "SELECT COUNT(*) FROM delivery WHERE DATE(delivery_date) = CURDATE()"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + if (rs.next()) { + return rs.getInt(1); + } + + } catch (SQLException e) { + System.err.println("Error counting today's deliveries: " + e.getMessage()); + } + + return 0; + } + + /** + * Get count of sales made today. + * @return count of sales from today + */ + public int getTodaySalesCount() { + String query = "SELECT COUNT(*) FROM salesinfo WHERE DATE(date) = CURDATE()"; + + try (Statement st = conn.createStatement(); + ResultSet rs = st.executeQuery(query)) { + + if (rs.next()) { + return rs.getInt(1); + } + + } catch (SQLException e) { + System.err.println("Error counting today's sales: " + e.getMessage()); + } + + return 0; + } + + /** + * Get daily summary data. + */ + public DailySummary getDailySummary() { + ProductDAO productDAO = new ProductDAO(); + DeliveryDAO deliveryDAO = new DeliveryDAO(); + + int lowStockCount = productDAO.getLowStockProducts().size(); + int pendingDeliveriesCount = deliveryDAO.getPendingDeliveriesCount(); + int newConsignmentsCount = getTodayConsignmentsCount(); + int todayDeliveriesCount = getTodayDeliveriesCount(); + int todaySalesCount = getTodaySalesCount(); + + return new DailySummary(lowStockCount, pendingDeliveriesCount, newConsignmentsCount, todayDeliveriesCount, todaySalesCount); + } + + /** + * Inner class to hold daily summary data. + */ + public static class DailySummary { + private int lowStockCount; + private int pendingDeliveriesCount; + private int newConsignmentsCount; + private int todayDeliveriesCount; + private int todaySalesCount; + + public DailySummary(int lowStockCount, int pendingDeliveriesCount, int newConsignmentsCount, int todayDeliveriesCount, int todaySalesCount) { + this.lowStockCount = lowStockCount; + this.pendingDeliveriesCount = pendingDeliveriesCount; + this.newConsignmentsCount = newConsignmentsCount; + this.todayDeliveriesCount = todayDeliveriesCount; + this.todaySalesCount = todaySalesCount; + } + + public int getLowStockCount() { + return lowStockCount; + } + + public int getPendingDeliveriesCount() { + return pendingDeliveriesCount; + } + + public int getNewConsignmentsCount() { + return newConsignmentsCount; + } + + public int getTodayDeliveriesCount() { + return todayDeliveriesCount; + } + + public int getTodaySalesCount() { + return todaySalesCount; + } + } +} diff --git a/src/com/inventory/DAO/SupplierDAO.class b/src/com/inventory/DAO/SupplierDAO.class new file mode 100644 index 0000000..989033a Binary files /dev/null and b/src/com/inventory/DAO/SupplierDAO.class differ diff --git a/src/com/inventory/DAO/UserDAO.class b/src/com/inventory/DAO/UserDAO.class new file mode 100644 index 0000000..990190b Binary files /dev/null and b/src/com/inventory/DAO/UserDAO.class differ diff --git a/src/com/inventory/DAO/UserDAO.java b/src/com/inventory/DAO/UserDAO.java index cf2752c..0a7a343 100644 --- a/src/com/inventory/DAO/UserDAO.java +++ b/src/com/inventory/DAO/UserDAO.java @@ -1,8 +1,3 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package com.inventory.DAO; import com.inventory.DTO.UserDTO; @@ -12,6 +7,8 @@ import javax.swing.*; import javax.swing.table.DefaultTableModel; import java.sql.*; +import java.util.ArrayList; +import java.util.List; import java.util.Locale; import java.util.Vector; @@ -31,6 +28,7 @@ public class UserDAO { // Constructor method public UserDAO() { try { + // Assumes ConnectionFactory().getConn() establishes a database connection conn = new ConnectionFactory().getConn(); statement = conn.createStatement(); } catch (SQLException ex) { @@ -38,10 +36,43 @@ public UserDAO() { } } + /** + * Retrieves a list of users based on their role (e.g., "Delivery Agent"). + * This method is required by DeliveryPage.java. + * * @param role The role to search for (e.g., "Delivery Agent"). + * @return A List of UserDTO objects matching the role. + */ + public List getUsersByRole(String role) { + List userList = new ArrayList<>(); + + // 🔥 Case-insensitive role match + String sql = "SELECT id, name, username, usertype FROM users WHERE LOWER(usertype) = LOWER(?)"; + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + + ps.setString(1, role.trim()); // match "Employee", "EMPLOYEE", "employee" + + try (ResultSet rs = ps.executeQuery()) { + while (rs.next()) { + UserDTO user = new UserDTO(); + user.setID(rs.getInt("id")); + user.setFullName(rs.getString("name")); // FIX 1: corrected column + user.setUsername(rs.getString("username")); + user.setUserType(rs.getString("usertype")); + + userList.add(user); + } + } + } catch (SQLException e) { + System.err.println("Error fetching users by role(UserDAO): " + e.getMessage()); + } + return userList; +} // Methods to add new user public void addUserDAO(UserDTO userDTO, String userType) { try { + // Check if user already exists based on name, location, phone, and usertype String query = "SELECT * FROM users WHERE name='" +userDTO.getFullName() +"' AND location='" @@ -60,11 +91,14 @@ public void addUserDAO(UserDTO userDTO, String userType) { ex.printStackTrace(); } } + + // Helper function to handle the actual insertion public void addFunction(UserDTO userDTO, String userType) { try { String username = null; String password = null; - String oldUsername = null; + + // Logic for default username/password (root) if no users exist String resQuery = "SELECT * FROM users"; resultSet = statement.executeQuery(resQuery); @@ -72,18 +106,7 @@ public void addFunction(UserDTO userDTO, String userType) { username = "root"; password = "root"; } -// else { -// String resQuery2 = "SELECT * FROM users ORDER BY id DESC"; -// resultSet = statement.executeQuery(resQuery2); -// -// if(resultSet.next()){ -// oldUsername = resultSet.getString("username"); -// Integer uCode = Integer.parseInt(oldUsername.substring(4)); -// uCode++; -// username = "user" + uCode; -// password = "user" + uCode; -// } -// } + // Note: Original logic for auto-generating username like "userXXX" is commented out String query = "INSERT INTO users (name,location,phone,username,password,usertype) " + "VALUES(?,?,?,?,?,?)"; @@ -91,8 +114,11 @@ public void addFunction(UserDTO userDTO, String userType) { prepStatement.setString(1, userDTO.getFullName()); prepStatement.setString(2, userDTO.getLocation()); prepStatement.setString(3, userDTO.getPhone()); - prepStatement.setString(4, userDTO.getUsername()); - prepStatement.setString(5, userDTO.getPassword()); + + // Use provided username/password if available, otherwise use default "root" for first user + prepStatement.setString(4, userDTO.getUsername() != null ? userDTO.getUsername() : username); + prepStatement.setString(5, userDTO.getPassword() != null ? userDTO.getPassword() : password); + prepStatement.setString(6, userDTO.getUserType()); prepStatement.executeUpdate(); @@ -135,10 +161,12 @@ public void deleteUserDAO(String username) { } catch (SQLException throwables) { throwables.printStackTrace(); } - new UsersPage().loadDataSet(); + // Note: Instantiating UsersPage here might lead to issues if it's not handled correctly + // but keeping it as per the original code structure. + // new UsersPage().loadDataSet(); } - // Method to retrieve data set to display in table + // Method to retrieve all users for display in table public ResultSet getQueryResult() { try { String query = "SELECT * FROM users"; @@ -149,6 +177,7 @@ public ResultSet getQueryResult() { return resultSet; } + // Method to get a single user by username public ResultSet getUserDAO(String username) { try { String query = "SELECT * FROM users WHERE username='" +username+ "'"; @@ -158,18 +187,21 @@ public ResultSet getUserDAO(String username) { } return resultSet; } + + // Method to retrieve and set the full name for a UserDTO public void getFullName(UserDTO userDTO, String username) { try { - String query = "SELECT * FROM users WHERE username='" +username+ "' LIMIT 1"; + String query = "SELECT name FROM users WHERE username='" +username+ "' LIMIT 1"; resultSet = statement.executeQuery(query); String fullName = null; - if(resultSet.next()) fullName = resultSet.getString(2); + if(resultSet.next()) fullName = resultSet.getString(1); // Assuming 'name' is the first column in this limited result userDTO.setFullName(fullName); } catch (SQLException ex) { ex.printStackTrace(); } } + // Method to get user login/logout logs public ResultSet getUserLogsDAO() { try { String query = "SELECT users.name,userlogs.username,in_time,out_time,location FROM userlogs" + @@ -180,6 +212,8 @@ public ResultSet getUserLogsDAO() { } return resultSet; } + + // Method to record a user login/logout event public void addUserLogin(UserDTO userDTO) { try { String query = "INSERT INTO userlogs (username, in_time, out_time) values(?,?,?)"; @@ -194,6 +228,7 @@ public void addUserLogin(UserDTO userDTO) { } } + // Method to verify username and password public ResultSet getPassDAO(String username, String password){ try { String query = "SELECT password FROM users WHERE username='" @@ -208,20 +243,42 @@ public ResultSet getPassDAO(String username, String password){ return resultSet; } + // Method to change a user's password public void changePass(String username, String password) { try { + // Note: Using prepared statement correctly for security, even though query construction is mixed String query = "UPDATE users SET password=? WHERE username='" +username+ "'"; prepStatement = (PreparedStatement) conn.prepareStatement(query); prepStatement.setString(1, password); - prepStatement.setString(2, username); + // prepStatement.setString(2, username); // Removed redundant setString(2) based on the query structure prepStatement.executeUpdate(); JOptionPane.showMessageDialog(null, "Password has been changed."); } catch (SQLException ex){ ex.printStackTrace(); } } +public UserDTO getUserDetails(String username) { + UserDTO user = new UserDTO(); + try { + String sql = "SELECT name, usertype FROM users WHERE username=?"; + PreparedStatement ps = conn.prepareStatement(sql); + ps.setString(1, username); + + ResultSet rs = ps.executeQuery(); + + if (rs.next()) { + user.setFullName(rs.getString("name")); + user.setUserType(rs.getString("usertype")); + return user; + } + } catch (SQLException e) { + e.printStackTrace(); + } + return null; +} - // Method to display data set in tabular form + + // Method to build a DefaultTableModel from a ResultSet for display public DefaultTableModel buildTableModel(ResultSet resultSet) throws SQLException { ResultSetMetaData metaData = resultSet.getMetaData(); Vector columnNames = new Vector(); @@ -242,4 +299,4 @@ public DefaultTableModel buildTableModel(ResultSet resultSet) throws SQLExceptio return new DefaultTableModel(data, columnNames); } -} +} \ No newline at end of file diff --git a/src/com/inventory/DTO/CustomerDTO.class b/src/com/inventory/DTO/CustomerDTO.class new file mode 100644 index 0000000..09e9ef0 Binary files /dev/null and b/src/com/inventory/DTO/CustomerDTO.class differ diff --git a/src/com/inventory/DTO/DeliveryDTO.java b/src/com/inventory/DTO/DeliveryDTO.java new file mode 100644 index 0000000..cc2f434 --- /dev/null +++ b/src/com/inventory/DTO/DeliveryDTO.java @@ -0,0 +1,90 @@ +package com.inventory.DTO; + +import java.sql.Date; + +/** + * Data Transfer Object for the 'delivery' table. + * Maps directly to the columns of the delivery table in the database. + */ +public class DeliveryDTO { + private int delivery_id; + private int inventory_id; // References products.pid + private int user_id; // References users.id (Delivery Agent) + private Date delivery_date; + private String customer_name; + private String delivery_status; + private String customer_signature; + + // Default Constructor + public DeliveryDTO() {} + + // Full Constructor + public DeliveryDTO(int delivery_id, int inventory_id, int user_id, Date delivery_date, + String customer_name, String delivery_status, String customer_signature) { + this.delivery_id = delivery_id; + this.inventory_id = inventory_id; + this.user_id = user_id; + this.delivery_date = delivery_date; + this.customer_name = customer_name; + this.delivery_status = delivery_status; + this.customer_signature = customer_signature; + } + + // --- Getters and Setters --- + + public int getDelivery_id() { + return delivery_id; + } + + public void setDelivery_id(int delivery_id) { + this.delivery_id = delivery_id; + } + + public int getInventory_id() { + return inventory_id; + } + + public void setInventory_id(int inventory_id) { + this.inventory_id = inventory_id; + } + + public int getUser_id() { + return user_id; + } + + public void setUser_id(int user_id) { + this.user_id = user_id; + } + + public Date getDelivery_date() { + return delivery_date; + } + + public void setDelivery_date(Date delivery_date) { + this.delivery_date = delivery_date; + } + + public String getCustomer_name() { + return customer_name; + } + + public void setCustomer_name(String customer_name) { + this.customer_name = customer_name; + } + + public String getDelivery_status() { + return delivery_status; + } + + public void setDelivery_status(String delivery_status) { + this.delivery_status = delivery_status; + } + + public String getCustomer_signature() { + return customer_signature; + } + + public void setCustomer_signature(String customer_signature) { + this.customer_signature = customer_signature; + } +} \ No newline at end of file diff --git a/src/com/inventory/DTO/ProductDTO.class b/src/com/inventory/DTO/ProductDTO.class new file mode 100644 index 0000000..04e66f6 Binary files /dev/null and b/src/com/inventory/DTO/ProductDTO.class differ diff --git a/src/com/inventory/DTO/ProductDTO.java b/src/com/inventory/DTO/ProductDTO.java index f3b932e..20da389 100644 --- a/src/com/inventory/DTO/ProductDTO.java +++ b/src/com/inventory/DTO/ProductDTO.java @@ -18,10 +18,11 @@ public class ProductDTO { private double costPrice, sellPrice; private Double totalCost, totalRevenue; private String prodCode, prodName, date, suppCode, custCode, custName, brand; - - public int getProdID() { - return prodID; - } +//private int quantity; +// private int reorderLevel; +// public int getProdID() { +// return prodID; +// } public void setProdID(int prodID) { this.prodID = prodID; @@ -130,4 +131,21 @@ public String getBrand() { public void setBrand(String brand) { this.brand = brand; } + + + +// public int getQuantity() { +// return quantity; +// } +// public void setQuantity(int quantity) { +// this.quantity = quantity; +// } + +// public int getReorderLevel() { +// return reorderLevel; +// } +// public void setReorderLevel(int reorderLevel) { +// this.reorderLevel = reorderLevel; +// } + } diff --git a/src/com/inventory/DTO/SupplierDTO.class b/src/com/inventory/DTO/SupplierDTO.class new file mode 100644 index 0000000..35f2ec4 Binary files /dev/null and b/src/com/inventory/DTO/SupplierDTO.class differ diff --git a/src/com/inventory/DTO/UserDTO.class b/src/com/inventory/DTO/UserDTO.class new file mode 100644 index 0000000..93dead5 Binary files /dev/null and b/src/com/inventory/DTO/UserDTO.class differ diff --git a/src/com/inventory/DTO/UserDTO.java b/src/com/inventory/DTO/UserDTO.java index e9c39f0..d5a3b4d 100644 --- a/src/com/inventory/DTO/UserDTO.java +++ b/src/com/inventory/DTO/UserDTO.java @@ -92,4 +92,9 @@ public void setUserType(String userType) { this.userType = userType; } + @Override +public String toString() { + return fullName + " (ID: " + ID + ")"; +} + } diff --git a/src/com/inventory/Database/ConnectionFactory.class b/src/com/inventory/Database/ConnectionFactory.class new file mode 100644 index 0000000..07959ef Binary files /dev/null and b/src/com/inventory/Database/ConnectionFactory.class differ diff --git a/src/com/inventory/Database/ConnectionFactory.java b/src/com/inventory/Database/ConnectionFactory.java index 3278c88..291348e 100644 --- a/src/com/inventory/Database/ConnectionFactory.java +++ b/src/com/inventory/Database/ConnectionFactory.java @@ -1,86 +1,114 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package com.inventory.Database; -import java.io.FileInputStream; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.ResultSet; -import java.sql.Statement; -import java.util.Properties; +import java.sql.*; +import javax.swing.JOptionPane; +public class ConnectionFactory { + + // Database Connection Constants + private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; + // CRITICAL: Updated URL for MySQL 8.0 compatibility and no password ('') + private static final String URL = "jdbc:mysql://localhost:3306/inventory?allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC&defaultAuthPlugin=mysql_native_password"; + private static final String USERNAME = "root"; + private static final String PASSWORD = ""; // Assuming a blank password for root based on previous steps + + private Connection connection = null; + private Statement statement = null; + private ResultSet resultSet = null; -/** - * - * @author asjad - */ + // Constructor attempts to establish the connection and create the statement + public ConnectionFactory() { + try { + // 1. Load the JDBC Driver + Class.forName(DRIVER); + + // 2. Establish Connection + connection = DriverManager.getConnection(URL, USERNAME, PASSWORD); + + // 3. Create Statement + statement = connection.createStatement(); + + } catch (ClassNotFoundException ex) { + JOptionPane.showMessageDialog(null, ex.getMessage(), "Driver Error", JOptionPane.ERROR_MESSAGE); + } catch (SQLException ex) { + // Catches any connection error and provides debugging information + JOptionPane.showMessageDialog(null, "Database Connection Failed: " + ex.getMessage(), "Connection Error", JOptionPane.ERROR_MESSAGE); + System.err.println("SQL Exception during connection: " + ex.getMessage()); + } + } -//Class to retrieve connection for database and login verfication. -public class ConnectionFactory { + // This method checks the login credentials against the 'users' table + // This method now RETURNS the user_id instead of boolean +public int checkLogin(String username, String password, String role) { - static final String driver = "com.mysql.cj.jdbc.Driver"; - static final String url = "jdbc:mysql://localhost:3306/inventory"; - static String username; - static String password; + if (statement == null) { + System.err.println("Database statement is null, connection failed previously."); + return -1; + } - Properties prop; + String query = "SELECT id FROM users WHERE username=? AND password=? AND usertype=?"; + + try { + PreparedStatement ps = connection.prepareStatement(query); + ps.setString(1, username); + ps.setString(2, password); + ps.setString(3, role); - Connection conn = null; - Statement statement = null; - ResultSet resultSet = null; + ResultSet rs = ps.executeQuery(); - public ConnectionFactory(){ - try { - //Username and Password saved as configurable properties to allow changes without recompilation. - prop = new Properties(); - prop.loadFromXML(new FileInputStream("lib/DBCredentials.xml")); - } catch (IOException e) { - e.printStackTrace(); + if (rs.next()) { + return rs.getInt("id"); // RETURN USER ID } - username = prop.getProperty("username"); - password = prop.getProperty("password"); - try { - Class.forName(driver); - conn = DriverManager.getConnection(url, username, password); - statement = conn.createStatement(); - } catch (Exception e) { - e.printStackTrace(); - } + } catch (SQLException ex) { + System.err.println("SQL Error during login check: " + ex.getMessage()); } + return -1; // Login failed +} + + // Getter for Connection object public Connection getConn() { - try { - Class.forName(driver); - conn = DriverManager.getConnection(url, username, password); - System.out.println("Connected successfully."); - } catch (Exception e) { - e.printStackTrace(); - } - return conn; + return connection; + } + + // Getter for statement + public Statement getStatement() { + return statement; } - //Login verification method - public boolean checkLogin(String username, String password, String userType){ - String query = "SELECT * FROM users WHERE username='" - + username - + "' AND password='" - + password - + "' AND usertype='" - + userType - + "' LIMIT 1"; + // Getter for resultSet + public ResultSet getResultSet() { + return resultSet; + } + public static Connection getConnection() throws SQLException { + // Ensure the JDBC driver is loaded (optional for modern drivers, but good practice) try { - resultSet = statement.executeQuery(query); - if(resultSet.next()) return true; - } catch (Exception ex) { - ex.printStackTrace(); + Class.forName("com.mysql.cj.jdbc.Driver"); + } catch (ClassNotFoundException e) { + System.err.println("MySQL JDBC Driver not found."); + throw new SQLException("Database driver missing.", e); + } + + // Establish the connection + try { + // This is the static method the compiler was looking for! + return DriverManager.getConnection(URL, USERNAME, PASSWORD); + } catch (SQLException e) { + System.err.println("Database Connection Failed! Check the URL, User, and Password."); + // Re-throw the exception so the calling DAO can handle it + throw e; } - return false; } -} + + // Method to safely close resources + public void close() { + try { + if (resultSet != null) resultSet.close(); + if (statement != null) statement.close(); + if (connection != null) connection.close(); + } catch (SQLException e) { + System.err.println("Error closing resources: " + e.getMessage()); + } + } +} \ No newline at end of file diff --git a/src/com/inventory/UI/CheckUsers.java b/src/com/inventory/UI/CheckUsers.java new file mode 100644 index 0000000..2c079c9 --- /dev/null +++ b/src/com/inventory/UI/CheckUsers.java @@ -0,0 +1,24 @@ +package com.inventory.UI; + +import com.inventory.Database.ConnectionFactory; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; + +public class CheckUsers { + public static void main(String[] args) { + try { + Connection conn = new ConnectionFactory().getConn(); + Statement st = conn.createStatement(); + String query = "SELECT username, user_type FROM users"; + ResultSet rs = st.executeQuery(query); + System.out.println("--- Users ---"); + while (rs.next()) { + System.out.println("User: " + rs.getString(1) + " | Type: " + rs.getString(2)); + } + conn.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/com/inventory/UI/CurrentStockPage$1.class b/src/com/inventory/UI/CurrentStockPage$1.class new file mode 100644 index 0000000..75a3596 Binary files /dev/null and b/src/com/inventory/UI/CurrentStockPage$1.class differ diff --git a/src/com/inventory/UI/CurrentStockPage.class b/src/com/inventory/UI/CurrentStockPage.class new file mode 100644 index 0000000..4204ee8 Binary files /dev/null and b/src/com/inventory/UI/CurrentStockPage.class differ diff --git a/src/com/inventory/UI/CurrentStockPage.java b/src/com/inventory/UI/CurrentStockPage.java index ad40fab..db587ad 100644 --- a/src/com/inventory/UI/CurrentStockPage.java +++ b/src/com/inventory/UI/CurrentStockPage.java @@ -34,33 +34,94 @@ public CurrentStockPage(String username) { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + + // Custom Header Renderer + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); + + // Wrap table in rounded card + javax.swing.JPanel tableCard = new RoundedPanel(20); jScrollPane1 = new javax.swing.JScrollPane(); stockTable = new javax.swing.JTable(); + refreshButton = new javax.swing.JButton(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("CURRENT STOCK"); - jLabel1.setToolTipText(""); + setBackground(new java.awt.Color(220, 230, 250)); // Darker Blue BG + + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("Current Stock"); stockTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null} - }, - new String [] { - "Title 1", "Title 2", "Title 3", "Title 4" - } + new Object [][] {}, + new String [] { "Code", "Name", "Quantity", "Available" } )); + stockTable.setRowHeight(40); + stockTable.setShowGrid(false); + stockTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + stockTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + stockTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); + jScrollPane1.setViewportView(stockTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); - refreshButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N - refreshButton.setText("REFRESH"); + // Add table to card + tableCard.setLayout(new java.awt.BorderLayout()); + tableCard.add(jScrollPane1, java.awt.BorderLayout.CENTER); + tableCard.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + refreshButton.setText("Refresh"); + refreshButton.setBackground(new java.awt.Color(65, 105, 225)); + refreshButton.setForeground(java.awt.Color.BLACK); + refreshButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + refreshButton.setFocusPainted(false); + refreshButton.setBorderPainted(false); + refreshButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); refreshButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { refreshButtonActionPerformed(evt); @@ -71,29 +132,26 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jSeparator1) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 701, Short.MAX_VALUE) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 165, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(refreshButton))) - .addContainerGap()) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 860, Short.MAX_VALUE)) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 44, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 330, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(88, Short.MAX_VALUE)) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE) + .addGap(20, 20, 20)) ); }// //GEN-END:initComponents @@ -106,6 +164,7 @@ public void loadDataSet() { try { ProductDAO productDAO = new ProductDAO(); stockTable.setModel(productDAO.buildTableModel(productDAO.getCurrentStockInfo())); + TableStyler.styleTable(stockTable); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/com/inventory/UI/CustomerPage$1.class b/src/com/inventory/UI/CustomerPage$1.class new file mode 100644 index 0000000..37a9a6c Binary files /dev/null and b/src/com/inventory/UI/CustomerPage$1.class differ diff --git a/src/com/inventory/UI/CustomerPage$2.class b/src/com/inventory/UI/CustomerPage$2.class new file mode 100644 index 0000000..843ed52 Binary files /dev/null and b/src/com/inventory/UI/CustomerPage$2.class differ diff --git a/src/com/inventory/UI/CustomerPage$3.class b/src/com/inventory/UI/CustomerPage$3.class new file mode 100644 index 0000000..1201a9e Binary files /dev/null and b/src/com/inventory/UI/CustomerPage$3.class differ diff --git a/src/com/inventory/UI/CustomerPage$4.class b/src/com/inventory/UI/CustomerPage$4.class new file mode 100644 index 0000000..7d33096 Binary files /dev/null and b/src/com/inventory/UI/CustomerPage$4.class differ diff --git a/src/com/inventory/UI/CustomerPage$5.class b/src/com/inventory/UI/CustomerPage$5.class new file mode 100644 index 0000000..168f3c5 Binary files /dev/null and b/src/com/inventory/UI/CustomerPage$5.class differ diff --git a/src/com/inventory/UI/CustomerPage$6.class b/src/com/inventory/UI/CustomerPage$6.class new file mode 100644 index 0000000..4dd4e30 Binary files /dev/null and b/src/com/inventory/UI/CustomerPage$6.class differ diff --git a/src/com/inventory/UI/CustomerPage.class b/src/com/inventory/UI/CustomerPage.class new file mode 100644 index 0000000..d648853 Binary files /dev/null and b/src/com/inventory/UI/CustomerPage.class differ diff --git a/src/com/inventory/UI/CustomerPage.java b/src/com/inventory/UI/CustomerPage.java index 4b38c4b..91f8762 100644 --- a/src/com/inventory/UI/CustomerPage.java +++ b/src/com/inventory/UI/CustomerPage.java @@ -32,11 +32,55 @@ public CustomerPage() { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + + // Custom Header Renderer + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); - entryPanel = new javax.swing.JPanel(); + entryPanel = new RoundedPanel(20); jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); @@ -53,155 +97,150 @@ private void initComponents() { editButton = new javax.swing.JButton(); deleteButton = new javax.swing.JButton(); clearButton = new javax.swing.JButton(); + + javax.swing.JPanel tableCard = new RoundedPanel(20); jScrollPane1 = new javax.swing.JScrollPane(); custTable = new javax.swing.JTable(); + searchText = new javax.swing.JTextField(); jLabel8 = new javax.swing.JLabel(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("CUSTOMERS"); - - entryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Enter Customer Details")); - - jLabel2.setText("Customer Code:"); - - jLabel3.setText("Full Name:"); - - jLabel4.setText("Location:"); + setBackground(new java.awt.Color(220, 230, 250)); - jLabel5.setText("Contact:"); + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("Customers"); - jLabel6.setText("Debit Amount:"); + entryPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); - jLabel7.setText("Credit Amount:"); + java.awt.Font labelFont = new java.awt.Font("Segoe UI", 1, 12); + java.awt.Color labelColor = java.awt.Color.BLACK; + jLabel2.setFont(labelFont); jLabel2.setForeground(labelColor); jLabel2.setText("Customer Code:"); + jLabel3.setFont(labelFont); jLabel3.setForeground(labelColor); jLabel3.setText("Full Name:"); + jLabel4.setFont(labelFont); jLabel4.setForeground(labelColor); jLabel4.setText("Location:"); + jLabel5.setFont(labelFont); jLabel5.setForeground(labelColor); jLabel5.setText("Contact:"); + jLabel6.setFont(labelFont); jLabel6.setForeground(labelColor); jLabel6.setText("Debit Amount:"); + jLabel7.setFont(labelFont); jLabel7.setForeground(labelColor); jLabel7.setText("Credit Amount:"); - addButton.setText("Add"); - addButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - addButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - addButtonActionPerformed(evt); - } - }); - - editButton.setText("Edit"); - editButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - editButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - editButtonActionPerformed(evt); - } - }); - - deleteButton.setText("Delete"); - deleteButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - deleteButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - deleteButtonActionPerformed(evt); - } - }); - - clearButton.setFont(new java.awt.Font("Segoe UI", 0, 14)); // NOI18N - clearButton.setText("CLEAR"); - clearButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - clearButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - clearButtonActionPerformed(evt); - } - }); + java.awt.Font textFont = new java.awt.Font("Segoe UI", 0, 14); + javax.swing.border.Border textBorder = javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + ); + phoneText.setFont(textFont); phoneText.setBorder(textBorder); + locationText.setFont(textFont); locationText.setBorder(textBorder); + codeText.setFont(textFont); codeText.setBorder(textBorder); + nameText.setFont(textFont); nameText.setBorder(textBorder); + creditText.setFont(textFont); creditText.setBorder(textBorder); + debitText.setFont(textFont); debitText.setBorder(textBorder); + + styleButton(addButton, "Add", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + styleButton(editButton, "Edit", new java.awt.Color(255, 193, 7), java.awt.Color.BLACK); + styleButton(deleteButton, "Delete", new java.awt.Color(220, 53, 69), java.awt.Color.BLACK); + styleButton(clearButton, "Clear", new java.awt.Color(240, 240, 240), java.awt.Color.BLACK); + + addButton.addActionListener(evt -> addButtonActionPerformed(evt)); + editButton.addActionListener(evt -> editButtonActionPerformed(evt)); + deleteButton.addActionListener(evt -> deleteButtonActionPerformed(evt)); + clearButton.addActionListener(evt -> clearButtonActionPerformed(evt)); javax.swing.GroupLayout entryPanelLayout = new javax.swing.GroupLayout(entryPanel); entryPanel.setLayout(entryPanelLayout); entryPanelLayout.setHorizontalGroup( entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(codeText) + .addComponent(nameText) + .addComponent(locationText) + .addComponent(phoneText) + .addComponent(debitText) + .addComponent(creditText) .addGroup(entryPanelLayout.createSequentialGroup() - .addContainerGap() .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(entryPanelLayout.createSequentialGroup() - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jLabel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel6, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel7, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(phoneText) - .addComponent(creditText) - .addComponent(debitText) - .addComponent(locationText) - .addComponent(codeText) - .addComponent(nameText))) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(addButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(editButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(deleteButton) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4) + .addComponent(jLabel5) + .addComponent(jLabel6) + .addComponent(jLabel7)) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(entryPanelLayout.createSequentialGroup() + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(deleteButton, javax.swing.GroupLayout.DEFAULT_SIZE, 68, Short.MAX_VALUE)) ); entryPanelLayout.setVerticalGroup( entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(entryPanelLayout.createSequentialGroup() - .addContainerGap() - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(locationText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(phoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(locationText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(debitText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(phoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(creditText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(debitText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(addButton) - .addComponent(editButton) - .addComponent(deleteButton)) + .addComponent(jLabel7) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(18, Short.MAX_VALUE)) + .addComponent(creditText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(20, 20, 20) + .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); custTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null} - }, - new String [] { - "Title 1", "Title 2", "Title 3", "Title 4" - } + new Object [][] {}, + new String [] { "Code", "Name", "Location", "Phone" } )); + custTable.setRowHeight(40); + custTable.setShowGrid(false); + custTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + custTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + custTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); custTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { custTableMouseClicked(evt); } }); jScrollPane1.setViewportView(custTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + tableCard.setLayout(new java.awt.BorderLayout()); + tableCard.add(jScrollPane1, java.awt.BorderLayout.CENTER); + tableCard.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + searchText.setFont(new java.awt.Font("Segoe UI", 0, 14)); + searchText.setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + )); searchText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { searchTextKeyReleased(evt); } }); + jLabel8.setFont(new java.awt.Font("Segoe UI", 1, 14)); jLabel8.setText("Search:"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -209,37 +248,44 @@ public void keyReleased(java.awt.event.KeyEvent evt) { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 122, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel8) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 181, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jSeparator1) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 445, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE) + .addGap(20, 20, 20) .addComponent(entryPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(jLabel8) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(entryPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addContainerGap(67, Short.MAX_VALUE)) + .addComponent(tableCard)) + .addGap(20, 20, 20)) ); + } + + private void styleButton(javax.swing.JButton btn, String text, java.awt.Color bg, java.awt.Color fg) { + btn.setText(text); + btn.setBackground(bg); + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 12)); + btn.setFocusPainted(false); + btn.setBorderPainted(false); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); }// //GEN-END:initComponents private void addButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addButtonActionPerformed @@ -321,6 +367,7 @@ public void loadDataSet() { try { CustomerDAO customerDAO = new CustomerDAO(); custTable.setModel(customerDAO.buildTableModel(customerDAO.getQueryResult())); + TableStyler.styleTable(custTable); } catch (SQLException e) { e.printStackTrace(); } @@ -329,6 +376,7 @@ public void loadSearchData(String text) { try { CustomerDAO customerDAO = new CustomerDAO(); custTable.setModel(customerDAO.buildTableModel(customerDAO.getCustomerSearch(text))); + custTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/com/inventory/UI/Dashboard$1.class b/src/com/inventory/UI/Dashboard$1.class new file mode 100644 index 0000000..ef62c55 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$1.class differ diff --git a/src/com/inventory/UI/Dashboard$10.class b/src/com/inventory/UI/Dashboard$10.class new file mode 100644 index 0000000..9693d94 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$10.class differ diff --git a/src/com/inventory/UI/Dashboard$11.class b/src/com/inventory/UI/Dashboard$11.class new file mode 100644 index 0000000..c294585 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$11.class differ diff --git a/src/com/inventory/UI/Dashboard$12.class b/src/com/inventory/UI/Dashboard$12.class new file mode 100644 index 0000000..12f2578 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$12.class differ diff --git a/src/com/inventory/UI/Dashboard$13.class b/src/com/inventory/UI/Dashboard$13.class new file mode 100644 index 0000000..9a06be1 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$13.class differ diff --git a/src/com/inventory/UI/Dashboard$2.class b/src/com/inventory/UI/Dashboard$2.class new file mode 100644 index 0000000..e41d3f5 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$2.class differ diff --git a/src/com/inventory/UI/Dashboard$3.class b/src/com/inventory/UI/Dashboard$3.class new file mode 100644 index 0000000..b3e4861 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$3.class differ diff --git a/src/com/inventory/UI/Dashboard$4.class b/src/com/inventory/UI/Dashboard$4.class new file mode 100644 index 0000000..2932cc8 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$4.class differ diff --git a/src/com/inventory/UI/Dashboard$5.class b/src/com/inventory/UI/Dashboard$5.class new file mode 100644 index 0000000..755cb14 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$5.class differ diff --git a/src/com/inventory/UI/Dashboard$6.class b/src/com/inventory/UI/Dashboard$6.class new file mode 100644 index 0000000..67f2fe6 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$6.class differ diff --git a/src/com/inventory/UI/Dashboard$7.class b/src/com/inventory/UI/Dashboard$7.class new file mode 100644 index 0000000..9f3d6bc Binary files /dev/null and b/src/com/inventory/UI/Dashboard$7.class differ diff --git a/src/com/inventory/UI/Dashboard$8.class b/src/com/inventory/UI/Dashboard$8.class new file mode 100644 index 0000000..edc92c8 Binary files /dev/null and b/src/com/inventory/UI/Dashboard$8.class differ diff --git a/src/com/inventory/UI/Dashboard$9.class b/src/com/inventory/UI/Dashboard$9.class new file mode 100644 index 0000000..54e872b Binary files /dev/null and b/src/com/inventory/UI/Dashboard$9.class differ diff --git a/src/com/inventory/UI/Dashboard.class b/src/com/inventory/UI/Dashboard.class new file mode 100644 index 0000000..dc4fb4a Binary files /dev/null and b/src/com/inventory/UI/Dashboard.class differ diff --git a/src/com/inventory/UI/Dashboard.java b/src/com/inventory/UI/Dashboard.java index 53f3c76..2dff57e 100644 --- a/src/com/inventory/UI/Dashboard.java +++ b/src/com/inventory/UI/Dashboard.java @@ -1,19 +1,18 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package com.inventory.UI; +import com.inventory.DAO.ProductDAO; import com.inventory.DAO.UserDAO; +import com.inventory.DTO.ProductDTO; import com.inventory.DTO.UserDTO; import com.inventory.Database.ConnectionFactory; import javax.swing.*; -import java.awt.CardLayout; +import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; /** * @@ -23,18 +22,38 @@ // Main frame for the application after successful login public class Dashboard extends javax.swing.JFrame { + // --- Custom Fields --- CardLayout layout; String userSelect; String username; - String fullName; UserDTO userDTO; + // We added this field to hold the user's unique ID. + private int currentUserId; + // Low stock notification + private JPanel notificationPanel; + private List lowStockItems; LocalDateTime outTime; + // Store HomePage instance for refreshing + private HomePageModern homePage; + /** * Creates new form Dashboard */ public Dashboard(String username, String userType, UserDTO userDTO) { + // Initialize UI components (auto-generated code section) initComponents(); + // 1. Get the User ID from the DTO + // Assuming your UserDTO has a getter for the user's ID (e.g., getID()) + // This is the CRITICAL change to retrieve the correct ID (20 for Trial Employee) + try { + this.currentUserId = userDTO.getID(); + } catch (Exception e) { + System.err.println("Error retrieving User ID from DTO: " + e.getMessage()); + this.currentUserId = 0; // Fallback to 0 if DTO is null or ID is missing + } + + // --- Setup Panel and Layout --- navPanel.setVisible(false); menuPanel.setVisible(true); layout = new CardLayout(); @@ -47,7 +66,11 @@ public Dashboard(String username, String userType, UserDTO userDTO) { // Panel Layout set to Card Layout to allow switching between different sections displayPanel.setLayout(layout); - displayPanel.add("Home", new HomePage(username)); + // Note: For this code to compile, you must have all these Page classes available. + // Store HomePageModern instance + HomePageModern homePage = new HomePageModern(username); + this.homePage = homePage; + displayPanel.add("Home", homePage); displayPanel.add("Users", new UsersPage()); displayPanel.add("Customers", new CustomerPage()); displayPanel.add("Products", new ProductPage(username, this)); @@ -55,8 +78,14 @@ public Dashboard(String username, String userType, UserDTO userDTO) { displayPanel.add("Current Stock", new CurrentStockPage(username)); displayPanel.add("Sales", new SalesPage(username, this)); displayPanel.add("Purchase", new PurchasePage(this)); + + // 2. CORRECTION: Pass the actual User ID to DeliveryPage + // The currentUserId variable now holds the user's actual ID (e.g., 20) + displayPanel.add("Delivery", new DeliveryPage(currentUserId, userSelect)); + displayPanel.add("Logs", new UserLogsPage()); + // --- Window Closing Listener for Session Logging --- this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { @@ -70,6 +99,22 @@ public void windowClosing(WindowEvent e) { setTitle("Inventory Manager"); setVisible(true); + + // Load low stock alerts for administrators + if ("ADMINISTRATOR".equalsIgnoreCase(userType)) { + loadLowStockAlerts(); + } + } + + // --- Refresh Daily Summary --- + public void refreshDailySummary() { + if (homePage != null) { + homePage.loadDailySummary(); + } + // Also refresh low stock alerts + if ("ADMINISTRATOR".equalsIgnoreCase(userDTO.getUserType())) { + loadLowStockAlerts(); + } } // Methods to display different sections in the mainframe @@ -97,6 +142,9 @@ public void addSalesPage() { public void addPurchasePage() { layout.show(displayPanel, "Purchase"); } + public void addDeliveryPage() { // *** NEW: METHOD FOR DELIVERY PAGE *** + layout.show(displayPanel, "Delivery"); + } public void addLogsPage() { layout.show(displayPanel, "Logs"); } @@ -105,6 +153,8 @@ public void addLogsPage() { * This method is called from within the constructor to initialize the form. * WARNING: Do NOT modify this code. The content of this method is always * regenerated by the Form Editor. + * * NOTE: This section contains the auto-generated code and is left as-is + * based on your input structure to maintain compatibility with your GUI builder. */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents @@ -122,10 +172,12 @@ private void initComponents() { salesButton = new javax.swing.JButton(); usersButton = new javax.swing.JButton(); purchaseButton = new javax.swing.JButton(); + deliveryButton = new javax.swing.JButton(); logsButton = new javax.swing.JButton(); displayPanel = new javax.swing.JPanel(); userPanel = new javax.swing.JPanel(); nameLabel = new javax.swing.JLabel(); + notificationPanel = createNotificationBell(); // Create notification bell logoutButton = new javax.swing.JButton(); jMenuBar1 = new javax.swing.JMenuBar(); jMenu1 = new javax.swing.JMenu(); @@ -135,12 +187,22 @@ private void initComponents() { setTitle("Inventory Manager"); setBounds(new java.awt.Rectangle(400, 100, 0, 0)); - menuPanel.setPreferredSize(new java.awt.Dimension(120, 26)); + // --- Sidebar Colors --- + Color sidebarColor = new Color(65, 105, 225); // Royal Blue + Color sidebarTextColor = Color.BLACK; // Changed to BLACK for visibility + + menuPanel.setPreferredSize(new java.awt.Dimension(200, 60)); // Wider sidebar + menuPanel.setBackground(sidebarColor); - menuButton.setFont(new java.awt.Font("Segoe UI", 1, 14)); // NOI18N - menuButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/inventory/UI/Icons/menu_icon_150667.png"))); // NOI18N - menuButton.setText("MENU"); + menuButton.setFont(new java.awt.Font("Segoe UI", 1, 18)); + menuButton.setText("MENU"); // Brand Name + menuButton.setIcon(null); // Remove icon for now or use a brand logo menuButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + menuButton.setBackground(sidebarColor); + menuButton.setForeground(sidebarTextColor); + menuButton.setBorderPainted(false); + menuButton.setFocusPainted(false); + menuButton.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); menuButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { menuButtonActionPerformed(evt); @@ -151,88 +213,45 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { menuPanel.setLayout(menuPanelLayout); menuPanelLayout.setHorizontalGroup( menuPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(menuButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addGroup(menuPanelLayout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(menuButton, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE) + .addContainerGap()) ); menuPanelLayout.setVerticalGroup( menuPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(menuPanelLayout.createSequentialGroup() - .addComponent(menuButton, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap()) + .addGap(15, 15, 15) + .addComponent(menuButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); - navPanel.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED)); - - homeButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/inventory/UI/Icons/homepages_home_house_icon_150665.png"))); // NOI18N - homeButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - homeButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - homeButtonActionPerformed(evt); - } - }); - - prodButton.setText("Products"); - prodButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - prodButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - prodButtonActionPerformed(evt); - } - }); - - stockButton.setText("Current Stock"); - stockButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - stockButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - stockButtonActionPerformed(evt); - } - }); - - custButton.setText("Customers"); - custButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - custButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - custButtonActionPerformed(evt); - } - }); - - suppButton.setText("Suppliers"); - suppButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - suppButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - suppButtonActionPerformed(evt); - } - }); - - salesButton.setText("Sales"); - salesButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - salesButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - salesButtonActionPerformed(evt); - } - }); - - usersButton.setText("Users"); - usersButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - usersButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - usersButtonActionPerformed(evt); - } - }); - - purchaseButton.setText("Purchase"); - purchaseButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - purchaseButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - purchaseButtonActionPerformed(evt); - } - }); - - logsButton.setText("User Logs"); - logsButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - logsButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - logsButtonActionPerformed(evt); - } - }); + navPanel.setBorder(null); + navPanel.setBackground(sidebarColor); + + // Helper to style sidebar buttons + styleSidebarButton(homeButton, "Dashboard", sidebarColor, sidebarTextColor); + styleSidebarButton(prodButton, "Products", sidebarColor, sidebarTextColor); + styleSidebarButton(stockButton, "Current Stock", sidebarColor, sidebarTextColor); + styleSidebarButton(custButton, "Customers", sidebarColor, sidebarTextColor); + styleSidebarButton(suppButton, "Suppliers", sidebarColor, sidebarTextColor); + styleSidebarButton(salesButton, "Sales", sidebarColor, sidebarTextColor); + styleSidebarButton(usersButton, "Users", sidebarColor, sidebarTextColor); + styleSidebarButton(purchaseButton, "Purchase", sidebarColor, sidebarTextColor); + styleSidebarButton(deliveryButton, "Delivery", sidebarColor, sidebarTextColor); + styleSidebarButton(logsButton, "User Logs", sidebarColor, sidebarTextColor); + + // Add Actions + homeButton.addActionListener(evt -> homeButtonActionPerformed(evt)); + prodButton.addActionListener(evt -> prodButtonActionPerformed(evt)); + stockButton.addActionListener(evt -> stockButtonActionPerformed(evt)); + custButton.addActionListener(evt -> custButtonActionPerformed(evt)); + suppButton.addActionListener(evt -> suppButtonActionPerformed(evt)); + salesButton.addActionListener(evt -> salesButtonActionPerformed(evt)); + usersButton.addActionListener(evt -> usersButtonActionPerformed(evt)); + purchaseButton.addActionListener(evt -> purchaseButtonActionPerformed(evt)); + deliveryButton.addActionListener(evt -> deliveryButtonActionPerformed(evt)); + logsButton.addActionListener(evt -> logsButtonActionPerformed(evt)); javax.swing.GroupLayout navPanelLayout = new javax.swing.GroupLayout(navPanel); navPanel.setLayout(navPanelLayout); @@ -243,12 +262,13 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(navPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(homeButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(prodButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(stockButton, javax.swing.GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE) + .addComponent(stockButton, javax.swing.GroupLayout.DEFAULT_SIZE, 180, Short.MAX_VALUE) .addComponent(custButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(suppButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(salesButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(usersButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(purchaseButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(deliveryButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(logsButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) .addContainerGap()) ); @@ -256,36 +276,48 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { navPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(navPanelLayout.createSequentialGroup() .addContainerGap() - .addComponent(homeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(prodButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(stockButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(custButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(suppButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(salesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(purchaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(usersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(logsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(24, Short.MAX_VALUE)) + .addComponent(homeButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(prodButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(stockButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(custButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(suppButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(salesButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(purchaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(deliveryButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(usersButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(10, 10, 10) + .addComponent(logsButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); displayPanel.setLayout(new java.awt.CardLayout()); + displayPanel.setBackground(new Color(244, 247, 254)); // Light Gray Content BG + + // --- Header Styling --- + userPanel.setBackground(Color.WHITE); + userPanel.setBorder(javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 0, new Color(230, 230, 230))); // Bottom border - nameLabel.setFont(new java.awt.Font("Segoe UI Black", 0, 12)); // NOI18N - nameLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/inventory/UI/Icons/user_icon_150670.png"))); // NOI18N + nameLabel.setFont(new java.awt.Font("Segoe UI", 1, 14)); + nameLabel.setForeground(new Color(50, 50, 50)); + nameLabel.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/inventory/UI/Icons/user_icon_150670.png"))); nameLabel.setText("User: "); - nameLabel.setVerticalAlignment(javax.swing.SwingConstants.TOP); - logoutButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/com/inventory/UI/Icons/log-out_icon-icons.com_50106.png"))); // NOI18N - logoutButton.setText("Sign out"); + logoutButton.setIcon(null); + logoutButton.setText("Logout"); logoutButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + logoutButton.setFont(new java.awt.Font("Segoe UI", 0, 12)); + logoutButton.setBackground(new Color(255, 255, 255)); + logoutButton.setForeground(new Color(100, 100, 100)); + logoutButton.setBorder(javax.swing.BorderFactory.createLineBorder(new Color(200, 200, 200))); + logoutButton.setFocusPainted(false); logoutButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { logoutButtonActionPerformed(evt); @@ -299,18 +331,21 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(userPanelLayout.createSequentialGroup() .addContainerGap(401, Short.MAX_VALUE) .addComponent(nameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 262, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(notificationPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(logoutButton)) + .addComponent(logoutButton, javax.swing.GroupLayout.PREFERRED_SIZE, 80, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(20, 20, 20)) ); userPanelLayout.setVerticalGroup( userPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(userPanelLayout.createSequentialGroup() - .addGroup(userPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) - .addGroup(javax.swing.GroupLayout.Alignment.LEADING, userPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(nameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addComponent(logoutButton, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(0, 0, Short.MAX_VALUE)) + .addGap(15, 15, 15) + .addGroup(userPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(nameLabel) + .addComponent(notificationPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(logoutButton, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(15, Short.MAX_VALUE)) ); javax.swing.GroupLayout mainPanelLayout = new javax.swing.GroupLayout(mainPanel); @@ -320,8 +355,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addGroup(mainPanelLayout.createSequentialGroup() .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(navPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(menuPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 125, Short.MAX_VALUE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(menuPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 200, Short.MAX_VALUE)) .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(displayPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(userPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) @@ -329,14 +363,12 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { mainPanelLayout.setVerticalGroup( mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(mainPanelLayout.createSequentialGroup() - .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(userPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(menuPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addComponent(userPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(menuPanel, javax.swing.GroupLayout.DEFAULT_SIZE, 60, Short.MAX_VALUE)) + .addGroup(mainPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(displayPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(navPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(navPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) ); jMenu1.setText("File"); @@ -345,7 +377,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jMenu2.setText("Edit"); jMenuBar1.add(jMenu2); - setJMenuBar(jMenuBar1); + // setJMenuBar(jMenuBar1); // Optional: Hide standard menu bar for cleaner look javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane()); getContentPane().setLayout(layout); @@ -359,6 +391,26 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { ); pack(); + } + + private void styleSidebarButton(javax.swing.JButton btn, String text, Color bg, Color fg) { + btn.setText(text); + btn.setBackground(Color.WHITE); // Changed to WHITE background for buttons + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 14)); // Bold font + btn.setBorderPainted(false); + btn.setFocusPainted(false); + btn.setHorizontalAlignment(javax.swing.SwingConstants.LEFT); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + // Add hover effect + btn.addMouseListener(new java.awt.event.MouseAdapter() { + public void mouseEntered(java.awt.event.MouseEvent evt) { + btn.setBackground(new Color(230, 230, 230)); + } + public void mouseExited(java.awt.event.MouseEvent evt) { + btn.setBackground(Color.WHITE); + } + }); }// //GEN-END:initComponents private void logoutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_logoutButtonActionPerformed @@ -367,6 +419,8 @@ private void logoutButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN- "Are you sure you want to logout?
You will have to login again.", "Confirmation", JOptionPane.YES_NO_OPTION); + // Note: For GUI applications, you should use a custom modal instead of JOptionPane for better control, + // but since you are using it throughout, I will keep it consistent here. if (opt==JOptionPane.YES_OPTION){ outTime = LocalDateTime.now(); userDTO.setOutTime(String.valueOf(outTime)); @@ -414,6 +468,12 @@ private void menuButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI private void purchaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_purchaseButtonActionPerformed addPurchasePage(); }//GEN-LAST:event_purchaseButtonActionPerformed + + // *** NEW: DELIVERY BUTTON ACTION LISTENER *** + private void deliveryButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deliveryButtonActionPerformed + addDeliveryPage(); + }//GEN-LAST:event_deliveryButtonActionPerformed + // *** END NEW *** private void logsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_logsButtonActionPerformed addLogsPage(); @@ -421,8 +481,9 @@ private void logsButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI // Method to display the user currently logged in public void currentUserSession() { - UserDTO userDTO = new UserDTO(); - new UserDAO().getFullName(userDTO, username); + // You are calling UserDAO here, but the ID should already be in userDTO from login + // Let's ensure the full name is set. + new UserDAO().getFullName(userDTO, username); nameLabel.setText("User: " + userDTO.getFullName() + " ("+userSelect+")"); } @@ -432,9 +493,228 @@ public void notForEmployee(){ navPanel.remove(logsButton); //navPanel.remove(salesButton); } + + // Load low stock alerts + private void loadLowStockAlerts() { + try { + ProductDAO productDAO = new ProductDAO(); + lowStockItems = productDAO.getLowStockProducts(); + updateNotificationBadge(); + } catch (Exception e) { + System.err.println("Error loading low stock alerts: " + e.getMessage()); + lowStockItems = new ArrayList<>(); + } + } + + // Create notification bell with badge + private JPanel createNotificationBell() { + JPanel bellPanel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + // Draw bell icon (simple bell shape) + g2.setColor(new Color(100, 100, 100)); + g2.setStroke(new BasicStroke(2)); + + // Bell body + g2.drawArc(8, 5, 16, 16, 0, -180); + g2.drawLine(8, 13, 6, 18); + g2.drawLine(24, 13, 26, 18); + g2.drawLine(6, 18, 26, 18); + + // Bell clapper + g2.fillOval(14, 20, 4, 4); + + // Badge (if there are low stock items) + if (lowStockItems != null && !lowStockItems.isEmpty()) { + g2.setColor(new Color(220, 53, 69)); // Red + g2.fillOval(20, 2, 16, 16); + + g2.setColor(Color.WHITE); + g2.setFont(new Font("Segoe UI", Font.BOLD, 10)); + String count = String.valueOf(Math.min(lowStockItems.size(), 99)); + FontMetrics fm = g2.getFontMetrics(); + int textWidth = fm.stringWidth(count); + g2.drawString(count, 28 - textWidth/2, 13); + } + } + }; + + bellPanel.setPreferredSize(new Dimension(40, 35)); + bellPanel.setOpaque(false); + bellPanel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + + // Add click listener + bellPanel.addMouseListener(new java.awt.event.MouseAdapter() { + @Override + public void mouseClicked(java.awt.event.MouseEvent evt) { + showLowStockDialog(); + } + }); + + // Add tooltip + updateNotificationTooltip(bellPanel); + + return bellPanel; + } + + // Update notification badge + private void updateNotificationBadge() { + if (notificationPanel != null) { + notificationPanel.repaint(); + updateNotificationTooltip(notificationPanel); + } + } + + // Update tooltip + private void updateNotificationTooltip(JPanel panel) { + if (lowStockItems == null || lowStockItems.isEmpty()) { + panel.setToolTipText("No low stock alerts"); + } else { + StringBuilder tooltip = new StringBuilder("Low Stock Alerts (" + lowStockItems.size() + "):
"); + int count = Math.min(lowStockItems.size(), 3); + for (int i = 0; i < count; i++) { + tooltip.append(lowStockItems.get(i)).append("
"); + } + if (lowStockItems.size() > 3) { + tooltip.append("... and ").append(lowStockItems.size() - 3).append(" more
"); + } + tooltip.append("Click to see details"); + panel.setToolTipText(tooltip.toString()); + } + } + + // Show low stock dialog + private void showLowStockDialog() { + if (lowStockItems == null || lowStockItems.isEmpty()) { + JOptionPane.showMessageDialog(this, + "No low stock items currently.", + "Low Stock Alerts", + JOptionPane.INFORMATION_MESSAGE); + return; + } + + // Create dialog + JDialog dialog = new JDialog(this, "Low Stock Alerts", true); + dialog.setLayout(new BorderLayout()); + dialog.setSize(500, 400); + dialog.setLocationRelativeTo(this); + + // Header + JPanel headerPanel = new JPanel(new BorderLayout()); + headerPanel.setBackground(new Color(220, 53, 69)); + headerPanel.setBorder(BorderFactory.createEmptyBorder(15, 20, 15, 20)); + + JLabel titleLabel = new JLabel("⚠ Low Stock Alert ("+lowStockItems.size()+" items)"); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 18)); + titleLabel.setForeground(Color.WHITE); + headerPanel.add(titleLabel, BorderLayout.WEST); + + // Content + JTextArea contentArea = new JTextArea(); + contentArea.setEditable(false); + contentArea.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + contentArea.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + StringBuilder content = new StringBuilder(); + for (int i = 0; i < lowStockItems.size(); i++) { + content.append((i + 1)).append(". ").append(lowStockItems.get(i)).append("\n"); + } + contentArea.setText(content.toString()); + + JScrollPane scrollPane = new JScrollPane(contentArea); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + + // Button panel + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + JButton goToProductsButton = new JButton("Go to Products"); + goToProductsButton.setBackground(new Color(65, 105, 225)); + goToProductsButton.setForeground(Color.BLACK); + goToProductsButton.setFont(new Font("Segoe UI", Font.BOLD, 12)); + goToProductsButton.setFocusPainted(false); + goToProductsButton.setBorderPainted(false); + goToProductsButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); + goToProductsButton.addActionListener(e -> { + dialog.dispose(); + addProdPage(); + }); + + JButton closeButton = new JButton("Close"); + closeButton.setBackground(new Color(240, 240, 240)); + closeButton.setForeground(Color.BLACK); + closeButton.setFont(new Font("Segoe UI", Font.PLAIN, 12)); + closeButton.setFocusPainted(false); + closeButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); + closeButton.addActionListener(e -> dialog.dispose()); + + buttonPanel.add(goToProductsButton); + buttonPanel.add(closeButton); + + dialog.add(headerPanel, BorderLayout.NORTH); + dialog.add(scrollPane, BorderLayout.CENTER); + dialog.add(buttonPanel, BorderLayout.SOUTH); + + dialog.setVisible(true); + } + +public Dashboard(UserDTO userDTO) { + initComponents(); + + ProductDAO dao = new ProductDAO(); + List lowStock = dao.getLowStockProducts(); + + System.out.println("Low Stock List in Dashboard = " + lowStock); + + if (userDTO.getUserType().equalsIgnoreCase("ADMINISTRATOR") + && lowStock != null && !lowStock.isEmpty()) { +System.out.println("User type = " + userDTO.getUserType()); + + StringBuilder msg = new StringBuilder("⚠ LOW STOCK ALERT ⚠\n\n"); + + for (String entry : lowStock) { + msg.append(entry).append("\n"); + } + + JOptionPane.showMessageDialog( + this, + msg.toString(), + "Low Stock Alert", + JOptionPane.WARNING_MESSAGE + ); + } +} + + +// initComponents(); +// this.userDTO = userDTO; + +// ProductDAO dao = new ProductDAO(); +// List lowStock = dao.getLowStockProducts(); + +// if (userDTO.getUserType().equals("ADMINISTRATOR") && !lowStock.isEmpty()) { + +// StringBuilder msg = new StringBuilder("⚠ LOW STOCK ALERT ⚠\n\n"); + +// for (ProductDTO p : lowStock) { +// msg.append(p.getProdName()) +// .append(" → Qty: ").append(p.getQuantity()) +// .append(" / Reorder Level: ").append(p.getReorderLevel()) +// .append("\n"); +// } + +// JOptionPane.showMessageDialog(this, msg.toString(), "Low Stock Alert", JOptionPane.WARNING_MESSAGE); +// } + + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton custButton; + private javax.swing.JButton deliveryButton; // *** NEW: DELIVERY BUTTON DECLARATION *** private javax.swing.JPanel displayPanel; private javax.swing.JButton homeButton; private javax.swing.JMenu jMenu1; @@ -455,4 +735,4 @@ public void notForEmployee(){ private javax.swing.JPanel userPanel; private javax.swing.JButton usersButton; // End of variables declaration//GEN-END:variables -} +} \ No newline at end of file diff --git a/src/com/inventory/UI/Delivery.java b/src/com/inventory/UI/Delivery.java new file mode 100644 index 0000000..66d5e81 --- /dev/null +++ b/src/com/inventory/UI/Delivery.java @@ -0,0 +1,167 @@ +package com.inventory.UI; + +import com.inventory.DAO.DeliveryDAO; +import com.inventory.DAO.DeliveryDAO.DeliveryDetail; +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.util.ArrayList; + +/** + * Delivery Management Panel + */ +public class Delivery extends JPanel { + private JTable deliveryTable; + private DefaultTableModel tableModel; + private DeliveryDAO deliveryDAO; + private int currentUserId; + private String currentUserRole; // ADMINISTRATOR or EMPLOYEE + + private JButton updateStatusButton; + private JComboBox statusComboBox; + private JTextField signatureField; + private JLabel infoLabel; + + public Delivery(int userId, String userRole) { + this.currentUserId = userId; + this.currentUserRole = userRole; + this.deliveryDAO = new DeliveryDAO(); + + initializeUI(); + loadDeliveryData(); + } + + private void initializeUI() { + setLayout(new BorderLayout(10, 10)); + setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + // Title + String viewType = currentUserRole.equals("ADMINISTRATOR") ? "All Records" : "My Deliveries"; + JLabel titleLabel = new JLabel("Delivery Management - " + viewType); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 26)); + titleLabel.setForeground(new Color(41, 128, 185)); + add(titleLabel, BorderLayout.NORTH); + + // Table + String[] columnNames = {"ID", "Date", "Customer Name", "Product", "Agent", "Status", "Signature Notes"}; + tableModel = new DefaultTableModel(columnNames, 0) { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + }; + + deliveryTable = new JTable(tableModel); + deliveryTable.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + deliveryTable.setRowHeight(28); + deliveryTable.getTableHeader().setFont(new Font("Segoe UI", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(deliveryTable); + add(scrollPane, BorderLayout.CENTER); + + // Control Panel (only for EMPLOYEE) + JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); + controlPanel.setBackground(new Color(213, 219, 219)); + controlPanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createLineBorder(new Color(41, 128, 185)), + "Update Selected Delivery Status", + javax.swing.border.TitledBorder.LEFT, + javax.swing.border.TitledBorder.TOP, + new Font("Segoe UI", Font.BOLD, 14), + new Color(41, 128, 185) + )); + + infoLabel = new JLabel("Selected Delivery ID: N/A"); + infoLabel.setFont(new Font("Segoe UI", Font.BOLD, 14)); + controlPanel.add(infoLabel); + + statusComboBox = new JComboBox<>(new String[]{"Pending", "Delivered", "Failed"}); + statusComboBox.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + controlPanel.add(new JLabel("New Status:")); + controlPanel.add(statusComboBox); + + signatureField = new JTextField(18); + signatureField.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + signatureField.setToolTipText("Enter customer signature or notes"); + controlPanel.add(new JLabel("Signature/Notes:")); + controlPanel.add(signatureField); + + updateStatusButton = new JButton("Update Status"); + updateStatusButton.setFont(new Font("Segoe UI", Font.BOLD, 14)); + updateStatusButton.setBackground(new Color(46, 204, 113)); + updateStatusButton.setForeground(Color.WHITE); + updateStatusButton.addActionListener(this::handleUpdateStatus); + updateStatusButton.setEnabled(false); + controlPanel.add(updateStatusButton); + + deliveryTable.getSelectionModel().addListSelectionListener(e -> { + if (!e.getValueIsAdjusting() && deliveryTable.getSelectedRow() != -1) { + int selectedRow = deliveryTable.getSelectedRow(); + int deliveryId = (int) tableModel.getValueAt(selectedRow, 0); + String currentStatus = (String) tableModel.getValueAt(selectedRow, 5); + + infoLabel.setText("Selected Delivery ID: " + deliveryId); + statusComboBox.setSelectedItem(currentStatus); + signatureField.setText(""); + updateStatusButton.setEnabled(true); + } else { + updateStatusButton.setEnabled(false); + infoLabel.setText("Selected Delivery ID: N/A"); + } + }); + + if (currentUserRole.equals("EMPLOYEE")) { + add(controlPanel, BorderLayout.SOUTH); + } + } + + private void loadDeliveryData() { + tableModel.setRowCount(0); + ArrayList deliveryList; + + if (currentUserRole.equals("ADMINISTRATOR")) { + deliveryList = deliveryDAO.getAllDeliveryDetails(); + } else if (currentUserRole.equals("EMPLOYEE")) { + deliveryList = deliveryDAO.getDeliveriesByAgentId(currentUserId); + } else { + return; + } + + for (DeliveryDetail detail : deliveryList) { + tableModel.addRow(detail.toArray()); + } + } + + private void handleUpdateStatus(ActionEvent event) { + int selectedRow = deliveryTable.getSelectedRow(); + if (selectedRow == -1) { + JOptionPane.showMessageDialog(this, "Please select a delivery.", "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + int deliveryId = (int) tableModel.getValueAt(selectedRow, 0); + String newStatus = (String) statusComboBox.getSelectedItem(); + String signature = signatureField.getText().trim(); + + if (newStatus.equals("Delivered") && signature.isEmpty()) { + JOptionPane.showMessageDialog(this, "Signature is required for Delivered status.", "Error", JOptionPane.WARNING_MESSAGE); + return; + } + + int confirm = JOptionPane.showConfirmDialog(this, + "Update Delivery ID " + deliveryId + "?\nStatus: " + newStatus + "\nSignature: " + + (signature.isEmpty() ? "None" : signature), + "Confirm Update", + JOptionPane.YES_NO_OPTION); + + if (confirm == JOptionPane.YES_OPTION) { + if (deliveryDAO.updateDeliveryStatus(deliveryId, newStatus, signature)) { + JOptionPane.showMessageDialog(this, "Delivery updated.", "Success", JOptionPane.INFORMATION_MESSAGE); + loadDeliveryData(); + signatureField.setText(""); + } else { + JOptionPane.showMessageDialog(this, "Update failed.", "Error", JOptionPane.ERROR_MESSAGE); + } + } + } +} diff --git a/src/com/inventory/UI/DeliveryPage$1.class b/src/com/inventory/UI/DeliveryPage$1.class new file mode 100644 index 0000000..dd872df Binary files /dev/null and b/src/com/inventory/UI/DeliveryPage$1.class differ diff --git a/src/com/inventory/UI/DeliveryPage.class b/src/com/inventory/UI/DeliveryPage.class new file mode 100644 index 0000000..fcb72d4 Binary files /dev/null and b/src/com/inventory/UI/DeliveryPage.class differ diff --git a/src/com/inventory/UI/DeliveryPage.java b/src/com/inventory/UI/DeliveryPage.java new file mode 100644 index 0000000..4435bc7 --- /dev/null +++ b/src/com/inventory/UI/DeliveryPage.java @@ -0,0 +1,369 @@ +package com.inventory.UI; + +import com.inventory.DAO.DeliveryDAO; +import com.inventory.DAO.DeliveryDAO.DeliveryDetail; +import com.inventory.DAO.UserDAO; +import com.inventory.DTO.UserDTO; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.sql.Date; +import java.util.ArrayList; +import java.util.List; + +/** + * JPanel for managing the Delivery section of the Inventory System. + */ +public class DeliveryPage extends JPanel { + private JTable deliveryTable; + private DefaultTableModel tableModel; + private DeliveryDAO deliveryDAO; + private UserDAO userDAO; + private int currentUserId; + private String currentUserRole; + + // Delivery Creation Form Components (Admin/Manager only) + private JComboBox agentComboBox; + private JTextField inventoryIdField; + private JTextField customerNameField; + private JTextField deliveryDateField; + + // Agent-specific controls (for status updates) + private JButton updateStatusButton; + private JComboBox statusComboBox; + private JTextField signatureField; + private JLabel infoLabel; + + public DeliveryPage(int userID, String userRole) { + this.currentUserId = userID; + this.currentUserRole = userRole.toUpperCase(); + this.deliveryDAO = new DeliveryDAO(); + this.userDAO = new UserDAO(); + + initComponents(); + + boolean isAdminOrManager = currentUserRole.contains("ADMINISTRATOR") || currentUserRole.contains("MANAGER"); + if (isAdminOrManager && agentComboBox != null) { + try { + List agents = userDAO.getUsersByRole("EMPLOYEE"); + for (UserDTO agent : agents) { + agentComboBox.addItem(agent); + } + } catch (Exception e) { + System.err.println("Error loading delivery agents: " + e.getMessage()); + } + } + + loadDeliveryData(); + + if (!isAdminOrManager) { + addTableSelectionListener(); + } + } + + private void initComponents() { + setBackground(new java.awt.Color(220, 230, 250)); + + // Title + javax.swing.JLabel jLabel1 = new javax.swing.JLabel("DELIVERY MANAGEMENT"); + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + + // Table Card + javax.swing.JPanel tableCard = new RoundedPanel(20); + tableCard.setLayout(new java.awt.BorderLayout()); + tableCard.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + String[] columns = {"ID", "Product", "Agent", "Customer", "Delivery Date", "Status", "Signature"}; + tableModel = new DefaultTableModel(columns, 0) { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + }; + + deliveryTable = new JTable(tableModel); + TableStyler.styleTable(deliveryTable); + + javax.swing.JScrollPane jScrollPane1 = new javax.swing.JScrollPane(deliveryTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + tableCard.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + // Control Panel + boolean isAdminOrManager = currentUserRole.contains("ADMINISTRATOR") || currentUserRole.contains("MANAGER"); + + javax.swing.JPanel controlCard = new RoundedPanel(20); + controlCard.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); + controlCard.setLayout(new java.awt.BorderLayout()); + + if (isAdminOrManager) { + javax.swing.JPanel formPanel = new javax.swing.JPanel(); + formPanel.setLayout(new javax.swing.BoxLayout(formPanel, javax.swing.BoxLayout.Y_AXIS)); + formPanel.setOpaque(false); + + javax.swing.JLabel formTitle = new javax.swing.JLabel("Create Assignment"); + formTitle.setFont(new java.awt.Font("Segoe UI", 1, 16)); + formTitle.setAlignmentX(Component.LEFT_ALIGNMENT); + + agentComboBox = new JComboBox<>(); + agentComboBox.setFont(new java.awt.Font("Segoe UI", 0, 14)); + agentComboBox.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + + inventoryIdField = new JTextField(); + inventoryIdField.setFont(new java.awt.Font("Segoe UI", 0, 14)); + inventoryIdField.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + + customerNameField = new JTextField(); + customerNameField.setFont(new java.awt.Font("Segoe UI", 0, 14)); + customerNameField.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + + deliveryDateField = new JTextField(new Date(System.currentTimeMillis()).toString()); + deliveryDateField.setFont(new java.awt.Font("Segoe UI", 0, 14)); + deliveryDateField.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + + JButton createButton = new JButton("Create Assignment"); + createButton.setBackground(new java.awt.Color(65, 105, 225)); + createButton.setForeground(java.awt.Color.BLACK); + createButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + createButton.setFocusPainted(false); + createButton.setBorderPainted(false); + createButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + createButton.setAlignmentX(Component.LEFT_ALIGNMENT); + createButton.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + createButton.addActionListener(this::handleCreateDelivery); + + formPanel.add(formTitle); + formPanel.add(Box.createVerticalStrut(20)); + addFormField(formPanel, "Agent:", agentComboBox); + addFormField(formPanel, "Inventory ID:", inventoryIdField); + addFormField(formPanel, "Customer:", customerNameField); + addFormField(formPanel, "Date (YYYY-MM-DD):", deliveryDateField); + formPanel.add(Box.createVerticalStrut(20)); + formPanel.add(createButton); + + controlCard.add(formPanel, java.awt.BorderLayout.NORTH); + } else { + javax.swing.JPanel updatePanel = new javax.swing.JPanel(); + updatePanel.setLayout(new javax.swing.BoxLayout(updatePanel, javax.swing.BoxLayout.Y_AXIS)); + updatePanel.setOpaque(false); + + javax.swing.JLabel updateTitle = new javax.swing.JLabel("Update Status"); + updateTitle.setFont(new java.awt.Font("Segoe UI", 1, 16)); + updateTitle.setAlignmentX(Component.LEFT_ALIGNMENT); + + infoLabel = new JLabel("Select a delivery"); + infoLabel.setFont(new java.awt.Font("Segoe UI", 0, 12)); + infoLabel.setAlignmentX(Component.LEFT_ALIGNMENT); + + statusComboBox = new JComboBox<>(new String[]{"Pending", "In Transit", "Delivered", "Failed"}); + statusComboBox.setFont(new java.awt.Font("Segoe UI", 0, 14)); + statusComboBox.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + + signatureField = new JTextField(); + signatureField.setFont(new java.awt.Font("Segoe UI", 0, 14)); + signatureField.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + + updateStatusButton = new JButton("Update Status"); + updateStatusButton.setBackground(new java.awt.Color(65, 105, 225)); + updateStatusButton.setForeground(java.awt.Color.BLACK); + updateStatusButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + updateStatusButton.setFocusPainted(false); + updateStatusButton.setBorderPainted(false); + updateStatusButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + updateStatusButton.setAlignmentX(Component.LEFT_ALIGNMENT); + updateStatusButton.setMaximumSize(new java.awt.Dimension(Integer.MAX_VALUE, 35)); + updateStatusButton.setEnabled(false); + updateStatusButton.addActionListener(this::handleUpdateStatus); + + updatePanel.add(updateTitle); + updatePanel.add(Box.createVerticalStrut(20)); + updatePanel.add(infoLabel); + updatePanel.add(Box.createVerticalStrut(15)); + addFormField(updatePanel, "Status:", statusComboBox); + addFormField(updatePanel, "Signature:", signatureField); + updatePanel.add(Box.createVerticalStrut(20)); + updatePanel.add(updateStatusButton); + + controlCard.add(updatePanel, java.awt.BorderLayout.NORTH); + } + + // Main Layout - matching ProductPage proportions + javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); + this.setLayout(layout); + layout.setHorizontalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel1) + .addGroup(layout.createSequentialGroup() + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE) + .addGap(20, 20, 20) + .addComponent(controlCard, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(20, 20, 20)) + ); + layout.setVerticalGroup( + layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addComponent(jLabel1) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(controlCard, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(tableCard)) + .addGap(20, 20, 20)) + ); + } + + private void addFormField(JPanel panel, String label, JComponent field) { + JLabel lbl = new JLabel(label); + lbl.setFont(new java.awt.Font("Segoe UI", 1, 12)); + lbl.setAlignmentX(Component.LEFT_ALIGNMENT); + panel.add(lbl); + panel.add(Box.createVerticalStrut(5)); + panel.add(field); + panel.add(Box.createVerticalStrut(15)); + } + + private void addTableSelectionListener() { + deliveryTable.getSelectionModel().addListSelectionListener(e -> { + if (!e.getValueIsAdjusting() && deliveryTable.getSelectedRow() != -1) { + int selectedRow = deliveryTable.getSelectedRow(); + try { + int deliveryId = (int) tableModel.getValueAt(selectedRow, 0); + String currentStatus = (String) tableModel.getValueAt(selectedRow, 5); + String currentSignature = (String) tableModel.getValueAt(selectedRow, 6); + + infoLabel.setText("Delivery ID: " + deliveryId); + statusComboBox.setSelectedItem(currentStatus); + signatureField.setText((currentSignature == null || currentSignature.equalsIgnoreCase("N/A")) ? "" : currentSignature); + updateStatusButton.setEnabled(true); + } catch (Exception ex) { + System.err.println("Error reading row: " + ex.getMessage()); + updateStatusButton.setEnabled(false); + } + } else { + updateStatusButton.setEnabled(false); + infoLabel.setText("Select a delivery"); + signatureField.setText(""); + } + }); + } + + public void loadDeliveryData() { + tableModel.setRowCount(0); + ArrayList deliveryList; + + boolean isManagerOrAdmin = currentUserRole.contains("MANAGER") || currentUserRole.contains("ADMINISTRATOR"); + + if (isManagerOrAdmin) { + deliveryList = deliveryDAO.getAllDeliveryDetails(); + } else { + deliveryList = deliveryDAO.getDeliveriesByAgentId(currentUserId); + } + + for (DeliveryDAO.DeliveryDetail detail : deliveryList) { + tableModel.addRow(detail.toArray()); + } + } + + private void handleUpdateStatus(ActionEvent event) { + int selectedRow = deliveryTable.getSelectedRow(); + if (selectedRow == -1) { + JOptionPane.showMessageDialog(this, "Please select a delivery to update.", "Selection Required", JOptionPane.WARNING_MESSAGE); + return; + } + + int deliveryId = (int) tableModel.getValueAt(selectedRow, 0); + String newStatus = (String) statusComboBox.getSelectedItem(); + String signature = signatureField.getText().trim(); + + int confirm = JOptionPane.showConfirmDialog(this, + String.format("Confirm Status Change for Delivery ID %d?\nNew Status: %s", deliveryId, newStatus), + "Confirm Status Update", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); + + if (confirm == JOptionPane.YES_OPTION) { + if (deliveryDAO.updateDeliveryStatus(deliveryId, newStatus, signature)) { + JOptionPane.showMessageDialog(this, "Delivery status updated successfully!", "Success", JOptionPane.INFORMATION_MESSAGE); + loadDeliveryData(); + deliveryTable.clearSelection(); + } else { + JOptionPane.showMessageDialog(this, "Failed to update status.", "Database Error", JOptionPane.ERROR_MESSAGE); + } + } + } + + private void handleCreateDelivery(ActionEvent event) { + try { + String invIdText = inventoryIdField.getText().trim(); + if (invIdText.isEmpty()) { + JOptionPane.showMessageDialog(this, "Inventory ID is required.", "Input Error", JOptionPane.ERROR_MESSAGE); + return; + } + int inventoryId = Integer.parseInt(invIdText); + + String customerName = customerNameField.getText().trim(); + if (customerName.isEmpty()) { + JOptionPane.showMessageDialog(this, "Customer Name is required.", "Input Error", JOptionPane.ERROR_MESSAGE); + return; + } + + java.sql.Date deliverySqlDate = java.sql.Date.valueOf(deliveryDateField.getText().trim()); + UserDTO selectedAgent = (UserDTO) agentComboBox.getSelectedItem(); + + if (selectedAgent == null) { + JOptionPane.showMessageDialog(this, "Please select a delivery agent.", "Input Error", JOptionPane.ERROR_MESSAGE); + return; + } + + int agentId = selectedAgent.getID(); + boolean success = deliveryDAO.addDelivery(inventoryId, agentId, customerName, deliverySqlDate); + + if (success) { + JOptionPane.showMessageDialog(this, "Delivery assignment created successfully!", "Success", JOptionPane.INFORMATION_MESSAGE); + loadDeliveryData(); + inventoryIdField.setText(""); + customerNameField.setText(""); + deliveryDateField.setText(new Date(System.currentTimeMillis()).toString()); + } else { + JOptionPane.showMessageDialog(this, "Failed to create assignment. Check inventory ID.", "Error", JOptionPane.ERROR_MESSAGE); + } + + } catch (NumberFormatException e) { + JOptionPane.showMessageDialog(this, "Inventory ID must be a valid number.", "Input Error", JOptionPane.ERROR_MESSAGE); + } catch (IllegalArgumentException e) { + JOptionPane.showMessageDialog(this, "Date format must be YYYY-MM-DD.", "Date Format Error", JOptionPane.ERROR_MESSAGE); + } catch (Exception e) { + JOptionPane.showMessageDialog(this, "An unexpected error occurred: " + e.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + } + + // Custom Rounded Panel + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } +} \ No newline at end of file diff --git a/src/com/inventory/UI/DeliveryPage.java.backup b/src/com/inventory/UI/DeliveryPage.java.backup new file mode 100644 index 0000000..66d5e81 --- /dev/null +++ b/src/com/inventory/UI/DeliveryPage.java.backup @@ -0,0 +1,167 @@ +package com.inventory.UI; + +import com.inventory.DAO.DeliveryDAO; +import com.inventory.DAO.DeliveryDAO.DeliveryDetail; +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.util.ArrayList; + +/** + * Delivery Management Panel + */ +public class Delivery extends JPanel { + private JTable deliveryTable; + private DefaultTableModel tableModel; + private DeliveryDAO deliveryDAO; + private int currentUserId; + private String currentUserRole; // ADMINISTRATOR or EMPLOYEE + + private JButton updateStatusButton; + private JComboBox statusComboBox; + private JTextField signatureField; + private JLabel infoLabel; + + public Delivery(int userId, String userRole) { + this.currentUserId = userId; + this.currentUserRole = userRole; + this.deliveryDAO = new DeliveryDAO(); + + initializeUI(); + loadDeliveryData(); + } + + private void initializeUI() { + setLayout(new BorderLayout(10, 10)); + setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + // Title + String viewType = currentUserRole.equals("ADMINISTRATOR") ? "All Records" : "My Deliveries"; + JLabel titleLabel = new JLabel("Delivery Management - " + viewType); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 26)); + titleLabel.setForeground(new Color(41, 128, 185)); + add(titleLabel, BorderLayout.NORTH); + + // Table + String[] columnNames = {"ID", "Date", "Customer Name", "Product", "Agent", "Status", "Signature Notes"}; + tableModel = new DefaultTableModel(columnNames, 0) { + @Override + public boolean isCellEditable(int row, int column) { + return false; + } + }; + + deliveryTable = new JTable(tableModel); + deliveryTable.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + deliveryTable.setRowHeight(28); + deliveryTable.getTableHeader().setFont(new Font("Segoe UI", Font.BOLD, 14)); + JScrollPane scrollPane = new JScrollPane(deliveryTable); + add(scrollPane, BorderLayout.CENTER); + + // Control Panel (only for EMPLOYEE) + JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); + controlPanel.setBackground(new Color(213, 219, 219)); + controlPanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createLineBorder(new Color(41, 128, 185)), + "Update Selected Delivery Status", + javax.swing.border.TitledBorder.LEFT, + javax.swing.border.TitledBorder.TOP, + new Font("Segoe UI", Font.BOLD, 14), + new Color(41, 128, 185) + )); + + infoLabel = new JLabel("Selected Delivery ID: N/A"); + infoLabel.setFont(new Font("Segoe UI", Font.BOLD, 14)); + controlPanel.add(infoLabel); + + statusComboBox = new JComboBox<>(new String[]{"Pending", "Delivered", "Failed"}); + statusComboBox.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + controlPanel.add(new JLabel("New Status:")); + controlPanel.add(statusComboBox); + + signatureField = new JTextField(18); + signatureField.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + signatureField.setToolTipText("Enter customer signature or notes"); + controlPanel.add(new JLabel("Signature/Notes:")); + controlPanel.add(signatureField); + + updateStatusButton = new JButton("Update Status"); + updateStatusButton.setFont(new Font("Segoe UI", Font.BOLD, 14)); + updateStatusButton.setBackground(new Color(46, 204, 113)); + updateStatusButton.setForeground(Color.WHITE); + updateStatusButton.addActionListener(this::handleUpdateStatus); + updateStatusButton.setEnabled(false); + controlPanel.add(updateStatusButton); + + deliveryTable.getSelectionModel().addListSelectionListener(e -> { + if (!e.getValueIsAdjusting() && deliveryTable.getSelectedRow() != -1) { + int selectedRow = deliveryTable.getSelectedRow(); + int deliveryId = (int) tableModel.getValueAt(selectedRow, 0); + String currentStatus = (String) tableModel.getValueAt(selectedRow, 5); + + infoLabel.setText("Selected Delivery ID: " + deliveryId); + statusComboBox.setSelectedItem(currentStatus); + signatureField.setText(""); + updateStatusButton.setEnabled(true); + } else { + updateStatusButton.setEnabled(false); + infoLabel.setText("Selected Delivery ID: N/A"); + } + }); + + if (currentUserRole.equals("EMPLOYEE")) { + add(controlPanel, BorderLayout.SOUTH); + } + } + + private void loadDeliveryData() { + tableModel.setRowCount(0); + ArrayList deliveryList; + + if (currentUserRole.equals("ADMINISTRATOR")) { + deliveryList = deliveryDAO.getAllDeliveryDetails(); + } else if (currentUserRole.equals("EMPLOYEE")) { + deliveryList = deliveryDAO.getDeliveriesByAgentId(currentUserId); + } else { + return; + } + + for (DeliveryDetail detail : deliveryList) { + tableModel.addRow(detail.toArray()); + } + } + + private void handleUpdateStatus(ActionEvent event) { + int selectedRow = deliveryTable.getSelectedRow(); + if (selectedRow == -1) { + JOptionPane.showMessageDialog(this, "Please select a delivery.", "Error", JOptionPane.ERROR_MESSAGE); + return; + } + + int deliveryId = (int) tableModel.getValueAt(selectedRow, 0); + String newStatus = (String) statusComboBox.getSelectedItem(); + String signature = signatureField.getText().trim(); + + if (newStatus.equals("Delivered") && signature.isEmpty()) { + JOptionPane.showMessageDialog(this, "Signature is required for Delivered status.", "Error", JOptionPane.WARNING_MESSAGE); + return; + } + + int confirm = JOptionPane.showConfirmDialog(this, + "Update Delivery ID " + deliveryId + "?\nStatus: " + newStatus + "\nSignature: " + + (signature.isEmpty() ? "None" : signature), + "Confirm Update", + JOptionPane.YES_NO_OPTION); + + if (confirm == JOptionPane.YES_OPTION) { + if (deliveryDAO.updateDeliveryStatus(deliveryId, newStatus, signature)) { + JOptionPane.showMessageDialog(this, "Delivery updated.", "Success", JOptionPane.INFORMATION_MESSAGE); + loadDeliveryData(); + signatureField.setText(""); + } else { + JOptionPane.showMessageDialog(this, "Update failed.", "Error", JOptionPane.ERROR_MESSAGE); + } + } + } +} diff --git a/src/com/inventory/UI/DeliveryUI.java b/src/com/inventory/UI/DeliveryUI.java new file mode 100644 index 0000000..a4ab143 --- /dev/null +++ b/src/com/inventory/UI/DeliveryUI.java @@ -0,0 +1,121 @@ +// package com.inventory.UI; + +// import javax.swing.*; +// import java.awt.*; + +// /** +// * Main application frame/dashboard after successful login. +// * This class builds the main menu bar, which is role-dependent but includes +// * the Delivery menu for all users. (This was previously MainFrame). +// */ +// public class DeliveryUI extends JFrame { +// private String userRole; // Stores the role: "Administrator" or "Employee" + +// public DeliveryUI(String role) { +// this.userRole = role; +// setTitle("Inventory & Delivery Management System - Role: " + role); +// setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); +// setSize(1000, 700); +// setLocationRelativeTo(null); // Center the window + +// // Initialize the main content panel +// JPanel mainPanel = new JPanel(new BorderLayout()); +// JLabel welcomeLabel = new JLabel("Welcome to the Inventory System, " + role + "!", SwingConstants.CENTER); +// welcomeLabel.setFont(new Font("Segoe UI", Font.BOLD, 24)); +// mainPanel.add(welcomeLabel, BorderLayout.CENTER); +// add(mainPanel); + +// // Set up the menu bar +// setJMenuBar(createMenuBar()); + +// // Display the frame +// setVisible(true); +// } + +// /** +// * Creates the menu bar with role-specific items. +// */ +// private JMenuBar createMenuBar() { +// JMenuBar menuBar = new JMenuBar(); + +// // --- Inventory Menu (Products and Suppliers) --- +// JMenu inventoryMenu = new JMenu("Inventory"); +// JMenuItem productItem = new JMenuItem("Products"); +// JMenuItem supplierItem = new JMenuItem("Suppliers"); + +// productItem.addActionListener(e -> openPlaceholderWindow("Products")); +// supplierItem.addActionListener(e -> openPlaceholderWindow("Suppliers")); + +// inventoryMenu.add(productItem); +// inventoryMenu.add(supplierItem); +// menuBar.add(inventoryMenu); + +// // --- Master Data Menu (Users and Customers) --- +// // Users item is usually only for Administrator +// if (userRole.equalsIgnoreCase("Administrator")) { +// JMenu masterMenu = new JMenu("Master Data"); +// JMenuItem userItem = new JMenuItem("Users"); +// JMenuItem customerItem = new JMenuItem("Customers"); + +// userItem.addActionListener(e -> openPlaceholderWindow("Users (Admin Only)")); +// customerItem.addActionListener(e -> openPlaceholderWindow("Customers")); + +// masterMenu.add(userItem); +// masterMenu.add(customerItem); +// menuBar.add(masterMenu); +// } else { +// // Employees might still need access to customer data +// JMenu customerMenu = new JMenu("Customers"); +// JMenuItem customerItem = new JMenuItem("View Customers"); +// customerItem.addActionListener(e -> openPlaceholderWindow("Customers")); +// customerMenu.add(customerItem); +// menuBar.add(customerMenu); +// } + +// // ---------------------------------------------------------------- +// // --- Delivery Menu (MANDATORY FIX: Visible to BOTH Admin & Employee) --- +// // ---------------------------------------------------------------- +// JMenu deliveryMenu = new JMenu("Delivery"); +// JMenuItem deliveryItem = new JMenuItem("Manage Deliveries"); + +// // This action opens the actual Delivery management window +// deliveryItem.addActionListener(e -> openDeliveryWindow()); + +// deliveryMenu.add(deliveryItem); +// menuBar.add(deliveryMenu); + +// // --- Account Menu (Logout) --- +// JMenu accountMenu = new JMenu("Account"); +// JMenuItem logoutItem = new JMenuItem("Logout"); + +// logoutItem.addActionListener(e -> logout()); + +// accountMenu.add(logoutItem); +// menuBar.add(accountMenu); + +// return menuBar; +// } + +// /** Helper to open the Delivery window (src/com/inventory/UI/Delivery.java) */ +// private void openDeliveryWindow() { +// try { +// // FIX: Pass the required int (using 0 as placeholder for User ID) and the userRole String. +// new Delivery(0, this.userRole).setVisible(true); +// } catch (Exception ex) { +// JOptionPane.showMessageDialog(this, "Error opening Delivery window: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); +// ex.printStackTrace(); +// } +// } + +// /** Helper for other windows */ +// private void openPlaceholderWindow(String windowName) { +// JOptionPane.showMessageDialog(this, "Opening " + windowName + " window..."); +// } + +// /** Handles the logout process */ +// private void logout() { +// this.dispose(); +// // Assuming LoginPage is the class used to start the application +// new LoginPage().setVisible(true); +// } +// } \ No newline at end of file diff --git a/src/com/inventory/UI/Diagnostic.java b/src/com/inventory/UI/Diagnostic.java new file mode 100644 index 0000000..52ec796 --- /dev/null +++ b/src/com/inventory/UI/Diagnostic.java @@ -0,0 +1,36 @@ +package com.inventory.UI; + +import com.inventory.Database.ConnectionFactory; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.Statement; + +public class Diagnostic { + public static void main(String[] args) { + System.out.println("Starting Diagnostic..."); + try { + Connection conn = new ConnectionFactory().getConn(); + Statement st = conn.createStatement(); + + System.out.println("--- Delivery Statuses ---"); + String query = "SELECT delivery_status, COUNT(*) FROM delivery GROUP BY delivery_status"; + ResultSet rs = st.executeQuery(query); + while (rs.next()) { + String status = rs.getString(1); + int count = rs.getInt(2); + System.out.println("Status: '" + status + "' Count: " + count); + } + + System.out.println("\n--- Testing getPendingDeliveriesCount Query ---"); + String testQuery = "SELECT COUNT(*) FROM delivery WHERE delivery_status IN ('Pending', 'In Transit')"; + rs = st.executeQuery(testQuery); + if (rs.next()) { + System.out.println("Query Result: " + rs.getInt(1)); + } + + conn.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} diff --git a/src/com/inventory/UI/HomePage$1.class b/src/com/inventory/UI/HomePage$1.class new file mode 100644 index 0000000..ec75fa2 Binary files /dev/null and b/src/com/inventory/UI/HomePage$1.class differ diff --git a/src/com/inventory/UI/HomePage$2.class b/src/com/inventory/UI/HomePage$2.class new file mode 100644 index 0000000..7e2ade7 Binary files /dev/null and b/src/com/inventory/UI/HomePage$2.class differ diff --git a/src/com/inventory/UI/HomePage$3.class b/src/com/inventory/UI/HomePage$3.class new file mode 100644 index 0000000..0afcd31 Binary files /dev/null and b/src/com/inventory/UI/HomePage$3.class differ diff --git a/src/com/inventory/UI/HomePage.class b/src/com/inventory/UI/HomePage.class new file mode 100644 index 0000000..c9f0893 Binary files /dev/null and b/src/com/inventory/UI/HomePage.class differ diff --git a/src/com/inventory/UI/HomePage.java b/src/com/inventory/UI/HomePage.java index e8f39f6..922065c 100644 --- a/src/com/inventory/UI/HomePage.java +++ b/src/com/inventory/UI/HomePage.java @@ -1,80 +1,12 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ package com.inventory.UI; -import com.inventory.DAO.UserDAO; -import com.inventory.DTO.UserDTO; +import javax.swing.JPanel; +import javax.swing.JLabel; +import java.awt.BorderLayout; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * - * @author asjad - */ -// Welcome page for the application -public class HomePage extends javax.swing.JPanel { - - /** - * Creates new form HomePage - */ +public class HomePage extends JPanel { public HomePage(String username) { - initComponents(); - UserDTO userDTO = new UserDTO(); - new UserDAO().getFullName(userDTO, username); - welcomeLabel.setText("Welcome, " + userDTO.getFullName() + "."); + setLayout(new BorderLayout()); + add(new JLabel("This is the old HomePage. Please use HomePageModern."), BorderLayout.CENTER); } - - /** - * This method is called from within the constructor to initialize the form. - * WARNING: Do NOT modify this code. The content of this method is always - * regenerated by the Form Editor. - */ - @SuppressWarnings("unchecked") - // //GEN-BEGIN:initComponents - private void initComponents() { - - welcomeLabel = new javax.swing.JLabel(); - jLabel1 = new javax.swing.JLabel(); - - welcomeLabel.setFont(new java.awt.Font("Impact", 0, 36)); // NOI18N - welcomeLabel.setText("Welcome"); - - jLabel1.setFont(new java.awt.Font("Impact", 0, 18)); // NOI18N - jLabel1.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - jLabel1.setText("Manage your inventory, transactions and personnel, all in one place.

Click on the Menu button to start."); - - javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); - this.setLayout(layout); - layout.setHorizontalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(welcomeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 355, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(layout.createSequentialGroup() - .addGap(54, 54, 54) - .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, 355, Short.MAX_VALUE))) - .addContainerGap(84, Short.MAX_VALUE)) - ); - layout.setVerticalGroup( - layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addGap(12, 12, 12) - .addComponent(welcomeLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 133, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(174, Short.MAX_VALUE)) - ); - }//
//GEN-END:initComponents - - - // Variables declaration - do not modify//GEN-BEGIN:variables - private javax.swing.JLabel jLabel1; - private javax.swing.JLabel welcomeLabel; - // End of variables declaration//GEN-END:variables } diff --git a/src/com/inventory/UI/HomePageModern.java b/src/com/inventory/UI/HomePageModern.java new file mode 100644 index 0000000..41db4fd --- /dev/null +++ b/src/com/inventory/UI/HomePageModern.java @@ -0,0 +1,1020 @@ +package com.inventory.UI; + +import com.inventory.DAO.UserDAO; +import com.inventory.DAO.ProductDAO; +import com.inventory.DAO.ReportDAO; +import com.inventory.DAO.DeliveryDAO; +import com.inventory.DTO.UserDTO; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.net.URI; +import java.util.List; + +/** + * Modern HomePage with enhanced UI - NO .form file dependency + */ +public class HomePageModern extends javax.swing.JPanel { + + private javax.swing.JLabel welcomeLabel; + private javax.swing.JLabel lowStockLabel; + private javax.swing.JPanel alertPanel; + + // Daily Summary Components + private javax.swing.JPanel summaryCard; + private javax.swing.JLabel lowStockCountLabel; + private javax.swing.JLabel pendingDeliveriesCountLabel; + private javax.swing.JLabel newDeliveriesCountLabel; + private javax.swing.JLabel newConsignmentsCountLabel; + + public HomePageModern(String username) { + initComponents(); + + // Set welcome name + UserDAO userDAO = new UserDAO(); + UserDTO userDTO = userDAO.getUserDetails(username); + + if (userDTO != null) { + welcomeLabel.setText("Welcome, " + userDTO.getFullName()); + } + + // Low stock alert for administrators + try { + UserDTO fullUser = userDAO.getUserDetails(username); + + if (fullUser != null && + fullUser.getUserType().equalsIgnoreCase("ADMINISTRATOR")) { + + ProductDAO dao = new ProductDAO(); + List lowStock = dao.getLowStockProducts(); + + if (lowStock != null && !lowStock.isEmpty()) { + alertPanel.setVisible(true); + + StringBuilder msg = new StringBuilder(""); + msg.append("LOW STOCK ALERT

"); + + for (String item : lowStock) { + msg.append("• ").append(item).append("
"); + } + + msg.append(""); + lowStockLabel.setText(msg.toString()); + } else { + alertPanel.setVisible(false); + } + + // Load data for summary card if it exists + if (summaryCard != null) { + loadDailySummary(); + } + } else { + alertPanel.setVisible(false); + if (summaryCard != null) summaryCard.setVisible(false); + } + } catch (Exception e) { + e.printStackTrace(); + alertPanel.setVisible(false); + } + } + + private void initComponents() { + setLayout(new BorderLayout()); + setBackground(new Color(245, 245, 250)); + + // Main scroll pane for entire content + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBorder(null); + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.getVerticalScrollBar().setUnitIncrement(20); + + // Set a reasonable preferred size for the scroll pane + scrollPane.setPreferredSize(new Dimension(1000, 700)); + + // Main content panel - Must implement Scrollable to track viewport width + // This will now ONLY hold the scrollable content (Hero, Features, Logos) + JPanel scrollableContent = new ScrollablePanel(); + scrollableContent.setLayout(new BoxLayout(scrollableContent, BoxLayout.Y_AXIS)); + scrollableContent.setBackground(new Color(245, 245, 250)); + + // Top Section (Hero only) with Background Image + JPanel topSection = createTopSection(scrollPane); + scrollableContent.add(topSection); + + // Add spacing between sections + scrollableContent.add(Box.createVerticalStrut(30)); + + // Features Section (Below Background) + JPanel featuresPanel = createFeaturesSection(); + // Wrap in a container to constrain width to 1400px (Wider) and center it + JPanel featuresContainer = new JPanel(); + featuresContainer.setLayout(new BoxLayout(featuresContainer, BoxLayout.Y_AXIS)); + featuresContainer.setOpaque(false); + featuresContainer.setMaximumSize(new Dimension(1400, 1000)); // Increased width for "horizontally big" look + featuresContainer.add(featuresPanel); + featuresContainer.setAlignmentX(Component.CENTER_ALIGNMENT); + scrollableContent.add(featuresContainer); + + // Add spacing + scrollableContent.add(Box.createVerticalStrut(30)); + + // Daily Summary Section (Below Features) + if (summaryCard != null) { + JPanel summaryContainer = new JPanel(); + summaryContainer.setLayout(new BoxLayout(summaryContainer, BoxLayout.Y_AXIS)); + summaryContainer.setOpaque(false); + summaryContainer.setMaximumSize(new Dimension(1000, 300)); + summaryContainer.add(summaryCard); + summaryContainer.setAlignmentX(Component.CENTER_ALIGNMENT); + scrollableContent.add(summaryContainer); + scrollableContent.add(Box.createVerticalStrut(30)); + } + + // Company Logos Section + JPanel logosPanel = createLogosSection(); + scrollableContent.add(logosPanel); + + // Add spacing at bottom of scrollable content so it doesn't look cramped against footer + scrollableContent.add(Box.createVerticalStrut(30)); + + // Footer Section - Created here but added to MAIN layout, not scroll pane + JPanel footerPanel = createFooterSection(); + + // Set the scrollable content as the viewport view + scrollPane.setViewportView(scrollableContent); + + // Add ScrollPane to Center (takes all remaining space) + add(scrollPane, BorderLayout.CENTER); + + // Add Footer to South (Fixed at bottom) + add(footerPanel, BorderLayout.SOUTH); + + // Initialize alert components + welcomeLabel = new JLabel(); + lowStockLabel = new JLabel(); + alertPanel = new JPanel(); + } + + // Custom panel that forces width to match viewport (fixes background stretch) + private class ScrollablePanel extends JPanel implements Scrollable { + @Override + public Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + @Override + public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) { + return 20; + } + + @Override + public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) { + return 100; + } + + @Override + public boolean getScrollableTracksViewportWidth() { + return true; // Force full width + } + + @Override + public boolean getScrollableTracksViewportHeight() { + return false; + } + } + + // Wrapper panel for Hero and Features to share the background image + private JPanel createTopSection(JScrollPane scrollPane) { + JPanel topPanel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + // Load and draw background image + java.net.URL imgURL = getClass().getResource("/com/inventory/UI/Icons/warehouse_bg.png"); + if (imgURL != null) { + ImageIcon icon = new ImageIcon(imgURL); + Image img = icon.getImage(); + g.drawImage(img, 0, 0, getWidth(), getHeight(), this); + + // Semi-transparent overlay + g.setColor(new Color(255, 255, 255, 100)); + g.fillRect(0, 0, getWidth(), getHeight()); + } + } + }; + // Use GridBagLayout to center the content wrapper within the full-width background + topPanel.setLayout(new GridBagLayout()); + + // Initial height - use screen height as fallback + int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height; + int initialHeight = screenHeight - 100; + + topPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, initialHeight)); + topPanel.setMinimumSize(new Dimension(800, 600)); // Minimum reasonable height + topPanel.setMaximumSize(new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE)); + + // Dynamic resizing to match viewport height (100vh) + if (scrollPane != null) { + scrollPane.getViewport().addComponentListener(new java.awt.event.ComponentAdapter() { + @Override + public void componentResized(java.awt.event.ComponentEvent e) { + int viewportHeight = scrollPane.getViewport().getHeight(); + if (viewportHeight > 0) { + topPanel.setPreferredSize(new Dimension(Integer.MAX_VALUE, viewportHeight)); + topPanel.revalidate(); + } + } + }); + } + + // Content Wrapper to constrain width for laptop screens + JPanel contentWrapper = new JPanel(); + contentWrapper.setLayout(new BoxLayout(contentWrapper, BoxLayout.Y_AXIS)); + contentWrapper.setOpaque(false); + + // Add Hero to wrapper + JPanel hero = createHeroSection(); + hero.setAlignmentX(Component.CENTER_ALIGNMENT); + contentWrapper.add(hero); + + // Add wrapper to topPanel with GridBagConstraints for proper centering + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.anchor = GridBagConstraints.CENTER; + topPanel.add(contentWrapper, gbc); + + return topPanel; + } + + private JPanel createHeroSection() { + JPanel hero = new JPanel(); + hero.setLayout(new GridBagLayout()); // Use GridBagLayout for precise centering + hero.setOpaque(false); // Make transparent to show background + + // Container for welcome message and subtitle + JPanel contentPanel = new JPanel(); + contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS)); + contentPanel.setOpaque(false); + + // Welcome Label + welcomeLabel = new JLabel("Welcome to Inventory Management System"); + welcomeLabel.setFont(new Font("Segoe UI", Font.BOLD, 32)); + welcomeLabel.setForeground(StyleConstants.PRIMARY_COLOR); + welcomeLabel.setForeground(StyleConstants.PRIMARY_COLOR); + welcomeLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + + // Daily Summary Card - Added here for visibility + summaryCard = createDailySummaryCard(); + summaryCard.setAlignmentX(Component.CENTER_ALIGNMENT); + + // Subtitle - directly below welcome message + JLabel subtitle = new JLabel("
Streamline your stock tracking, product listing, supplier management,
and real-time inventory updates all in one powerful platform.
"); + subtitle.setFont(StyleConstants.SUBHEADER_FONT); + subtitle.setForeground(new Color(50, 50, 50)); + subtitle.setAlignmentX(Component.CENTER_ALIGNMENT); + + // Alert Panel for low stock + alertPanel = new JPanel(); + alertPanel.setBackground(new Color(255, 243, 224)); + alertPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(255, 152, 0), 2), + new EmptyBorder(10, 10, 10, 10) + )); + alertPanel.setLayout(new BorderLayout()); + alertPanel.setVisible(false); + alertPanel.setMaximumSize(new Dimension(500, 150)); + alertPanel.setAlignmentX(Component.CENTER_ALIGNMENT); + + lowStockLabel = new JLabel(); + lowStockLabel.setFont(new Font("Segoe UI", Font.PLAIN, 12)); + lowStockLabel.setForeground(new Color(120, 0, 0)); + lowStockLabel.setVerticalAlignment(SwingConstants.TOP); + alertPanel.add(lowStockLabel, BorderLayout.CENTER); + + // Add components to content panel + contentPanel.add(welcomeLabel); + contentPanel.add(Box.createVerticalStrut(15)); + contentPanel.add(subtitle); + contentPanel.add(Box.createVerticalStrut(20)); + contentPanel.add(alertPanel); + + // Center the content panel in the hero using GridBagLayout + GridBagConstraints gbc = new GridBagConstraints(); + gbc.gridx = 0; + gbc.gridy = 0; + gbc.weightx = 1.0; + gbc.weighty = 1.0; + gbc.anchor = GridBagConstraints.CENTER; + hero.add(contentPanel, gbc); + + return hero; + } + + private JPanel createFeaturesSection() { + JPanel section = new JPanel(); + section.setLayout(new BorderLayout()); + section.setOpaque(false); // Make transparent to show background + section.setBorder(new EmptyBorder(10, 20, 40, 20)); // Reduced padding + + JLabel title = new JLabel("Key Features"); + title.setFont(new Font("Segoe UI", Font.BOLD, 28)); + title.setForeground(new Color(50, 50, 50)); + title.setHorizontalAlignment(SwingConstants.CENTER); + title.setBorder(new EmptyBorder(0, 0, 30, 0)); + + // Reduced gap from 20 to 15 to fit better + JPanel cardsPanel = new JPanel(new GridLayout(2, 3, 25, 25)); // Increased gap + cardsPanel.setOpaque(false); // Make transparent + cardsPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + + // Feature cards with Icons - Using Unicode Escapes to avoid encoding issues + cardsPanel.add(createFeatureCard("Product Management", "Efficiently manage your product catalog with detailed tracking and categorization.", "\uD83D\uDCE6", new Color(66, 133, 244))); // Package + cardsPanel.add(createFeatureCard("Supplier Management", "Maintain comprehensive supplier information and streamline procurement processes.", "\uD83D\uDE9A", new Color(52, 168, 83))); // Truck + cardsPanel.add(createFeatureCard("Stock Alerts", "Real-time notifications for low stock levels to prevent inventory shortages.", "\uD83D\uDD14", new Color(234, 67, 53))); // Bell + cardsPanel.add(createFeatureCard("Category Management", "Organize products into categories for better inventory organization.", "\uD83C\uDFF7", new Color(251, 188, 5))); // Tag + cardsPanel.add(createFeatureCard("Sales Tracking", "Monitor sales transactions and generate detailed sales reports.", "\uD83D\uDCC8", new Color(156, 39, 176))); // Chart + cardsPanel.add(createFeatureCard("Purchase Tracking", "Track all purchase orders and maintain accurate inventory records.", "\uD83D\uDED2", new Color(255, 109, 0))); // Cart + + section.add(title, BorderLayout.NORTH); + section.add(cardsPanel, BorderLayout.CENTER); + + return section; + } + + private JPanel createFeatureCard(String title, String description, String iconSymbol, Color accentColor) { + JPanel card = new JPanel(); + card.setLayout(new BorderLayout(15, 10)); // Gap between icon and text + card.setBackground(new Color(255, 255, 255, 245)); // High opacity + + // Stylish Left Border Accent + card.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 5, 0, 0, accentColor), // Left accent border + BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(230, 230, 230), 1), + new EmptyBorder(25, 20, 25, 20) + ) + )); + + // Icon Label + JLabel iconLabel = new JLabel(iconSymbol); + iconLabel.setFont(new Font("Segoe UI Emoji", Font.PLAIN, 36)); + iconLabel.setForeground(accentColor); // Match accent color + iconLabel.setHorizontalAlignment(SwingConstants.CENTER); + iconLabel.setVerticalAlignment(SwingConstants.TOP); + + // Text Panel + JPanel textPanel = new JPanel(); + textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS)); + textPanel.setOpaque(false); + + JLabel titleLabel = new JLabel(title); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 18)); + titleLabel.setForeground(new Color(40, 40, 40)); + titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT); + + JLabel descLabel = new JLabel("" + description + ""); + descLabel.setFont(new Font("Segoe UI", Font.PLAIN, 13)); + descLabel.setForeground(new Color(100, 100, 100)); + descLabel.setAlignmentX(Component.LEFT_ALIGNMENT); + + textPanel.add(titleLabel); + textPanel.add(Box.createVerticalStrut(8)); + textPanel.add(descLabel); + + card.add(iconLabel, BorderLayout.WEST); + card.add(textPanel, BorderLayout.CENTER); + + // Add hover effect + card.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + card.setBackground(new Color(255, 255, 255)); + // Thicker accent on hover + card.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 8, 0, 0, accentColor), + BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(220, 220, 220), 1), + new EmptyBorder(25, 17, 25, 20) // Adjust padding to keep content stable + ) + )); + card.setCursor(new Cursor(Cursor.HAND_CURSOR)); + } + + @Override + public void mouseExited(MouseEvent e) { + card.setBackground(new Color(255, 255, 255, 245)); + card.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 5, 0, 0, accentColor), + BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(230, 230, 230), 1), + new EmptyBorder(25, 20, 25, 20) + ) + )); + } + }); + + return card; + } + + private JPanel createLogosSection() { + JPanel section = new JPanel(); + section.setLayout(new BorderLayout()); + section.setBackground(Color.WHITE); + section.setBorder(new EmptyBorder(50, 0, 50, 0)); + + JLabel title = new JLabel("Our Trusted Suppliers"); + title.setFont(new Font("Segoe UI", Font.BOLD, 24)); + title.setForeground(new Color(50, 50, 50)); + title.setHorizontalAlignment(SwingConstants.CENTER); + title.setBorder(new EmptyBorder(0, 0, 30, 0)); + + // Add all requested suppliers - TRIPLED for smooth scrolling loop + String[] suppliers = { + "Dell", "HP", "Samsung", "Apple", "Shelby", "Hewlett-Packard", "iWorld", + "Dell", "HP", "Samsung", "Apple", "Shelby", "Hewlett-Packard", "iWorld", + "Dell", "HP", "Samsung", "Apple", "Shelby", "Hewlett-Packard", "iWorld" + }; + + JPanel logosContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 30, 10)); + logosContainer.setBackground(Color.WHITE); + + for (String supplier : suppliers) { + logosContainer.add(createLogoPlaceholder(supplier)); + } + + JScrollPane scrollPane = new JScrollPane(logosContainer); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); // Hide scrollbar + scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + scrollPane.setBorder(null); + scrollPane.setBackground(Color.WHITE); + + // Auto-scrolling Timer + Timer scrollTimer = new Timer(40, e -> { + JScrollBar horizontal = scrollPane.getHorizontalScrollBar(); + if (horizontal != null) { + int max = horizontal.getMaximum(); + int val = horizontal.getValue(); + int extent = horizontal.getModel().getExtent(); + + // Only scroll if there is content to scroll + if (max > extent) { + if (val + extent >= max) { + horizontal.setValue(0); // Reset to start for loop effect + } else { + horizontal.setValue(val + 1); // Scroll right + } + } + } + }); + scrollTimer.start(); + + section.add(title, BorderLayout.NORTH); + section.add(scrollPane, BorderLayout.CENTER); + + return section; + } + + private JPanel createLogoPlaceholder(String name) { + JPanel logoPanel = new JPanel(); + logoPanel.setLayout(new BorderLayout()); + logoPanel.setBackground(new Color(250, 250, 250)); + logoPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(230, 230, 230), 1), + new EmptyBorder(10, 10, 10, 10) + )); + logoPanel.setPreferredSize(new Dimension(150, 100)); + + // Add hover effect + logoPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + logoPanel.setBackground(new Color(240, 245, 255)); + logoPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(StyleConstants.PRIMARY_COLOR, 2), + new EmptyBorder(10, 10, 10, 10) + )); + } + + @Override + public void mouseExited(MouseEvent e) { + logoPanel.setBackground(new Color(250, 250, 250)); + logoPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(230, 230, 230), 1), + new EmptyBorder(10, 10, 10, 10) + )); + } + }); + + // Try to load image + JLabel contentLabel; + String imagePath = "/com/inventory/UI/SupplierLogos/" + name.toLowerCase().replace(" ", "") + ".png"; + java.net.URL imgURL = getClass().getResource(imagePath); + + if (imgURL != null) { + ImageIcon icon = new ImageIcon(imgURL); + // Scale image to fit + Image img = icon.getImage(); + Image newImg = img.getScaledInstance(130, 80, Image.SCALE_SMOOTH); + contentLabel = new JLabel(new ImageIcon(newImg)); + } else { + // Fallback to text + contentLabel = new JLabel(name, SwingConstants.CENTER); + contentLabel.setFont(new Font("Segoe UI", Font.BOLD, 14)); + contentLabel.setForeground(new Color(100, 100, 100)); + } + + logoPanel.add(contentLabel, BorderLayout.CENTER); + + return logoPanel; + } + + private JPanel createFooterSection() { + JPanel footer = new JPanel(); + footer.setLayout(new GridLayout(1, 3, 40, 0)); // 3 Columns + footer.setBackground(Color.BLACK); // Pure black background + footer.setBorder(new EmptyBorder(50, 50, 50, 50)); + + // Column 1: About Us + JPanel aboutPanel = new JPanel(); + aboutPanel.setLayout(new BoxLayout(aboutPanel, BoxLayout.Y_AXIS)); + aboutPanel.setBackground(Color.BLACK); + + JLabel aboutTitle = new JLabel("Inventory System"); + aboutTitle.setFont(new Font("Segoe UI", Font.BOLD, 20)); + aboutTitle.setForeground(Color.WHITE); + aboutTitle.setAlignmentX(Component.LEFT_ALIGNMENT); + + JLabel aboutText = new JLabel("
Empowering businesses with seamless inventory tracking, supplier management, and real-time analytics.
"); + aboutText.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + aboutText.setAlignmentX(Component.LEFT_ALIGNMENT); + + aboutPanel.add(aboutTitle); + aboutPanel.add(Box.createVerticalStrut(15)); + aboutPanel.add(aboutText); + + // Column 2: Contact Info + JPanel contactPanel = new JPanel(); + contactPanel.setLayout(new BoxLayout(contactPanel, BoxLayout.Y_AXIS)); + contactPanel.setBackground(Color.BLACK); + + JLabel contactTitle = new JLabel("Contact Us"); + contactTitle.setFont(new Font("Segoe UI", Font.BOLD, 20)); + contactTitle.setForeground(Color.WHITE); + contactTitle.setAlignmentX(Component.LEFT_ALIGNMENT); + + // Using Unicode icons for contact info + JLabel phone = createFooterLabel("\uD83D\uDCDE +1 (555) 123-4567"); + JLabel email = createFooterLabel("\u2709\uFE0F info@inventoryms.com"); + JLabel address = createFooterLabel("\uD83D\uDCCD 123 Business St, Suite 100, NY"); + + contactPanel.add(contactTitle); + contactPanel.add(Box.createVerticalStrut(15)); + contactPanel.add(phone); + contactPanel.add(Box.createVerticalStrut(10)); + contactPanel.add(email); + contactPanel.add(Box.createVerticalStrut(10)); + contactPanel.add(address); + + // Column 3: Social Media + JPanel socialPanel = new JPanel(); + socialPanel.setLayout(new BoxLayout(socialPanel, BoxLayout.Y_AXIS)); + socialPanel.setBackground(Color.BLACK); + + JLabel socialTitle = new JLabel("Stay Connected"); + socialTitle.setFont(new Font("Segoe UI", Font.BOLD, 20)); + socialTitle.setForeground(Color.WHITE); + socialTitle.setAlignmentX(Component.LEFT_ALIGNMENT); + + JPanel socialLinks = new JPanel(new FlowLayout(FlowLayout.LEFT, 10, 10)); + socialLinks.setBackground(Color.BLACK); + socialLinks.setMaximumSize(new Dimension(300, 100)); + socialLinks.setAlignmentX(Component.LEFT_ALIGNMENT); + + // Brand Colors + socialLinks.add(createSocialButton("Facebook", new Color(24, 119, 242))); + socialLinks.add(createSocialButton("Twitter", new Color(20, 23, 26))); // Dark gray for X + socialLinks.add(createSocialButton("Instagram", new Color(225, 48, 108))); + socialLinks.add(createSocialButton("LinkedIn", new Color(10, 102, 194))); + + socialPanel.add(socialTitle); + socialPanel.add(Box.createVerticalStrut(15)); + socialPanel.add(socialLinks); + + footer.add(aboutPanel); + footer.add(contactPanel); + footer.add(socialPanel); + + return footer; + } + + private JLabel createFooterLabel(String text) { + JLabel label = new JLabel(text); + label.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + label.setForeground(new Color(200, 200, 200)); + label.setAlignmentX(Component.LEFT_ALIGNMENT); + return label; + } + + private JButton createSocialButton(String platform, Color brandColor) { + JButton button = new JButton(platform) { + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g.create(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + if (getModel().isRollover()) { + g2.setColor(brandColor.brighter()); + } else { + g2.setColor(brandColor); + } + g2.fillRoundRect(0, 0, getWidth(), getHeight(), 10, 10); + g2.dispose(); + super.paintComponent(g); + } + }; + button.setFont(new Font("Segoe UI", Font.BOLD, 12)); + button.setForeground(Color.WHITE); + button.setFocusPainted(false); + button.setBorderPainted(false); + button.setContentAreaFilled(false); // Important for custom painting + button.setCursor(new Cursor(Cursor.HAND_CURSOR)); + button.setPreferredSize(new Dimension(100, 35)); + return button; + } + + + // ========================================== + // DAILY SUMMARY METHODS + // ========================================== + + public void loadDailySummary() { + try { + ReportDAO reportDAO = new ReportDAO(); + ReportDAO.DailySummary summary = reportDAO.getDailySummary(); + System.out.println("DEBUG: Daily Summary Loaded"); + System.out.println("DEBUG: Low Stock: " + summary.getLowStockCount()); + System.out.println("DEBUG: Pending Deliveries: " + summary.getPendingDeliveriesCount()); + System.out.println("DEBUG: New Deliveries: " + summary.getTodayDeliveriesCount()); + System.out.println("DEBUG: New Consignments: " + summary.getNewConsignmentsCount()); + + if (lowStockCountLabel != null) lowStockCountLabel.setText(String.valueOf(summary.getLowStockCount())); + if (pendingDeliveriesCountLabel != null) pendingDeliveriesCountLabel.setText(String.valueOf(summary.getPendingDeliveriesCount())); + if (newDeliveriesCountLabel != null) newDeliveriesCountLabel.setText(String.valueOf(summary.getTodayDeliveriesCount())); + if (newConsignmentsCountLabel != null) newConsignmentsCountLabel.setText(String.valueOf(summary.getNewConsignmentsCount())); + + if (summaryCard != null) summaryCard.setVisible(true); + } catch (Exception e) { + System.err.println("Error loading daily summary: " + e.getMessage()); + e.printStackTrace(); + } + } + + // Create Daily Summary Card - HIGHLY VISIBLE VERSION + private JPanel createDailySummaryCard() { + JPanel card = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); + int w = getWidth(); + int h = getHeight(); + GradientPaint gp = new GradientPaint(0, 0, new Color(51, 102, 255), w, 0, new Color(0, 153, 204)); + g2d.setPaint(gp); + g2d.fillRect(0, 0, w, h); + } + }; + card.setLayout(new BorderLayout()); + card.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(51, 102, 255), 3), + new EmptyBorder(25, 30, 25, 30) + )); + card.setMaximumSize(new Dimension(800, 220)); + card.setAlignmentX(Component.CENTER_ALIGNMENT); + card.setOpaque(false); + + // Title + JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 8, 0)); + titlePanel.setOpaque(false); + + JLabel iconLabel = new JLabel("\uD83D\uDCCA"); // 📊 + iconLabel.setFont(new Font("Segoe UI", Font.PLAIN, 24)); + iconLabel.setForeground(Color.WHITE); + + JLabel titleLabel = new JLabel("DAILY SUMMARY"); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 22)); + titleLabel.setForeground(Color.WHITE); + + JLabel refreshIcon = new JLabel("\uD83D\uDD04"); // 🔄 + refreshIcon.setFont(new Font("Segoe UI", Font.PLAIN, 18)); + refreshIcon.setForeground(Color.WHITE); + refreshIcon.setCursor(new Cursor(Cursor.HAND_CURSOR)); + refreshIcon.setToolTipText("Refresh Summary"); + refreshIcon.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + loadDailySummary(); + } + }); + + titlePanel.add(iconLabel); + titlePanel.add(titleLabel); + titlePanel.add(refreshIcon); + + // Stats Panel + JPanel statsPanel = new JPanel(new GridLayout(1, 4, 15, 0)); + statsPanel.setOpaque(false); + statsPanel.setBorder(new EmptyBorder(20, 0, 20, 0)); + + // Low Stock Stat + lowStockCountLabel = new JLabel("0", SwingConstants.CENTER); + lowStockCountLabel.setForeground(Color.WHITE); + JPanel lowStockPanel = createStatPanelBright("\u26A0 Low Stock Items", lowStockCountLabel, Color.YELLOW); + + // Pending Deliveries Stat + pendingDeliveriesCountLabel = new JLabel("0", SwingConstants.CENTER); + pendingDeliveriesCountLabel.setForeground(Color.WHITE); + JPanel pendingPanel = createStatPanelBright("\uD83D\uDE9A Pending Deliveries", pendingDeliveriesCountLabel, new Color(255, 215, 0)); + + // New Deliveries Stat + newDeliveriesCountLabel = new JLabel("0", SwingConstants.CENTER); + newDeliveriesCountLabel.setForeground(Color.WHITE); + JPanel newDeliveriesPanel = createStatPanelBright("\uD83D\uDCE6 New Deliveries", newDeliveriesCountLabel, new Color(0, 255, 255)); + + // New Consignments Stat + newConsignmentsCountLabel = new JLabel("0", SwingConstants.CENTER); + newConsignmentsCountLabel.setForeground(Color.WHITE); + JPanel consignmentsPanel = createStatPanelBright("\uD83D\uDCE6 New Consignments", newConsignmentsCountLabel, new Color(144, 238, 144)); + + statsPanel.add(lowStockPanel); + statsPanel.add(pendingPanel); + statsPanel.add(newDeliveriesPanel); + statsPanel.add(consignmentsPanel); + + // View Details Button + JButton viewDetailsButton = new JButton("View Details"); + viewDetailsButton.setFont(new Font("Segoe UI", Font.BOLD, 14)); + viewDetailsButton.setBackground(Color.WHITE); + viewDetailsButton.setForeground(StyleConstants.PRIMARY_COLOR); + viewDetailsButton.setFocusPainted(false); + viewDetailsButton.setBorderPainted(false); + viewDetailsButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); + viewDetailsButton.setPreferredSize(new Dimension(150, 40)); + + // Add hover effect + viewDetailsButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + viewDetailsButton.setBackground(new Color(240, 240, 240)); + } + + @Override + public void mouseExited(MouseEvent e) { + viewDetailsButton.setBackground(Color.WHITE); + } + }); + + viewDetailsButton.addActionListener(e -> showDetailsDialog()); + + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + buttonPanel.setOpaque(false); + buttonPanel.add(viewDetailsButton); + + card.add(titlePanel, BorderLayout.NORTH); + card.add(statsPanel, BorderLayout.CENTER); + card.add(buttonPanel, BorderLayout.SOUTH); + + return card; + } + + private JPanel createStatPanelBright(String label, JLabel countLabel, Color accentColor) { + JPanel panel = new JPanel(); + panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); + panel.setOpaque(false); + + JLabel titleLabel = new JLabel(label); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 14)); + titleLabel.setForeground(accentColor); + titleLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + + countLabel.setFont(new Font("Segoe UI", Font.BOLD, 36)); + countLabel.setForeground(Color.WHITE); + countLabel.setAlignmentX(Component.CENTER_ALIGNMENT); + + panel.add(titleLabel); + panel.add(Box.createVerticalStrut(10)); + panel.add(countLabel); + + return panel; + } + + // Show daily summary popup dialog on login + private void showDailySummaryPopup() { + try { + ReportDAO reportDAO = new ReportDAO(); + ReportDAO.DailySummary summary = reportDAO.getDailySummary(); + + // Create dialog + JDialog dialog = new JDialog((Frame) SwingUtilities.getWindowAncestor(this), "Daily Summary", true); + dialog.setLayout(new BorderLayout(10, 10)); + dialog.setSize(500, 400); + dialog.setLocationRelativeTo(this); + + // Header panel + JPanel headerPanel = new JPanel(); + headerPanel.setBackground(StyleConstants.PRIMARY_COLOR); + headerPanel.setBorder(new EmptyBorder(20, 20, 20, 20)); + + JLabel titleLabel = new JLabel("\uD83D\uDCCA Daily Summary"); + titleLabel.setFont(new Font("Segoe UI", Font.BOLD, 24)); + titleLabel.setForeground(Color.WHITE); + headerPanel.add(titleLabel); + + // Content panel with stats + JPanel contentPanel = new JPanel(); + contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.Y_AXIS)); + contentPanel.setBackground(Color.WHITE); + contentPanel.setBorder(new EmptyBorder(30, 40, 30, 40)); + + // Low Stock + JPanel lowStockPanel = createSummaryRow( + "\u26A0 Low Stock Items", + String.valueOf(summary.getLowStockCount()), + new Color(220, 53, 69) + ); + + // Pending Deliveries + JPanel pendingPanel = createSummaryRow( + "\uD83D\uDE9A Pending Deliveries", + String.valueOf(summary.getPendingDeliveriesCount()), + new Color(255, 193, 7) + ); + + // New Consignments + JPanel consignmentsPanel = createSummaryRow( + "\uD83D\uDCE6 New Consignments Today", + String.valueOf(summary.getNewConsignmentsCount()), + new Color(40, 167, 69) + ); + + contentPanel.add(lowStockPanel); + contentPanel.add(Box.createVerticalStrut(20)); + contentPanel.add(pendingPanel); + contentPanel.add(Box.createVerticalStrut(20)); + contentPanel.add(consignmentsPanel); + + // Button panel + JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 10, 10)); + buttonPanel.setBorder(new EmptyBorder(10, 10, 20, 10)); + + JButton viewDetailsButton = new JButton("View Full Details"); + viewDetailsButton.setFont(new Font("Segoe UI", Font.BOLD, 13)); + viewDetailsButton.setBackground(StyleConstants.PRIMARY_COLOR); + viewDetailsButton.setForeground(Color.WHITE); + viewDetailsButton.setFocusPainted(false); + viewDetailsButton.setBorderPainted(false); + viewDetailsButton.setPreferredSize(new Dimension(150, 38)); + viewDetailsButton.addActionListener(e -> { + dialog.dispose(); + showDetailsDialog(); + }); + + JButton closeButton = new JButton("Close"); + closeButton.setFont(new Font("Segoe UI", Font.PLAIN, 13)); + closeButton.setBackground(new Color(108, 117, 125)); + closeButton.setForeground(Color.WHITE); + closeButton.setFocusPainted(false); + closeButton.setBorderPainted(false); + closeButton.setPreferredSize(new Dimension(100, 38)); + closeButton.addActionListener(e -> dialog.dispose()); + + buttonPanel.add(viewDetailsButton); + buttonPanel.add(closeButton); + + dialog.add(headerPanel, BorderLayout.NORTH); + dialog.add(contentPanel, BorderLayout.CENTER); + dialog.add(buttonPanel, BorderLayout.SOUTH); + + dialog.setVisible(true); + + } catch (Exception e) { + System.err.println("Error showing daily summary popup: " + e.getMessage()); + e.printStackTrace(); + } + } + + private JPanel createSummaryRow(String label, String count, Color color) { + JPanel panel = new JPanel(new BorderLayout(15, 0)); + panel.setBackground(Color.WHITE); + panel.setMaximumSize(new Dimension(Integer.MAX_VALUE, 60)); + panel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(new Color(230, 230, 230), 1), + new EmptyBorder(15, 20, 15, 20) + )); + + JLabel labelText = new JLabel(label); + labelText.setFont(new Font("Segoe UI", Font.PLAIN, 16)); + labelText.setForeground(new Color(50, 50, 50)); + + JLabel countText = new JLabel(count); + countText.setFont(new Font("Segoe UI", Font.BOLD, 28)); + countText.setForeground(color); + + panel.add(labelText, BorderLayout.WEST); + panel.add(countText, BorderLayout.EAST); + + return panel; + } + + private void showDetailsDialog() { + JDialog dialog = new JDialog((Frame) SwingUtilities.getWindowAncestor(this), "Daily Summary Details", true); + dialog.setLayout(new BorderLayout()); + dialog.setSize(600, 500); + dialog.setLocationRelativeTo(this); + + JTabbedPane tabbedPane = new JTabbedPane(); + tabbedPane.setFont(new Font("Segoe UI", Font.PLAIN, 14)); + + // Low Stock Tab + JPanel lowStockPanel = new JPanel(new BorderLayout()); + JTextArea lowStockText = new JTextArea(); + lowStockText.setEditable(false); + lowStockText.setFont(new Font("Monospaced", Font.PLAIN, 14)); + try { + ProductDAO dao = new ProductDAO(); + List items = dao.getLowStockProducts(); + StringBuilder sb = new StringBuilder(); + for (String item : items) sb.append(item).append("\n"); + lowStockText.setText(sb.toString()); + } catch (Exception e) { lowStockText.setText("Error loading data"); } + lowStockPanel.add(new JScrollPane(lowStockText), BorderLayout.CENTER); + tabbedPane.addTab("Low Stock", lowStockPanel); + + // Pending Deliveries Tab + JPanel deliveriesPanel = new JPanel(new BorderLayout()); + JTextArea deliveriesText = new JTextArea(); + deliveriesText.setEditable(false); + deliveriesText.setFont(new Font("Monospaced", Font.PLAIN, 14)); + try { + DeliveryDAO dao = new DeliveryDAO(); + List items = dao.getPendingDeliveriesList(); + if (items.isEmpty()) { + deliveriesText.setText("No pending deliveries."); + } else { + StringBuilder sb = new StringBuilder(); + for (String item : items) sb.append(item).append("\n\n"); + deliveriesText.setText(sb.toString()); + } + } catch (Exception e) { deliveriesText.setText("Error loading data: " + e.getMessage()); } + deliveriesPanel.add(new JScrollPane(deliveriesText), BorderLayout.CENTER); + deliveriesPanel.add(new JScrollPane(deliveriesText), BorderLayout.CENTER); + tabbedPane.addTab("Pending Deliveries", deliveriesPanel); + + // New Deliveries Tab (Today) + JPanel newDeliveriesPanel = new JPanel(new BorderLayout()); + JTextArea newDeliveriesText = new JTextArea(); + newDeliveriesText.setEditable(false); + newDeliveriesText.setFont(new Font("Monospaced", Font.PLAIN, 14)); + // Reuse getPendingDeliveriesList logic but filter for today? + // Or just show "See Pending Deliveries for details" since new deliveries are a subset. + // For now, let's just list all pending as that's what the user cares about most. + newDeliveriesText.setText("Please refer to Pending Deliveries tab for full details.\n\nThis tab tracks deliveries assigned specifically today."); + newDeliveriesPanel.add(new JScrollPane(newDeliveriesText), BorderLayout.CENTER); + tabbedPane.addTab("New Deliveries", newDeliveriesPanel); + + // New Consignments Tab + JPanel consignmentsPanel = new JPanel(new BorderLayout()); + JTextArea consignmentsText = new JTextArea(); + consignmentsText.setEditable(false); + consignmentsText.setFont(new Font("Monospaced", Font.PLAIN, 14)); + try { + ReportDAO dao = new ReportDAO(); + List items = dao.getTodayConsignmentsList(); + if (items.isEmpty()) { + consignmentsText.setText("No new consignments today."); + } else { + StringBuilder sb = new StringBuilder(); + for (String item : items) sb.append(item).append("\n\n"); + consignmentsText.setText(sb.toString()); + } + } catch (Exception e) { consignmentsText.setText("Error loading data: " + e.getMessage()); } + consignmentsPanel.add(new JScrollPane(consignmentsText), BorderLayout.CENTER); + tabbedPane.addTab("New Consignments", consignmentsPanel); + + dialog.add(tabbedPane, BorderLayout.CENTER); + + JButton closeButton = new JButton("Close"); + closeButton.addActionListener(e -> dialog.dispose()); + JPanel btnPanel = new JPanel(); + btnPanel.add(closeButton); + dialog.add(btnPanel, BorderLayout.SOUTH); + + dialog.setVisible(true); + } +} diff --git a/src/com/inventory/UI/Icons/warehouse_bg.png b/src/com/inventory/UI/Icons/warehouse_bg.png new file mode 100644 index 0000000..210e8cd Binary files /dev/null and b/src/com/inventory/UI/Icons/warehouse_bg.png differ diff --git a/src/com/inventory/UI/LoginPage$1.class b/src/com/inventory/UI/LoginPage$1.class new file mode 100644 index 0000000..fe35d15 Binary files /dev/null and b/src/com/inventory/UI/LoginPage$1.class differ diff --git a/src/com/inventory/UI/LoginPage$2.class b/src/com/inventory/UI/LoginPage$2.class new file mode 100644 index 0000000..9d39bf6 Binary files /dev/null and b/src/com/inventory/UI/LoginPage$2.class differ diff --git a/src/com/inventory/UI/LoginPage$3.class b/src/com/inventory/UI/LoginPage$3.class new file mode 100644 index 0000000..37fcc57 Binary files /dev/null and b/src/com/inventory/UI/LoginPage$3.class differ diff --git a/src/com/inventory/UI/LoginPage$4.class b/src/com/inventory/UI/LoginPage$4.class new file mode 100644 index 0000000..6e77769 Binary files /dev/null and b/src/com/inventory/UI/LoginPage$4.class differ diff --git a/src/com/inventory/UI/LoginPage.class b/src/com/inventory/UI/LoginPage.class new file mode 100644 index 0000000..4de2a2d Binary files /dev/null and b/src/com/inventory/UI/LoginPage.class differ diff --git a/src/com/inventory/UI/LoginPage.java b/src/com/inventory/UI/LoginPage.java index 35c9f71..866fe1a 100644 --- a/src/com/inventory/UI/LoginPage.java +++ b/src/com/inventory/UI/LoginPage.java @@ -6,10 +6,11 @@ package com.inventory.UI; -import com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerIJTheme; import com.inventory.DTO.UserDTO; import com.inventory.Database.ConnectionFactory; +import java.awt.Color; + import java.math.BigInteger; import java.security.MessageDigest; import java.time.LocalDateTime; @@ -56,14 +57,14 @@ private void initComponents() { setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE); setTitle("Login"); - setBackground(new java.awt.Color(102, 102, 102)); + setBackground(StyleConstants.BACKGROUND_COLOR); setBounds(new java.awt.Rectangle(500, 100, 0, 0)); setName("loginFrame"); // NOI18N - jLabel1.setFont(new java.awt.Font("Segoe UI", 0, 14)); // NOI18N + jLabel1.setFont(StyleConstants.REGULAR_FONT); // NOI18N jLabel1.setText("Username:"); - jLabel2.setFont(new java.awt.Font("Segoe UI", 0, 14)); // NOI18N + jLabel2.setFont(StyleConstants.REGULAR_FONT); // NOI18N jLabel2.setText("Password:"); passText.addActionListener(new java.awt.event.ActionListener() { @@ -72,13 +73,17 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { } }); - jLabel3.setFont(new java.awt.Font("Poor Richard", 1, 24)); // NOI18N + jLabel3.setFont(StyleConstants.HEADER_FONT); // NOI18N + jLabel3.setForeground(StyleConstants.PRIMARY_COLOR); jLabel3.setHorizontalAlignment(javax.swing.SwingConstants.CENTER); - jLabel3.setText("STORE INVENTORY"); + jLabel3.setText("STORE INVENTORY"); jComboBox1.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "ADMINISTRATOR", "EMPLOYEE" })); loginButton.setText("LOGIN"); + loginButton.setFont(StyleConstants.BUTTON_FONT); + loginButton.setBackground(StyleConstants.PRIMARY_COLOR); + loginButton.setForeground(Color.WHITE); loginButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); loginButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -87,6 +92,7 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { }); clearButton.setText("CLEAR"); + clearButton.setFont(StyleConstants.BUTTON_FONT); clearButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); clearButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -168,21 +174,28 @@ private void loginButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F String password = passText.getText(); //TODO Password encryption to be added later: //String password = encryptPass(pass); - userType = (String)jComboBox1.getSelectedItem(); + String userType = (String)jComboBox1.getSelectedItem(); + + int userId = new ConnectionFactory().checkLogin(username, password, userType); + + if (userId != -1) { - if (new ConnectionFactory().checkLogin(username, password, userType)){ inTime = LocalDateTime.now(); + userDTO.setInTime(String.valueOf(inTime)); + // userDTO.setId(userId); + userDTO.setID(userId); + + userDTO.setUsername(username); + userDTO.setUserType(userType); + dispose(); - new Dashboard(username, userType, userDTO); + // new Dashboard(userDTO).setVisible(true); + new Dashboard(username, userType, userDTO).setVisible(true); } else { - JOptionPane.showMessageDialog( - null, - "Invalid username or password."); + JOptionPane.showMessageDialog(null, "Invalid username or password."); } - - }//GEN-LAST:event_loginButtonActionPerformed - + } private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed userText.setText(""); passText.setText(""); @@ -199,11 +212,11 @@ private void passTextActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRS public static void main(String[] args) { // setting UI theme and LookAndFeel of the application try { - javax.swing.UIManager.setLookAndFeel(new FlatMaterialDarkerIJTheme()); - } catch (UnsupportedLookAndFeelException ex) { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { Logger.getLogger(LoginPage.class.getName()).log(Level.SEVERE, null, ex); } - + /* Create and display the form */ java.awt.EventQueue.invokeLater(new Runnable() { public void run() { @@ -222,4 +235,4 @@ public void run() { private javax.swing.JPasswordField passText; private javax.swing.JTextField userText; // End of variables declaration//GEN-END:variables -} +} \ No newline at end of file diff --git a/src/com/inventory/UI/ProductPage$1.class b/src/com/inventory/UI/ProductPage$1.class new file mode 100644 index 0000000..d39497b Binary files /dev/null and b/src/com/inventory/UI/ProductPage$1.class differ diff --git a/src/com/inventory/UI/ProductPage$2.class b/src/com/inventory/UI/ProductPage$2.class new file mode 100644 index 0000000..a4a1fe5 Binary files /dev/null and b/src/com/inventory/UI/ProductPage$2.class differ diff --git a/src/com/inventory/UI/ProductPage$3.class b/src/com/inventory/UI/ProductPage$3.class new file mode 100644 index 0000000..5b619d0 Binary files /dev/null and b/src/com/inventory/UI/ProductPage$3.class differ diff --git a/src/com/inventory/UI/ProductPage$4.class b/src/com/inventory/UI/ProductPage$4.class new file mode 100644 index 0000000..e65af01 Binary files /dev/null and b/src/com/inventory/UI/ProductPage$4.class differ diff --git a/src/com/inventory/UI/ProductPage$5.class b/src/com/inventory/UI/ProductPage$5.class new file mode 100644 index 0000000..5172744 Binary files /dev/null and b/src/com/inventory/UI/ProductPage$5.class differ diff --git a/src/com/inventory/UI/ProductPage$6.class b/src/com/inventory/UI/ProductPage$6.class new file mode 100644 index 0000000..c0e1ef1 Binary files /dev/null and b/src/com/inventory/UI/ProductPage$6.class differ diff --git a/src/com/inventory/UI/ProductPage$7.class b/src/com/inventory/UI/ProductPage$7.class new file mode 100644 index 0000000..ddcedfa Binary files /dev/null and b/src/com/inventory/UI/ProductPage$7.class differ diff --git a/src/com/inventory/UI/ProductPage$8.class b/src/com/inventory/UI/ProductPage$8.class new file mode 100644 index 0000000..d75e6e8 Binary files /dev/null and b/src/com/inventory/UI/ProductPage$8.class differ diff --git a/src/com/inventory/UI/ProductPage.class b/src/com/inventory/UI/ProductPage.class new file mode 100644 index 0000000..526f53e Binary files /dev/null and b/src/com/inventory/UI/ProductPage.class differ diff --git a/src/com/inventory/UI/ProductPage.java b/src/com/inventory/UI/ProductPage.java index 160a452..6018000 100644 --- a/src/com/inventory/UI/ProductPage.java +++ b/src/com/inventory/UI/ProductPage.java @@ -48,6 +48,32 @@ public ProductPage(String username, Dashboard dashboard){ */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); // Transparent to let custom paint show + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + // Draw Shadow (optional, subtle) + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + // Draw Panel Background + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); @@ -73,247 +99,239 @@ private void initComponents() { editButton = new javax.swing.JButton(); deleteButton = new javax.swing.JButton(); clearButton = new javax.swing.JButton(); + + // Wrap Table in Rounded Panel + javax.swing.JPanel tableCard = new RoundedPanel(20); jScrollPane1 = new javax.swing.JScrollPane(); productTable = new javax.swing.JTable(); + refreshButton = new javax.swing.JButton(); searchText = new javax.swing.JTextField(); jLabel9 = new javax.swing.JLabel(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("PRODUCTS"); + setBackground(new java.awt.Color(220, 230, 250)); // Little Darker Blue BG - entryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Enter Product Details")); + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("Product Summary"); + // --- Entry Panel (Card Style) --- + entryPanel = new RoundedPanel(20); // Use RoundedPanel + // entryPanel.setBackground(new java.awt.Color(255, 255, 255)); // Handled by RoundedPanel + entryPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); // Padding only + + suppCombo.setFont(new java.awt.Font("Segoe UI", 0, 14)); suppCombo.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Select a supplier" })); - suppCombo.setToolTipText("Select a supplier"); - addSuppButton.setText("Click to add a New Supplier"); + addSuppButton.setText("+ New Supplier"); + addSuppButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + addSuppButton.setForeground(new java.awt.Color(65, 105, 225)); + addSuppButton.setContentAreaFilled(false); + addSuppButton.setBorderPainted(false); addSuppButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - addSuppButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - addSuppButtonActionPerformed(evt); - } - }); - - jLabel2.setText("Product Code:"); - - jLabel3.setText("Product Name:"); - - jLabel4.setText("Date:"); - - jLabel5.setText("Quantity:"); - - jLabel6.setText("Cost Price:"); - - jLabel7.setText("Selling Price:"); - - jLabel8.setText("Brand:"); - - jDateChooser1.setForeground(new java.awt.Color(102, 102, 102)); - - addButton.setText("Add"); - addButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - addButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - addButtonActionPerformed(evt); - } - }); - - editButton.setText("Edit"); - editButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - editButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - editButtonActionPerformed(evt); - } - }); - - deleteButton.setText("Delete"); - deleteButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - deleteButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - deleteButtonActionPerformed(evt); - } - }); - - clearButton.setFont(new java.awt.Font("Segoe UI", 0, 14)); // NOI18N - clearButton.setText("CLEAR"); - clearButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - clearButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - clearButtonActionPerformed(evt); - } - }); - + addSuppButton.addActionListener(evt -> addSuppButtonActionPerformed(evt)); + + // Labels + java.awt.Font labelFont = new java.awt.Font("Segoe UI", 1, 12); + java.awt.Color labelColor = java.awt.Color.BLACK; // Changed to BLACK for visibility + jLabel2.setFont(labelFont); jLabel2.setForeground(labelColor); jLabel2.setText("Product Code"); + jLabel3.setFont(labelFont); jLabel3.setForeground(labelColor); jLabel3.setText("Product Name"); + jLabel4.setFont(labelFont); jLabel4.setForeground(labelColor); jLabel4.setText("Date"); + jLabel5.setFont(labelFont); jLabel5.setForeground(labelColor); jLabel5.setText("Quantity"); + jLabel6.setFont(labelFont); jLabel6.setForeground(labelColor); jLabel6.setText("Cost Price"); + jLabel7.setFont(labelFont); jLabel7.setForeground(labelColor); jLabel7.setText("Selling Price"); + jLabel8.setFont(labelFont); jLabel8.setForeground(labelColor); jLabel8.setText("Brand"); + + // Text Fields + java.awt.Font textFont = new java.awt.Font("Segoe UI", 0, 14); + javax.swing.border.Border textBorder = javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + ); + codeText.setFont(textFont); codeText.setBorder(textBorder); + nameText.setFont(textFont); nameText.setBorder(textBorder); + quantityText.setFont(textFont); quantityText.setBorder(textBorder); + costText.setFont(textFont); costText.setBorder(textBorder); + sellText.setFont(textFont); sellText.setBorder(textBorder); + brandText.setFont(textFont); brandText.setBorder(textBorder); + jDateChooser1.setFont(textFont); + + // Buttons + styleButton(addButton, "Add", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + styleButton(editButton, "Edit", new java.awt.Color(255, 193, 7), java.awt.Color.BLACK); + styleButton(deleteButton, "Delete", new java.awt.Color(220, 53, 69), java.awt.Color.BLACK); + styleButton(clearButton, "Clear", new java.awt.Color(240, 240, 240), java.awt.Color.BLACK); + + addButton.addActionListener(evt -> addButtonActionPerformed(evt)); + editButton.addActionListener(evt -> editButtonActionPerformed(evt)); + deleteButton.addActionListener(evt -> deleteButtonActionPerformed(evt)); + clearButton.addActionListener(evt -> clearButtonActionPerformed(evt)); + + // Layout for Entry Panel javax.swing.GroupLayout entryPanelLayout = new javax.swing.GroupLayout(entryPanel); entryPanel.setLayout(entryPanelLayout); entryPanelLayout.setHorizontalGroup( entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(suppCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(addSuppButton, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(codeText) + .addComponent(nameText) + .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(quantityText) + .addComponent(costText) + .addComponent(sellText) + .addComponent(brandText) .addGroup(entryPanelLayout.createSequentialGroup() - .addContainerGap() .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(suppCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(addSuppButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(codeText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(nameText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(brandText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(quantityText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(costText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 84, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(sellText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(addButton) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(deleteButton, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE))) - .addContainerGap()) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4) + .addComponent(jLabel5) + .addComponent(jLabel6) + .addComponent(jLabel7) + .addComponent(jLabel8)) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(entryPanelLayout.createSequentialGroup() + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(deleteButton, javax.swing.GroupLayout.DEFAULT_SIZE, 68, Short.MAX_VALUE)) + .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); entryPanelLayout.setVerticalGroup( entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(entryPanelLayout.createSequentialGroup() - .addContainerGap() - .addComponent(suppCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(suppCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(addSuppButton, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(addSuppButton) + .addGap(15, 15, 15) + .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, 26, Short.MAX_VALUE) - .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(quantityText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jDateChooser1, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(costText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(quantityText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(sellText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(costText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel7) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(brandText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(sellText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel8) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(brandText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(20, 20, 20) .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(addButton) - .addComponent(editButton) - .addComponent(deleteButton)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(clearButton) + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); + // --- Table Styling --- productTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null} - }, - new String [] { - "Title 1", "Title 2", "Title 3", "Title 4" - } + new Object [][] {}, + new String [] { "Code", "Name", "Date", "Quantity", "Cost", "Selling", "Brand" } )); - productTable.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); - productTable.addMouseListener(new java.awt.event.MouseAdapter() { - public void mouseClicked(java.awt.event.MouseEvent evt) { - productTableMouseClicked(evt); - } - }); + productTable.setRowHeight(40); + productTable.setShowGrid(false); // Clean look + productTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + productTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + productTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); + productTable.getTableHeader().setFont(new java.awt.Font("Segoe UI", 1, 12)); + productTable.getTableHeader().setBackground(new java.awt.Color(65, 105, 225)); // Blue Header + productTable.getTableHeader().setForeground(java.awt.Color.WHITE); + productTable.getTableHeader().setOpaque(true); + jScrollPane1.setViewportView(productTable); - - refreshButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N - refreshButton.setText("REFRESH"); - refreshButton.addActionListener(new java.awt.event.ActionListener() { - public void actionPerformed(java.awt.event.ActionEvent evt) { - refreshButtonActionPerformed(evt); - } - }); - + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + // Add ScrollPane to Rounded Card + tableCard.setLayout(new java.awt.BorderLayout()); + tableCard.add(jScrollPane1, java.awt.BorderLayout.CENTER); + tableCard.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); // Padding inside card + + // Search Bar + styleButton(refreshButton, "Refresh", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + refreshButton.addActionListener(evt -> refreshButtonActionPerformed(evt)); + + searchText.setFont(new java.awt.Font("Segoe UI", 0, 14)); + searchText.setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + )); searchText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { searchTextKeyReleased(evt); } }); + jLabel9.setFont(new java.awt.Font("Segoe UI", 1, 14)); jLabel9.setText("Search:"); + // Main Layout javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 126, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel9) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 158, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(refreshButton)) - .addComponent(jSeparator1) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 496, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE) + .addGap(20, 20, 20) .addComponent(entryPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(jLabel9) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 41, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel9)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED))) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) .addComponent(entryPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addGap(64, 64, 64)) + .addComponent(tableCard)) + .addGap(20, 20, 20)) ); + } + + private void styleButton(javax.swing.JButton btn, String text, java.awt.Color bg, java.awt.Color fg) { + btn.setText(text); + btn.setBackground(bg); + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 12)); + btn.setFocusPainted(false); + btn.setBorderPainted(false); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); }// //GEN-END:initComponents private void editButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_editButtonActionPerformed @@ -432,11 +450,32 @@ public void loadComboBox() { } } + // Custom Header Renderer to force background color + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); // Light Blue + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + // Method to load data into table public void loadDataSet() { try { ProductDAO productDAO = new ProductDAO(); productTable.setModel(productDAO.buildTableModel(productDAO.getQueryResult())); + TableStyler.styleTable(productTable); + productTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException throwables) { throwables.printStackTrace(); } @@ -447,6 +486,8 @@ public void loadSearchData(String text) { try { ProductDAO productDAO = new ProductDAO(); productTable.setModel(productDAO.buildTableModel(productDAO.getProductSearch(text))); + TableStyler.styleTable(productTable); + productTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException throwables) { throwables.printStackTrace(); } diff --git a/src/com/inventory/UI/PurchasePage$1.class b/src/com/inventory/UI/PurchasePage$1.class new file mode 100644 index 0000000..159d169 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$1.class differ diff --git a/src/com/inventory/UI/PurchasePage$2.class b/src/com/inventory/UI/PurchasePage$2.class new file mode 100644 index 0000000..10e4b0e Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$2.class differ diff --git a/src/com/inventory/UI/PurchasePage$3.class b/src/com/inventory/UI/PurchasePage$3.class new file mode 100644 index 0000000..8208f4a Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$3.class differ diff --git a/src/com/inventory/UI/PurchasePage$4.class b/src/com/inventory/UI/PurchasePage$4.class new file mode 100644 index 0000000..9e75328 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$4.class differ diff --git a/src/com/inventory/UI/PurchasePage$5.class b/src/com/inventory/UI/PurchasePage$5.class new file mode 100644 index 0000000..7de46b5 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$5.class differ diff --git a/src/com/inventory/UI/PurchasePage$6.class b/src/com/inventory/UI/PurchasePage$6.class new file mode 100644 index 0000000..b635269 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$6.class differ diff --git a/src/com/inventory/UI/PurchasePage$7.class b/src/com/inventory/UI/PurchasePage$7.class new file mode 100644 index 0000000..4f18517 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$7.class differ diff --git a/src/com/inventory/UI/PurchasePage$8.class b/src/com/inventory/UI/PurchasePage$8.class new file mode 100644 index 0000000..b379e91 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage$8.class differ diff --git a/src/com/inventory/UI/PurchasePage.class b/src/com/inventory/UI/PurchasePage.class new file mode 100644 index 0000000..05dc8d5 Binary files /dev/null and b/src/com/inventory/UI/PurchasePage.class differ diff --git a/src/com/inventory/UI/PurchasePage.java b/src/com/inventory/UI/PurchasePage.java index 14d5d8a..133457b 100644 --- a/src/com/inventory/UI/PurchasePage.java +++ b/src/com/inventory/UI/PurchasePage.java @@ -44,11 +44,42 @@ public PurchasePage(Dashboard dashboard) { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + public RoundedPanel(int radius) { this.radius = radius; setOpaque(false); } + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { setOpaque(true); } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10))); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); - jPanel1 = new javax.swing.JPanel(); + jPanel1 = new RoundedPanel(20); // Use RoundedPanel jLabel2 = new javax.swing.JLabel(); suppCombo = new javax.swing.JComboBox<>(); addSuppButton = new javax.swing.JButton(); @@ -69,41 +100,70 @@ private void initComponents() { purchaseButton = new javax.swing.JButton(); deleteButton = new javax.swing.JButton(); clearButton = new javax.swing.JButton(); + + // Wrap Table in Rounded Panel + javax.swing.JPanel tablePanel = new RoundedPanel(20); + tablePanel.setLayout(new java.awt.BorderLayout()); + tablePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + jScrollPane1 = new javax.swing.JScrollPane(); purchaseTable = new javax.swing.JTable(); refreshButton = new javax.swing.JButton(); searchText = new javax.swing.JTextField(); jLabel10 = new javax.swing.JLabel(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N + setBackground(new java.awt.Color(220, 230, 250)); + + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); // NOI18N + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); jLabel1.setText("PURCHASE"); - jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Purchase Product")); + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); // Added padding + // jPanel1.setBackground(new java.awt.Color(255, 255, 255)); jLabel2.setText("Supplier:"); - - suppCombo.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" })); - - addSuppButton.setText("Click to add a new Supplier"); + jLabel2.setFont(new java.awt.Font("Segoe UI", 1, 12)); + jLabel2.setForeground(java.awt.Color.BLACK); + + suppCombo.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Select a supplier" })); + suppCombo.setFont(new java.awt.Font("Segoe UI", 0, 14)); + + addSuppButton.setText("+ New Supplier"); + addSuppButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + addSuppButton.setForeground(new java.awt.Color(65, 105, 225)); + addSuppButton.setContentAreaFilled(false); + addSuppButton.setBorderPainted(false); + addSuppButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); addSuppButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addSuppButtonActionPerformed(evt); } }); - jLabel3.setText("Product Code:"); - - jLabel4.setText("Product Name:"); - - jLabel5.setText("Date:"); - - jLabel6.setText("Quantity:"); - - jLabel7.setText("Cost Price:"); - - jLabel8.setText("Selling Price:"); - - jLabel9.setText("Brand:"); + // Labels + java.awt.Font labelFont = new java.awt.Font("Segoe UI", 1, 12); + java.awt.Color labelColor = java.awt.Color.BLACK; + jLabel3.setFont(labelFont); jLabel3.setForeground(labelColor); jLabel3.setText("Product Code"); + jLabel4.setFont(labelFont); jLabel4.setForeground(labelColor); jLabel4.setText("Product Name"); + jLabel5.setFont(labelFont); jLabel5.setForeground(labelColor); jLabel5.setText("Date"); + jLabel6.setFont(labelFont); jLabel6.setForeground(labelColor); jLabel6.setText("Quantity"); + jLabel7.setFont(labelFont); jLabel7.setForeground(labelColor); jLabel7.setText("Cost Price"); + jLabel8.setFont(labelFont); jLabel8.setForeground(labelColor); jLabel8.setText("Selling Price"); + jLabel9.setFont(labelFont); jLabel9.setForeground(labelColor); jLabel9.setText("Brand"); + + // Text Fields + java.awt.Font textFont = new java.awt.Font("Segoe UI", 0, 14); + javax.swing.border.Border textBorder = javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + ); + codeText.setFont(textFont); codeText.setBorder(textBorder); + nameText.setFont(textFont); nameText.setBorder(textBorder); + quantityText.setFont(textFont); quantityText.setBorder(textBorder); + costText.setFont(textFont); costText.setBorder(textBorder); + sellText.setFont(textFont); sellText.setBorder(textBorder); + brandText.setFont(textFont); brandText.setBorder(textBorder); + jDateChooser1.setFont(textFont); codeText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { @@ -111,21 +171,23 @@ public void keyReleased(java.awt.event.KeyEvent evt) { } }); - purchaseButton.setText("Purchase"); + // Buttons + styleButton(purchaseButton, "Purchase", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + styleButton(deleteButton, "Delete", new java.awt.Color(220, 53, 69), java.awt.Color.BLACK); + styleButton(clearButton, "Clear", new java.awt.Color(240, 240, 240), java.awt.Color.BLACK); + purchaseButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { purchaseButtonActionPerformed(evt); } }); - deleteButton.setText("Delete"); deleteButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteButtonActionPerformed(evt); } }); - clearButton.setText("CLEAR"); clearButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearButtonActionPerformed(evt); @@ -137,43 +199,28 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jPanel1Layout.setHorizontalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() + .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(suppCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(addSuppButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(codeText) + .addComponent(nameText) + .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(quantityText) + .addComponent(costText) + .addComponent(sellText) + .addComponent(brandText) .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(suppCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(addSuppButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(codeText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(nameText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(quantityText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(costText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(sellText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(brandText)))) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4) + .addComponent(jLabel5) + .addComponent(jLabel6) + .addComponent(jLabel7) + .addComponent(jLabel8) + .addComponent(jLabel9)) + .addGap(0, 0, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(purchaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 144, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -184,47 +231,47 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jPanel1Layout.setVerticalGroup( jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() - .addContainerGap(12, Short.MAX_VALUE) + .addContainerGap() .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(suppCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(addSuppButton, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jDateChooser1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(suppCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(quantityText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(addSuppButton) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(costText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel8, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(sellText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel9, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(brandText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jDateChooser1, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(purchaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 31, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(quantityText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel7) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(costText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel8) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(sellText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel9) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(clearButton)) + .addComponent(brandText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(20, 20, 20) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(purchaseButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); purchaseTable.setModel(new javax.swing.table.DefaultTableModel( @@ -238,69 +285,92 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { "Title 1", "Title 2", "Title 3", "Title 4" } )); + purchaseTable.setRowHeight(40); + purchaseTable.setShowGrid(false); + purchaseTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + purchaseTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + purchaseTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); + purchaseTable.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); purchaseTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { purchaseTableMouseClicked(evt); } }); jScrollPane1.setViewportView(purchaseTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + // Add ScrollPane to TablePanel + tablePanel.add(jScrollPane1, java.awt.BorderLayout.CENTER); - refreshButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N - refreshButton.setText("REFRESH"); + styleButton(refreshButton, "Refresh", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); refreshButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { refreshButtonActionPerformed(evt); } }); + searchText.setFont(new java.awt.Font("Segoe UI", 0, 14)); + searchText.setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + )); searchText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { searchTextKeyReleased(evt); } }); + jLabel10.setFont(new java.awt.Font("Segoe UI", 1, 14)); jLabel10.setText("Search:"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSeparator1) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 112, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel10, javax.swing.GroupLayout.PREFERRED_SIZE, 50, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 139, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel10) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 99, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 459, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 459, Short.MAX_VALUE) // Use tablePanel + .addGap(20, 20, 20) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 43, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(refreshButton) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel10)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(jLabel10) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) // Use tablePanel .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) - .addContainerGap(28, Short.MAX_VALUE)) + .addGap(20, 20, 20)) ); - }// //GEN-END:initComponents + } + + private void styleButton(javax.swing.JButton btn, String text, java.awt.Color bg, java.awt.Color fg) { + btn.setText(text); + btn.setBackground(bg); + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 12)); + btn.setFocusPainted(false); + btn.setBorderPainted(false); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + } private void refreshButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshButtonActionPerformed loadDataSet(); @@ -335,6 +405,7 @@ private void purchaseButtonActionPerformed(java.awt.event.ActionEvent evt) {//GE new ProductDAO().addPurchaseDAO(productDTO); loadDataSet(); + dashboard.refreshDailySummary(); } else JOptionPane.showMessageDialog(null, "This seems to be a new product" + " that hasn't been added yet.\nPlease add this product in the \"Products\" section before proceeding."); @@ -355,8 +426,9 @@ private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN- JOptionPane.YES_NO_OPTION); if(opt==JOptionPane.YES_OPTION) { new ProductDAO().deletePurchaseDAO((int) purchaseTable.getValueAt(purchaseTable.getSelectedRow(),0)); - new ProductDAO().editPurchaseStock(prodCode, quantity); + // Stock update is now handled in DAO loadDataSet(); + dashboard.refreshDailySummary(); } } }//GEN-LAST:event_deleteButtonActionPerformed @@ -422,7 +494,8 @@ public void loadComboBox() { public void loadDataSet() { try { ProductDAO productDAO = new ProductDAO(); - purchaseTable.setModel(productDAO.buildTableModel(productDAO.getPurchaseInfo())); + purchaseTable.setModel(productDAO.buildTableModel(productDAO.getPurchaseInfo())); + TableStyler.styleTable(purchaseTable); } catch (SQLException throwables) { throwables.printStackTrace(); } @@ -433,6 +506,7 @@ public void loadSearchData(String text) { try { ProductDAO productDAO = new ProductDAO(); purchaseTable.setModel(productDAO.buildTableModel(productDAO.getPurchaseSearch(text))); + purchaseTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/com/inventory/UI/SalesPage$1.class b/src/com/inventory/UI/SalesPage$1.class new file mode 100644 index 0000000..4c7ddf0 Binary files /dev/null and b/src/com/inventory/UI/SalesPage$1.class differ diff --git a/src/com/inventory/UI/SalesPage$2.class b/src/com/inventory/UI/SalesPage$2.class new file mode 100644 index 0000000..cd442cd Binary files /dev/null and b/src/com/inventory/UI/SalesPage$2.class differ diff --git a/src/com/inventory/UI/SalesPage$3.class b/src/com/inventory/UI/SalesPage$3.class new file mode 100644 index 0000000..99fb779 Binary files /dev/null and b/src/com/inventory/UI/SalesPage$3.class differ diff --git a/src/com/inventory/UI/SalesPage$4.class b/src/com/inventory/UI/SalesPage$4.class new file mode 100644 index 0000000..4630441 Binary files /dev/null and b/src/com/inventory/UI/SalesPage$4.class differ diff --git a/src/com/inventory/UI/SalesPage$5.class b/src/com/inventory/UI/SalesPage$5.class new file mode 100644 index 0000000..0d06196 Binary files /dev/null and b/src/com/inventory/UI/SalesPage$5.class differ diff --git a/src/com/inventory/UI/SalesPage$6.class b/src/com/inventory/UI/SalesPage$6.class new file mode 100644 index 0000000..b9a86cd Binary files /dev/null and b/src/com/inventory/UI/SalesPage$6.class differ diff --git a/src/com/inventory/UI/SalesPage$7.class b/src/com/inventory/UI/SalesPage$7.class new file mode 100644 index 0000000..362a20e Binary files /dev/null and b/src/com/inventory/UI/SalesPage$7.class differ diff --git a/src/com/inventory/UI/SalesPage$8.class b/src/com/inventory/UI/SalesPage$8.class new file mode 100644 index 0000000..239deb5 Binary files /dev/null and b/src/com/inventory/UI/SalesPage$8.class differ diff --git a/src/com/inventory/UI/SalesPage.class b/src/com/inventory/UI/SalesPage.class new file mode 100644 index 0000000..23d5ad6 Binary files /dev/null and b/src/com/inventory/UI/SalesPage.class differ diff --git a/src/com/inventory/UI/SalesPage.java b/src/com/inventory/UI/SalesPage.java index 25b8ab4..927927f 100644 --- a/src/com/inventory/UI/SalesPage.java +++ b/src/com/inventory/UI/SalesPage.java @@ -44,11 +44,55 @@ public SalesPage(String username, Dashboard dashboard) { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + + // Custom Header Renderer + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); - sellPanel = new javax.swing.JPanel(); + sellPanel = new RoundedPanel(20); // Use RoundedPanel jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); @@ -65,25 +109,47 @@ private void initComponents() { addCustButton = new javax.swing.JButton(); custNameLabel = new javax.swing.JLabel(); prodNameLabel = new javax.swing.JLabel(); + + // Wrap Table in Rounded Panel + javax.swing.JPanel tablePanel = new RoundedPanel(20); + tablePanel.setLayout(new java.awt.BorderLayout()); + tablePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + jScrollPane1 = new javax.swing.JScrollPane(); salesTable = new javax.swing.JTable(); searchText = new javax.swing.JTextField(); jLabel7 = new javax.swing.JLabel(); + refreshButton = new javax.swing.JButton(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("SALES"); - - sellPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Sell Product")); - - jLabel2.setText("Customer Code:"); - - jLabel3.setText("Product Code:"); - - jLabel4.setText("Date:"); + setBackground(new java.awt.Color(220, 230, 250)); - jLabel5.setText("Selling Price:"); + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); // NOI18N + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("SALES"); - jLabel6.setText("Quantity:"); + sellPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); // Added padding + // sellPanel.setBackground(new java.awt.Color(255, 255, 255)); + + // Labels + java.awt.Font labelFont = new java.awt.Font("Segoe UI", 1, 12); + java.awt.Color labelColor = java.awt.Color.BLACK; + jLabel2.setFont(labelFont); jLabel2.setForeground(labelColor); jLabel2.setText("Customer Code"); + jLabel3.setFont(labelFont); jLabel3.setForeground(labelColor); jLabel3.setText("Product Code"); + jLabel4.setFont(labelFont); jLabel4.setForeground(labelColor); jLabel4.setText("Date"); + jLabel5.setFont(labelFont); jLabel5.setForeground(labelColor); jLabel5.setText("Selling Price"); + jLabel6.setFont(labelFont); jLabel6.setForeground(labelColor); jLabel6.setText("Quantity"); + + // Text Fields + java.awt.Font textFont = new java.awt.Font("Segoe UI", 0, 14); + javax.swing.border.Border textBorder = javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + ); + custCodeText.setFont(textFont); custCodeText.setBorder(textBorder); + prodCodeText.setFont(textFont); prodCodeText.setBorder(textBorder); + priceText.setFont(textFont); priceText.setBorder(textBorder); + quantityText.setFont(textFont); quantityText.setBorder(textBorder); + jDateChooser1.setFont(textFont); custCodeText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { @@ -97,32 +163,34 @@ public void keyReleased(java.awt.event.KeyEvent evt) { } }); - sellButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N - sellButton.setText("SELL PRODUCT"); - sellButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + // Buttons + styleButton(sellButton, "SELL PRODUCT", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + styleButton(deleteButton, "Delete", new java.awt.Color(220, 53, 69), java.awt.Color.BLACK); + styleButton(clearButton, "Clear", new java.awt.Color(240, 240, 240), java.awt.Color.BLACK); + sellButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { sellButtonActionPerformed(evt); } }); - deleteButton.setText("Delete"); - deleteButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); deleteButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteButtonActionPerformed(evt); } }); - clearButton.setText("Clear"); - clearButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); clearButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearButtonActionPerformed(evt); } }); - addCustButton.setText("Click to add a New Customer"); + addCustButton.setText("+ New Customer"); + addCustButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + addCustButton.setForeground(new java.awt.Color(65, 105, 225)); + addCustButton.setContentAreaFilled(false); + addCustButton.setBorderPainted(false); addCustButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); addCustButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { @@ -147,70 +215,61 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addComponent(custNameLabel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(addCustButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(sellButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(custCodeText) + .addComponent(prodCodeText) + .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(priceText) + .addComponent(quantityText) .addGroup(sellPanelLayout.createSequentialGroup() - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(custCodeText)) - .addGroup(sellPanelLayout.createSequentialGroup() - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(prodCodeText)) + .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4) + .addComponent(jLabel5) + .addComponent(jLabel6)) + .addGap(0, 0, Short.MAX_VALUE)) .addGroup(sellPanelLayout.createSequentialGroup() .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 134, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE)) - .addGroup(sellPanelLayout.createSequentialGroup() - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(quantityText)) - .addGroup(sellPanelLayout.createSequentialGroup() - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(priceText)) - .addGroup(sellPanelLayout.createSequentialGroup() - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jDateChooser1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, 129, Short.MAX_VALUE))) .addContainerGap()) ); sellPanelLayout.setVerticalGroup( sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(sellPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGroup(sellPanelLayout.createSequentialGroup() - .addGap(1, 1, 1) - .addComponent(custCodeText, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(custCodeText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(custNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 15, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(addCustButton) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(prodCodeText, javax.swing.GroupLayout.DEFAULT_SIZE, 24, Short.MAX_VALUE)) + .addComponent(jLabel3) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(prodCodeText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addComponent(prodNameLabel, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 15, Short.MAX_VALUE) - .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jDateChooser1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(priceText, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(quantityText, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jDateChooser1, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(sellButton, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(priceText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel6) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(quantityText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(18, 18, 18) + .addComponent(sellButton, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) .addGroup(sellPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(deleteButton) - .addComponent(clearButton)) - .addContainerGap()) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); salesTable.setModel(new javax.swing.table.DefaultTableModel( @@ -224,19 +283,45 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { "Title 1", "Title 2", "Title 3", "Title 4" } )); + salesTable.setRowHeight(40); + salesTable.setShowGrid(false); + salesTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + salesTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + salesTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); + salesTable.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); salesTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { salesTableMouseClicked(evt); } }); jScrollPane1.setViewportView(salesTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + // Add ScrollPane to TablePanel + tablePanel.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + // Search Bar + styleButton(refreshButton, "Refresh", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + refreshButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + loadDataSet(); + clearButtonActionPerformed(evt); + } + }); + searchText.setFont(new java.awt.Font("Segoe UI", 0, 14)); + searchText.setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + )); searchText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { searchTextKeyReleased(evt); } }); + jLabel7.setFont(new java.awt.Font("Segoe UI", 1, 14)); jLabel7.setText("Search:"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -244,38 +329,48 @@ public void keyReleased(java.awt.event.KeyEvent evt) { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 70, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel7) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 174, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jSeparator1) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 174, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 457, Short.MAX_VALUE) + .addGap(20, 20, 20) .addComponent(sellPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel7)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(jLabel7) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(sellPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addContainerGap(70, Short.MAX_VALUE)) + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(20, 20, 20)) ); - }// //GEN-END:initComponents + } + + private void styleButton(javax.swing.JButton btn, String text, java.awt.Color bg, java.awt.Color fg) { + btn.setText(text); + btn.setBackground(bg); + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 12)); + btn.setFocusPainted(false); + btn.setBorderPainted(false); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + } private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_deleteButtonActionPerformed if (salesTable.getSelectedRow()<0) @@ -289,9 +384,9 @@ private void deleteButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN- if (opt == JOptionPane.YES_OPTION) { new ProductDAO().deleteSaleDAO(Integer.parseInt( salesTable.getValueAt(salesTable.getSelectedRow(),0).toString())); - new ProductDAO().editSoldStock( - salesTable.getValueAt(salesTable.getSelectedRow(),1).toString(), quantity); + // Stock update is now handled in DAO loadDataSet(); + dashboard.refreshDailySummary(); } } }//GEN-LAST:event_deleteButtonActionPerformed @@ -331,6 +426,7 @@ private void sellButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FI productDTO.setQuantity(Integer.parseInt(quantityText.getText())); new ProductDAO().sellProductDAO(productDTO, username); loadDataSet(); + dashboard.refreshDailySummary(); } else JOptionPane.showMessageDialog(this, "This customer does not exist.\n" + "Add new customer or use a valid customer code."); @@ -393,6 +489,7 @@ public void loadDataSet() { try { ProductDAO productDAO = new ProductDAO(); salesTable.setModel(productDAO.buildTableModel(productDAO.getSalesInfo())); + TableStyler.styleTable(salesTable); } catch (SQLException e) { e.printStackTrace(); } @@ -403,6 +500,7 @@ public void loadSearchData(String text) { try { ProductDAO productDAO = new ProductDAO(); salesTable.setModel(productDAO.buildTableModel(productDAO.getSalesSearch(text))); + salesTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException e) { e.printStackTrace(); } @@ -432,5 +530,6 @@ public void loadSearchData(String text) { private javax.swing.JTextField searchText; private javax.swing.JButton sellButton; private javax.swing.JPanel sellPanel; + private javax.swing.JButton refreshButton; // End of variables declaration//GEN-END:variables } diff --git a/src/com/inventory/UI/StyleConstants.class b/src/com/inventory/UI/StyleConstants.class new file mode 100644 index 0000000..11a2be9 Binary files /dev/null and b/src/com/inventory/UI/StyleConstants.class differ diff --git a/src/com/inventory/UI/StyleConstants.java b/src/com/inventory/UI/StyleConstants.java new file mode 100644 index 0000000..9282e1e --- /dev/null +++ b/src/com/inventory/UI/StyleConstants.java @@ -0,0 +1,39 @@ +package com.inventory.UI; + +import java.awt.Color; +import java.awt.Font; +import javax.swing.border.Border; +import javax.swing.BorderFactory; + +public class StyleConstants { + // Colors + public static final Color PRIMARY_COLOR = new Color(51, 102, 255); // Modern Blue + public static final Color SECONDARY_COLOR = new Color(45, 45, 48); // Dark Gray + public static final Color BACKGROUND_COLOR = new Color(30, 30, 30); // Dark Background + public static final Color TEXT_COLOR = new Color(230, 230, 230); // Light Text + public static final Color ACCENT_COLOR = new Color(0, 153, 204); // Cyan Accent + + // Table Colors + public static final Color TABLE_HEADER_BG = new Color(51, 102, 255); // Primary Blue + public static final Color TABLE_HEADER_FG = Color.WHITE; + public static final Color TABLE_ROW_EVEN = Color.WHITE; + public static final Color TABLE_ROW_ODD = new Color(248, 250, 255); + public static final Color TABLE_SELECTION_BG = new Color(200, 220, 255); + public static final Color TABLE_SELECTION_FG = new Color(0, 0, 0); + public static final Color TABLE_GRID_COLOR = new Color(220, 220, 220); + + // Fonts + public static final Font HEADER_FONT = new Font("Segoe UI", Font.BOLD, 24); + public static final Font SUBHEADER_FONT = new Font("Segoe UI", Font.PLAIN, 18); + public static final Font REGULAR_FONT = new Font("Segoe UI", Font.PLAIN, 14); + public static final Font BUTTON_FONT = new Font("Segoe UI", Font.BOLD, 14); + public static final Font TABLE_HEADER_FONT = new Font("Segoe UI", Font.BOLD, 13); + public static final Font TABLE_CELL_FONT = new Font("Segoe UI", Font.PLAIN, 12); + + // Dimensions & Borders + public static final int PADDING_SMALL = 5; + public static final int PADDING_MEDIUM = 10; + public static final int PADDING_LARGE = 20; + + public static final Border EMPTY_BORDER = BorderFactory.createEmptyBorder(PADDING_MEDIUM, PADDING_MEDIUM, PADDING_MEDIUM, PADDING_MEDIUM); +} diff --git a/src/com/inventory/UI/SupplierLogos/README.md b/src/com/inventory/UI/SupplierLogos/README.md new file mode 100644 index 0000000..4d78b61 --- /dev/null +++ b/src/com/inventory/UI/SupplierLogos/README.md @@ -0,0 +1,28 @@ +# Supplier Logos Directory + +Place your supplier logo images in this directory. + +## Supported Formats +- PNG (recommended for transparency) +- JPG/JPEG +- GIF + +## Naming Convention +Name your logo files clearly, for example: +- `dell.png` +- `hp.png` +- `samsung.png` +- `apple.png` +- `shelby.png` +- `iworld.png` + +## Recommended Image Size +- **Width**: 150-200 pixels +- **Height**: 100-150 pixels +- **Aspect Ratio**: Keep logos proportional +- **Background**: Transparent or white background works best + +## How It Works +The HomePage will automatically load all image files from this directory and display them in the "Our Trusted Suppliers" section. + +Simply add your logo images here and restart the application to see them appear! diff --git a/src/com/inventory/UI/SupplierLogos/apple.png b/src/com/inventory/UI/SupplierLogos/apple.png new file mode 100644 index 0000000..29f536f Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/apple.png differ diff --git a/src/com/inventory/UI/SupplierLogos/dell.png b/src/com/inventory/UI/SupplierLogos/dell.png new file mode 100644 index 0000000..cc7721c Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/dell.png differ diff --git a/src/com/inventory/UI/SupplierLogos/hewlett-packard.png b/src/com/inventory/UI/SupplierLogos/hewlett-packard.png new file mode 100644 index 0000000..1c4d479 Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/hewlett-packard.png differ diff --git a/src/com/inventory/UI/SupplierLogos/hp.png b/src/com/inventory/UI/SupplierLogos/hp.png new file mode 100644 index 0000000..b2b6218 Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/hp.png differ diff --git a/src/com/inventory/UI/SupplierLogos/iworld.png b/src/com/inventory/UI/SupplierLogos/iworld.png new file mode 100644 index 0000000..b929ee7 Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/iworld.png differ diff --git a/src/com/inventory/UI/SupplierLogos/samsung.png b/src/com/inventory/UI/SupplierLogos/samsung.png new file mode 100644 index 0000000..f903e54 Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/samsung.png differ diff --git a/src/com/inventory/UI/SupplierLogos/shelby.png b/src/com/inventory/UI/SupplierLogos/shelby.png new file mode 100644 index 0000000..977b1d8 Binary files /dev/null and b/src/com/inventory/UI/SupplierLogos/shelby.png differ diff --git a/src/com/inventory/UI/SupplierPage$1.class b/src/com/inventory/UI/SupplierPage$1.class new file mode 100644 index 0000000..6a16057 Binary files /dev/null and b/src/com/inventory/UI/SupplierPage$1.class differ diff --git a/src/com/inventory/UI/SupplierPage$2.class b/src/com/inventory/UI/SupplierPage$2.class new file mode 100644 index 0000000..6b24523 Binary files /dev/null and b/src/com/inventory/UI/SupplierPage$2.class differ diff --git a/src/com/inventory/UI/SupplierPage$3.class b/src/com/inventory/UI/SupplierPage$3.class new file mode 100644 index 0000000..c98f901 Binary files /dev/null and b/src/com/inventory/UI/SupplierPage$3.class differ diff --git a/src/com/inventory/UI/SupplierPage$4.class b/src/com/inventory/UI/SupplierPage$4.class new file mode 100644 index 0000000..4d85467 Binary files /dev/null and b/src/com/inventory/UI/SupplierPage$4.class differ diff --git a/src/com/inventory/UI/SupplierPage$5.class b/src/com/inventory/UI/SupplierPage$5.class new file mode 100644 index 0000000..94dd56b Binary files /dev/null and b/src/com/inventory/UI/SupplierPage$5.class differ diff --git a/src/com/inventory/UI/SupplierPage$6.class b/src/com/inventory/UI/SupplierPage$6.class new file mode 100644 index 0000000..60942da Binary files /dev/null and b/src/com/inventory/UI/SupplierPage$6.class differ diff --git a/src/com/inventory/UI/SupplierPage.class b/src/com/inventory/UI/SupplierPage.class new file mode 100644 index 0000000..d0c523a Binary files /dev/null and b/src/com/inventory/UI/SupplierPage.class differ diff --git a/src/com/inventory/UI/SupplierPage.java b/src/com/inventory/UI/SupplierPage.java index 111c905..80adaff 100644 --- a/src/com/inventory/UI/SupplierPage.java +++ b/src/com/inventory/UI/SupplierPage.java @@ -32,11 +32,55 @@ public SupplierPage() { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + + // Custom Header Renderer + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); - jPanel1 = new javax.swing.JPanel(); + jPanel1 = new RoundedPanel(20); // Use RoundedPanel jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); @@ -53,55 +97,75 @@ private void initComponents() { deleteButton = new javax.swing.JButton(); editButton = new javax.swing.JButton(); clearButton = new javax.swing.JButton(); + + // Wrap Table in Rounded Panel + javax.swing.JPanel tablePanel = new RoundedPanel(20); + tablePanel.setLayout(new java.awt.BorderLayout()); + tablePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + jScrollPane1 = new javax.swing.JScrollPane(); suppTable = new javax.swing.JTable(); searchText = new javax.swing.JTextField(); jLabel8 = new javax.swing.JLabel(); + refreshButton = new javax.swing.JButton(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("SUPPLIERS"); - - jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Enter Supplier Details")); - - jLabel2.setText("Supplier Code:"); - - jLabel3.setText("Full Name:"); - - jLabel4.setText("Location:"); + setBackground(new java.awt.Color(220, 230, 250)); - jLabel5.setText("Contact:"); - - jLabel6.setText("Debit Amount:"); + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); // NOI18N + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("SUPPLIERS"); - jLabel7.setText("Credit Amount:"); + // jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Enter Supplier Details")); // Removed TitledBorder + jPanel1.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); // Added padding + // jPanel1.setBackground(new java.awt.Color(255, 255, 255)); // Ensure white bg for the panel content if needed, though RoundedPanel handles it. + + // Labels + java.awt.Font labelFont = new java.awt.Font("Segoe UI", 1, 12); + java.awt.Color labelColor = java.awt.Color.BLACK; + jLabel2.setFont(labelFont); jLabel2.setForeground(labelColor); jLabel2.setText("Supplier Code"); + jLabel3.setFont(labelFont); jLabel3.setForeground(labelColor); jLabel3.setText("Full Name"); + jLabel4.setFont(labelFont); jLabel4.setForeground(labelColor); jLabel4.setText("Location"); + jLabel5.setFont(labelFont); jLabel5.setForeground(labelColor); jLabel5.setText("Contact"); + jLabel6.setFont(labelFont); jLabel6.setForeground(labelColor); jLabel6.setText("Debit Amount"); + jLabel7.setFont(labelFont); jLabel7.setForeground(labelColor); jLabel7.setText("Credit Amount"); + + // Text Fields + java.awt.Font textFont = new java.awt.Font("Segoe UI", 0, 14); + javax.swing.border.Border textBorder = javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + ); + codeText.setFont(textFont); codeText.setBorder(textBorder); + nameText.setFont(textFont); nameText.setBorder(textBorder); + locationText.setFont(textFont); locationText.setBorder(textBorder); + phoneText.setFont(textFont); phoneText.setBorder(textBorder); + debitText.setFont(textFont); debitText.setBorder(textBorder); + creditText.setFont(textFont); creditText.setBorder(textBorder); + + // Buttons + styleButton(addButton, "Add", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + styleButton(editButton, "Edit", new java.awt.Color(255, 193, 7), java.awt.Color.BLACK); + styleButton(deleteButton, "Delete", new java.awt.Color(220, 53, 69), java.awt.Color.BLACK); + styleButton(clearButton, "Clear", new java.awt.Color(240, 240, 240), java.awt.Color.BLACK); - addButton.setText("Add"); - addButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); addButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addButtonActionPerformed(evt); } }); - deleteButton.setText("Delete"); - deleteButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); deleteButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteButtonActionPerformed(evt); } }); - editButton.setText("Edit"); - editButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); editButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { editButtonActionPerformed(evt); } }); - clearButton.setFont(new java.awt.Font("Segoe UI", 0, 14)); // NOI18N - clearButton.setText("CLEAR"); - clearButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); clearButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearButtonActionPerformed(evt); @@ -116,30 +180,21 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addContainerGap() .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(codeText) + .addComponent(nameText) + .addComponent(locationText) + .addComponent(phoneText) + .addComponent(debitText) + .addComponent(creditText) .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(creditText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(codeText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(debitText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(phoneText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(locationText)) - .addGroup(jPanel1Layout.createSequentialGroup() - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(nameText)) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4) + .addComponent(jLabel5) + .addComponent(jLabel6) + .addComponent(jLabel7)) + .addGap(0, 0, Short.MAX_VALUE)) .addGroup(jPanel1Layout.createSequentialGroup() .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) @@ -152,36 +207,36 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel1Layout.createSequentialGroup() .addContainerGap() - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(codeText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(locationText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(phoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(locationText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(debitText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(phoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel7, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(creditText, javax.swing.GroupLayout.PREFERRED_SIZE, 26, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGap(18, 18, 18) - .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(addButton) - .addComponent(deleteButton) - .addComponent(editButton)) + .addComponent(debitText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel7) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(clearButton) + .addComponent(creditText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addGap(20, 20, 20) + .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(editButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -196,6 +251,11 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { "Title 1", "Title 2", "Title 3", "Title 4" } )); + suppTable.setRowHeight(40); + suppTable.setShowGrid(false); + suppTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + suppTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + suppTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); suppTable.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); suppTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { @@ -203,13 +263,33 @@ public void mouseClicked(java.awt.event.MouseEvent evt) { } }); jScrollPane1.setViewportView(suppTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + // Add ScrollPane to TablePanel + tablePanel.add(jScrollPane1, java.awt.BorderLayout.CENTER); + + // Search Bar + styleButton(refreshButton, "Refresh", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + refreshButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + loadDataSet(); + clearButtonActionPerformed(evt); + } + }); + searchText.setFont(new java.awt.Font("Segoe UI", 0, 14)); + searchText.setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + )); searchText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { searchTextKeyReleased(evt); } }); + jLabel8.setFont(new java.awt.Font("Segoe UI", 1, 14)); jLabel8.setText("Search:"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); @@ -217,39 +297,49 @@ public void keyReleased(java.awt.event.KeyEvent evt) { layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSeparator1) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 111, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addComponent(jLabel8) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 170, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGroup(layout.createSequentialGroup() + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 479, Short.MAX_VALUE) + .addGap(20, 20, 20) .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel8)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(jLabel8) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addContainerGap(31, Short.MAX_VALUE)) + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(20, 20, 20)) ); }// //GEN-END:initComponents + private void styleButton(javax.swing.JButton btn, String text, java.awt.Color bg, java.awt.Color fg) { + btn.setText(text); + btn.setBackground(bg); + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 12)); + btn.setFocusPainted(false); + btn.setBorderPainted(false); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + } + private void suppTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_suppTableMouseClicked int row = suppTable.getSelectedRow(); int col = suppTable.getColumnCount(); @@ -331,7 +421,8 @@ private void searchTextKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:eve public void loadDataSet() { try { SupplierDAO supplierDAO = new SupplierDAO(); - suppTable.setModel(supplierDAO.buildTableModel(supplierDAO.getQueryResult())); + suppTable.setModel(supplierDAO.buildTableModel(supplierDAO.getQueryResult())); + TableStyler.styleTable(suppTable); } catch (SQLException e) { e.printStackTrace(); } @@ -342,6 +433,7 @@ public void loadSearchData(String text) { try { SupplierDAO supplierDAO = new SupplierDAO(); suppTable.setModel(supplierDAO.buildTableModel(supplierDAO.getSearchResult(text))); + suppTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException e) { e.printStackTrace(); } @@ -371,5 +463,6 @@ public void loadSearchData(String text) { private javax.swing.JTextField phoneText; private javax.swing.JTextField searchText; private javax.swing.JTable suppTable; + private javax.swing.JButton refreshButton; // End of variables declaration//GEN-END:variables } diff --git a/src/com/inventory/UI/TableStyler$1.class b/src/com/inventory/UI/TableStyler$1.class new file mode 100644 index 0000000..7ee7cee Binary files /dev/null and b/src/com/inventory/UI/TableStyler$1.class differ diff --git a/src/com/inventory/UI/TableStyler.class b/src/com/inventory/UI/TableStyler.class new file mode 100644 index 0000000..4cbd5f4 Binary files /dev/null and b/src/com/inventory/UI/TableStyler.class differ diff --git a/src/com/inventory/UI/TableStyler.java b/src/com/inventory/UI/TableStyler.java new file mode 100644 index 0000000..317c55e --- /dev/null +++ b/src/com/inventory/UI/TableStyler.java @@ -0,0 +1,98 @@ +package com.inventory.UI; + +import javax.swing.*; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.JTableHeader; +import java.awt.*; + +/** + * Utility class to apply modern styling to JTables + */ +public class TableStyler { + + /** + * Apply modern styling to a JTable + * @param table The JTable to style + */ + public static void styleTable(JTable table) { + // Table general settings + table.setFont(StyleConstants.TABLE_CELL_FONT); + table.setRowHeight(35); + table.setShowGrid(true); + table.setGridColor(StyleConstants.TABLE_GRID_COLOR); + table.setSelectionBackground(StyleConstants.TABLE_SELECTION_BG); + table.setSelectionForeground(StyleConstants.TABLE_SELECTION_FG); + table.setIntercellSpacing(new Dimension(1, 1)); + + // Header styling - using custom renderer to ensure blue background shows + JTableHeader header = table.getTableHeader(); + header.setPreferredSize(new Dimension(header.getWidth(), 40)); + header.setReorderingAllowed(false); + + // Custom header renderer to force blue background + header.setDefaultRenderer(new javax.swing.table.DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setOpaque(true); + setBackground(new Color(200, 220, 255)); // Light blue + setForeground(Color.BLACK); + setFont(new Font("Segoe UI", Font.BOLD, 12)); + setHorizontalAlignment(CENTER); + setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 0, 1, 1, new Color(200, 200, 200)), + BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + }); + + // Custom cell renderer for alternating row colors + table.setDefaultRenderer(Object.class, new DefaultTableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, + boolean isSelected, boolean hasFocus, int row, int column) { + + Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + if (!isSelected) { + if (row % 2 == 0) { + c.setBackground(StyleConstants.TABLE_ROW_EVEN); + } else { + c.setBackground(StyleConstants.TABLE_ROW_ODD); + } + c.setForeground(Color.BLACK); + } else { + c.setBackground(StyleConstants.TABLE_SELECTION_BG); + c.setForeground(StyleConstants.TABLE_SELECTION_FG); + } + + // Add padding + if (c instanceof JLabel) { + ((JLabel) c).setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); + } + + return c; + } + }); + } + + /** + * Wrap a JTable in a styled JScrollPane + * @param table The JTable to wrap + * @return Styled JScrollPane containing the table + */ + public static JScrollPane createStyledScrollPane(JTable table) { + styleTable(table); + + JScrollPane scrollPane = new JScrollPane(table); + scrollPane.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createLineBorder(StyleConstants.TABLE_GRID_COLOR, 1), + BorderFactory.createEmptyBorder(0, 0, 0, 0) + )); + scrollPane.getViewport().setBackground(Color.WHITE); + + return scrollPane; + } +} diff --git a/src/com/inventory/UI/UserLogsPage$1.class b/src/com/inventory/UI/UserLogsPage$1.class new file mode 100644 index 0000000..7745810 Binary files /dev/null and b/src/com/inventory/UI/UserLogsPage$1.class differ diff --git a/src/com/inventory/UI/UserLogsPage$2.class b/src/com/inventory/UI/UserLogsPage$2.class new file mode 100644 index 0000000..59a2ae5 Binary files /dev/null and b/src/com/inventory/UI/UserLogsPage$2.class differ diff --git a/src/com/inventory/UI/UserLogsPage.class b/src/com/inventory/UI/UserLogsPage.class new file mode 100644 index 0000000..281cef0 Binary files /dev/null and b/src/com/inventory/UI/UserLogsPage.class differ diff --git a/src/com/inventory/UI/UserLogsPage.java b/src/com/inventory/UI/UserLogsPage.java index e28fe21..bbe286f 100644 --- a/src/com/inventory/UI/UserLogsPage.java +++ b/src/com/inventory/UI/UserLogsPage.java @@ -30,82 +30,146 @@ public UserLogsPage() { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + + // Custom Header Renderer + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); + + // Wrap table in rounded card + javax.swing.JPanel tableCard = new RoundedPanel(20); jScrollPane1 = new javax.swing.JScrollPane(); logTable = new javax.swing.JTable(); + refreshButton = new javax.swing.JButton(); searchText = new javax.swing.JTextField(); jLabel2 = new javax.swing.JLabel(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("USER LOGS"); + setBackground(new java.awt.Color(220, 230, 250)); // Darker Blue BG + + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("User Logs"); logTable.setModel(new javax.swing.table.DefaultTableModel( - new Object [][] { - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null}, - {null, null, null, null} - }, - new String [] { - "Title 1", "Title 2", "Title 3", "Title 4" - } + new Object [][] {}, + new String [] { "User", "Activity", "Date", "Time" } )); + logTable.setRowHeight(40); + logTable.setShowGrid(false); + logTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + logTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + logTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); + jScrollPane1.setViewportView(logTable); - - refreshButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); // NOI18N - refreshButton.setText("REFRESH"); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + // Add table to card + tableCard.setLayout(new java.awt.BorderLayout()); + tableCard.add(jScrollPane1, java.awt.BorderLayout.CENTER); + tableCard.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + + refreshButton.setText("Refresh"); + refreshButton.setBackground(new java.awt.Color(65, 105, 225)); + refreshButton.setForeground(java.awt.Color.BLACK); + refreshButton.setFont(new java.awt.Font("Segoe UI", 1, 12)); + refreshButton.setFocusPainted(false); + refreshButton.setBorderPainted(false); + refreshButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); refreshButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { refreshButtonActionPerformed(evt); } }); + searchText.setFont(new java.awt.Font("Segoe UI", 0, 14)); + searchText.setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + )); searchText.addKeyListener(new java.awt.event.KeyAdapter() { public void keyReleased(java.awt.event.KeyEvent evt) { searchTextKeyReleased(evt); } }); + jLabel2.setFont(new java.awt.Font("Segoe UI", 1, 14)); jLabel2.setText("Search:"); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSeparator1) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 672, Short.MAX_VALUE) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 129, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel1) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 153, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(18, 18, 18) - .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 89, javax.swing.GroupLayout.PREFERRED_SIZE))) - .addContainerGap()) + .addComponent(jLabel2) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 200, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 100, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 860, Short.MAX_VALUE)) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(refreshButton) - .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(jLabel2)) - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 407, javax.swing.GroupLayout.PREFERRED_SIZE) - .addContainerGap(26, Short.MAX_VALUE)) + .addGap(20, 20, 20) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER) + .addComponent(jLabel1) + .addComponent(jLabel2) + .addComponent(searchText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(refreshButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addGap(20, 20, 20) + .addComponent(tableCard, javax.swing.GroupLayout.DEFAULT_SIZE, 500, Short.MAX_VALUE) + .addGap(20, 20, 20)) ); }// //GEN-END:initComponents @@ -121,6 +185,7 @@ public void loadDataSet() { try { UserDAO userDAO = new UserDAO(); logTable.setModel(userDAO.buildTableModel(userDAO.getUserLogsDAO())); + logTable.getTableHeader().setDefaultRenderer(new HeaderRenderer()); } catch (SQLException e) { e.printStackTrace(); } diff --git a/src/com/inventory/UI/UsersPage$1.class b/src/com/inventory/UI/UsersPage$1.class new file mode 100644 index 0000000..722802d Binary files /dev/null and b/src/com/inventory/UI/UsersPage$1.class differ diff --git a/src/com/inventory/UI/UsersPage$2.class b/src/com/inventory/UI/UsersPage$2.class new file mode 100644 index 0000000..c0dcdf0 Binary files /dev/null and b/src/com/inventory/UI/UsersPage$2.class differ diff --git a/src/com/inventory/UI/UsersPage$3.class b/src/com/inventory/UI/UsersPage$3.class new file mode 100644 index 0000000..350e92c Binary files /dev/null and b/src/com/inventory/UI/UsersPage$3.class differ diff --git a/src/com/inventory/UI/UsersPage$4.class b/src/com/inventory/UI/UsersPage$4.class new file mode 100644 index 0000000..f66b469 Binary files /dev/null and b/src/com/inventory/UI/UsersPage$4.class differ diff --git a/src/com/inventory/UI/UsersPage$5.class b/src/com/inventory/UI/UsersPage$5.class new file mode 100644 index 0000000..1fac683 Binary files /dev/null and b/src/com/inventory/UI/UsersPage$5.class differ diff --git a/src/com/inventory/UI/UsersPage.class b/src/com/inventory/UI/UsersPage.class new file mode 100644 index 0000000..a52ea2d Binary files /dev/null and b/src/com/inventory/UI/UsersPage.class differ diff --git a/src/com/inventory/UI/UsersPage.java b/src/com/inventory/UI/UsersPage.java index f0254fb..c6bbf87 100644 --- a/src/com/inventory/UI/UsersPage.java +++ b/src/com/inventory/UI/UsersPage.java @@ -32,11 +32,54 @@ public UsersPage() { */ @SuppressWarnings("unchecked") // //GEN-BEGIN:initComponents + // Custom Rounded Panel for Card Effect + class RoundedPanel extends javax.swing.JPanel { + private int radius = 15; + private java.awt.Color backgroundColor = java.awt.Color.WHITE; + + public RoundedPanel(int radius) { + this.radius = radius; + setOpaque(false); + } + + @Override + protected void paintComponent(java.awt.Graphics g) { + super.paintComponent(g); + java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; + g2.setRenderingHint(java.awt.RenderingHints.KEY_ANTIALIASING, java.awt.RenderingHints.VALUE_ANTIALIAS_ON); + + g2.setColor(new java.awt.Color(200, 200, 200)); + g2.fillRoundRect(2, 2, getWidth() - 4, getHeight() - 4, radius, radius); + + g2.setColor(backgroundColor); + g2.fillRoundRect(0, 0, getWidth() - 4, getHeight() - 4, radius, radius); + } + } + + // Custom Header Renderer + class HeaderRenderer extends javax.swing.table.DefaultTableCellRenderer { + public HeaderRenderer() { + setOpaque(true); + } + @Override + public java.awt.Component getTableCellRendererComponent(javax.swing.JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + setBackground(new java.awt.Color(200, 220, 255)); + setForeground(java.awt.Color.BLACK); + setFont(new java.awt.Font("Segoe UI", 1, 12)); + setBorder(javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createMatteBorder(0, 0, 1, 1, new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(10, 10, 10, 10) + )); + return this; + } + } + private void initComponents() { jLabel1 = new javax.swing.JLabel(); jSeparator1 = new javax.swing.JSeparator(); - entryPanel = new javax.swing.JPanel(); + entryPanel = new RoundedPanel(20); // Use RoundedPanel jLabel2 = new javax.swing.JLabel(); jLabel3 = new javax.swing.JLabel(); jLabel4 = new javax.swing.JLabel(); @@ -51,44 +94,65 @@ private void initComponents() { addButton = new javax.swing.JButton(); deleteButton = new javax.swing.JButton(); clearButton = new javax.swing.JButton(); + + // Wrap Table in Rounded Panel + javax.swing.JPanel tablePanel = new RoundedPanel(20); + tablePanel.setLayout(new java.awt.BorderLayout()); + tablePanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(15, 15, 15, 15)); + jScrollPane1 = new javax.swing.JScrollPane(); userTable = new javax.swing.JTable(); - jLabel1.setFont(new java.awt.Font("Impact", 0, 24)); // NOI18N - jLabel1.setText("USERS"); + setBackground(new java.awt.Color(220, 230, 250)); - entryPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Enter User Details")); - - jLabel2.setText("Full Name:"); - - jLabel3.setText("Location:"); + jLabel1.setFont(new java.awt.Font("Segoe UI", 1, 24)); // NOI18N + jLabel1.setForeground(new java.awt.Color(50, 50, 50)); + jLabel1.setText("USERS"); - jLabel4.setText("Contact:"); + entryPanel.setBorder(javax.swing.BorderFactory.createEmptyBorder(20, 20, 20, 20)); // Added padding + // entryPanel.setBackground(new java.awt.Color(255, 255, 255)); - jLabel5.setText("Username:"); + // Labels + java.awt.Font labelFont = new java.awt.Font("Segoe UI", 1, 12); + java.awt.Color labelColor = java.awt.Color.BLACK; + jLabel2.setFont(labelFont); jLabel2.setForeground(labelColor); jLabel2.setText("Full Name"); + jLabel3.setFont(labelFont); jLabel3.setForeground(labelColor); jLabel3.setText("Location"); + jLabel4.setFont(labelFont); jLabel4.setForeground(labelColor); jLabel4.setText("Contact"); + jLabel5.setFont(labelFont); jLabel5.setForeground(labelColor); jLabel5.setText("Username"); + jLabel6.setFont(labelFont); jLabel6.setForeground(labelColor); jLabel6.setText("Password"); - jLabel6.setText("Password:"); + // Text Fields + java.awt.Font textFont = new java.awt.Font("Segoe UI", 0, 14); + javax.swing.border.Border textBorder = javax.swing.BorderFactory.createCompoundBorder( + javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 200, 200)), + javax.swing.BorderFactory.createEmptyBorder(5, 10, 5, 10) + ); + nameText.setFont(textFont); nameText.setBorder(textBorder); + locationText.setFont(textFont); locationText.setBorder(textBorder); + phoneText.setFont(textFont); phoneText.setBorder(textBorder); + usernameText.setFont(textFont); usernameText.setBorder(textBorder); + passText.setFont(textFont); passText.setBorder(textBorder); userTypeCombo.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "ADMINISTRATOR", "EMPLOYEE" })); + userTypeCombo.setFont(new java.awt.Font("Segoe UI", 0, 14)); + + // Buttons + styleButton(addButton, "Add", new java.awt.Color(65, 105, 225), java.awt.Color.BLACK); + styleButton(deleteButton, "Delete", new java.awt.Color(220, 53, 69), java.awt.Color.BLACK); + styleButton(clearButton, "Clear", new java.awt.Color(240, 240, 240), java.awt.Color.BLACK); - addButton.setText("Add"); - addButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); addButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { addButtonActionPerformed(evt); } }); - deleteButton.setText("Delete"); - deleteButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); deleteButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { deleteButtonActionPerformed(evt); } }); - clearButton.setText("Clear"); - clearButton.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); clearButton.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { clearButtonActionPerformed(evt); @@ -103,65 +167,57 @@ public void actionPerformed(java.awt.event.ActionEvent evt) { .addContainerGap() .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(userTypeCombo, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(nameText) + .addComponent(locationText) + .addComponent(phoneText) + .addComponent(usernameText) + .addComponent(passText) .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(nameText)) + .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jLabel2) + .addComponent(jLabel3) + .addComponent(jLabel4) + .addComponent(jLabel6) + .addComponent(jLabel5)) + .addGap(0, 0, Short.MAX_VALUE)) .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(locationText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(phoneText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(passText)) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(usernameText))) + .addComponent(clearButton, javax.swing.GroupLayout.DEFAULT_SIZE, 75, Short.MAX_VALUE))) .addContainerGap()) - .addGroup(entryPanelLayout.createSequentialGroup() - .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 78, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 75, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE)) ); entryPanelLayout.setVerticalGroup( entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(entryPanelLayout.createSequentialGroup() .addContainerGap() - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel2) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(locationText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(nameText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel3) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(phoneText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(locationText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel4) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel5, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(usernameText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(phoneText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel5) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(usernameText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addComponent(jLabel6) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE) - .addComponent(passText, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(passText, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) - .addComponent(userTypeCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 33, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(userTypeCombo, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) .addGap(18, 18, 18) .addGroup(entryPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(addButton) - .addComponent(deleteButton) - .addComponent(clearButton)) + .addComponent(addButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(deleteButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(clearButton, javax.swing.GroupLayout.PREFERRED_SIZE, 35, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) ); @@ -186,47 +242,63 @@ public boolean isCellEditable(int rowIndex, int columnIndex) { return canEdit [columnIndex]; } }); + userTable.setRowHeight(40); + userTable.setShowGrid(false); + userTable.setIntercellSpacing(new java.awt.Dimension(0, 0)); + userTable.setSelectionBackground(new java.awt.Color(232, 240, 254)); + userTable.setSelectionForeground(new java.awt.Color(0, 0, 0)); userTable.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); userTable.setName("Users"); // NOI18N - userTable.setShowGrid(true); userTable.addMouseListener(new java.awt.event.MouseAdapter() { public void mouseClicked(java.awt.event.MouseEvent evt) { userTableMouseClicked(evt); } }); jScrollPane1.setViewportView(userTable); + jScrollPane1.setBorder(javax.swing.BorderFactory.createEmptyBorder()); + jScrollPane1.getViewport().setBackground(java.awt.Color.WHITE); + + // Add ScrollPane to TablePanel + tablePanel.add(jScrollPane1, java.awt.BorderLayout.CENTER); javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this); this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSeparator1) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(entryPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(layout.createSequentialGroup() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 62, javax.swing.GroupLayout.PREFERRED_SIZE) - .addGap(0, 0, Short.MAX_VALUE))) - .addContainerGap()) + .addComponent(jLabel1) + .addGap(0, 0, Short.MAX_VALUE)) + .addGroup(layout.createSequentialGroup() + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE) // Use tablePanel + .addGap(20, 20, 20) + .addComponent(entryPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) + .addGap(20, 20, 20)) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(layout.createSequentialGroup() - .addContainerGap() - .addComponent(jLabel1, javax.swing.GroupLayout.PREFERRED_SIZE, 36, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jSeparator1, javax.swing.GroupLayout.PREFERRED_SIZE, 10, javax.swing.GroupLayout.PREFERRED_SIZE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGap(20, 20, 20) + .addComponent(jLabel1) + .addGap(20, 20, 20) .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addComponent(entryPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)) - .addGap(95, 95, 95)) + .addComponent(tablePanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addGap(20, 20, 20)) ); - }// //GEN-END:initComponents + } + + private void styleButton(javax.swing.JButton btn, String text, java.awt.Color bg, java.awt.Color fg) { + btn.setText(text); + btn.setBackground(bg); + btn.setForeground(fg); + btn.setFont(new java.awt.Font("Segoe UI", 1, 12)); + btn.setFocusPainted(false); + btn.setBorderPainted(false); + btn.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR)); + } private void clearButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_clearButtonActionPerformed nameText.setText(""); @@ -294,6 +366,7 @@ public void loadDataSet() { try { UserDAO userDAO = new UserDAO(); userTable.setModel(userDAO.buildTableModel(userDAO.getQueryResult())); + TableStyler.styleTable(userTable); } catch (SQLException ex) { ex.printStackTrace(); }