Merge conflict resolution and updates
This commit is contained in:
107
Petstoredata.sql
107
Petstoredata.sql
@@ -146,6 +146,14 @@ CREATE TABLE saleItem (
|
||||
FOREIGN KEY (prodId) REFERENCES product(prodId)
|
||||
);
|
||||
|
||||
CREATE TABLE purchaseOrder (
|
||||
purchaseOrderId INT AUTO_INCREMENT PRIMARY KEY,
|
||||
supId INT NOT NULL,
|
||||
orderDate DATE NOT NULL,
|
||||
status VARCHAR(50) NOT NULL,
|
||||
FOREIGN KEY (supId) REFERENCES supplier(supId)
|
||||
);
|
||||
|
||||
CREATE TABLE activityLog (
|
||||
logId INT AUTO_INCREMENT PRIMARY KEY,
|
||||
employeeId INT NOT NULL,
|
||||
@@ -281,20 +289,97 @@ VALUES
|
||||
|
||||
INSERT INTO sale (saleDate, totalAmount, paymentMethod, employeeId, storeId)
|
||||
VALUES
|
||||
(NOW(), 60.00, 'Card', 2, 1),
|
||||
('2026-01-28 10:30:00', 50.00, 'Cash', 1, 1),
|
||||
('2026-01-29 14:15:00', 120.00, 'Card', 4, 3),
|
||||
('2026-01-30 16:45:00', 80.00, 'Card', 2, 2),
|
||||
('2026-02-01 11:20:00', 150.00, 'Cash', 5, 4);
|
||||
-- January Sales
|
||||
('2026-01-05 09:15:00', 125.00, 'Card', 1, 1), -- Sale 1: Dog food + treats
|
||||
('2026-01-08 11:30:00', 200.00, 'Card', 2, 1), -- Sale 2: Bird cage + fish tank
|
||||
('2026-01-12 14:20:00', 60.00, 'Cash', 3, 2), -- Sale 3: Cat toys + hamster wheel
|
||||
('2026-01-15 10:45:00', 150.00, 'Debit', 1, 1), -- Sale 4: Dog food (bulk purchase)
|
||||
('2026-01-18 16:30:00', 80.00, 'Card', 4, 3), -- Sale 5: Fish tank
|
||||
('2026-01-22 13:15:00', 95.00, 'Cash', 2, 2), -- Sale 6: Mixed items
|
||||
('2026-01-25 15:40:00', 240.00, 'Card', 5, 4), -- Sale 7: Two bird cages
|
||||
('2026-01-28 10:30:00', 80.00, 'Cash', 1, 1), -- Sale 8: Dog food + cat toys
|
||||
-- February Sales
|
||||
('2026-02-01 09:00:00', 175.00, 'Card', 3, 3), -- Sale 9: Dog food + treats (bulk)
|
||||
('2026-02-03 11:20:00', 120.00, 'Card', 2, 1), -- Sale 10: Bird cage
|
||||
('2026-02-05 14:50:00', 45.00, 'Cash', 4, 2), -- Sale 11: Hamster wheel + cat toys
|
||||
('2026-02-08 16:15:00', 160.00, 'Debit', 1, 1), -- Sale 12: Fish tank + accessories
|
||||
('2026-02-10 10:25:00', 100.00, 'Card', 5, 4), -- Sale 13: Dog treats (bulk)
|
||||
('2026-02-12 13:45:00', 50.00, 'Cash', 2, 2), -- Sale 14: Dog food
|
||||
('2026-02-15 15:30:00', 85.00, 'Card', 3, 3), -- Sale 15: Mixed pet supplies
|
||||
('2026-02-18 11:10:00', 200.00, 'Card', 1, 1), -- Sale 16: Bird cage + hamster wheel
|
||||
('2026-02-20 14:35:00', 155.00, 'Debit', 4, 3), -- Sale 17: Fish tank + cat toys
|
||||
('2026-02-22 16:50:00', 75.00, 'Cash', 2, 1), -- Sale 18: Dog treats + toys
|
||||
('2026-02-24 10:15:00', 140.00, 'Card', 5, 4), -- Sale 19: Dog food + treats
|
||||
(NOW(), 95.00, 'Card', 1, 1); -- Sale 20: Recent sale (current timestamp)
|
||||
|
||||
INSERT INTO saleItem (saleId, prodId, quantity, unitPrice)
|
||||
VALUES
|
||||
(1, 2, 2, 10.00),
|
||||
(2, 1, 1, 50.00),
|
||||
(3, 3, 1, 120.00),
|
||||
(4, 4, 1, 80.00),
|
||||
(5, 6, 6, 25.00),
|
||||
(2, 2, 3, 10.00);
|
||||
-- Sale 1 items (Dog food + treats)
|
||||
(1, 1, 2, 50.00), -- 2x Premium Dog Food
|
||||
(1, 6, 1, 25.00), -- 1x Organic Dog Treats
|
||||
-- Sale 2 items (Bird cage + fish tank)
|
||||
(2, 3, 1, 120.00), -- 1x Bird Cage Large
|
||||
(2, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon
|
||||
-- Sale 3 items (Cat toys + hamster wheel)
|
||||
(3, 2, 3, 10.00), -- 3x Cat Toy Ball
|
||||
(3, 5, 2, 15.00), -- 2x Hamster Wheel
|
||||
-- Sale 4 items (Dog food bulk)
|
||||
(4, 1, 3, 50.00), -- 3x Premium Dog Food
|
||||
-- Sale 5 items (Fish tank)
|
||||
(5, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon
|
||||
-- Sale 6 items (Mixed)
|
||||
(6, 2, 4, 10.00), -- 4x Cat Toy Ball
|
||||
(6, 5, 1, 15.00), -- 1x Hamster Wheel
|
||||
(6, 6, 1, 25.00), -- 1x Organic Dog Treats
|
||||
(6, 1, 1, 50.00), -- 1x Premium Dog Food (partial - discount applied)
|
||||
-- Sale 7 items (Two bird cages)
|
||||
(7, 3, 2, 120.00), -- 2x Bird Cage Large
|
||||
-- Sale 8 items (Dog food + cat toys)
|
||||
(8, 1, 1, 50.00), -- 1x Premium Dog Food
|
||||
(8, 2, 3, 10.00), -- 3x Cat Toy Ball
|
||||
-- Sale 9 items (Dog food + treats bulk)
|
||||
(9, 1, 3, 50.00), -- 3x Premium Dog Food
|
||||
(9, 6, 1, 25.00), -- 1x Organic Dog Treats
|
||||
-- Sale 10 items (Bird cage)
|
||||
(10, 3, 1, 120.00), -- 1x Bird Cage Large
|
||||
-- Sale 11 items (Hamster wheel + cat toys)
|
||||
(11, 5, 1, 15.00), -- 1x Hamster Wheel
|
||||
(11, 2, 3, 10.00), -- 3x Cat Toy Ball
|
||||
-- Sale 12 items (Fish tank + accessories)
|
||||
(12, 4, 2, 80.00), -- 2x Fish Tank 20 Gallon
|
||||
-- Sale 13 items (Dog treats bulk)
|
||||
(13, 6, 4, 25.00), -- 4x Organic Dog Treats
|
||||
-- Sale 14 items (Dog food)
|
||||
(14, 1, 1, 50.00), -- 1x Premium Dog Food
|
||||
-- Sale 15 items (Mixed supplies)
|
||||
(15, 2, 2, 10.00), -- 2x Cat Toy Ball
|
||||
(15, 5, 1, 15.00), -- 1x Hamster Wheel
|
||||
(15, 6, 2, 25.00), -- 2x Organic Dog Treats
|
||||
-- Sale 16 items (Bird cage + hamster wheel)
|
||||
(16, 3, 1, 120.00), -- 1x Bird Cage Large
|
||||
(16, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon
|
||||
-- Sale 17 items (Fish tank + cat toys)
|
||||
(17, 4, 1, 80.00), -- 1x Fish Tank 20 Gallon
|
||||
(17, 1, 1, 50.00), -- 1x Premium Dog Food
|
||||
(17, 6, 1, 25.00), -- 1x Organic Dog Treats
|
||||
-- Sale 18 items (Dog treats + toys)
|
||||
(18, 6, 2, 25.00), -- 2x Organic Dog Treats
|
||||
(18, 2, 2, 10.00), -- 2x Cat Toy Ball
|
||||
(18, 5, 1, 15.00), -- 1x Hamster Wheel
|
||||
-- Sale 19 items (Dog food + treats)
|
||||
(19, 1, 2, 50.00), -- 2x Premium Dog Food
|
||||
(19, 6, 2, 25.00), -- 2x Organic Dog Treats (discount applied)
|
||||
-- Sale 20 items (Recent sale)
|
||||
(20, 2, 5, 10.00), -- 5x Cat Toy Ball
|
||||
(20, 5, 3, 15.00); -- 3x Hamster Wheel
|
||||
|
||||
INSERT INTO purchaseOrder (supId, orderDate, status)
|
||||
VALUES
|
||||
(1, '2025-01-15', 'Delivered'),
|
||||
(2, '2025-01-20', 'Pending'),
|
||||
(3, '2025-02-01', 'Delivered'),
|
||||
(4, '2025-02-10', 'In Transit'),
|
||||
(1, '2025-02-15', 'Pending');
|
||||
|
||||
INSERT INTO activityLog (employeeId, activity)
|
||||
VALUES
|
||||
|
||||
48
README.md
Normal file
48
README.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Pet Shop Desktop (JavaFX)
|
||||
|
||||
Desktop pet shop management app built with JavaFX and MySQL.
|
||||
|
||||
Made by **Group 2**, Shiv, Nikitha, Alex, Harkamal.
|
||||
|
||||
## Requirements
|
||||
|
||||
- IntelliJ IDEA (Community or Ultimate)
|
||||
- Java 17+
|
||||
- Maven (handled through IntelliJ)
|
||||
- Docker and Docker Compose (for the local MySQL container)
|
||||
|
||||
## Database setup (IntelliJ)
|
||||
|
||||
1. Open the project in IntelliJ.
|
||||
2. Open **View → Tool Windows → Services**.
|
||||
3. Add a Docker connection if needed, then open the **Docker** section in Services.
|
||||
4. Start the Compose stack from `docker-compose.yml` (Compose Up, or Start).
|
||||
5. Confirm the `mysql` service is running.
|
||||
|
||||
The container uses `mysql:8.4`, creates the `Petstoredb` database, and imports `Petstoredata.sql`.
|
||||
|
||||
## App configuration
|
||||
|
||||
An example connection file is provided at `connectionpetstore.properties.example`. Copy it to `connectionpetstore.properties` and edit the values to match the local database setup.
|
||||
|
||||
## Run the app (IntelliJ, Maven)
|
||||
|
||||
1. Open **View → Tool Windows → Maven**.
|
||||
2. Click **Reload All Maven Projects** if the dependencies have not loaded yet.
|
||||
3. In the Maven tool window, expand **Plugins → javafx**.
|
||||
4. Double click **javafx:run**.
|
||||
|
||||
Optional, run a clean first:
|
||||
- In the Maven tool window, expand **Lifecycle** and run **clean**.
|
||||
|
||||
## Default accounts
|
||||
|
||||
On first run, the app creates a `users` table (if missing) and seeds two accounts:
|
||||
|
||||
- Admin: `admin` / `admin123`
|
||||
- Staff: `staff` / `staff123`
|
||||
|
||||
## Notes
|
||||
|
||||
- `connectionpetstore.properties` is gitignored so credentials are not committed.
|
||||
- If the app cannot connect to MySQL, confirm the Compose stack is running and MySQL is available.
|
||||
5
pom.xml
5
pom.xml
@@ -10,7 +10,7 @@
|
||||
<name>PetShopDesktop</name>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<javafx.version>25.0.2</javafx.version>
|
||||
<javafx.version>17.0.10</javafx.version>
|
||||
<junit.version>5.12.1</junit.version>
|
||||
</properties>
|
||||
|
||||
@@ -53,8 +53,7 @@
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>3.13.0</version>
|
||||
<configuration>
|
||||
<source>23</source>
|
||||
<target>23</target>
|
||||
<release>17</release>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
|
||||
93
src/main/java/org/example/petshopdesktop/DTOs/SaleDTO.java
Normal file
93
src/main/java/org/example/petshopdesktop/DTOs/SaleDTO.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package org.example.petshopdesktop.DTOs;
|
||||
|
||||
import javafx.beans.property.*;
|
||||
|
||||
public class SaleDTO {
|
||||
|
||||
private IntegerProperty saleId;
|
||||
private StringProperty saleDate;
|
||||
private StringProperty employeeName;
|
||||
private StringProperty productName;
|
||||
private IntegerProperty quantity;
|
||||
private DoubleProperty unitPrice;
|
||||
private DoubleProperty total;
|
||||
private StringProperty paymentMethod;
|
||||
|
||||
public SaleDTO(int saleId, String saleDate, String employeeName, String productName,
|
||||
int quantity, double unitPrice, double total, String paymentMethod) {
|
||||
this.saleId = new SimpleIntegerProperty(saleId);
|
||||
this.saleDate = new SimpleStringProperty(saleDate);
|
||||
this.employeeName = new SimpleStringProperty(employeeName);
|
||||
this.productName = new SimpleStringProperty(productName);
|
||||
this.quantity = new SimpleIntegerProperty(quantity);
|
||||
this.unitPrice = new SimpleDoubleProperty(unitPrice);
|
||||
this.total = new SimpleDoubleProperty(total);
|
||||
this.paymentMethod = new SimpleStringProperty(paymentMethod);
|
||||
}
|
||||
|
||||
// Getters
|
||||
public int getSaleId() {
|
||||
return saleId.get();
|
||||
}
|
||||
|
||||
public String getSaleDate() {
|
||||
return saleDate.get();
|
||||
}
|
||||
|
||||
public String getEmployeeName() {
|
||||
return employeeName.get();
|
||||
}
|
||||
|
||||
public String getProductName() {
|
||||
return productName.get();
|
||||
}
|
||||
|
||||
public int getQuantity() {
|
||||
return quantity.get();
|
||||
}
|
||||
|
||||
public double getUnitPrice() {
|
||||
return unitPrice.get();
|
||||
}
|
||||
|
||||
public double getTotal() {
|
||||
return total.get();
|
||||
}
|
||||
|
||||
public String getPaymentMethod() {
|
||||
return paymentMethod.get();
|
||||
}
|
||||
|
||||
// Properties
|
||||
public IntegerProperty saleIdProperty() {
|
||||
return saleId;
|
||||
}
|
||||
|
||||
public StringProperty saleDateProperty() {
|
||||
return saleDate;
|
||||
}
|
||||
|
||||
public StringProperty employeeNameProperty() {
|
||||
return employeeName;
|
||||
}
|
||||
|
||||
public StringProperty productNameProperty() {
|
||||
return productName;
|
||||
}
|
||||
|
||||
public IntegerProperty quantityProperty() {
|
||||
return quantity;
|
||||
}
|
||||
|
||||
public DoubleProperty unitPriceProperty() {
|
||||
return unitPrice;
|
||||
}
|
||||
|
||||
public DoubleProperty totalProperty() {
|
||||
return total;
|
||||
}
|
||||
|
||||
public StringProperty paymentMethodProperty() {
|
||||
return paymentMethod;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,3 @@
|
||||
//Initial commmit
|
||||
|
||||
package org.example.petshopdesktop;
|
||||
|
||||
import javafx.application.Application;
|
||||
|
||||
BIN
src/main/java/org/example/petshopdesktop/Validator.class
Normal file
BIN
src/main/java/org/example/petshopdesktop/Validator.class
Normal file
Binary file not shown.
@@ -3,14 +3,14 @@ package org.example.petshopdesktop;
|
||||
public class Validator {
|
||||
|
||||
/**
|
||||
* Checks if string is not empty
|
||||
* Checks if string is not blank
|
||||
* @param value string to check
|
||||
* @param name name of the input
|
||||
* @return error msg if string is not empty, otherwise empty
|
||||
* @return error msg if string is blank, otherwise empty
|
||||
*/
|
||||
public static String isPresent(String value, String name){
|
||||
String msg =""; //OK so far
|
||||
if(value.isEmpty() || name.isBlank()){
|
||||
String msg = "";
|
||||
if (value == null || value.isBlank()){
|
||||
msg += name + " is required. \n";
|
||||
}
|
||||
return msg;
|
||||
@@ -23,7 +23,7 @@ public class Validator {
|
||||
* @return error msg if input is not a number or negative, otherwise empty
|
||||
*/
|
||||
public static String isNonNegativeDouble(String value, String name){
|
||||
String msg =""; //OK so far
|
||||
String msg ="";
|
||||
double result;
|
||||
try{
|
||||
result = Double.parseDouble(value);
|
||||
@@ -40,13 +40,13 @@ public class Validator {
|
||||
/**
|
||||
* Checks if the input is a double in 2 different range
|
||||
* @param value input of string
|
||||
* @param name name of inpt
|
||||
* @param name name of input
|
||||
* @param minValue min value of range
|
||||
* @param maxValue max value of range
|
||||
* @return error msg if input is out of range, otherwise empty
|
||||
*/
|
||||
public static String isDoubleInRange(String value, String name, double minValue, double maxValue){
|
||||
String msg =""; //OK so far
|
||||
String msg ="";
|
||||
double result;
|
||||
try{
|
||||
result = Double.parseDouble(value);
|
||||
@@ -67,7 +67,7 @@ public class Validator {
|
||||
* @return error msg if input is not a number or negative, otherwise empty
|
||||
*/
|
||||
public static String isNonNegativeInteger(String value, String name){
|
||||
String msg =""; //OK so far
|
||||
String msg ="";
|
||||
int result;
|
||||
try{
|
||||
result = Integer.parseInt(value);
|
||||
@@ -85,6 +85,7 @@ public class Validator {
|
||||
* check if the string is a given amount of characters or fewer
|
||||
* @param value input of string
|
||||
* @param name name of input
|
||||
* @param length max allowed length
|
||||
* @return error msg if input is more than given characters length
|
||||
*/
|
||||
public static String isLessThanVarChars(String value, String name, int length){
|
||||
@@ -102,8 +103,7 @@ public class Validator {
|
||||
* @return error msg if input is not a valid email format, otherwise empty
|
||||
*/
|
||||
public static String isValidEmail(String value, String name){
|
||||
String msg = ""; //OK so far
|
||||
// Email regex
|
||||
String msg = "";
|
||||
String regex = "^[A-Za-z0-9+_.-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,}$";
|
||||
|
||||
if (!value.matches(regex)){
|
||||
@@ -119,8 +119,7 @@ public class Validator {
|
||||
* @return error msg if input is not in valid phone format, otherwise empty
|
||||
*/
|
||||
public static String isValidPhoneNumber(String value, String name){
|
||||
String msg = ""; //OK so far
|
||||
// Phone regex
|
||||
String msg = "";
|
||||
String regex = "^\\d{3}-\\d{3}-\\d{4}$";
|
||||
|
||||
if (!value.matches(regex)){
|
||||
|
||||
BIN
src/main/java/org/example/petshopdesktop/auth/Role.class
Normal file
BIN
src/main/java/org/example/petshopdesktop/auth/Role.class
Normal file
Binary file not shown.
@@ -1,13 +1,6 @@
|
||||
package org.example.petshopdesktop.auth;
|
||||
|
||||
/*
|
||||
Petshop Desktop
|
||||
Purpose: Application role definitions used by session state and role based access control.
|
||||
*/
|
||||
public enum Role {
|
||||
// Administrative access, includes system management screens.
|
||||
ADMIN,
|
||||
|
||||
// Staff access, limited to day to day operational screens.
|
||||
STAFF
|
||||
}
|
||||
|
||||
@@ -1,24 +1,15 @@
|
||||
package org.example.petshopdesktop.auth;
|
||||
|
||||
/*
|
||||
Petshop Desktop
|
||||
Purpose: In memory session state for the authenticated user.
|
||||
Notes: Session is process local and cleared on logout or application restart.
|
||||
*/
|
||||
public class UserSession {
|
||||
|
||||
// Singleton instance used to share session state across controllers.
|
||||
private static UserSession instance;
|
||||
|
||||
// Current authenticated username, null when logged out.
|
||||
private String username;
|
||||
|
||||
// Current authenticated role, null when logged out.
|
||||
private Role role;
|
||||
|
||||
private UserSession() {}
|
||||
|
||||
// Lazily initialised singleton accessor.
|
||||
public static UserSession getInstance() {
|
||||
if (instance == null) {
|
||||
instance = new UserSession();
|
||||
@@ -26,13 +17,11 @@ public class UserSession {
|
||||
return instance;
|
||||
}
|
||||
|
||||
// Stores identity and role for the active session.
|
||||
public void login(String username, Role role) {
|
||||
this.username = username;
|
||||
this.role = role;
|
||||
}
|
||||
|
||||
// Clears session state and returns the application to an unauthenticated state.
|
||||
public void logout() {
|
||||
this.username = null;
|
||||
this.role = null;
|
||||
@@ -46,13 +35,10 @@ public class UserSession {
|
||||
return role;
|
||||
}
|
||||
|
||||
// Convenience check for administrative privileges.
|
||||
// Role.ADMIN.equals(role) remains safe when role is null.
|
||||
public boolean isAdmin() {
|
||||
return Role.ADMIN.equals(role);
|
||||
}
|
||||
|
||||
// Session is considered active only when both username and role are set.
|
||||
public boolean isLoggedIn() {
|
||||
return username != null && role != null;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,6 @@ import org.example.petshopdesktop.models.User;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/*
|
||||
Petshop Desktop
|
||||
Purpose: Authentication controller responsible for validating credentials and initialising the user session.
|
||||
*/
|
||||
public class LoginController {
|
||||
|
||||
@FXML
|
||||
@@ -31,18 +27,15 @@ public class LoginController {
|
||||
|
||||
@FXML
|
||||
void btnLoginClicked(ActionEvent event) {
|
||||
// Input normalisation keeps authentication behaviour consistent.
|
||||
String username = txtUsername.getText().trim();
|
||||
String password = txtPassword.getText();
|
||||
|
||||
// Basic validation to avoid unnecessary database calls.
|
||||
if (username.isEmpty() || password.isEmpty()) {
|
||||
lblError.setText("Please enter username and password.");
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Credential verification returns a fully populated User on success.
|
||||
User user = UserDB.authenticate(username, password);
|
||||
if (user == null) {
|
||||
lblError.setText("Invalid username or password.");
|
||||
@@ -50,7 +43,6 @@ public class LoginController {
|
||||
return;
|
||||
}
|
||||
|
||||
// Session state is stored in memory for use by controllers and UI RBAC.
|
||||
UserSession.getInstance().login(user.getUsername(), user.getRole());
|
||||
openMainLayout();
|
||||
|
||||
@@ -61,7 +53,6 @@ public class LoginController {
|
||||
|
||||
private void openMainLayout() {
|
||||
try {
|
||||
// View transition into the post login application shell.
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
getClass().getResource("/org/example/petshopdesktop/main-layout-view.fxml"));
|
||||
Scene scene = new Scene(loader.load());
|
||||
|
||||
@@ -11,12 +11,23 @@ import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
import org.example.petshopdesktop.auth.UserSession;
|
||||
|
||||
/*
|
||||
Petshop Desktop
|
||||
Purpose: Main application shell controller, includes navigation and UI level role based access control.
|
||||
*/
|
||||
public class MainLayoutController {
|
||||
|
||||
private static final String NAV_BASE_STYLE = "-fx-background-color: transparent; " +
|
||||
"-fx-text-fill: #cbd5e1; " +
|
||||
"-fx-background-radius: 10; " +
|
||||
"-fx-cursor: hand; " +
|
||||
"-fx-focus-color: transparent; " +
|
||||
"-fx-faint-focus-color: transparent;";
|
||||
|
||||
private static final String NAV_ACTIVE_STYLE = "-fx-background-color: #FF6B6B; " +
|
||||
"-fx-text-fill: white; " +
|
||||
"-fx-background-radius: 10; " +
|
||||
"-fx-cursor: hand; " +
|
||||
"-fx-focus-color: transparent; " +
|
||||
"-fx-faint-focus-color: transparent; " +
|
||||
"-fx-effect: dropshadow(gaussian, rgba(0,0,0,0.22), 10, 0.15, 0, 2);";
|
||||
|
||||
@FXML
|
||||
private Button btnAdoptions;
|
||||
|
||||
@@ -124,7 +135,6 @@ public class MainLayoutController {
|
||||
|
||||
@FXML
|
||||
void btnLogoutClicked(ActionEvent event) {
|
||||
// Logout clears session state before returning to the login view.
|
||||
UserSession.getInstance().logout();
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(
|
||||
@@ -141,22 +151,18 @@ public class MainLayoutController {
|
||||
|
||||
@FXML
|
||||
public void initialize() {
|
||||
// RBAC state is applied once during initial layout load.
|
||||
applyRBAC();
|
||||
|
||||
// Default landing view after successful authentication.
|
||||
loadView("pet-view.fxml");
|
||||
updateButtons(btnPets);
|
||||
}
|
||||
|
||||
private void applyRBAC() {
|
||||
UserSession session = UserSession.getInstance();
|
||||
|
||||
// Session identity is displayed in the header for clarity and auditing.
|
||||
lblUsername.setText(session.getUsername());
|
||||
lblRole.setText(session.getRole().toString());
|
||||
lblRole.setText("Leon's Petstore");
|
||||
|
||||
// UI level RBAC hides admin only navigation entries for non admin users.
|
||||
// setManaged(false) removes the node from layout calculations to avoid empty spacing.
|
||||
boolean isAdmin = session.isAdmin();
|
||||
btnInventory.setVisible(isAdmin);
|
||||
btnInventory.setManaged(isAdmin);
|
||||
@@ -165,7 +171,6 @@ public class MainLayoutController {
|
||||
btnProductSuppliers.setVisible(isAdmin);
|
||||
btnProductSuppliers.setManaged(isAdmin);
|
||||
|
||||
// Privileged operations should still be enforced within the relevant controllers and database methods.
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,10 +179,8 @@ public class MainLayoutController {
|
||||
*/
|
||||
private void loadView(String fxmlFile) {
|
||||
try {
|
||||
//Get the location of the fxml for view
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/org/example/petshopdesktop/modelviews/" + fxmlFile));
|
||||
Parent view = loader.load();
|
||||
//Clear any content that is in the stack pane and add the new view to display
|
||||
spContentArea.getChildren().clear();
|
||||
spContentArea.getChildren().add(view);
|
||||
} catch (Exception e) {
|
||||
@@ -191,21 +194,13 @@ public class MainLayoutController {
|
||||
* @param activeButton the button to be set active
|
||||
*/
|
||||
private void updateButtons(Button activeButton) {
|
||||
//reset all buttons
|
||||
Button[] BUTTONS = {btnAdoptions, btnPets, btnAppointments, btnInventory,
|
||||
btnSalesHistory, btnServices, btnSuppliers, btnProductSuppliers, btnProducts};
|
||||
btnSalesHistory, btnServices, btnSuppliers, btnProductSuppliers, btnProducts, btnPurchaseOrders};
|
||||
for (Button button : BUTTONS) {
|
||||
//set all buttons to inactive
|
||||
button.setStyle("-fx-background-color: transparent; " +
|
||||
"-fx-text-fill: #CCCCCC; " +
|
||||
"-fx-cursor: hand");
|
||||
button.setStyle(NAV_BASE_STYLE);
|
||||
}
|
||||
|
||||
//set active button
|
||||
activeButton.setStyle("-fx-background-color: #FF6B6B; " +
|
||||
"-fx-text-fill: white; " +
|
||||
"-fx-cursor: hand; " +
|
||||
"-fx-background-radius: 8");
|
||||
activeButton.setStyle(NAV_ACTIVE_STYLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
package org.example.petshopdesktop.controllers;
|
||||
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.*;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import org.example.petshopdesktop.DTOs.SaleDTO;
|
||||
import org.example.petshopdesktop.database.SaleDB;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class SaleController {
|
||||
|
||||
@@ -13,38 +16,137 @@ public class SaleController {
|
||||
private Button btnRefresh;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colCustomerName;
|
||||
private TableColumn<SaleDTO, String> colCustomerName;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colSaleDate;
|
||||
private TableColumn<SaleDTO, String> colSaleDate;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colSaleId;
|
||||
private TableColumn<SaleDTO, Integer> colSaleId;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colSalePaymentType;
|
||||
private TableColumn<SaleDTO, String> colSalePaymentType;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colSaleQuantity;
|
||||
private TableColumn<SaleDTO, Integer> colSaleQuantity;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colSaleTotal;
|
||||
private TableColumn<SaleDTO, Double> colSaleTotal;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colSaleUnitPrice;
|
||||
private TableColumn<SaleDTO, Double> colSaleUnitPrice;
|
||||
|
||||
@FXML
|
||||
private TableColumn<?, ?> colServiceProduct;
|
||||
private TableColumn<SaleDTO, String> colServiceProduct;
|
||||
|
||||
@FXML
|
||||
private TableView<?> tvSales;
|
||||
private TableView<SaleDTO> tvSales;
|
||||
|
||||
@FXML
|
||||
private TextField txtSearch;
|
||||
|
||||
@FXML
|
||||
void btnRefresh(ActionEvent event) {
|
||||
private ObservableList<SaleDTO> salesData;
|
||||
|
||||
/**
|
||||
* Initialize the controller - set up table columns and load data
|
||||
*/
|
||||
@FXML
|
||||
public void initialize() {
|
||||
// Set up table columns
|
||||
colSaleId.setCellValueFactory(new PropertyValueFactory<>("saleId"));
|
||||
colSaleDate.setCellValueFactory(new PropertyValueFactory<>("saleDate"));
|
||||
colCustomerName.setCellValueFactory(new PropertyValueFactory<>("employeeName"));
|
||||
colServiceProduct.setCellValueFactory(new PropertyValueFactory<>("productName"));
|
||||
colSaleQuantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
|
||||
colSaleUnitPrice.setCellValueFactory(new PropertyValueFactory<>("unitPrice"));
|
||||
colSaleTotal.setCellValueFactory(new PropertyValueFactory<>("total"));
|
||||
colSalePaymentType.setCellValueFactory(new PropertyValueFactory<>("paymentMethod"));
|
||||
|
||||
// Format currency columns
|
||||
colSaleUnitPrice.setCellFactory(tc -> new TableCell<SaleDTO, Double>() {
|
||||
@Override
|
||||
protected void updateItem(Double price, boolean empty) {
|
||||
super.updateItem(price, empty);
|
||||
if (empty || price == null) {
|
||||
setText(null);
|
||||
} else {
|
||||
setText(String.format("$%.2f", price));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
colSaleTotal.setCellFactory(tc -> new TableCell<SaleDTO, Double>() {
|
||||
@Override
|
||||
protected void updateItem(Double total, boolean empty) {
|
||||
super.updateItem(total, empty);
|
||||
if (empty || total == null) {
|
||||
setText(null);
|
||||
} else {
|
||||
setText(String.format("$%.2f", total));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Load initial data
|
||||
loadSales();
|
||||
|
||||
// Add search functionality
|
||||
txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
|
||||
if (newValue == null || newValue.trim().isEmpty()) {
|
||||
loadSales();
|
||||
} else {
|
||||
searchSales(newValue.trim());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all sales from database
|
||||
*/
|
||||
private void loadSales() {
|
||||
try {
|
||||
salesData = SaleDB.getSales();
|
||||
tvSales.setItems(salesData);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
showError("Failed to load sales data", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Search sales based on filter text
|
||||
* @param filter search term
|
||||
*/
|
||||
private void searchSales(String filter) {
|
||||
try {
|
||||
ObservableList<SaleDTO> filteredSales = SaleDB.getFilteredSales(filter);
|
||||
tvSales.setItems(filteredSales);
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
showError("Failed to search sales", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refresh button handler - reload all sales data
|
||||
* @param event button click event
|
||||
*/
|
||||
@FXML
|
||||
void btnRefresh(ActionEvent event) {
|
||||
txtSearch.clear();
|
||||
loadSales();
|
||||
}
|
||||
|
||||
/**
|
||||
* Show error alert
|
||||
* @param title alert title
|
||||
* @param message error message
|
||||
*/
|
||||
private void showError(String title, String message) {
|
||||
Alert alert = new Alert(Alert.AlertType.ERROR);
|
||||
alert.setTitle(title);
|
||||
alert.setHeaderText(null);
|
||||
alert.setContentText(message);
|
||||
alert.showAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,10 +115,10 @@ public class AdoptionDB {
|
||||
Connection conn = ConnectionDB.getConnection();
|
||||
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery("SELECT customerId, firstName, lastName FROM customer");
|
||||
ResultSet rs = stmt.executeQuery("SELECT customerId, firstName, lastName, email, phone FROM customer");
|
||||
|
||||
while (rs.next()) {
|
||||
customers.add(new Customer(rs.getInt(1), rs.getString(2), rs.getString(3)));
|
||||
customers.add(new Customer(rs.getInt(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5)));
|
||||
}
|
||||
|
||||
conn.close();
|
||||
|
||||
@@ -23,7 +23,7 @@ public class ProductSupplierDB {
|
||||
//Execute Query
|
||||
Statement stmt = conn.createStatement();
|
||||
String sql = "SELECT ps.supId, ps.prodId, s.supCompany, p.prodName, ps.cost " +
|
||||
"FROM productsupplier ps " +
|
||||
"FROM productSupplier ps " +
|
||||
"LEFT JOIN product p " +
|
||||
"ON p.prodId = ps.prodId " +
|
||||
"LEFT JOIN supplier s " +
|
||||
@@ -62,7 +62,7 @@ public class ProductSupplierDB {
|
||||
String sql =
|
||||
"SELECT ps.supId, ps.prodId, s.supCompany, p.prodName, ps.cost " +
|
||||
"FROM product p " +
|
||||
"LEFT JOIN productsupplier ps " +
|
||||
"LEFT JOIN productSupplier ps " +
|
||||
"ON p.prodId = ps.prodId " +
|
||||
"LEFT JOIN supplier s " +
|
||||
"ON s.supId = ps.supId " +
|
||||
@@ -108,7 +108,7 @@ public class ProductSupplierDB {
|
||||
int numRows = 0;
|
||||
|
||||
Connection conn = ConnectionDB.getConnection();
|
||||
String sql = "INSERT INTO productsupplier (prodId, supId, cost) " +
|
||||
String sql = "INSERT INTO productSupplier (prodId, supId, cost) " +
|
||||
"VALUES (?, ?, ?)";
|
||||
|
||||
//These are the values from productSupplier to put into query above
|
||||
@@ -141,7 +141,7 @@ public class ProductSupplierDB {
|
||||
|
||||
try{
|
||||
//Delete old data first
|
||||
String sql = "DELETE FROM productsupplier WHERE supId = ? AND prodId = ?";
|
||||
String sql = "DELETE FROM productSupplier WHERE supId = ? AND prodId = ?";
|
||||
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||
stmt.setInt(1, oldSupId);
|
||||
stmt.setInt(2, oldProdId);
|
||||
@@ -149,7 +149,7 @@ public class ProductSupplierDB {
|
||||
|
||||
//Then change the data by inserting a new relation with given keys (only if delete worked)
|
||||
if(numRows > 0){
|
||||
sql = "INSERT INTO productsupplier (prodId, supId, cost) " +
|
||||
sql = "INSERT INTO productSupplier (prodId, supId, cost) " +
|
||||
"VALUES (?, ?, ?)";
|
||||
stmt = conn.prepareStatement(sql);
|
||||
stmt.setInt(1, productSupplier.getProdId());
|
||||
@@ -184,7 +184,7 @@ public class ProductSupplierDB {
|
||||
int numRows = 0;
|
||||
Connection conn = ConnectionDB.getConnection();
|
||||
|
||||
String sql = "DELETE FROM productsupplier WHERE supId = ? AND prodId = ?";
|
||||
String sql = "DELETE FROM productSupplier WHERE supId = ? AND prodId = ?";
|
||||
PreparedStatement stmt = conn.prepareStatement(sql);
|
||||
stmt.setInt(1, supId);
|
||||
stmt.setInt(2, prodId);
|
||||
|
||||
113
src/main/java/org/example/petshopdesktop/database/SaleDB.java
Normal file
113
src/main/java/org/example/petshopdesktop/database/SaleDB.java
Normal file
@@ -0,0 +1,113 @@
|
||||
package org.example.petshopdesktop.database;
|
||||
|
||||
import javafx.collections.FXCollections;
|
||||
import javafx.collections.ObservableList;
|
||||
import org.example.petshopdesktop.DTOs.SaleDTO;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
public class SaleDB {
|
||||
|
||||
/**
|
||||
* Get all sale items with details
|
||||
* @return ObservableList of SaleDTOs
|
||||
* @throws SQLException if database operation fails
|
||||
*/
|
||||
public static ObservableList<SaleDTO> getSales() throws SQLException {
|
||||
ObservableList<SaleDTO> sales = FXCollections.observableArrayList();
|
||||
Connection conn = ConnectionDB.getConnection();
|
||||
|
||||
String sql = """
|
||||
SELECT
|
||||
s.saleId,
|
||||
DATE_FORMAT(s.saleDate, '%Y-%m-%d %H:%i') as saleDate,
|
||||
CONCAT(e.firstName, ' ', e.lastName) as employeeName,
|
||||
p.prodName,
|
||||
si.quantity,
|
||||
si.unitPrice,
|
||||
(si.quantity * si.unitPrice) as lineTotal,
|
||||
s.paymentMethod
|
||||
FROM sale s
|
||||
JOIN saleItem si ON s.saleId = si.saleId
|
||||
JOIN product p ON si.prodId = p.prodId
|
||||
JOIN employee e ON s.employeeId = e.employeeId
|
||||
ORDER BY s.saleDate DESC, s.saleId, si.saleItemId
|
||||
""";
|
||||
|
||||
Statement stmt = conn.createStatement();
|
||||
ResultSet rs = stmt.executeQuery(sql);
|
||||
|
||||
while (rs.next()) {
|
||||
sales.add(new SaleDTO(
|
||||
rs.getInt("saleId"),
|
||||
rs.getString("saleDate"),
|
||||
rs.getString("employeeName"),
|
||||
rs.getString("prodName"),
|
||||
rs.getInt("quantity"),
|
||||
rs.getDouble("unitPrice"),
|
||||
rs.getDouble("lineTotal"),
|
||||
rs.getString("paymentMethod")
|
||||
));
|
||||
}
|
||||
|
||||
conn.close();
|
||||
return sales;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filtered sale items
|
||||
* @param filter search term
|
||||
* @return ObservableList of SaleDTOs matching the filter
|
||||
* @throws SQLException if database operation fails
|
||||
*/
|
||||
public static ObservableList<SaleDTO> getFilteredSales(String filter) throws SQLException {
|
||||
ObservableList<SaleDTO> sales = FXCollections.observableArrayList();
|
||||
Connection conn = ConnectionDB.getConnection();
|
||||
|
||||
String sql = """
|
||||
SELECT
|
||||
s.saleId,
|
||||
DATE_FORMAT(s.saleDate, '%Y-%m-%d %H:%i') as saleDate,
|
||||
CONCAT(e.firstName, ' ', e.lastName) as employeeName,
|
||||
p.prodName,
|
||||
si.quantity,
|
||||
si.unitPrice,
|
||||
(si.quantity * si.unitPrice) as lineTotal,
|
||||
s.paymentMethod
|
||||
FROM sale s
|
||||
JOIN saleItem si ON s.saleId = si.saleId
|
||||
JOIN product p ON si.prodId = p.prodId
|
||||
JOIN employee e ON s.employeeId = e.employeeId
|
||||
WHERE s.saleId LIKE ?
|
||||
OR p.prodName LIKE ?
|
||||
OR CONCAT(e.firstName, ' ', e.lastName) LIKE ?
|
||||
OR s.paymentMethod LIKE ?
|
||||
ORDER BY s.saleDate DESC, s.saleId, si.saleItemId
|
||||
""";
|
||||
|
||||
PreparedStatement pstmt = conn.prepareStatement(sql);
|
||||
String searchPattern = "%" + filter + "%";
|
||||
pstmt.setString(1, searchPattern);
|
||||
pstmt.setString(2, searchPattern);
|
||||
pstmt.setString(3, searchPattern);
|
||||
pstmt.setString(4, searchPattern);
|
||||
|
||||
ResultSet rs = pstmt.executeQuery();
|
||||
|
||||
while (rs.next()) {
|
||||
sales.add(new SaleDTO(
|
||||
rs.getInt("saleId"),
|
||||
rs.getString("saleDate"),
|
||||
rs.getString("employeeName"),
|
||||
rs.getString("prodName"),
|
||||
rs.getInt("quantity"),
|
||||
rs.getDouble("unitPrice"),
|
||||
rs.getDouble("lineTotal"),
|
||||
rs.getString("paymentMethod")
|
||||
));
|
||||
}
|
||||
|
||||
conn.close();
|
||||
return sales;
|
||||
}
|
||||
}
|
||||
@@ -5,10 +5,6 @@ import org.example.petshopdesktop.models.User;
|
||||
|
||||
import java.sql.*;
|
||||
|
||||
/*
|
||||
Petshop Desktop
|
||||
Purpose: User authentication and role lookup against the users table.
|
||||
*/
|
||||
public class UserDB {
|
||||
|
||||
/**
|
||||
@@ -34,8 +30,6 @@ public class UserDB {
|
||||
int userId = rs.getInt("user_id");
|
||||
String uname = rs.getString("username");
|
||||
|
||||
// Role values are stored in the database as strings and normalised to match the enum.
|
||||
// Table constraints limit role values, Role.valueOf is expected to be safe under normal operation.
|
||||
Role role = Role.valueOf(rs.getString("role").toUpperCase());
|
||||
|
||||
return new User(userId, uname, role);
|
||||
@@ -59,7 +53,6 @@ public class UserDB {
|
||||
)
|
||||
""";
|
||||
|
||||
// Default accounts support initial development and testing, credentials should be rotated or removed for deployment.
|
||||
String seedAdmin = """
|
||||
INSERT IGNORE INTO users (username, password_hash, role)
|
||||
VALUES ('admin', SHA2('admin123', 256), 'ADMIN')
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.AdoptionDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.AdoptionDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0"
|
||||
spacing="20.0" style="-fx-font-size: 14px;"
|
||||
xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1"
|
||||
xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.AppointmentDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.InventoryDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.InventoryDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.PetDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductSupplierDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ProductSupplierDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
<?import javafx.scene.text.Font?>
|
||||
<?import javafx.scene.control.ComboBox?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ServiceDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.ServiceDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.SupplierDialogController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" prefHeight="523.0" prefWidth="790.0" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.dialogcontrollers.SupplierDialogController">
|
||||
<children>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="79.0" prefWidth="727.0" spacing="20.0" style="-fx-background-color: #2C3E50; -fx-background-radius: 14;">
|
||||
<children>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
<VBox alignment="CENTER" prefHeight="400.0" prefWidth="380.0" spacing="16.0"
|
||||
style="-fx-background-color: #2C3E50;"
|
||||
xmlns="http://javafx.com/javafx/25"
|
||||
xmlns="http://javafx.com/javafx/17"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="org.example.petshopdesktop.controllers.LoginController">
|
||||
<padding>
|
||||
|
||||
@@ -5,131 +5,146 @@
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.Separator?>
|
||||
<?import javafx.scene.layout.BorderPane?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.StackPane?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="742.0" prefWidth="1069.0" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.MainLayoutController">
|
||||
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="742.0" prefWidth="1069.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.MainLayoutController">
|
||||
<left>
|
||||
<VBox prefHeight="700.0" prefWidth="250.0" spacing="15.0" style="-fx-background-color: #2C3E50;" BorderPane.alignment="CENTER">
|
||||
<VBox prefHeight="700.0" prefWidth="250.0" spacing="10.0" style="-fx-background-color: #2C3E50;" BorderPane.alignment="CENTER">
|
||||
<padding>
|
||||
<Insets bottom="30.0" left="30.0" right="30.0" top="30.0" />
|
||||
<Insets bottom="22.0" left="22.0" right="22.0" top="24.0" />
|
||||
</padding>
|
||||
<children>
|
||||
<Label fx:id="lblUsername" text="Name" textFill="WHITE">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="30.0" />
|
||||
<Font name="System Bold" size="24.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label fx:id="lblRole" text="Pet Store Manager" textFill="#ffe66d">
|
||||
<Label fx:id="lblRole" text="Leon's Petstore" textFill="#ffe66d">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="16.0" />
|
||||
<Font name="System" size="14.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="20.0" />
|
||||
<Insets bottom="8.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Separator prefWidth="200.0" style="-fx-background-color: #444444;" />
|
||||
<Button fx:id="btnPets" mnemonicParsing="false" onAction="#btnPetsClicked" prefWidth="250.0" style="-fx-background-color: #FF6b6b; -fx-background-radius: 8; -fx-cursor: hand;" text="🐾 Pets" textFill="WHITE">
|
||||
<VBox.margin>
|
||||
<Insets />
|
||||
</VBox.margin>
|
||||
<Separator prefWidth="200.0" style="-fx-background-color: #444444; -fx-opacity: 0.35;" />
|
||||
|
||||
<Label text="PETS" textFill="#94a3b8">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="110.0" top="12.0" />
|
||||
<Insets top="8.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
|
||||
<Button fx:id="btnPets" alignment="CENTER_LEFT" mnemonicParsing="false" onAction="#btnPetsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Pets" textFill="#cbd5e1">
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
</Button>
|
||||
<Button fx:id="btnAdoptions" layoutX="40.0" layoutY="234.0" mnemonicParsing="false" onAction="#btnAdoptionsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="❤ Adoptions" textFill="#cccccc">
|
||||
<Button fx:id="btnAdoptions" alignment="CENTER_LEFT" layoutX="40.0" layoutY="234.0" mnemonicParsing="false" onAction="#btnAdoptionsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Adoptions" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="75.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnAppointments" layoutX="40.0" layoutY="294.0" mnemonicParsing="false" onAction="#btnAppointmentsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="📅 Appointments" textFill="#cccccc">
|
||||
<Button fx:id="btnAppointments" alignment="CENTER_LEFT" layoutX="40.0" layoutY="294.0" mnemonicParsing="false" onAction="#btnAppointmentsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Appointments" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="50.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnServices" layoutX="40.0" layoutY="354.0" mnemonicParsing="false" onAction="#btnServicesClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="✂ Services" textFill="#cccccc">
|
||||
<Button fx:id="btnServices" alignment="CENTER_LEFT" layoutX="40.0" layoutY="354.0" mnemonicParsing="false" onAction="#btnServicesClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Services" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="85.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Separator layoutX="40.0" layoutY="156.0" prefWidth="200.0" style="-fx-background-color: #444444;" />
|
||||
<Button fx:id="btnProducts" layoutX="40.0" layoutY="414.0" mnemonicParsing="false" onAction="#btnProductsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="📦 Products" textFill="#cccccc">
|
||||
<Separator layoutX="40.0" layoutY="156.0" prefWidth="200.0" style="-fx-background-color: #444444; -fx-opacity: 0.35;" />
|
||||
|
||||
<Label text="PRODUCTS" textFill="#94a3b8">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="80.0" top="12.0" />
|
||||
<Insets top="8.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
|
||||
<Button fx:id="btnProducts" alignment="CENTER_LEFT" layoutX="40.0" layoutY="414.0" mnemonicParsing="false" onAction="#btnProductsClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Products" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnInventory" layoutX="40.0" layoutY="492.0" mnemonicParsing="false" onAction="#btnInventoryClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="📋 Inventory" textFill="#cccccc">
|
||||
<Button fx:id="btnInventory" alignment="CENTER_LEFT" layoutX="40.0" layoutY="492.0" mnemonicParsing="false" onAction="#btnInventoryClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Inventory" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="74.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnSuppliers" layoutX="40.0" layoutY="552.0" mnemonicParsing="false" onAction="#btnSuppliersClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="🏭 Suppliers" textFill="#cccccc">
|
||||
<Button fx:id="btnSuppliers" alignment="CENTER_LEFT" layoutX="40.0" layoutY="552.0" mnemonicParsing="false" onAction="#btnSuppliersClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Suppliers" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="76.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnProductSuppliers" layoutX="40.0" layoutY="612.0" mnemonicParsing="false" onAction="#btnProductSuppliersClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="🔗 Product-Suppliers" textFill="#cccccc">
|
||||
<Button fx:id="btnProductSuppliers" alignment="CENTER_LEFT" layoutX="40.0" layoutY="612.0" mnemonicParsing="false" onAction="#btnProductSuppliersClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Product-Suppliers" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="18.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnSalesHistory" layoutX="40.0" layoutY="672.0" mnemonicParsing="false" onAction="#btnSalesHistoryClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;" text="📄 Sales History" textFill="#cccccc">
|
||||
<Button fx:id="btnSalesHistory" alignment="CENTER_LEFT" layoutX="40.0" layoutY="672.0" mnemonicParsing="false" onAction="#btnSalesHistoryClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Sales History" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="45.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
|
||||
<Button fx:id="btnPurchaseOrders"
|
||||
mnemonicParsing="false"
|
||||
onAction="#btnPurchaseOrdersClicked"
|
||||
prefWidth="250.0"
|
||||
style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand;"
|
||||
text="🧾 Purchase Orders"
|
||||
textFill="#cccccc">
|
||||
<Button fx:id="btnPurchaseOrders" alignment="CENTER_LEFT" mnemonicParsing="false" onAction="#btnPurchaseOrdersClicked" prefWidth="250.0" style="-fx-background-color: transparent; -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Purchase Orders" textFill="#cbd5e1">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="40.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
</Button>
|
||||
<Button fx:id="btnLogout" mnemonicParsing="false" onAction="#btnLogoutClicked" prefWidth="250.0" style="-fx-background-color: #34495E; -fx-background-radius: 8; -fx-cursor: hand;" text="🚪 Logout" textFill="#cccccc">
|
||||
|
||||
<Region VBox.vgrow="ALWAYS" />
|
||||
|
||||
<Button fx:id="btnLogout" alignment="CENTER_LEFT" mnemonicParsing="false" onAction="#btnLogoutClicked" prefWidth="250.0" style="-fx-background-color: rgba(255,255,255,0.08); -fx-background-radius: 10; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Logout" textFill="#e2e8f0">
|
||||
<font>
|
||||
<Font name="Comic Sans MS Bold" size="14.0" />
|
||||
<Font name="System" size="13.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets bottom="12.0" left="12.0" right="94.0" top="12.0" />
|
||||
<Insets bottom="10.0" left="14.0" right="14.0" top="10.0" />
|
||||
</padding>
|
||||
<VBox.margin>
|
||||
<Insets top="20.0" />
|
||||
<Insets top="12.0" />
|
||||
</VBox.margin>
|
||||
</Button>
|
||||
</children>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.AdoptionController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.AdoptionController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.AppointmentController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.AppointmentController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.InventoryController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.InventoryController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.PetController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.PetController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.ProductSupplierController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.ProductSupplierController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.ProductController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.ProductController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<VBox spacing="20.0"
|
||||
style="-fx-font-size: 14px;"
|
||||
xmlns="http://javafx.com/javafx/25"
|
||||
xmlns="http://javafx.com/javafx/17"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="org.example.petshopdesktop.controllers.PurchaseOrderController">
|
||||
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.control.TextField?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.Region?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity"
|
||||
minWidth="-Infinity"
|
||||
spacing="20"
|
||||
style="-fx-font-size:14px;"
|
||||
xmlns="http://javafx.com/javafx/25"
|
||||
xmlns:fx="http://javafx.com/fxml/1"
|
||||
fx:controller="org.example.petshopdesktop.controllers.PurchaseOrderdialogController">
|
||||
|
||||
<padding>
|
||||
<Insets top="20" right="20" bottom="20" left="20"/>
|
||||
</padding>
|
||||
|
||||
<!-- HEADER -->
|
||||
<HBox alignment="CENTER_LEFT" spacing="20">
|
||||
|
||||
<Label text="Purchase Orders" textFill="#2c3e50">
|
||||
<font>
|
||||
<Font name="System Bold" size="30"/>
|
||||
</font>
|
||||
</Label>
|
||||
|
||||
<Region HBox.hgrow="ALWAYS"/>
|
||||
|
||||
</HBox>
|
||||
|
||||
<!-- SEARCH BAR -->
|
||||
<HBox alignment="CENTER_LEFT"
|
||||
spacing="10"
|
||||
style="-fx-background-color:white; -fx-background-radius:14;">
|
||||
|
||||
<padding>
|
||||
<Insets top="10" bottom="10" left="15" right="15"/>
|
||||
</padding>
|
||||
|
||||
<TextField fx:id="txtSearch"
|
||||
promptText="Search Purchase Orders..."
|
||||
style="-fx-border-width:0; -fx-background-color:transparent;"
|
||||
HBox.hgrow="ALWAYS"/>
|
||||
|
||||
</HBox>
|
||||
|
||||
<!-- TABLE -->
|
||||
<TableView fx:id="tvPurchaseOrders"
|
||||
prefHeight="362"
|
||||
style="-fx-background-color:white; -fx-background-radius:12;"
|
||||
VBox.vgrow="ALWAYS">
|
||||
|
||||
<columns>
|
||||
|
||||
<TableColumn fx:id="colOrderId"
|
||||
text="Order ID"
|
||||
prefWidth="120"/>
|
||||
|
||||
<TableColumn fx:id="colSupplier"
|
||||
text="Supplier"
|
||||
prefWidth="250"/>
|
||||
|
||||
<TableColumn fx:id="colOrderDate"
|
||||
text="Order Date"
|
||||
prefWidth="200"/>
|
||||
|
||||
<TableColumn fx:id="colStatus"
|
||||
text="Status"
|
||||
prefWidth="180"/>
|
||||
|
||||
</columns>
|
||||
|
||||
</TableView>
|
||||
|
||||
</VBox>
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.SaleController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.SaleController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.ServiceController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.ServiceController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/25" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.SupplierController">
|
||||
<VBox minHeight="-Infinity" minWidth="-Infinity" spacing="20.0" style="-fx-font-size: 14px;" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.example.petshopdesktop.controllers.SupplierController">
|
||||
<padding>
|
||||
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
|
||||
</padding>
|
||||
|
||||
Reference in New Issue
Block a user