From d6fc00f2320baff978ddabc5f2faa155fd9847d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Th=C3=A0nh=20=C4=90=E1=BA=A1t?= <91755733+lds217@users.noreply.github.com> Date: Fri, 30 May 2025 01:01:01 +0700 Subject: [PATCH] [add] Update medical invoice format and enhance CheckUpPage UI with improved navigation and service details. Add checkout page --- medical_invoice.pdf | Bin 28553 -> 27149 bytes .../client/ui/assets/icon/cashier-machine.png | Bin 0 -> 11297 bytes .../BsK/client/ui/assets/icon/dashboard.png | Bin 0 -> 7856 bytes .../BsK/client/ui/assets/icon/database.png | Bin 0 -> 21578 bytes .../client/ui/assets/icon/health-check.png | Bin 0 -> 16562 bytes .../java/BsK/client/ui/assets/icon/info.png | Bin 0 -> 20169 bytes .../BsK/client/ui/assets/icon/warehouse.png | Bin 0 -> 11119 bytes .../ui/component/CheckUpPage/CheckUpPage.java | 108 ++- .../PrintDialog/EditableMedicalInvoice.java | 0 .../PrintDialog/MedicineInvoice.java | 315 ++++++--- .../CheckUpPage/PrintDialog/PrintDialog.java | 6 - .../component/CheckoutPage/CheckoutPage.java | 489 +++++++++++++ .../StandaloneMedicineDialog.java | 646 ++++++++++++++++++ .../DashboardPage/DashboardPage.java | 272 +++++--- 14 files changed, 1631 insertions(+), 205 deletions(-) create mode 100644 src/main/java/BsK/client/ui/assets/icon/cashier-machine.png create mode 100644 src/main/java/BsK/client/ui/assets/icon/dashboard.png create mode 100644 src/main/java/BsK/client/ui/assets/icon/database.png create mode 100644 src/main/java/BsK/client/ui/assets/icon/health-check.png create mode 100644 src/main/java/BsK/client/ui/assets/icon/info.png create mode 100644 src/main/java/BsK/client/ui/assets/icon/warehouse.png delete mode 100644 src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/EditableMedicalInvoice.java delete mode 100644 src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/PrintDialog.java create mode 100644 src/main/java/BsK/client/ui/component/CheckoutPage/CheckoutPage.java create mode 100644 src/main/java/BsK/client/ui/component/CheckoutPage/StandaloneMedicineDialog.java diff --git a/medical_invoice.pdf b/medical_invoice.pdf index dd4f5da6e739744d2a5225cd0957b57e76590f7a..d38a18b6520d701599a6309569dcde56c2fbd5b3 100644 GIT binary patch literal 27149 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 U+l#+E7!C)+F==RoWP~yQAKrhTy8r+H literal 28553 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 diff --git a/src/main/java/BsK/client/ui/assets/icon/cashier-machine.png b/src/main/java/BsK/client/ui/assets/icon/cashier-machine.png new file mode 100644 index 0000000000000000000000000000000000000000..58c827a5ca5d57b82bd5fe34dca3927320a3011d GIT binary patch literal 11297 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 V*&hA*jt)S6u*McfH3s-={{x1pz6<~W literal 0 HcmV?d00001 diff --git a/src/main/java/BsK/client/ui/assets/icon/dashboard.png b/src/main/java/BsK/client/ui/assets/icon/dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..11070022b542db40f49550ae72c26da571b894c1 GIT binary patch literal 7856 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 X%I>)ZO;{0tBmhcXPpw+T?&<#pEhfiU literal 0 HcmV?d00001 diff --git a/src/main/java/BsK/client/ui/assets/icon/info.png b/src/main/java/BsK/client/ui/assets/icon/info.png new file mode 100644 index 0000000000000000000000000000000000000000..a762a6c7a75298f892716580d8609baea0bb97af GIT binary patch literal 20169 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 literal 0 HcmV?d00001 diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java index 2a04f65..e2f1289 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/CheckUpPage.java @@ -26,6 +26,7 @@ import org.slf4j.LoggerFactory; import javax.swing.*; import javax.swing.border.TitledBorder; +import javax.swing.border.Border; import javax.swing.table.DefaultTableModel; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; @@ -73,6 +74,7 @@ public class CheckUpPage extends JPanel { private JComboBox callRoomComboBox; private JButton callPatientButton; private JLabel callingStatusLabel; + private JLabel activeNavItem = null; // To keep track of the active navigation item private QueueViewPage tvQueueFrame; @@ -157,49 +159,99 @@ public class CheckUpPage extends JPanel { JPanel navItemsPanel = new JPanel(); navItemsPanel.setBackground(new Color(63, 81, 181)); - navItemsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 20, 10)); + navItemsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 15)); // Increased vgap to 15 navItemsPanel.setAlignmentY(Component.CENTER_ALIGNMENT); - String[] navBarItems = {"Thống kê", "Thăm khám", "Dữ liệu", "Kho", "Người dùng", "Thông tin"}; - String[] destination = {"DashboardPage", "CheckUpPage", "PatientDataPage", "InventoryPage", "UserPage", "InfoPage"}; + String[] navBarItems = {"Thống kê", "Thăm khám", "Dữ liệu", "Kho", "Thanh toán", "Người dùng", "Thông tin"}; + String[] destination = {"DashboardPage", "CheckUpPage", "PatientDataPage", "InventoryPage", "CheckoutPage", "UserPage", "InfoPage"}; + String[] iconFiles = {"dashboard.png", "health-check.png", "database.png", "warehouse.png", "cashier-machine.png", "user.png", "info.png"}; // Icon files corresponding to items + + final Color defaultNavColor = new Color(63, 81, 181); // Base navbar color (transparent items) + final Color hoverNavColor = new Color(50, 70, 170); // Darker for hover + final Color activeNavColor = new Color(33, 150, 243); // Existing active/click color + + // Define borders + final Border defaultNavItemBorder = BorderFactory.createEmptyBorder(12, 15, 12, 15); // Increased top/bottom padding to 12 + final Border activePageSpecificBorder = BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 0, 3, 0, activeNavColor), + BorderFactory.createEmptyBorder(12, 15, 9, 15) // Adjusted padding for the border (12 top, 9 bottom to account for 3px border) + ); + for (int i = 0; i < navBarItems.length; i++) { - String item = navBarItems[i]; - String dest = destination[i]; - JLabel label = new JLabel(item); + final String itemText = navBarItems[i]; + final String dest = destination[i]; + String iconFileName = iconFiles[i]; + + final JLabel label = new JLabel(itemText); label.setForeground(Color.WHITE); label.setHorizontalAlignment(SwingConstants.CENTER); - label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - label.setFont(new Font("Arial", Font.BOLD, 14)); - label.setBorder(BorderFactory.createEmptyBorder(7, 15, 10, 15)); + label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + label.setFont(new Font("Arial", Font.BOLD, 12)); + label.setBorder(defaultNavItemBorder); // Apply default padding + label.setOpaque(false); // Default is transparent - if (item.equals("Thăm khám")) { - label.setBorder(BorderFactory.createMatteBorder(0, 0, 5, 0, new Color(33, 150, 243))); + try { + String iconPath = "src/main/java/BsK/client/ui/assets/icon/" + iconFileName; + ImageIcon originalIcon = new ImageIcon(iconPath); + Image scaledImage = originalIcon.getImage().getScaledInstance(36, 36, Image.SCALE_SMOOTH); // Icon size 36x36 + ImageIcon scaledIcon = new ImageIcon(scaledImage); + label.setIcon(scaledIcon); + } catch (Exception e) { + log.error("Error loading icon: {} for nav item: {}", iconFileName, itemText, e); } + + label.setVerticalTextPosition(SwingConstants.BOTTOM); + label.setHorizontalTextPosition(SwingConstants.CENTER); + + // Initial active state for "Thăm khám" + if (itemText.equals("Thăm khám")) { + label.setBorder(activePageSpecificBorder); + label.setBackground(activeNavColor); // Set background for active + label.setOpaque(true); + activeNavItem = label; // Set as initially active + } + label.addMouseListener(new java.awt.event.MouseAdapter() { @Override public void mouseClicked(java.awt.event.MouseEvent e) { - mainFrame.showPage(dest); - for (Component comp : navItemsPanel.getComponents()) { - JLabel lbl = (JLabel) comp; - lbl.setBackground(null); - lbl.setOpaque(false); + if (activeNavItem != null && activeNavItem != label) { + // Reset previous active item + activeNavItem.setBackground(defaultNavColor); // Or null for transparent against navBar + activeNavItem.setOpaque(false); + activeNavItem.setForeground(Color.WHITE); + activeNavItem.setBorder(defaultNavItemBorder); // Reset to default border } - label.setBackground(new Color(33, 150, 243)); - label.setOpaque(true); - label.setForeground(Color.WHITE); + + activeNavItem = label; + // Apply active styling + activeNavItem.setBackground(activeNavColor); + activeNavItem.setOpaque(true); + activeNavItem.setForeground(Color.WHITE); // Ensure text is white on active background + if (itemText.equals("Thăm khám")) { // Specific border for "Thăm khám" page + activeNavItem.setBorder(activePageSpecificBorder); + } else { + // For other items, active state might just be the background + default padding + // Or a generic active border if desired. For now, background is the main indicator. + activeNavItem.setBorder(defaultNavItemBorder); // Ensure it has correct padding + } + mainFrame.showPage(dest); } + @Override public void mouseEntered(java.awt.event.MouseEvent e) { - label.setForeground(new Color(200, 230, 255)); - label.setBackground(new Color(33, 150, 243)); - label.setOpaque(true); + if (label != activeNavItem) { + label.setForeground(new Color(200, 230, 255)); + label.setBackground(hoverNavColor); + label.setOpaque(true); + } } + @Override public void mouseExited(java.awt.event.MouseEvent e) { - if (label.getBackground() != new Color(33, 150, 243)) { - label.setForeground(Color.WHITE); - label.setBackground(null); - label.setOpaque(false); + if (label != activeNavItem) { + label.setForeground(Color.WHITE); + label.setBackground(defaultNavColor); // Or null + label.setOpaque(false); } } }); @@ -254,7 +306,7 @@ public class CheckUpPage extends JPanel { } }); navBar.add(welcomeLabel, BorderLayout.EAST); - navBar.setPreferredSize(new Dimension(1200, 50)); + navBar.setPreferredSize(new Dimension(1200, 85)); // Increased preferred height to 85 // Panels RoundedPanel leftPanel = new RoundedPanel(20, Color.WHITE, false); @@ -534,7 +586,7 @@ public class CheckUpPage extends JPanel { genderComboBox.getSelectedItem().toString(), customerAddressField.getText() + ", " + (wardComboBox.getSelectedItem() != null ? wardComboBox.getSelectedItem().toString() : "") + ", " + (districtComboBox.getSelectedItem() != null ? districtComboBox.getSelectedItem().toString() : "") + ", " + (provinceComboBox.getSelectedItem() != null ? provinceComboBox.getSelectedItem().toString() : ""), doctorComboBox.getSelectedItem().toString(), diagnosisField.getText(), - notesField.getText(), medicinePrescription); + notesField.getText(), medicinePrescription, servicePrescription); medicineInvoice.createDialog(mainFrame); break; default: diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/EditableMedicalInvoice.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/EditableMedicalInvoice.java deleted file mode 100644 index e69de29..0000000 diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/MedicineInvoice.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/MedicineInvoice.java index 7343dd2..92d0178 100644 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/MedicineInvoice.java +++ b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/MedicineInvoice.java @@ -29,6 +29,7 @@ import java.io.*; import java.util.ArrayList; import java.time.LocalDate; import java.time.format.DateTimeFormatter; +import java.text.DecimalFormat; public class MedicineInvoice{ @@ -44,6 +45,8 @@ public class MedicineInvoice{ private String date; private String id; private String[][] med; // Name, Quantity, Price + private String[][] services; // Name, Quantity, Price + private static final DecimalFormat vndFormatter = new DecimalFormat("#,##0"); public static void main(String[] args) { SwingUtilities.invokeLater(() -> { @@ -51,10 +54,15 @@ public class MedicineInvoice{ openDialogButton.addActionListener(e -> new MedicineInvoice("1212", "Nguyễn Văn A", "01/01/1990", "0123456789", "Nam", "123 Đường ABC, Quận XYZ, TP HCM", "Bác sĩ XYZ", "Sốt cao", - "Nghỉ ngơi nhiều, uống nhiều nước", new String[][]{ + "Nghỉ ngơi nhiều, uống nhiều nước", + new String[][]{ {"Paracetamol", "2", "5000"}, {"Vitamin C", "1", "10000"}, {"Amoxicillin", "1", "20000"} + }, + new String[][] { + {"Khám tổng quát", "1", "150000"}, + {"Xét nghiệm máu", "1", "80000"} } ).createDialog(null)); JFrame frame = new JFrame("Main Application"); @@ -68,7 +76,7 @@ public class MedicineInvoice{ public MedicineInvoice(String id, String patientName, String patientDOB, String patientPhone, String patientGender, String patientAddress, String doctorName, String diagnosis, - String notes, String[][] med) { + String notes, String[][] med, String[][] services) { this.id = id; this.patientName = patientName; this.patientDOB = patientDOB; @@ -87,13 +95,14 @@ public class MedicineInvoice{ this.date = formattedDate; this.med = med; + this.services = services; } public void createDialog(JFrame parent) { dialog = new JDialog(parent, "Medicine Invoice", true); dialog.setSize(600, 600); - dialog.setResizable(false); + dialog.setResizable(true); dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); dialog.setLayout(new BorderLayout()); @@ -163,98 +172,246 @@ public class MedicineInvoice{ private void generatePdf(String pdfPath) throws Exception { PdfWriter writer = new PdfWriter(pdfPath); PdfDocument pdfDoc = new PdfDocument(writer); - Document document = new Document(pdfDoc); + Document document = new Document(pdfDoc); // Default A4 size + // Set document margins - REDUCED + document.setMargins(20, 25, 20, 25); // Smaller margins (top, right, bottom, left) - String boldFontPath = "src/main/java/BsK/client/ui/assets/font/SVN-Arial Bold.ttf"; // Update with your font path + String boldFontPath = "src/main/java/BsK/client/ui/assets/font/SVN-Arial Bold.ttf"; PdfFont boldFont = PdfFontFactory.createFont(boldFontPath, "Identity-H", true); - String fontPath = "src/main/java/BsK/client/ui/assets/font/SVN-Arial Regular.ttf"; // Update with your font path + String fontPath = "src/main/java/BsK/client/ui/assets/font/SVN-Arial Regular.ttf"; PdfFont font = PdfFontFactory.createFont(fontPath, "Identity-H", true); - // Add logo - String logoPath = "src/main/java/BsK/client/ui/assets/icon/add.png"; // Path to your logo - ImageData imageData = ImageDataFactory.create(logoPath); - Image logo = new Image(imageData).scaleToFit(75, 75); - logo.setFixedPosition(50, 750); - document.add(logo); + // --- HEADER SECTION --- + Table headerTable = new Table(UnitValue.createPercentArray(new float[]{1.5f, 3.5f})) + .setWidth(UnitValue.createPercentValue(100)) + .setBorder(Border.NO_BORDER) + .setMarginBottom(5); // Reduced margin bottom - // Add clinic information - String clinicInfo = String.format("%s\n%s\nSố điện thoại: %s\nNgày: %s", LocalStorage.ClinicName, - LocalStorage.ClinicAddress, LocalStorage.ClinicPhone, date); - Paragraph clinicInfoParagraph = new Paragraph(clinicInfo) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT) + try { + String logoPath = "src/main/java/BsK/client/ui/assets/icon/clinic_logo.png"; + ImageData imageData = ImageDataFactory.create(logoPath); + Image logo = new Image(imageData).scaleToFit(60, 60).setMarginRight(15); // Slightly smaller logo & margin + headerTable.addCell(new Cell().add(logo).setBorder(Border.NO_BORDER).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + } catch (Exception e) { + headerTable.addCell(new Cell().setBorder(Border.NO_BORDER)); + System.err.println("Logo image not found or error loading: " + e.getMessage()); + } + + Paragraph clinicInfoParagraph = new Paragraph() + .add(new Text(LocalStorage.ClinicName + "\n").setFont(boldFont).setFontSize(12)) // Reduced font + .add(new Text("Địa chỉ: " + LocalStorage.ClinicAddress + "\n").setFontSize(9)) // Reduced font + .add(new Text("Điện thoại: " + LocalStorage.ClinicPhone).setFontSize(9)) // Reduced font .setFont(font); - document.add(clinicInfoParagraph); + headerTable.addCell(new Cell().add(clinicInfoParagraph) + .setTextAlignment(com.itextpdf.layout.property.TextAlignment.LEFT) + .setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE) + .setBorder(Border.NO_BORDER).setPaddingLeft(5)); // Reduced padding + + document.add(headerTable); - // Add title - String title = "TOA THUỐC\n"; - Paragraph titleParagraph = new Paragraph(title) - .setFontSize(24).setFont(boldFont) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER); + // --- INVOICE TITLE --- + Paragraph titleParagraph = new Paragraph("TOA THUỐC") + .setFontSize(18).setFont(boldFont) // Reduced font size + .setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER) + .setMarginBottom(8); // Reduced margin document.add(titleParagraph); - // Create a table with 2 columns, each taking 50% of the width - Table patientDoctorTable = new Table(UnitValue.createPercentArray(new float[]{50, 50})) - .setWidth(UnitValue.createPercentValue(100)); + // --- PATIENT AND INVOICE DETAILS SECTION --- + Table patientDoctorTable = new Table(UnitValue.createPercentArray(new float[]{55, 45})) // Adjusted column widths + .setWidth(UnitValue.createPercentValue(100)) + .setFontSize(9).setFont(font) // Reduced font size + .setMarginBottom(8); // Reduced margin - // Add patient and doctor information in the first column (left-aligned) - Cell patientDoctorCell = new Cell() - .add(new Paragraph(String.format("Họ và tên: %s\nNgày sinh: %s\nSố điện thoại: %s\nĐịa chỉ: %s", - patientName, patientDOB, patientPhone, patientAddress))) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.LEFT) - .setBorder(Border.NO_BORDER) - .setFont(font); - patientDoctorTable.addCell(patientDoctorCell); + Cell patientInfoCell = new Cell().setBorder(Border.NO_BORDER).setPadding(3); // Reduced padding + Paragraph pName = new Paragraph().add(new Text("Họ và tên: ").setFont(boldFont)).add(patientName); + pName.setMultipliedLeading(1.0f); + patientInfoCell.add(pName); + Paragraph pDOB = new Paragraph().add(new Text("Ngày sinh: ").setFont(boldFont)).add(patientDOB); + pDOB.setMultipliedLeading(1.0f); + patientInfoCell.add(pDOB); + Paragraph pGender = new Paragraph().add(new Text("Giới tính: ").setFont(boldFont)).add(patientGender); + pGender.setMultipliedLeading(1.0f); + patientInfoCell.add(pGender); + Paragraph pPhone = new Paragraph().add(new Text("Số điện thoại: ").setFont(boldFont)).add(patientPhone); + pPhone.setMultipliedLeading(1.0f); + patientInfoCell.add(pPhone); + Paragraph pAddress = new Paragraph().add(new Text("Địa chỉ: ").setFont(boldFont)).add(patientAddress); + pAddress.setMultipliedLeading(1.0f); + patientInfoCell.add(pAddress); + patientDoctorTable.addCell(patientInfoCell); - // Add date and invoice information in the second column (right-aligned) - Cell moreInfoCell = new Cell() - .add(new Paragraph(String.format("Phái: %s\nBác sĩ: %s\nĐơn thuốc số: %s", - patientGender, doctorName, id))) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.LEFT) - .setBorder(Border.NO_BORDER) - .setFont(font); - patientDoctorTable.addCell(moreInfoCell); - - // Add the table to the document + Cell doctorInvoiceCell = new Cell().setBorder(Border.NO_BORDER).setPadding(3); // Reduced padding + Paragraph pDoctor = new Paragraph().add(new Text("Bác sĩ: ").setFont(boldFont)).add(doctorName); + pDoctor.setMultipliedLeading(1.0f); + doctorInvoiceCell.add(pDoctor); + Paragraph pDate = new Paragraph().add(new Text("Ngày lập: ").setFont(boldFont)).add(date); + pDate.setMultipliedLeading(1.0f); + doctorInvoiceCell.add(pDate); + Paragraph pInvoiceId = new Paragraph().add(new Text("Đơn thuốc số: ").setFont(boldFont)).add(id); + pInvoiceId.setMultipliedLeading(1.0f); + doctorInvoiceCell.add(pInvoiceId); + Paragraph pSpace1 = new Paragraph(" "); + pSpace1.setMultipliedLeading(1.0f); + doctorInvoiceCell.add(pSpace1); + Paragraph pSpace2 = new Paragraph(" "); + pSpace2.setMultipliedLeading(1.0f); + doctorInvoiceCell.add(pSpace2); + patientDoctorTable.addCell(doctorInvoiceCell); + document.add(patientDoctorTable); - // Diagnosis and notes - String diagnosisNotes = String.format("Chẩn đoán: %s\nGhi chú: %s\n", diagnosis, notes); - Paragraph diagnosisNotesParagraph = new Paragraph(diagnosisNotes).setFont(font); - document.add(diagnosisNotesParagraph); + // --- DIAGNOSIS AND NOTES --- + Paragraph diagnosisParagraph = new Paragraph(); + diagnosisParagraph.add(new Text("Chẩn đoán: ").setFont(boldFont)).add(diagnosis); + diagnosisParagraph.setFont(font).setFontSize(9).setMarginBottom(2).setMultipliedLeading(1.0f); + document.add(diagnosisParagraph); - - // Add services and medicine table - Table table = new Table(UnitValue.createPercentArray(new float[]{4, 2, 2})) - .setFont(font) - .setWidth(UnitValue.createPercentValue(100)) - .setBorder(Border.NO_BORDER); - table.addHeaderCell("Service/Medicine"); - table.addHeaderCell("Quantity"); - table.addHeaderCell("Price"); - long total = 0; - for(int i = 0; i < med.length; i++) { - table.addCell(med[i][1]); - table.addCell(med[i][4]); - table.addCell(med[i][6]); - total += Long.parseLong(med[i][4]) * Long.parseLong(med[i][6]); + if (notes != null && !notes.trim().isEmpty()) { + Paragraph notesParagraph = new Paragraph(); + notesParagraph.add(new Text("Ghi chú (chung): ").setFont(boldFont)).add(notes); + notesParagraph.setFont(font).setFontSize(9).setMarginBottom(5).setMultipliedLeading(1.0f); + document.add(notesParagraph); + } else { + document.add(new Paragraph().setMarginBottom(5)); } - // Merge the last row for total - Cell totalCell = new Cell(1, 2) - .add(new Paragraph("Tổng cộng")) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT); - table.addCell(totalCell); - table.addCell(new Cell().add(new Paragraph(String.valueOf(total))) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.LEFT)); - document.add(table); + // --- MEDICINE TABLE --- + Paragraph medicineSectionTitle = new Paragraph("CHI TIẾT THUỐC") + .setFont(boldFont).setFontSize(11) // Reduced font size + .setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER) + .setMarginTop(3).setMarginBottom(3); // Reduced margins + document.add(medicineSectionTitle); + + Table medTable = new Table(UnitValue.createPercentArray(new float[]{3.8f, 1.7f, 1.5f, 1.5f, 2.5f})) // Adjusted column widths + .setWidth(UnitValue.createPercentValue(100)) + .setFontSize(8).setFont(font) // Reduced font size for table content + .setMarginBottom(5); // Reduced margin - // Add signature area - Paragraph signatureArea = new Paragraph("\n\n\nChữ Ký: ________________________") - .setFont(font) - .setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT); - document.add(signatureArea); + medTable.addHeaderCell(new Cell().add(new Paragraph("Tên thuốc")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + medTable.addHeaderCell(new Cell().add(new Paragraph("Liều dùng")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + medTable.addHeaderCell(new Cell().add(new Paragraph("Số lượng")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + medTable.addHeaderCell(new Cell().add(new Paragraph("Đơn giá (VNĐ)")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + medTable.addHeaderCell(new Cell().add(new Paragraph("Thành tiền (VNĐ)")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + + long medicineTotal = 0; + if (med != null) { + for (String[] medicine : med) { + if (medicine == null || medicine.length < 10) { + medTable.addCell(new Cell(1, 5).add(new Paragraph("Thông tin thuốc không đầy đủ").setItalic().setFontSize(8)).setPadding(2)); + continue; + } + Paragraph medNameAndNote = new Paragraph(); + medNameAndNote.add(new Text(medicine[1]).setFontSize(8)); + if (medicine[9] != null && !medicine[9].isEmpty()) { + medNameAndNote.add(new Text("\nGhi chú: " + medicine[9]).setFontSize(7).setItalic()); + } + medNameAndNote.setMultipliedLeading(1.0f); + medTable.addCell(new Cell().add(medNameAndNote).setPadding(2)); + + String dosageInfo = String.format("S: %s, T: %s, C: %s", medicine[4], medicine[5], medicine[6]); + medTable.addCell(new Cell().add(new Paragraph(dosageInfo).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + medTable.addCell(new Cell().add(new Paragraph(medicine[2] + " " + medicine[3]).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + try { + medTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(Long.parseLong(medicine[7]))).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + medTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(Long.parseLong(medicine[8]))).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + medicineTotal += Long.parseLong(medicine[8]); + } catch (NumberFormatException e) { + System.err.println("Error parsing medicine price/total: " + medicine[7] + " or " + medicine[8]); + medTable.addCell(new Cell().add(new Paragraph("Lỗi giá")).setFontSize(8).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + medTable.addCell(new Cell().add(new Paragraph("Lỗi giá")).setFontSize(8).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + } + } + } + document.add(medTable); + + Table medTotalTable = new Table(UnitValue.createPercentArray(new float[]{7.5f, 2.5f})) + .setWidth(UnitValue.createPercentValue(100)).setBorder(Border.NO_BORDER).setMarginBottom(3); + medTotalTable.addCell(new Cell().add(new Paragraph("Tổng tiền thuốc:")).setFont(boldFont).setFontSize(9).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setBorder(Border.NO_BORDER).setPadding(1)); + medTotalTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(medicineTotal) + " VNĐ")).setFont(boldFont).setFontSize(9).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setBorder(Border.NO_BORDER).setPadding(1)); + document.add(medTotalTable); + + long overallTotal = medicineTotal; + + // --- SERVICES TABLE --- + if (services != null && services.length > 0) { + Paragraph serviceSectionTitle = new Paragraph("CHI TIẾT DỊCH VỤ") + .setFont(boldFont).setFontSize(11) // Reduced font size + .setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER) + .setMarginTop(5).setMarginBottom(3); // Reduced margins + document.add(serviceSectionTitle); + + Table serviceTable = new Table(UnitValue.createPercentArray(new float[]{4.5f, 1.5f, 2f, 2.5f})) // Adjusted column widths + .setWidth(UnitValue.createPercentValue(100)) + .setFontSize(8).setFont(font) // Reduced font size for table content + .setMarginBottom(5); // Reduced margin + + serviceTable.addHeaderCell(new Cell().add(new Paragraph("Tên dịch vụ")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + serviceTable.addHeaderCell(new Cell().add(new Paragraph("Số lượng")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + serviceTable.addHeaderCell(new Cell().add(new Paragraph("Đơn giá (VNĐ)")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + serviceTable.addHeaderCell(new Cell().add(new Paragraph("Thành tiền (VNĐ)")).setFont(boldFont).setFontSize(9).setBackgroundColor(com.itextpdf.kernel.colors.ColorConstants.LIGHT_GRAY).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2)); + + long serviceTotal = 0; + for (String[] service : services) { + if (service == null || service.length < 5) { + serviceTable.addCell(new Cell(1, 4).add(new Paragraph("Thông tin dịch vụ không đầy đủ").setItalic().setFontSize(8)).setPadding(2)); + continue; + } + Paragraph serNameAndNote = new Paragraph(); + serNameAndNote.add(new Text(service[1]).setFontSize(8)); + if (service.length > 5 && service[5] != null && !service[5].isEmpty()) { + serNameAndNote.add(new Text("\nGhi chú: " + service[5]).setFontSize(7).setItalic()); + } + serNameAndNote.setMultipliedLeading(1.0f); + serviceTable.addCell(new Cell().add(serNameAndNote).setPadding(2)); + serviceTable.addCell(new Cell().add(new Paragraph(service[2]).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + try { + serviceTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(Long.parseLong(service[3]))).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + serviceTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(Long.parseLong(service[4]))).setFontSize(8)).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + serviceTotal += Long.parseLong(service[4]); + } catch (NumberFormatException e) { + System.err.println("Error parsing service price/total: " + service[3] + " or " + service[4]); + serviceTable.addCell(new Cell().add(new Paragraph("Lỗi giá")).setFontSize(8).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + serviceTable.addCell(new Cell().add(new Paragraph("Lỗi giá")).setFontSize(8).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setPadding(2).setVerticalAlignment(com.itextpdf.layout.property.VerticalAlignment.MIDDLE)); + } + } + document.add(serviceTable); + overallTotal += serviceTotal; + + Table serTotalTable = new Table(UnitValue.createPercentArray(new float[]{7.5f, 2.5f})) + .setWidth(UnitValue.createPercentValue(100)).setBorder(Border.NO_BORDER).setMarginBottom(3); + serTotalTable.addCell(new Cell().add(new Paragraph("Tổng tiền dịch vụ:")).setFont(boldFont).setFontSize(9).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setBorder(Border.NO_BORDER).setPadding(1)); + serTotalTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(serviceTotal) + " VNĐ")).setFont(boldFont).setFontSize(9).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setBorder(Border.NO_BORDER).setPadding(1)); + document.add(serTotalTable); + } + + // --- OVERALL TOTAL --- + document.add(new LineSeparator(new com.itextpdf.kernel.pdf.canvas.draw.SolidLine(0.5f)).setMarginTop(5).setMarginBottom(3)); + Table overallTotalTable = new Table(UnitValue.createPercentArray(new float[]{7.5f, 2.5f})) + .setWidth(UnitValue.createPercentValue(100)).setBorder(Border.NO_BORDER).setMarginBottom(10); + overallTotalTable.addCell(new Cell().add(new Paragraph("TỔNG CỘNG THANH TOÁN:")).setFont(boldFont).setFontSize(10).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setBorder(Border.NO_BORDER).setPadding(1)); + overallTotalTable.addCell(new Cell().add(new Paragraph(vndFormatter.format(overallTotal) + " VNĐ")).setFont(boldFont).setFontSize(10).setTextAlignment(com.itextpdf.layout.property.TextAlignment.RIGHT).setBorder(Border.NO_BORDER).setPadding(1)); + document.add(overallTotalTable); + + // --- SIGNATURE AREA --- + Table signatureTable = new Table(UnitValue.createPercentArray(new float[]{50, 50})) + .setWidth(UnitValue.createPercentValue(100)) + .setBorder(Border.NO_BORDER) + .setMarginTop(15); // Reduced margin + + signatureTable.addCell(new Cell().setBorder(Border.NO_BORDER)); + + Paragraph signatureParagraph = new Paragraph(); // Initialize paragraph + signatureParagraph.add(new Text("Ngày " + date.substring(0,2) + " tháng " + date.substring(3,5) + " năm " + date.substring(6) + "\n").setFontSize(9)); + signatureParagraph.add(new Text("Bác sĩ điều trị\n\n\n").setFontSize(9)); // Reduced newlines for space + signatureParagraph.add(new Text("(Ký, ghi rõ họ tên)").setFontSize(8).setItalic()); + signatureParagraph.setFont(font) + .setTextAlignment(com.itextpdf.layout.property.TextAlignment.CENTER) + .setMultipliedLeading(1.0f); // Applied to the Paragraph + + signatureTable.addCell(new Cell().add(signatureParagraph).setBorder(Border.NO_BORDER)); + document.add(signatureTable); document.close(); } @@ -288,6 +445,12 @@ public class MedicineInvoice{ // Put the panel inside a JScrollPane to make it scrollable JScrollPane scrollPane = new JScrollPane(pdfPanel); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); // Added for horizontal scroll if needed + + // Increase scroll sensitivity + JScrollBar verticalScrollBar = scrollPane.getVerticalScrollBar(); + verticalScrollBar.setUnitIncrement(20); // Increase for finer control, adjust as needed + verticalScrollBar.setBlockIncrement(100); // Increase for page-like scrolling, adjust as needed // Assuming `dialog` is the parent component dialog.add(scrollPane, BorderLayout.CENTER); diff --git a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/PrintDialog.java b/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/PrintDialog.java deleted file mode 100644 index c2671a0..0000000 --- a/src/main/java/BsK/client/ui/component/CheckUpPage/PrintDialog/PrintDialog.java +++ /dev/null @@ -1,6 +0,0 @@ -package BsK.client.ui.component.CheckUpPage.PrintDialog; - - -public class PrintDialog { - -} diff --git a/src/main/java/BsK/client/ui/component/CheckoutPage/CheckoutPage.java b/src/main/java/BsK/client/ui/component/CheckoutPage/CheckoutPage.java new file mode 100644 index 0000000..4d1aab5 --- /dev/null +++ b/src/main/java/BsK/client/ui/component/CheckoutPage/CheckoutPage.java @@ -0,0 +1,489 @@ +package BsK.client.ui.component.CheckoutPage; + +import BsK.client.LocalStorage; +import BsK.client.ui.component.MainFrame; +import BsK.client.ui.component.CheckoutPage.StandaloneMedicineDialog; +import BsK.client.ui.component.common.RoundedPanel; +import lombok.extern.slf4j.Slf4j; + +import javax.swing.*; +import javax.swing.border.Border; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.text.SimpleDateFormat; +import java.util.Date; + +@Slf4j +public class CheckoutPage extends JPanel { + private JLabel activeNavItem = null; + private MainFrame mainFrame; + + // Left Panel Components + private JTable finishedCheckupTable; + private DefaultTableModel finishedCheckupTableModel; + private JButton newStandaloneBillButton; + + // Right Panel Components (Bill Details) + private JLabel billIdLabel; + private JLabel billDateLabel; + private JTextField customerNameField; // For standalone bills + private JTextField customerPhoneField; // For standalone bills + private JTextField barcodeField; + private JButton scanBarcodeButton; + private JButton addMedicineItemButton; + private JButton removeMedicineItemButton; + private JTable billItemsTable; + private DefaultTableModel billItemsTableModel; + private JLabel subtotalAmountLabel; + private JTextField discountField; + private JLabel grandTotalAmountLabel; + private JButton processPaymentButton; + private JButton printBillButton; + + private StandaloneMedicineDialog standaloneMedicineDialog; + + + public CheckoutPage(MainFrame mainFrame) { + this.mainFrame = mainFrame; + setLayout(new BorderLayout()); + setBackground(new Color(240, 240, 240)); + + // --- Navigation Bar --- + JPanel navBar = new JPanel(); + navBar.setBackground(new Color(63, 81, 181)); + navBar.setLayout(new BoxLayout(navBar, BoxLayout.X_AXIS)); + + JPanel navItemsPanel = new JPanel(); + navItemsPanel.setBackground(new Color(63, 81, 181)); + navItemsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 15)); + navItemsPanel.setAlignmentY(Component.CENTER_ALIGNMENT); + + String[] navBarItems = {"Thống kê", "Thăm khám", "Dữ liệu", "Kho", "Thanh toán", "Người dùng", "Thông tin"}; + String[] destination = {"DashboardPage", "CheckUpPage", "PatientDataPage", "InventoryPage", "CheckoutPage", "UserPage", "InfoPage"}; + String[] iconFiles = {"dashboard.png", "health-check.png", "database.png", "warehouse.png", "cashier-machine.png", "user.png", "info.png"}; + + final Color defaultNavColor = new Color(63, 81, 181); + final Color hoverNavColor = new Color(50, 70, 170); + final Color activeNavColor = new Color(33, 150, 243); + + final Border defaultNavItemBorder = BorderFactory.createEmptyBorder(12, 15, 12, 15); + final Border activeCheckoutSpecificBorder = BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 0, 3, 0, activeNavColor), + BorderFactory.createEmptyBorder(12, 15, 9, 15) + ); + + for (int i = 0; i < navBarItems.length; i++) { + final String itemText = navBarItems[i]; + final String dest = destination[i]; + String iconFileName = iconFiles[i]; + final JLabel label = new JLabel(itemText); + // ... (rest of nav item setup - copied from DashboardPage/CheckUpPage) + label.setForeground(Color.WHITE); + label.setHorizontalAlignment(SwingConstants.CENTER); + label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + label.setFont(new Font("Arial", Font.BOLD, 12)); + label.setBorder(defaultNavItemBorder); + label.setOpaque(false); + + try { + String iconPath = "src/main/java/BsK/client/ui/assets/icon/" + iconFileName; + ImageIcon originalIcon = new ImageIcon(iconPath); + Image scaledImage = originalIcon.getImage().getScaledInstance(36, 36, Image.SCALE_SMOOTH); + ImageIcon scaledIcon = new ImageIcon(scaledImage); + label.setIcon(scaledIcon); + } catch (Exception e) { + log.error("Error loading icon: {} for nav item: {}", iconFileName, itemText, e); + } + + label.setVerticalTextPosition(SwingConstants.BOTTOM); + label.setHorizontalTextPosition(SwingConstants.CENTER); + + if (itemText.equals("Thanh toán")) { // Highlight "Thanh toán" as active + label.setBorder(activeCheckoutSpecificBorder); + label.setBackground(activeNavColor); + label.setOpaque(true); + activeNavItem = label; + } + + label.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (activeNavItem != null && activeNavItem != label) { + activeNavItem.setBackground(defaultNavColor); + activeNavItem.setOpaque(false); + activeNavItem.setForeground(Color.WHITE); + activeNavItem.setBorder(defaultNavItemBorder); + } + activeNavItem = label; + activeNavItem.setBackground(activeNavColor); + activeNavItem.setOpaque(true); + activeNavItem.setForeground(Color.WHITE); + if (itemText.equals("Thanh toán")) { + activeNavItem.setBorder(activeCheckoutSpecificBorder); + } else { + activeNavItem.setBorder(defaultNavItemBorder); + } + mainFrame.showPage(dest); + } + @Override + public void mouseEntered(MouseEvent e) { if (label != activeNavItem) { label.setForeground(new Color(200, 230, 255)); label.setBackground(hoverNavColor);label.setOpaque(true);}} + @Override + public void mouseExited(MouseEvent e) { if (label != activeNavItem) { label.setForeground(Color.WHITE); label.setBackground(defaultNavColor); label.setOpaque(false);}} + }); + navItemsPanel.add(label); + } + + navBar.add(navItemsPanel); + navBar.add(Box.createHorizontalGlue()); + JLabel welcomeLabel = new JLabel("Chào, " + LocalStorage.username + " "); + // ... (rest of welcomeLabel setup - copied from DashboardPage/CheckUpPage) + welcomeLabel.setForeground(Color.WHITE); + welcomeLabel.setHorizontalAlignment(SwingConstants.CENTER); + welcomeLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + welcomeLabel.setFont(new Font("Arial", Font.BOLD, 14)); + welcomeLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isLeftMouseButton(e)) { + JPopupMenu popupMenu = new JPopupMenu(); + JMenuItem profileItem = new JMenuItem("Hồ sơ cá nhân"); + JMenuItem settingsItem = new JMenuItem("Cài đặt"); + JMenuItem logoutItem = new JMenuItem("Đăng xuất"); + + profileItem.addActionListener(event -> { + JOptionPane.showMessageDialog(mainFrame, "Tính năng Hồ sơ cá nhân sắp ra mắt!", "Thông báo", JOptionPane.INFORMATION_MESSAGE); + }); + settingsItem.addActionListener(event -> { + JOptionPane.showMessageDialog(mainFrame, "Tính năng Cài đặt sắp ra mắt!", "Thông báo", JOptionPane.INFORMATION_MESSAGE); + }); + logoutItem.addActionListener(event -> { + // TODO: Implement actual logout with NetworkUtil.sendPacket if ClientHandler is available + // NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new LogoutRequest()); + LocalStorage.username = null; + LocalStorage.userId = -1; + mainFrame.showPage("LandingPage"); + }); + popupMenu.add(profileItem); + popupMenu.add(settingsItem); + popupMenu.addSeparator(); + popupMenu.add(logoutItem); + popupMenu.setPreferredSize(new Dimension(150, popupMenu.getPreferredSize().height)); + popupMenu.show(welcomeLabel, 0, welcomeLabel.getHeight()); + } + } + @Override + public void mouseEntered(MouseEvent e) { welcomeLabel.setForeground(new Color(200, 230, 255)); } + @Override + public void mouseExited(MouseEvent e) { welcomeLabel.setForeground(Color.WHITE); } + }); + navBar.add(welcomeLabel); + navBar.setPreferredSize(new Dimension(1200, 85)); + add(navBar, BorderLayout.NORTH); + + // --- Main Content Area --- + JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + mainSplitPane.setResizeWeight(0.35); // Give more space to bill details initially + mainSplitPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); + + // --- Left Panel: Queues and New Bill --- + JPanel leftPanel = new JPanel(new BorderLayout(10, 10)); + leftPanel.setBorder(BorderFactory.createEmptyBorder(10,0,0,0)); + + // Finished Checkup Queue Panel + RoundedPanel finishedQueuePanel = new RoundedPanel(15, Color.WHITE, false); + finishedQueuePanel.setLayout(new BorderLayout()); + finishedQueuePanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createLineBorder(new Color(63, 81, 181), 1, true), + "Chờ thanh toán (đã khám)", + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 16), new Color(63, 81, 181) + )); + + String[] finishedColumns = {"Mã Bill", "Tên BN", "Tổng tiền", "Trạng thái"}; + finishedCheckupTableModel = new DefaultTableModel(new Object[][]{}, finishedColumns) { + public boolean isCellEditable(int row, int column) { return false; } + }; + finishedCheckupTable = new JTable(finishedCheckupTableModel); + finishedCheckupTable.setRowHeight(25); + finishedCheckupTable.getTableHeader().setFont(new Font("Arial", Font.BOLD, 14)); + finishedCheckupTable.setFont(new Font("Arial", Font.PLAIN, 12)); + JScrollPane finishedTableScroll = new JScrollPane(finishedCheckupTable); + finishedQueuePanel.add(finishedTableScroll, BorderLayout.CENTER); + // TODO: Populate this table with patients who have Status.COMPLETED_CHECKUP or similar + // TODO: Add MouseListener to finishedCheckupTable to load bill details on selection + + leftPanel.add(finishedQueuePanel, BorderLayout.CENTER); + + newStandaloneBillButton = new JButton("Tạo hóa đơn mới (khách lẻ)"); + newStandaloneBillButton.setFont(new Font("Arial", Font.BOLD, 14)); + newStandaloneBillButton.setBackground(new Color(0, 150, 136)); + newStandaloneBillButton.setForeground(Color.WHITE); + newStandaloneBillButton.setFocusPainted(false); + newStandaloneBillButton.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + newStandaloneBillButton.setBorder(BorderFactory.createEmptyBorder(10,15,10,15)); + newStandaloneBillButton.addActionListener(e -> createNewStandaloneBill()); + JPanel newBillButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + newBillButtonPanel.setOpaque(false); + newBillButtonPanel.add(newStandaloneBillButton); + leftPanel.add(newBillButtonPanel, BorderLayout.SOUTH); + + mainSplitPane.setLeftComponent(leftPanel); + + // --- Right Panel: Bill Details --- + RoundedPanel rightPanel = new RoundedPanel(15, Color.WHITE, false); + rightPanel.setLayout(new BorderLayout(10,10)); + rightPanel.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(0, 10, 0, 0), + BorderFactory.createTitledBorder( + BorderFactory.createLineBorder(new Color(63, 81, 181), 1, true), + "Chi tiết hóa đơn", + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 16), new Color(63, 81, 181) + ) + )); + + JPanel billInfoAndActionsPanel = new JPanel(new GridBagLayout()); + GridBagConstraints gbc = new GridBagConstraints(); + gbc.insets = new Insets(5,5,5,5); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.anchor = GridBagConstraints.WEST; + + // Bill Info (ID, Date, Customer for standalone) + gbc.gridx = 0; gbc.gridy = 0; billInfoAndActionsPanel.add(new JLabel("Mã HĐ:"), gbc); + gbc.gridx = 1; billIdLabel = new JLabel("N/A"); billInfoAndActionsPanel.add(billIdLabel, gbc); + gbc.gridx = 2; billInfoAndActionsPanel.add(new JLabel("Ngày:"), gbc); + gbc.gridx = 3; billDateLabel = new JLabel(new SimpleDateFormat("dd/MM/yyyy").format(new Date())); billInfoAndActionsPanel.add(billDateLabel, gbc); + + gbc.gridx = 0; gbc.gridy = 1; billInfoAndActionsPanel.add(new JLabel("Tên KH (lẻ):"), gbc); + gbc.gridx = 1; gbc.gridwidth=3; customerNameField = new JTextField(20); billInfoAndActionsPanel.add(customerNameField, gbc); gbc.gridwidth=1; + gbc.gridx = 0; gbc.gridy = 2; billInfoAndActionsPanel.add(new JLabel("SĐT KH (lẻ):"), gbc); + gbc.gridx = 1; gbc.gridwidth=3; customerPhoneField = new JTextField(15); billInfoAndActionsPanel.add(customerPhoneField, gbc); gbc.gridwidth=1; + + // Barcode Scan + gbc.gridx = 0; gbc.gridy = 3; billInfoAndActionsPanel.add(new JLabel("Barcode:"), gbc); + gbc.gridx = 1; gbc.gridwidth=2; barcodeField = new JTextField(20); billInfoAndActionsPanel.add(barcodeField, gbc); + gbc.gridx = 3; gbc.gridwidth=1; scanBarcodeButton = new JButton("Quét"); billInfoAndActionsPanel.add(scanBarcodeButton, gbc); + scanBarcodeButton.addActionListener(e -> scanBarcodeAction()); + gbc.gridwidth=1; + + // Bill Items Table + String[] billItemCols = {"Mã Thuốc", "Tên thuốc", "SL", "ĐVT", "Đơn giá", "Thành tiền"}; + billItemsTableModel = new DefaultTableModel(new Object[][]{}, billItemCols) { + public boolean isCellEditable(int row, int column) { return false; } // Or allow SL edit + }; + billItemsTable = new JTable(billItemsTableModel); + billItemsTable.setRowHeight(25); + billItemsTable.getTableHeader().setFont(new Font("Arial", Font.BOLD, 14)); + billItemsTable.setFont(new Font("Arial", Font.PLAIN, 12)); + JScrollPane billItemsScroll = new JScrollPane(billItemsTable); + + gbc.gridx = 0; gbc.gridy = 4; gbc.gridwidth = 4; gbc.weightx = 1.0; gbc.weighty = 1.0; + gbc.fill = GridBagConstraints.BOTH; + billInfoAndActionsPanel.add(billItemsScroll, gbc); + gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weighty = 0.0; + + // Add/Remove Medicine Buttons for Bill Items + JPanel itemActionPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); + addMedicineItemButton = new JButton("Thêm thuốc vào HĐ"); + addMedicineItemButton.addActionListener(e -> openStandaloneMedicineDialog()); + removeMedicineItemButton = new JButton("Xóa thuốc khỏi HĐ"); + removeMedicineItemButton.addActionListener(e -> removeMedicineFromBillAction()); + itemActionPanel.add(addMedicineItemButton); + itemActionPanel.add(removeMedicineItemButton); + gbc.gridx = 0; gbc.gridy = 5; gbc.gridwidth = 4; billInfoAndActionsPanel.add(itemActionPanel, gbc); + + + // Totals Panel + JPanel totalsPanel = new JPanel(new GridBagLayout()); + GridBagConstraints totalGbc = new GridBagConstraints(); + totalGbc.insets = new Insets(3,10,3,10); + totalGbc.anchor = GridBagConstraints.EAST; + + totalGbc.gridx=0; totalGbc.gridy=0; totalsPanel.add(new JLabel("Tổng phụ:"), totalGbc); + totalGbc.gridx=1; subtotalAmountLabel = new JLabel("0 VNĐ"); totalsPanel.add(subtotalAmountLabel, totalGbc); + totalGbc.gridx=0; totalGbc.gridy++; totalsPanel.add(new JLabel("Giảm giá:"), totalGbc); + totalGbc.gridx=1; discountField = new JTextField("0", 8); discountField.setHorizontalAlignment(JTextField.RIGHT); totalsPanel.add(discountField, totalGbc); + // TODO: Add listener to discountField to update grand total + totalGbc.gridx=0; totalGbc.gridy++; totalsPanel.add(new JLabel("TỔNG CỘNG:"), totalGbc); + totalGbc.gridx=1; grandTotalAmountLabel = new JLabel("0 VNĐ"); + grandTotalAmountLabel.setFont(new Font("Arial", Font.BOLD, 16)); + grandTotalAmountLabel.setForeground(Color.RED); + totalsPanel.add(grandTotalAmountLabel, totalGbc); + + gbc.gridx = 0; gbc.gridy = 6; gbc.gridwidth = 4; gbc.anchor = GridBagConstraints.EAST; + billInfoAndActionsPanel.add(totalsPanel, gbc); + + + // Main Action Buttons (Payment, Print) + JPanel mainActionsPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10)); + processPaymentButton = new JButton("Thanh Toán"); + processPaymentButton.setFont(new Font("Arial", Font.BOLD, 16)); + processPaymentButton.setBackground(new Color(76, 175, 80)); + processPaymentButton.setForeground(Color.WHITE); + processPaymentButton.addActionListener(e -> processPaymentAction()); + + printBillButton = new JButton("In Hóa Đơn"); + printBillButton.setFont(new Font("Arial", Font.BOLD, 16)); + printBillButton.setBackground(new Color(33, 150, 243)); + printBillButton.setForeground(Color.WHITE); + printBillButton.addActionListener(e -> printBillAction()); + + mainActionsPanel.add(processPaymentButton); + mainActionsPanel.add(printBillButton); + + rightPanel.add(billInfoAndActionsPanel, BorderLayout.CENTER); + rightPanel.add(mainActionsPanel, BorderLayout.SOUTH); + + mainSplitPane.setRightComponent(new JScrollPane(rightPanel)); // Make right panel scrollable too + + add(mainSplitPane, BorderLayout.CENTER); + + // TODO: Load initial finished checkup queue + loadFinishedCheckupQueue(); + updateBillDetailsPanel(null); // Initially no bill selected or new bill + } + + private void loadFinishedCheckupQueue() { + // TODO: Network request to get patients with status like "ĐÃ KHÁM XONG" or "CHỜ THANH TOÁN" + // For now, add dummy data + finishedCheckupTableModel.addRow(new Object[]{"CK001", "Nguyễn Văn A", "250,000 VNĐ", "Chờ TT"}); + finishedCheckupTableModel.addRow(new Object[]{"CK002", "Trần Thị B", "180,000 VNĐ", "Chờ TT"}); + log.info("Dummy finished checkup queue loaded."); + } + + private void createNewStandaloneBill() { + log.info("Creating new standalone bill."); + // TODO: Generate a new Bill ID (e.g., "BL" + timestamp or sequence) + billIdLabel.setText("BL" + System.currentTimeMillis()%10000); + billDateLabel.setText(new SimpleDateFormat("dd/MM/yyyy").format(new Date())); + customerNameField.setText(""); + customerPhoneField.setText(""); + customerNameField.setEditable(true); + customerPhoneField.setEditable(true); + barcodeField.setText(""); + billItemsTableModel.setRowCount(0); // Clear items table + subtotalAmountLabel.setText("0 VNĐ"); + discountField.setText("0"); + grandTotalAmountLabel.setText("0 VNĐ"); + // TODO: Clear/reset any other relevant fields for a new bill + // TODO: Focus on customer name or barcode field + } + + private void updateBillDetailsPanel(/* BillObject bill/Patient patient */ Object selectedBillData) { + if (selectedBillData == null) { // For new bill or initial state + billIdLabel.setText("N/A"); + billDateLabel.setText(new SimpleDateFormat("dd/MM/yyyy").format(new Date())); + customerNameField.setText(""); customerNameField.setEditable(true); + customerPhoneField.setText(""); customerPhoneField.setEditable(true); + barcodeField.setText(""); + billItemsTableModel.setRowCount(0); + updateTotals(); + } else { + // TODO: Populate right panel based on selectedBillData (from finished queue) + // Example: + // billIdLabel.setText(bill.getId()); + // billDateLabel.setText(bill.getDate()); + // customerNameField.setText(patient.getName()); customerNameField.setEditable(false); + // customerPhoneField.setText(patient.getPhone()); customerPhoneField.setEditable(false); + // billItemsTableModel.setDataVector(bill.getItems(), billItemCols); + // updateTotals(); + log.info("Loading bill details for: " + selectedBillData.toString()); + } + } + + + private void scanBarcodeAction() { + String barcode = barcodeField.getText().trim(); + if (barcode.isEmpty()) { + JOptionPane.showMessageDialog(this, "Vui lòng nhập barcode.", "Barcode trống", JOptionPane.WARNING_MESSAGE); + return; + } + // TODO: Network request to find medicine by barcode + // If found, add to billItemsTable or open dialog with prefilled info + log.info("Barcode scanned (mock): " + barcode); + JOptionPane.showMessageDialog(this, "Đã quét barcode (mock): " + barcode + "\nTODO: Tìm thuốc và thêm vào HĐ.", "Quét Barcode", JOptionPane.INFORMATION_MESSAGE); + } + + private void openStandaloneMedicineDialog() { + if (standaloneMedicineDialog == null) { + standaloneMedicineDialog = new StandaloneMedicineDialog(mainFrame); + } + standaloneMedicineDialog.setVisible(true); + String[][] selectedMeds = standaloneMedicineDialog.getMedicinePrescription(); + if (selectedMeds != null) { + for (String[] med : selectedMeds) { + // med: ID, Tên thuốc, SL, ĐVT, Sáng, Trưa, Chiều, Đơn giá, Thành tiền, Ghi chú + // For bill, we might only need: ID, Tên thuốc, SL, ĐVT, Đơn giá, Thành tiền + if (med.length >= 9) { + billItemsTableModel.addRow(new Object[]{ + med[0], // ID + med[1], // Tên thuốc + med[2], // SL + med[3], // ĐVT + med[7], // Đơn giá + med[8] // Thành tiền + }); + } + } + updateTotals(); + } + } + + private void removeMedicineFromBillAction() { + int selectedRow = billItemsTable.getSelectedRow(); + if (selectedRow != -1) { + billItemsTableModel.removeRow(selectedRow); + updateTotals(); + } else { + JOptionPane.showMessageDialog(this, "Vui lòng chọn một thuốc để xóa khỏi hóa đơn.", "Chưa chọn thuốc", JOptionPane.WARNING_MESSAGE); + } + } + + private void updateTotals() { + double subtotal = 0; + for (int i = 0; i < billItemsTableModel.getRowCount(); i++) { + try { + // Assuming "Thành tiền" is at column 5 and is a string like "120,000" + String totalStr = billItemsTableModel.getValueAt(i, 5).toString().replace(",", ""); + subtotal += Double.parseDouble(totalStr); + } catch (Exception e) { + log.error("Error calculating subtotal for row " + i, e); + } + } + subtotalAmountLabel.setText(String.format("%,.0f VNĐ", subtotal)); + + double discount = 0; + try { + discount = Double.parseDouble(discountField.getText().replace(",", "")); + } catch (NumberFormatException e) { + // ignore, keep discount 0 + } + + double grandTotal = subtotal - discount; + grandTotalAmountLabel.setText(String.format("%,.0f VNĐ", grandTotal)); + } + + private void processPaymentAction() { + // TODO: Implement payment processing logic + // - Validate bill (items, total > 0) + // - Send request to backend to mark bill as paid, update inventory + // - Show success/failure message + // - Potentially clear the bill or offer to print + String billId = billIdLabel.getText(); + String total = grandTotalAmountLabel.getText(); + log.info("Processing payment for Bill ID: " + billId + ", Amount: " + total); + JOptionPane.showMessageDialog(this, "THANH TOÁN THÀNH CÔNG (mock)\nBill ID: "+billId+"\nTổng tiền: "+total+"\nTODO: Lưu HĐ, cập nhật kho...", "Xác nhận thanh toán", JOptionPane.INFORMATION_MESSAGE); + createNewStandaloneBill(); // Clear for next bill + } + + private void printBillAction() { + // TODO: Implement bill printing + // - Gather all necessary bill data (customer, items, totals) + // - Create a new Invoice/Bill printing class (similar to MedicineInvoice but for general bills) + // - Generate and show/print the PDF + log.info("Printing bill (mock) for Bill ID: " + billIdLabel.getText()); + JOptionPane.showMessageDialog(this, "Đang chuẩn bị in hóa đơn (mock)...\nTODO: Tạo file PDF hóa đơn.", "In Hóa Đơn", JOptionPane.INFORMATION_MESSAGE); + } +} \ No newline at end of file diff --git a/src/main/java/BsK/client/ui/component/CheckoutPage/StandaloneMedicineDialog.java b/src/main/java/BsK/client/ui/component/CheckoutPage/StandaloneMedicineDialog.java new file mode 100644 index 0000000..71f07c5 --- /dev/null +++ b/src/main/java/BsK/client/ui/component/CheckoutPage/StandaloneMedicineDialog.java @@ -0,0 +1,646 @@ +package BsK.client.ui.component.CheckoutPage; + +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableColumnModel; + +import BsK.client.network.handler.ClientHandler; +import BsK.client.network.handler.ResponseListener; +import BsK.common.packet.req.GetMedInfoRequest; +import BsK.common.packet.res.GetMedInfoResponse; +import BsK.common.util.network.NetworkUtil; +import BsK.common.util.text.TextUtils; +import lombok.extern.slf4j.Slf4j; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.awt.*; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +@Slf4j +public class StandaloneMedicineDialog extends JDialog { + private JTextField medicineNameField; + private JTextField barcodeField; // New field for barcode + private JTextField medicineCompanyField; + private JTextArea medicineDescriptionField; + private JSpinner quantitySpinner; + private JTextField quantityLeftField; + private JComboBox UnitComboBox; + private JTextField priceField; + private JTextField totalField; + private JSpinner morningSpinner, noonSpinner, eveningSpinner; + private JTextArea noteField; + private DefaultTableModel tableModel, selectedTableModel; + private String[] medcineColumns = {"ID", "Tên thuốc", "Barcode", "Công ty", "Mô tả", "Tồn kho", "ĐVT", "Giá"}; // Added Barcode Column + private String[][] medicineData; + private final ResponseListener getMedInfoResponseListener = this::getMedInfoHandler; + private TableColumnModel columnModel; + private HashMap selectedMedicine = new HashMap<>(); + private JTable medicineTable; + private JTable selectedTable; + private boolean isProgrammaticallySettingMedicineNameField = false; + + private String[][] medicinePrescription; + private static final Logger logger = LoggerFactory.getLogger(StandaloneMedicineDialog.class); + + public String[][] getMedicinePrescription() { + return medicinePrescription; + } + + void getMedInfoHandler(GetMedInfoResponse response) { + logger.info("Received medicine data for Standalone Dialog"); + medicineData = response.getMedInfo(); // Assuming GetMedInfoResponse also returns barcode in medInfo array + tableModel.setDataVector(medicineData, medcineColumns); + resizeMedicineTableColumns(); + } + + private void sendGetMedInfoRequest() { + logger.info("Sending GetMedInfoRequest for Standalone Dialog"); + NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new GetMedInfoRequest()); + } + + public StandaloneMedicineDialog(Frame parent) { + super(parent, "Thêm thuốc vào hóa đơn (khách lẻ)", true); + setDefaultCloseOperation(DISPOSE_ON_CLOSE); + setSize(1250, 800); + setLocationRelativeTo(parent); + setResizable(true); + + ClientHandler.addResponseListener(GetMedInfoResponse.class, getMedInfoResponseListener); + sendGetMedInfoRequest(); + + setLayout(new BorderLayout(10, 10)); + + JPanel mainInputPanel = new JPanel(new GridBagLayout()); + mainInputPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + GridBagConstraints mainGbc = new GridBagConstraints(); + mainGbc.fill = GridBagConstraints.HORIZONTAL; + mainGbc.anchor = GridBagConstraints.NORTHWEST; + mainGbc.insets = new Insets(5, 5, 5, 5); + mainGbc.weightx = 1.0; + + // Search Panel (Name and Barcode) + JPanel searchPanel = new JPanel(new GridBagLayout()); + searchPanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createEtchedBorder(), "Tìm kiếm thuốc", + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 14), new Color(50, 50, 50) + )); + mainGbc.gridx = 0; mainGbc.gridy = 0; + mainInputPanel.add(searchPanel, mainGbc); + + JPanel medicineInfoPanel = new JPanel(new GridBagLayout()); + medicineInfoPanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createEtchedBorder(), "Thông tin thuốc", + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 14), new Color(50, 50, 50) + )); + mainGbc.gridy = 1; + mainInputPanel.add(medicineInfoPanel, mainGbc); + + JPanel quantityPricePanel = new JPanel(new GridBagLayout()); + quantityPricePanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createEtchedBorder(), "Số lượng & Giá", + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 14), new Color(50, 50, 50) + )); + mainGbc.gridy = 2; + mainInputPanel.add(quantityPricePanel, mainGbc); + + JPanel dosagePanel = new JPanel(new GridBagLayout()); + dosagePanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createEtchedBorder(), "Liều dùng (nếu có)", // Dosage might be optional for direct sale + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 14), new Color(50, 50, 50) + )); + mainGbc.gridy = 3; + mainInputPanel.add(dosagePanel, mainGbc); + + JPanel notePanel = new JPanel(new GridBagLayout()); + notePanel.setBorder(BorderFactory.createTitledBorder( + BorderFactory.createEtchedBorder(), "Ghi chú (nếu có)", + javax.swing.border.TitledBorder.LEADING, javax.swing.border.TitledBorder.TOP, + new Font("Arial", Font.BOLD, 14), new Color(50, 50, 50) + )); + mainGbc.gridy = 4; + mainInputPanel.add(notePanel, mainGbc); + + JPanel addMedicineButtonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER)); + JButton addMedicineButton = new JButton("Thêm thuốc vào HĐ"); + addMedicineButtonPanel.add(addMedicineButton); + mainGbc.gridy = 5; + mainInputPanel.add(addMedicineButtonPanel, mainGbc); + + mainGbc.gridy = 6; mainGbc.weighty = 1.0; + mainInputPanel.add(new JPanel(), mainGbc); // Filler panel + + GridBagConstraints gbc = new GridBagConstraints(); + gbc.fill = GridBagConstraints.HORIZONTAL; + gbc.anchor = GridBagConstraints.WEST; + gbc.insets = new Insets(3, 5, 3, 5); // Reduced insets slightly + gbc.weightx = 0.0; gbc.weighty = 0.0; + + // Search Panel Content + gbc.gridy = 0; gbc.gridx = 0; + searchPanel.add(new JLabel("Tên thuốc:"), gbc); + gbc.gridx = 1; gbc.weightx = 1.0; + medicineNameField = new JTextField(20); + searchPanel.add(medicineNameField, gbc); + gbc.weightx = 0.0; + gbc.gridx = 2; gbc.insets = new Insets(3, 15, 3, 5); // More left inset for barcode label + searchPanel.add(new JLabel("Barcode:"), gbc); + gbc.insets = new Insets(3, 5, 3, 5); + gbc.gridx = 3; gbc.weightx = 1.0; + barcodeField = new JTextField(15); + searchPanel.add(barcodeField, gbc); + gbc.weightx = 0.0; + + // Medicine Info Panel Content + gbc.gridy = 0; gbc.gridx = 0; + medicineInfoPanel.add(new JLabel("Công ty:"), gbc); + gbc.gridx = 1; gbc.weightx = 1.0; + medicineCompanyField = new JTextField(20); + medicineCompanyField.setEditable(false); + medicineInfoPanel.add(medicineCompanyField, gbc); + gbc.weightx = 0.0; + + gbc.gridy++; gbc.gridx = 0; + gbc.anchor = GridBagConstraints.NORTHWEST; + medicineInfoPanel.add(new JLabel("Mô tả:"), gbc); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridx = 1; gbc.weightx = 1.0; + medicineDescriptionField = new JTextArea(2, 20); // Reduced rows + medicineDescriptionField.setLineWrap(true); + medicineDescriptionField.setWrapStyleWord(true); + medicineDescriptionField.setEditable(false); + JScrollPane descriptionScrollPane = new JScrollPane(medicineDescriptionField); + descriptionScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + medicineInfoPanel.add(descriptionScrollPane, gbc); + gbc.weightx = 0.0; + + // Quantity & Price Panel Content (similar to MedicineDialog) + gbc.gridy = 0; gbc.gridx = 0; + quantityPricePanel.add(new JLabel("Số lượng:"), gbc); + gbc.gridx = 1; gbc.weightx = 0.5; + quantitySpinner = new JSpinner(new SpinnerNumberModel(1, 1, 1000, 1)); // Increased max quantity + quantitySpinner.setPreferredSize(new Dimension(80, 25)); + quantityPricePanel.add(quantitySpinner, gbc); + gbc.gridx = 2; gbc.weightx = 0.0; + quantityPricePanel.add(new JLabel("Còn lại:"), gbc); + gbc.gridx = 3; gbc.weightx = 0.5; + quantityLeftField = new JTextField(5); + quantityLeftField.setEditable(false); + quantityPricePanel.add(quantityLeftField, gbc); + gbc.weightx = 0.0; + gbc.gridy++; gbc.gridx = 0; + quantityPricePanel.add(new JLabel("ĐVT:"), gbc); + gbc.gridx = 1; gbc.weightx = 0.5; + String[] units = {"Viên", "Vỉ", "Hộp", "Chai", "Tuýp", "Gói"}; + UnitComboBox = new JComboBox<>(units); + UnitComboBox.setEnabled(false); + quantityPricePanel.add(UnitComboBox, gbc); + gbc.gridx = 2; gbc.weightx = 0.0; + quantityPricePanel.add(new JLabel("Giá (VNĐ):"), gbc); + gbc.gridx = 3; gbc.weightx = 0.5; + priceField = new JTextField(10); + priceField.setEditable(false); + quantityPricePanel.add(priceField, gbc); + gbc.weightx = 0.0; + gbc.gridy++; gbc.gridx = 0; + quantityPricePanel.add(new JLabel("Thành tiền (VNĐ):"), gbc); + gbc.gridx = 1; gbc.gridwidth = 3; gbc.weightx = 1.0; + totalField = new JTextField(10); + totalField.setEditable(false); + quantityPricePanel.add(totalField, gbc); + gbc.gridwidth = 1; gbc.weightx = 0.0; + + // Dosage Panel Content + gbc.gridy = 0; gbc.gridx = 0; gbc.weightx = 0.0; + dosagePanel.add(new JLabel("Sáng:"), gbc); + gbc.gridx = 1; gbc.weightx = 0.3; + morningSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 10, 1)); + morningSpinner.setPreferredSize(new Dimension(60,25)); + dosagePanel.add(morningSpinner, gbc); + gbc.gridx = 2; gbc.weightx = 0.0; + dosagePanel.add(new JLabel("Trưa:"), gbc); + gbc.gridx = 3; gbc.weightx = 0.3; + noonSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 10, 1)); + noonSpinner.setPreferredSize(new Dimension(60,25)); + dosagePanel.add(noonSpinner, gbc); + gbc.gridx = 4; gbc.weightx = 0.0; + dosagePanel.add(new JLabel("Chiều:"), gbc); + gbc.gridx = 5; gbc.weightx = 0.3; + eveningSpinner = new JSpinner(new SpinnerNumberModel(0, 0, 10, 1)); + eveningSpinner.setPreferredSize(new Dimension(60,25)); + dosagePanel.add(eveningSpinner, gbc); + gbc.weightx = 0.0; + + // Note Panel Content + gbc.gridy = 0; gbc.gridx = 0; + notePanel.add(new JLabel("Ghi chú:"), gbc); + gbc.anchor = GridBagConstraints.WEST; + gbc.gridx = 1; gbc.weightx = 1.0; gbc.fill = GridBagConstraints.BOTH; gbc.weighty = 1.0; + noteField = new JTextArea(2, 20); // Reduced rows + noteField.setLineWrap(true); + noteField.setWrapStyleWord(true); + JScrollPane noteScrollPane = new JScrollPane(noteField); + noteScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + notePanel.add(noteScrollPane, gbc); + gbc.fill = GridBagConstraints.HORIZONTAL; gbc.weightx = 0.0; gbc.weighty = 0.0; + + // Medicine Table (Right Side) + tableModel = new DefaultTableModel(medicineData, medcineColumns) { + @Override public boolean isCellEditable(int row, int column) { return false; } + }; + medicineTable = new JTable(tableModel); + medicineTable.setFont(new Font("Arial", Font.PLAIN, 13)); + medicineTable.setRowHeight(22); + medicineTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + medicineTable.setAutoCreateRowSorter(true); + JScrollPane medicineTableScrollPane = new JScrollPane(medicineTable); + medicineTableScrollPane.setPreferredSize(new Dimension(650, 250)); // Wider table + + // Selected Medicine Table (Right Side, Bottom) + String[] selectedColumnNames = {"ID", "Tên thuốc", "SL", "ĐVT", "Sáng", "Trưa", "Chiều", "Đơn giá", "Thành tiền", "Ghi chú"}; + selectedTableModel = new DefaultTableModel(new String[][]{}, selectedColumnNames) { + @Override public boolean isCellEditable(int row, int column) { + // Allow editing for SL, Dosage, Note in selected table + return column == 2 || column == 4 || column == 5 || column == 6 || column == 9; + } + }; + selectedTable = new JTable(selectedTableModel); + selectedTable.setFont(new Font("Arial", Font.PLAIN, 13)); + selectedTable.setRowHeight(22); + JScrollPane selectedTableScrollPane = new JScrollPane(selectedTable); + selectedTableScrollPane.setPreferredSize(new Dimension(650, 180)); // Wider table + + JPanel removeButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + JButton removeMedicineButton = new JButton("Xóa thuốc đã chọn"); + removeButtonPanel.add(removeMedicineButton); + + JPanel rightPanel = new JPanel(new BorderLayout(0, 5)); + rightPanel.add(medicineTableScrollPane, BorderLayout.CENTER); + JPanel bottomRightsPanel = new JPanel(new BorderLayout(0,5)); + bottomRightsPanel.add(selectedTableScrollPane, BorderLayout.CENTER); + bottomRightsPanel.add(removeButtonPanel, BorderLayout.SOUTH); + rightPanel.add(bottomRightsPanel, BorderLayout.SOUTH); + + JScrollPane mainInputScrollPane = new JScrollPane(mainInputPanel); + mainInputScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); + mainInputScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + mainInputScrollPane.setBorder(BorderFactory.createEmptyBorder()); + + JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, mainInputScrollPane, rightPanel); + splitPane.setResizeWeight(0.42); // Adjusted resize weight slightly + add(splitPane, BorderLayout.CENTER); + + JPanel bottomButtonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + JButton okButton = new JButton("Lưu & Đóng"); + JButton cancelButton = new JButton("Hủy"); + bottomButtonPanel.add(okButton); + bottomButtonPanel.add(cancelButton); + add(bottomButtonPanel, BorderLayout.SOUTH); + + // Event Listeners + medicineNameField.getDocument().addDocumentListener(new DocumentListener() { + public void changedUpdate(DocumentEvent e) { if (!isProgrammaticallySettingMedicineNameField) SwingUtilities.invokeLater(() -> filterMedicineTableByName()); } + public void removeUpdate(DocumentEvent e) { if (!isProgrammaticallySettingMedicineNameField) SwingUtilities.invokeLater(() -> filterMedicineTableByName()); } + public void insertUpdate(DocumentEvent e) { if (!isProgrammaticallySettingMedicineNameField) SwingUtilities.invokeLater(() -> filterMedicineTableByName()); } + }); + + barcodeField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + filterMedicineTableByBarcode(); + } + } + }); + + medicineTable.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 1) { + SwingUtilities.invokeLater(() -> { + int selectedRow = medicineTable.getSelectedRow(); + if (selectedRow != -1) handleMedicineTableRowSelection(selectedRow); + }); + } + } + }); + + medicineNameField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + handleTableNavigationKeys(e, medicineTable); + } + }); + barcodeField.addKeyListener(new KeyAdapter() { // Allow table nav from barcode field too + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + filterMedicineTableByBarcode(); + } else { + handleTableNavigationKeys(e, medicineTable); + } + } + }); + + quantitySpinner.addChangeListener(e -> updateTotalField()); + UnitComboBox.addActionListener(e -> updateTotalField()); // Though disabled, good practice + + addMedicineButton.addActionListener(e -> addSelectedMedicine()); + removeMedicineButton.addActionListener(e -> removeSelectedMedicine()); + + okButton.addActionListener(e -> { + collectPrescriptionData(); + if (medicinePrescription == null || medicinePrescription.length == 0) { + // For standalone sale, it's okay to have no prescription if just closing + // But if they intend to add items, perhaps a different message or behavior + } + logger.info("Standalone prescription/items saved."); + // Log for debugging + for (String[] row : medicinePrescription) { + logger.info("Med: ID={}, Name={}, Qty={}, Unit={}, M={}, N={}, E={}, Price={}, Total={}, Note={}", + (Object[]) row); + } + dispose(); + }); + + cancelButton.addActionListener(e -> { + medicinePrescription = null; // Clear any collected data if cancelled + dispose(); + }); + } + + private void handleTableNavigationKeys(KeyEvent e, JTable targetTable) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + if (targetTable.getSelectedRow() != -1) addSelectedMedicine(); + } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { + if (targetTable.getRowCount() > 0) { + int selectedRow = targetTable.getSelectedRow(); + selectedRow = (selectedRow < targetTable.getRowCount() - 1) ? selectedRow + 1 : 0; + targetTable.setRowSelectionInterval(selectedRow, selectedRow); + targetTable.scrollRectToVisible(targetTable.getCellRect(selectedRow, 0, true)); + handleMedicineTableRowSelection(selectedRow); + } + } else if (e.getKeyCode() == KeyEvent.VK_UP) { + if (targetTable.getRowCount() > 0) { + int selectedRow = targetTable.getSelectedRow(); + selectedRow = (selectedRow > 0) ? selectedRow - 1 : targetTable.getRowCount() - 1; + targetTable.setRowSelectionInterval(selectedRow, selectedRow); + targetTable.scrollRectToVisible(targetTable.getCellRect(selectedRow, 0, true)); + handleMedicineTableRowSelection(selectedRow); + } + } + } + + private void filterMedicineTableByName() { + filterMedicineTable(medicineNameField.getText().trim(), null); + } + + private void filterMedicineTableByBarcode() { + filterMedicineTable(null, barcodeField.getText().trim()); + if (medicineTable.getRowCount() == 1) { // If unique match by barcode + medicineTable.setRowSelectionInterval(0,0); + handleMedicineTableRowSelection(0); + addSelectedMedicine(); // Optionally auto-add if unique and quantity is set + barcodeField.setText(""); // Clear barcode field after processing + medicineNameField.requestFocusInWindow(); // Or quantitySpinner + } + } + + private void filterMedicineTable(String nameFilter, String barcodeFilter) { + if (medicineData == null) return; + + boolean nameIsEmpty = (nameFilter == null || nameFilter.isEmpty()); + boolean barcodeIsEmpty = (barcodeFilter == null || barcodeFilter.isEmpty()); + + if (nameIsEmpty && barcodeIsEmpty) { + tableModel.setDataVector(medicineData, medcineColumns); + resizeMedicineTableColumns(); + medicineTable.clearSelection(); + clearInputFields(); // Also clear input fields when filter is cleared + } else { + List filteredData = new ArrayList<>(); + String lowerCaseNameFilter = nameIsEmpty ? "" : TextUtils.removeAccents(nameFilter.toLowerCase()); + // Barcode is usually exact match or startsWith, not contains typically + String lowerCaseBarcodeFilter = barcodeIsEmpty ? "" : barcodeFilter.toLowerCase(); + + for (String[] row : medicineData) { + boolean nameMatch = nameIsEmpty; // True if no name filter + boolean barcodeMatch = barcodeIsEmpty; // True if no barcode filter + + if (!nameIsEmpty && row.length > 1 && row[1] != null) { + nameMatch = TextUtils.removeAccents(row[1].toLowerCase()).contains(lowerCaseNameFilter); + } + // Assuming barcode is at index 2 in medicineData from server (ID, Name, Barcode, Company...) + if (!barcodeIsEmpty && row.length > 2 && row[2] != null) { + barcodeMatch = row[2].toLowerCase().equals(lowerCaseBarcodeFilter); // Exact match for barcode + } + + if (nameMatch && barcodeMatch) { // If name filter provided, must match name. If barcode provided, must match barcode. + filteredData.add(row); + } + } + tableModel.setDataVector(filteredData.toArray(new String[0][0]), medcineColumns); + resizeMedicineTableColumns(); + if (!filteredData.isEmpty()) { + medicineTable.setRowSelectionInterval(0,0); + handleMedicineTableRowSelection(0); + } else { + clearInputFields(); + } + } + } + + private void resizeMedicineTableColumns() { + if (medicineTable.getColumnCount() == 0) return; + columnModel = medicineTable.getColumnModel(); + // ID, Tên thuốc, Barcode, Công ty, Mô tả, Tồn kho, ĐVT, Giá + columnModel.getColumn(0).setPreferredWidth(30); // ID + columnModel.getColumn(1).setPreferredWidth(150); // Tên thuốc + columnModel.getColumn(2).setPreferredWidth(100); // Barcode + columnModel.getColumn(3).setPreferredWidth(100); // Công ty + columnModel.getColumn(4).setPreferredWidth(180); // Mô tả + columnModel.getColumn(5).setPreferredWidth(50); // Tồn kho + columnModel.getColumn(6).setPreferredWidth(40); // ĐVT + columnModel.getColumn(7).setPreferredWidth(60); // Giá + } + + private void handleMedicineTableRowSelection(int viewRow) { + if (viewRow < 0 || viewRow >= medicineTable.getRowCount()) { + clearInputFields(); + return; + } + int modelRow = medicineTable.convertRowIndexToModel(viewRow); + + isProgrammaticallySettingMedicineNameField = true; + medicineNameField.setText(tableModel.getValueAt(modelRow, 1).toString()); + isProgrammaticallySettingMedicineNameField = false; + // Assuming barcode is column 2. If not present in tableModel directly, might need to fetch from medicineData using ID + if (tableModel.getColumnCount() > 2 && tableModel.getValueAt(modelRow, 2) != null) { + barcodeField.setText(tableModel.getValueAt(modelRow, 2).toString()); + } + medicineCompanyField.setText(tableModel.getValueAt(modelRow, 3).toString()); + medicineDescriptionField.setText(tableModel.getValueAt(modelRow, 4).toString()); + quantityLeftField.setText(tableModel.getValueAt(modelRow, 5).toString()); + UnitComboBox.setSelectedItem(tableModel.getValueAt(modelRow, 6).toString()); + priceField.setText(tableModel.getValueAt(modelRow, 7).toString()); + + quantitySpinner.setValue(1); + morningSpinner.setValue(0); // Reset dosage for standalone sale, or make it optional + noonSpinner.setValue(0); + eveningSpinner.setValue(0); + noteField.setText(""); + updateTotalField(); + } + + private void clearInputFields() { + // Don't clear medicineNameField or barcodeField as they are used for filtering + medicineCompanyField.setText(""); + medicineDescriptionField.setText(""); + quantityLeftField.setText(""); + UnitComboBox.setSelectedIndex(0); // Or set to a default/blank if applicable + priceField.setText(""); + totalField.setText(""); + quantitySpinner.setValue(1); + morningSpinner.setValue(0); + noonSpinner.setValue(0); + eveningSpinner.setValue(0); + noteField.setText(""); + } + + private void updateTotalField() { + try { + int quantity = (Integer) quantitySpinner.getValue(); + if (quantity < 0) { quantitySpinner.setValue(0); quantity = 0; } + double price = priceField.getText().isEmpty() ? 0 : Double.parseDouble(priceField.getText().replace(",","")); + totalField.setText(String.format("%,.0f", quantity * price)); // Format with commas + } catch (NumberFormatException e) { + totalField.setText("Giá trị không hợp lệ"); + logger.error("Error parsing price for total calculation: " + priceField.getText(), e); + } + } + + private void addSelectedMedicine() { + int selectedRowInMedicineTable = medicineTable.getSelectedRow(); + String medicineId, name, unit, currentPrice, barcodeVal; + + if (selectedRowInMedicineTable != -1) { + int modelRow = medicineTable.convertRowIndexToModel(selectedRowInMedicineTable); + medicineId = tableModel.getValueAt(modelRow, 0).toString(); + name = tableModel.getValueAt(modelRow, 1).toString(); + barcodeVal = tableModel.getColumnCount() > 2 && tableModel.getValueAt(modelRow, 2) != null ? tableModel.getValueAt(modelRow, 2).toString() : "N/A"; + unit = tableModel.getValueAt(modelRow, 6).toString(); // ĐVT is at 6 (0-indexed) + currentPrice = tableModel.getValueAt(modelRow, 7).toString(); // Giá is at 7 + } else if (!medicineNameField.getText().isEmpty() || !barcodeField.getText().isEmpty()){ + // Attempt to find by name or barcode if no table selection but fields have text + String searchName = medicineNameField.getText().trim(); + String searchBarcode = barcodeField.getText().trim(); + String foundId = null, foundUnit = null, foundPrice = null, actualName = null, actualBarcode = null; + + for (String[] med : medicineData) { // medicineData: ID, Tên thuốc, Barcode, Công ty, Mô tả, Tồn kho, ĐVT, Giá + boolean nameMatches = !searchName.isEmpty() && TextUtils.removeAccents(med[1].toLowerCase()).contains(TextUtils.removeAccents(searchName.toLowerCase())); + boolean barcodeMatches = !searchBarcode.isEmpty() && med.length > 2 && med[2] != null && med[2].equalsIgnoreCase(searchBarcode); + if (nameMatches || barcodeMatches) { + foundId = med[0]; actualName = med[1]; actualBarcode = med[2]; + foundUnit = med[6]; foundPrice = med[7]; + break; // Take first match + } + } + if (foundId == null) { + JOptionPane.showMessageDialog(this, "Không tìm thấy thuốc khớp với tên hoặc barcode đã nhập.", "Không tìm thấy thuốc", JOptionPane.WARNING_MESSAGE); + return; + } + medicineId = foundId; name = actualName; unit = foundUnit; currentPrice = foundPrice; barcodeVal = actualBarcode; + } else { + JOptionPane.showMessageDialog(this, "Vui lòng chọn một thuốc từ danh sách hoặc nhập tên/barcode.", "Chưa chọn thuốc", JOptionPane.WARNING_MESSAGE); + return; + } + + int quantity = (Integer) quantitySpinner.getValue(); + int morningVal = (Integer) morningSpinner.getValue(); + int noonVal = (Integer) noonSpinner.getValue(); + int eveningVal = (Integer) eveningSpinner.getValue(); + String note = noteField.getText(); + String totalAmount = totalField.getText().replace(",",""); // Remove comma for internal storage if needed + + if (quantity <= 0) { + JOptionPane.showMessageDialog(this, "Số lượng phải lớn hơn 0.", "Số lượng không hợp lệ", JOptionPane.WARNING_MESSAGE); + return; + } + selectedTableModel.addRow(new Object[]{medicineId, name, quantity, unit, morningVal, noonVal, eveningVal, currentPrice, totalAmount, note}); + } + + private void removeSelectedMedicine() { + int selectedRow = selectedTable.getSelectedRow(); + if (selectedRow != -1) { + selectedTableModel.removeRow(selectedRow); + } else { + JOptionPane.showMessageDialog(this, "Vui lòng chọn một thuốc từ bảng dưới để xóa.", "Chưa chọn thuốc", JOptionPane.WARNING_MESSAGE); + } + } + + private void collectPrescriptionData() { + int rowCount = selectedTableModel.getRowCount(); + if (rowCount == 0) { + medicinePrescription = new String[0][0]; + return; + } + medicinePrescription = new String[rowCount][10]; + for (int i = 0; i < rowCount; i++) { + for (int j = 0; j < 10; j++) { + medicinePrescription[i][j] = selectedTableModel.getValueAt(i, j) != null ? selectedTableModel.getValueAt(i, j).toString() : ""; + } + } + } + + @Override + public void dispose() { + logger.info("Cleaning up StandaloneMedicineDialog listeners"); + ClientHandler.deleteListener(GetMedInfoResponse.class); // Ensure this matches the listener added + super.dispose(); + } + + // Main method for testing this dialog independently + public static void main(String[] args) { + SwingUtilities.invokeLater(() -> { + JFrame frame = new JFrame("Test Standalone Medicine Dialog"); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setSize(600, 400); + frame.setLocationRelativeTo(null); + JButton openDialogButton = new JButton("Open Standalone Medicine Dialog"); + openDialogButton.addActionListener(e -> { + StandaloneMedicineDialog dialog = new StandaloneMedicineDialog(frame); + dialog.setVisible(true); + String[][] prescription = dialog.getMedicinePrescription(); + if (prescription != null && prescription.length > 0) { + System.out.println("Standalone Items obtained:"); + for (String[] item : prescription) { + // Ensure correct number of items for format string + if (item.length == 10) { + System.out.println(String.format("ID:%s, Name:%s, Qty:%s, Unit:%s, M:%s, N:%s, E:%s, Price:%s, Total:%s, Note:%s", + (Object[]) item)); + } else { + System.out.println("Item with incorrect number of fields: " + java.util.Arrays.toString(item)); + } + } + } else { + System.out.println("No items or dialog was cancelled."); + } + }); + frame.setLayout(new FlowLayout()); + frame.add(openDialogButton); + frame.setVisible(true); + }); + } +} \ No newline at end of file diff --git a/src/main/java/BsK/client/ui/component/DashboardPage/DashboardPage.java b/src/main/java/BsK/client/ui/component/DashboardPage/DashboardPage.java index 5dd3e40..bb1eecc 100644 --- a/src/main/java/BsK/client/ui/component/DashboardPage/DashboardPage.java +++ b/src/main/java/BsK/client/ui/component/DashboardPage/DashboardPage.java @@ -4,134 +4,219 @@ import BsK.client.LocalStorage; import BsK.client.ui.component.MainFrame; import BsK.client.ui.component.common.RoundedButtonUI; import BsK.client.ui.component.common.RoundedPanel; +import lombok.extern.slf4j.Slf4j; import javax.swing.*; +import javax.swing.border.Border; import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +@Slf4j public class DashboardPage extends JPanel { + private JLabel activeNavItem = null; // To keep track of the active navigation item + public DashboardPage(MainFrame mainFrame) { setLayout(new BorderLayout()); + setBackground(new Color(240, 240, 240)); // A light background for the page - // Sidebar panel - JPanel sidebar = new JPanel() { - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - Graphics2D g2d = (Graphics2D) g; - int width = getWidth(); - int height = getHeight(); - Color color1 = new Color(63, 81, 181); - Color color2 = new Color(33, 150, 243); - GradientPaint gp = new GradientPaint(0, 0, color1, 0, height, color2); - g2d.setPaint(gp); - g2d.fillRect(0, 0, width, height); - } - }; - sidebar.setBackground(new Color(63, 81, 181)); - sidebar.setLayout(new GridLayout(15, 1)); - sidebar.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + // --- Navigation Bar (copied and adapted from CheckUpPage) --- + JPanel navBar = new JPanel(); + navBar.setBackground(new Color(63, 81, 181)); + navBar.setLayout(new BoxLayout(navBar, BoxLayout.X_AXIS)); - String[] sidebarItems = {"Thống kê","Thăm khám", "Dữ liệu bệnh nhân", "Kho", "Người dùng", "Thông tin"}; - String[] destination = {"DashboardPage","CheckUpPage", "PatientDataPage", "InventoryPage", "UserPage", "InfoPage"}; - for(int i = 0; i < sidebarItems.length; i++) { - String item = sidebarItems[i]; - String dest = destination[i]; - JLabel label = new JLabel(item); + JPanel navItemsPanel = new JPanel(); + navItemsPanel.setBackground(new Color(63, 81, 181)); + navItemsPanel.setLayout(new FlowLayout(FlowLayout.LEFT, 30, 15)); + navItemsPanel.setAlignmentY(Component.CENTER_ALIGNMENT); + + String[] navBarItems = {"Thống kê", "Thăm khám", "Dữ liệu", "Kho", "Thanh toán", "Người dùng", "Thông tin"}; + String[] destination = {"DashboardPage", "CheckUpPage", "PatientDataPage", "InventoryPage", "CheckoutPage", "UserPage", "InfoPage"}; + String[] iconFiles = {"dashboard.png", "health-check.png", "database.png", "warehouse.png", "cashier-machine.png", "user.png", "info.png"}; + + final Color defaultNavColor = new Color(63, 81, 181); + final Color hoverNavColor = new Color(50, 70, 170); + final Color activeNavColor = new Color(33, 150, 243); + + final Border defaultNavItemBorder = BorderFactory.createEmptyBorder(12, 15, 12, 15); + // Specific border for the active "Thống kê" page + final Border activeDashboardSpecificBorder = BorderFactory.createCompoundBorder( + BorderFactory.createMatteBorder(0, 0, 3, 0, activeNavColor), + BorderFactory.createEmptyBorder(12, 15, 9, 15) + ); + + for (int i = 0; i < navBarItems.length; i++) { + final String itemText = navBarItems[i]; + final String dest = destination[i]; + String iconFileName = iconFiles[i]; + + final JLabel label = new JLabel(itemText); label.setForeground(Color.WHITE); label.setHorizontalAlignment(SwingConstants.CENTER); - label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); // Change cursor to hand - label.setFont(new Font("Arial", Font.BOLD, 14)); + label.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + label.setFont(new Font("Arial", Font.BOLD, 12)); + label.setBorder(defaultNavItemBorder); + label.setOpaque(false); + + try { + String iconPath = "src/main/java/BsK/client/ui/assets/icon/" + iconFileName; + ImageIcon originalIcon = new ImageIcon(iconPath); + Image scaledImage = originalIcon.getImage().getScaledInstance(36, 36, Image.SCALE_SMOOTH); + ImageIcon scaledIcon = new ImageIcon(scaledImage); + label.setIcon(scaledIcon); + } catch (Exception e) { + log.error("Error loading icon: {} for nav item: {}", iconFileName, itemText, e); + } + + label.setVerticalTextPosition(SwingConstants.BOTTOM); + label.setHorizontalTextPosition(SwingConstants.CENTER); + + if (itemText.equals("Thống kê")) { // Highlight "Thống kê" as active + label.setBorder(activeDashboardSpecificBorder); + label.setBackground(activeNavColor); + label.setOpaque(true); + activeNavItem = label; + } - // Add a mouse listener to handle click events label.addMouseListener(new java.awt.event.MouseAdapter() { @Override public void mouseClicked(java.awt.event.MouseEvent e) { - // Handle the click event + if (activeNavItem != null && activeNavItem != label) { + activeNavItem.setBackground(defaultNavColor); + activeNavItem.setOpaque(false); + activeNavItem.setForeground(Color.WHITE); + activeNavItem.setBorder(defaultNavItemBorder); + } + activeNavItem = label; + activeNavItem.setBackground(activeNavColor); + activeNavItem.setOpaque(true); + activeNavItem.setForeground(Color.WHITE); + // Apply specific border only if it's the designated active page for this class + if (itemText.equals("Thống kê")) { + activeNavItem.setBorder(activeDashboardSpecificBorder); + } else { + activeNavItem.setBorder(defaultNavItemBorder); + } mainFrame.showPage(dest); - - // JOptionPane.showMessageDialog(null, item + " clicked!"); } @Override public void mouseEntered(java.awt.event.MouseEvent e) { - label.setForeground(new Color(200, 230, 255)); // Highlight on hover + if (label != activeNavItem) { + label.setForeground(new Color(200, 230, 255)); + label.setBackground(hoverNavColor); + label.setOpaque(true); + } } @Override public void mouseExited(java.awt.event.MouseEvent e) { - label.setForeground(Color.WHITE); // Restore original color + if (label != activeNavItem) { + label.setForeground(Color.WHITE); + label.setBackground(defaultNavColor); + label.setOpaque(false); + } } }); - - sidebar.add(label); + navItemsPanel.add(label); } -// Make the sidebar scrollable - JScrollPane sidebarScrollPane = new JScrollPane(sidebar); - sidebarScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); - sidebarScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - sidebarScrollPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT); - sidebarScrollPane.getViewport().setOpaque(false); - sidebarScrollPane.setOpaque(false); + navBar.add(navItemsPanel); + navBar.add(Box.createHorizontalGlue()); + JLabel welcomeLabel = new JLabel("Chào, " + LocalStorage.username + " "); + welcomeLabel.setForeground(Color.WHITE); + welcomeLabel.setHorizontalAlignment(SwingConstants.CENTER); + welcomeLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + welcomeLabel.setFont(new Font("Arial", Font.BOLD, 14)); + welcomeLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (SwingUtilities.isLeftMouseButton(e)) { + JPopupMenu popupMenu = new JPopupMenu(); + JMenuItem profileItem = new JMenuItem("Hồ sơ cá nhân"); + JMenuItem settingsItem = new JMenuItem("Cài đặt"); + JMenuItem logoutItem = new JMenuItem("Đăng xuất"); + profileItem.addActionListener(event -> { + JOptionPane.showMessageDialog(mainFrame, "Tính năng Hồ sơ cá nhân sắp ra mắt!", "Thông báo", JOptionPane.INFORMATION_MESSAGE); + }); + settingsItem.addActionListener(event -> { + JOptionPane.showMessageDialog(mainFrame, "Tính năng Cài đặt sắp ra mắt!", "Thông báo", JOptionPane.INFORMATION_MESSAGE); + }); + // For Logout, you'll need ClientHandler and LogoutRequest from CheckUpPage context if not already available + // For now, just a placeholder action + logoutItem.addActionListener(event -> { + // NetworkUtil.sendPacket(ClientHandler.ctx.channel(), new LogoutRequest()); // Requires imports + LocalStorage.username = null; + LocalStorage.userId = -1; + mainFrame.showPage("LandingPage"); + }); + popupMenu.add(profileItem); + popupMenu.add(settingsItem); + popupMenu.addSeparator(); + popupMenu.add(logoutItem); + popupMenu.setPreferredSize(new Dimension(150, popupMenu.getPreferredSize().height)); + popupMenu.show(welcomeLabel, 0, welcomeLabel.getHeight()); + } + } + @Override + public void mouseEntered(MouseEvent e) { + welcomeLabel.setForeground(new Color(200, 230, 255)); + } + @Override + public void mouseExited(MouseEvent e) { + welcomeLabel.setForeground(Color.WHITE); + } + }); + navBar.add(welcomeLabel); + navBar.setPreferredSize(new Dimension(1200, 85)); - // Topbar panel - JPanel topbar = new JPanel(); - topbar.setLayout(new BorderLayout()); - topbar.setBackground(Color.WHITE); - topbar.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + add(navBar, BorderLayout.NORTH); - JLabel title = new JLabel("Dashboard / Home"); - title.setFont(new Font("Arial", Font.BOLD, 18)); - topbar.add(title, BorderLayout.WEST); - - JLabel userInfo = new JLabel("Welcome, " + LocalStorage.username); - userInfo.setHorizontalAlignment(SwingConstants.RIGHT); - topbar.add(userInfo, BorderLayout.EAST); - - // Main content panel + // --- Main Content Panel (from existing DashboardPage) --- JPanel mainContent = new JPanel(); mainContent.setLayout(new BorderLayout()); mainContent.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); + mainContent.setOpaque(false); // Make it transparent to see page background // Top cards JPanel topCards = new JPanel(); + topCards.setOpaque(false); // Make transparent topCards.setLayout(new GridLayout(1, 4, 20, 20)); String[] cardTitles = {"Add Check", "Income", "Expense", "Other Income"}; - Color[] cardColors = {Color.PINK, Color.CYAN, Color.ORANGE, Color.GREEN}; + // Using slightly more professional/subtle colors + Color[] cardColors = {new Color(100, 181, 246), new Color(77, 208, 225), new Color(255, 183, 77), new Color(129, 199, 132)}; for (int i = 0; i < cardTitles.length; i++) { - JPanel card = new RoundedPanel(20, cardColors[i], true); - card.setBackground(cardColors[i]); - card.setLayout(new BorderLayout()); - card.setBorder(BorderFactory.createEmptyBorder(30, 20, 30, 20)); + RoundedPanel card = new RoundedPanel(15, cardColors[i], true); // Slightly smaller radius + card.setBackground(cardColors[i]); // Ensure background is set + card.setLayout(new BorderLayout(10,10)); + card.setBorder(BorderFactory.createEmptyBorder(20, 15, 20, 15)); // Adjusted padding - JLabel cardTitle = new JLabel(cardTitles[i]); - cardTitle.setForeground(Color.WHITE); - cardTitle.setHorizontalAlignment(SwingConstants.CENTER); - card.add(cardTitle, BorderLayout.NORTH); + JLabel cardTitleLabel = new JLabel(cardTitles[i]); + cardTitleLabel.setForeground(Color.WHITE); + cardTitleLabel.setFont(new Font("Arial", Font.BOLD, 16)); // Larger title + cardTitleLabel.setHorizontalAlignment(SwingConstants.CENTER); + card.add(cardTitleLabel, BorderLayout.NORTH); - JLabel cardValue = new JLabel("Value", SwingConstants.CENTER); - cardValue.setForeground(Color.WHITE); - cardValue.setFont(new Font("Arial", Font.BOLD, 16)); - card.add(cardValue, BorderLayout.CENTER); + JLabel cardValueLabel = new JLabel("N/A"); // Placeholder value + cardValueLabel.setForeground(Color.WHITE); + cardValueLabel.setFont(new Font("Arial", Font.PLAIN, 24)); // Larger value text + cardValueLabel.setHorizontalAlignment(SwingConstants.CENTER); + card.add(cardValueLabel, BorderLayout.CENTER); topCards.add(card); } - mainContent.add(topCards, BorderLayout.NORTH); - // Wrapper panel for spacing - JPanel wrapperPanel = new JPanel(); - wrapperPanel.setLayout(new BorderLayout()); - wrapperPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0)); // Add spacing above - wrapperPanel.setOpaque(false); // Ensure transparency for background compatibility + JPanel wrapperPanel = new JPanel(new BorderLayout()); + wrapperPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0)); + wrapperPanel.setOpaque(false); -// Data table inside a RoundedPanel - RoundedPanel dataTable = new RoundedPanel(20, Color.WHITE, false); - dataTable.setLayout(new BorderLayout()); - dataTable.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); // Adjust padding for better appearance + RoundedPanel dataTablePanel = new RoundedPanel(15, Color.WHITE, false); + dataTablePanel.setLayout(new BorderLayout()); + dataTablePanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15)); String[] columns = {"Name", "Gender", "Course", "Fees", "Action"}; String[][] data = { @@ -140,19 +225,18 @@ public class DashboardPage extends JPanel { {"Bora", "Male", "C#", "$300", "Edit/Delete"}, }; JTable table = new JTable(data, columns); + table.setRowHeight(25); + table.getTableHeader().setFont(new Font("Arial", Font.BOLD, 14)); + table.setFont(new Font("Arial", Font.PLAIN, 12)); JScrollPane tableScroll = new JScrollPane(table); - tableScroll.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); // Inner padding - dataTable.add(tableScroll, BorderLayout.CENTER); + tableScroll.setBorder(BorderFactory.createEmptyBorder(10,0,0,0)); // Top padding for header + dataTablePanel.add(tableScroll, BorderLayout.CENTER); -// Add RoundedPanel to the wrapper panel - wrapperPanel.add(dataTable, BorderLayout.CENTER); - -// Add the wrapper panel to the main content + wrapperPanel.add(dataTablePanel, BorderLayout.CENTER); mainContent.add(wrapperPanel, BorderLayout.CENTER); - - - // Notice board + // Notice board (keeping it commented as in original) + /* JPanel noticeBoard = new RoundedPanel(20, Color.WHITE, false); noticeBoard.setLayout(new BorderLayout()); noticeBoard.setBorder(BorderFactory.createTitledBorder("Notice Board")); @@ -161,21 +245,19 @@ public class DashboardPage extends JPanel { JTextArea noticeText = new JTextArea("04/10/2021\nHidemode Now\n\n03/10/2021\nFurther Reading\n"); noticeText.setEditable(false); noticeBoard.add(new JScrollPane(noticeText), BorderLayout.CENTER); + mainContent.add(noticeBoard, BorderLayout.EAST); + */ - //mainContent.add(noticeBoard, BorderLayout.EAST); - - // Adding panels to the frame - add(sidebarScrollPane, BorderLayout.WEST); - add(topbar, BorderLayout.NORTH); add(mainContent, BorderLayout.CENTER); } - + // Main method (usually for testing, can be kept or removed) public static void main(String[] args) { // JFrame frame = new JFrame("Dashboard"); // frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); -// frame.setSize(800, 600); -// frame.add(new DashboardPage()); +// frame.setSize(1200, 800); +// DashboardPage d = new DashboardPage(null); // Pass null or a mock MainFrame for testing +// frame.add(d); // frame.setVisible(true); } } \ No newline at end of file