Merge pull request #75 from RecentRunner/fix-features-icons-v2

Finalize feature fixes
This commit is contained in:
2026-04-01 19:31:28 -06:00
committed by GitHub
6 changed files with 78 additions and 17 deletions

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.entity; package com.petshop.backend.entity;
import com.petshop.backend.util.PhoneUtils;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp; import org.hibernate.annotations.UpdateTimestamp;
@@ -77,7 +78,7 @@ public class StoreLocation {
} }
public void setPhone(String phone) { public void setPhone(String phone) {
this.phone = phone; this.phone = PhoneUtils.normalize(phone);
} }
public String getEmail() { public String getEmail() {

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.entity; package com.petshop.backend.entity;
import com.petshop.backend.util.PhoneUtils;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp; import org.hibernate.annotations.UpdateTimestamp;
@@ -97,7 +98,7 @@ public class Supplier {
} }
public void setSupPhone(String supPhone) { public void setSupPhone(String supPhone) {
this.supPhone = supPhone; this.supPhone = PhoneUtils.normalize(supPhone);
} }
public LocalDateTime getCreatedAt() { public LocalDateTime getCreatedAt() {

View File

@@ -1,5 +1,6 @@
package com.petshop.backend.entity; package com.petshop.backend.entity;
import com.petshop.backend.util.PhoneUtils;
import jakarta.persistence.*; import jakarta.persistence.*;
import org.hibernate.annotations.CreationTimestamp; import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp; import org.hibernate.annotations.UpdateTimestamp;
@@ -118,7 +119,7 @@ public class User {
} }
public void setPhone(String phone) { public void setPhone(String phone) {
this.phone = phone; this.phone = PhoneUtils.normalize(phone);
} }
public String getAvatarUrl() { public String getAvatarUrl() {

View File

@@ -0,0 +1,24 @@
package com.petshop.backend.util;
public class PhoneUtils {
public static String normalize(String phone) {
if (phone == null) {
return null;
}
String digits = phone.replaceAll("\\D", "");
if (digits.length() >= 10) {
if (digits.length() == 11 && digits.startsWith("1")) {
digits = digits.substring(1);
}
digits = digits.substring(0, 10);
return String.format("(%s) %s-%s",
digits.substring(0, 3),
digits.substring(3, 6),
digits.substring(6));
}
return phone;
}
}

View File

@@ -0,0 +1,34 @@
-- Normalize existing phone numbers to (XXX) XXX-XXXX format
-- Update users table
UPDATE users
SET phone = '(' || SUBSTRING(clean_digits, 1, 3) || ') ' || SUBSTRING(clean_digits, 4, 3) || '-' || SUBSTRING(clean_digits, 7, 4)
FROM (
SELECT id,
RIGHT(regexp_replace(phone, '\D', '', 'g'), 10) as clean_digits
FROM users
WHERE regexp_replace(phone, '\D', '', 'g') ~ '\d{10,}$'
) AS sub
WHERE users.id = sub.id;
-- Update supplier table
UPDATE supplier
SET supPhone = '(' || SUBSTRING(clean_digits, 1, 3) || ') ' || SUBSTRING(clean_digits, 4, 3) || '-' || SUBSTRING(clean_digits, 7, 4)
FROM (
SELECT supId,
RIGHT(regexp_replace(supPhone, '\D', '', 'g'), 10) as clean_digits
FROM supplier
WHERE regexp_replace(supPhone, '\D', '', 'g') ~ '\d{10,}$'
) AS sub
WHERE supplier.supId = sub.supId;
-- Update storeLocation table
UPDATE storeLocation
SET phone = '(' || SUBSTRING(clean_digits, 1, 3) || ') ' || SUBSTRING(clean_digits, 4, 3) || '-' || SUBSTRING(clean_digits, 7, 4)
FROM (
SELECT storeId,
RIGHT(regexp_replace(phone, '\D', '', 'g'), 10) as clean_digits
FROM storeLocation
WHERE regexp_replace(phone, '\D', '', 'g') ~ '\d{10,}$'
) AS sub
WHERE storeLocation.storeId = sub.storeId;

View File

@@ -91,7 +91,7 @@
</padding> </padding>
</Label> </Label>
<Button fx:id="btnAnalytics" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnAnalyticsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Analytics" textFill="#cbd5e1"> <Button fx:id="btnAnalytics" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnAnalyticsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="📊 Analytics" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -99,7 +99,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnSalesHistory" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnSalesHistoryClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Sales History" textFill="#cbd5e1"> <Button fx:id="btnSalesHistory" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnSalesHistoryClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="💰 Sales History" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -107,7 +107,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnAppointments" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnAppointmentsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Appointments" textFill="#cbd5e1"> <Button fx:id="btnAppointments" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnAppointmentsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="📅 Appointments" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -115,7 +115,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnServices" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnServicesClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Services" textFill="#cbd5e1"> <Button fx:id="btnServices" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnServicesClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="✂️ Services" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -123,7 +123,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnChat" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnChatClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Chat" textFill="#cbd5e1"> <Button fx:id="btnChat" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnChatClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="💬 Chat" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -143,7 +143,7 @@
</padding> </padding>
</Label> </Label>
<Button fx:id="btnPets" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnPetsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Pets" textFill="#cbd5e1"> <Button fx:id="btnPets" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnPetsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="🐾 Pets" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -151,7 +151,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnAdoptions" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnAdoptionsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Adoptions" textFill="#cbd5e1"> <Button fx:id="btnAdoptions" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnAdoptionsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="🏠 Adoptions" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -159,7 +159,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnProducts" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnProductsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Products" textFill="#cbd5e1"> <Button fx:id="btnProducts" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnProductsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="📦 Products" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -179,7 +179,7 @@
</padding> </padding>
</Label> </Label>
<Button fx:id="btnInventory" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnInventoryClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Inventory" textFill="#cbd5e1"> <Button fx:id="btnInventory" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnInventoryClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="📋 Inventory" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -187,7 +187,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnSuppliers" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnSuppliersClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Suppliers" textFill="#cbd5e1"> <Button fx:id="btnSuppliers" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnSuppliersClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="🚛 Suppliers" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -195,7 +195,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnProductSuppliers" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnProductSuppliersClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Product-Suppliers" textFill="#cbd5e1"> <Button fx:id="btnProductSuppliers" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnProductSuppliersClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="🔗 Product-Suppliers" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -203,7 +203,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnPurchaseOrders" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnPurchaseOrdersClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Purchase Orders" textFill="#cbd5e1"> <Button fx:id="btnPurchaseOrders" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnPurchaseOrdersClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="📝 Purchase Orders" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -211,7 +211,7 @@
<Insets bottom="8.0" left="10.0" right="10.0" top="8.0" /> <Insets bottom="8.0" left="10.0" right="10.0" top="8.0" />
</padding> </padding>
</Button> </Button>
<Button fx:id="btnStaffAccounts" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnStaffAccountsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Staff Accounts" textFill="#cbd5e1"> <Button fx:id="btnStaffAccounts" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnStaffAccountsClicked" style="-fx-background-color: transparent; -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="👥 Staff Accounts" textFill="#cbd5e1">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>
@@ -220,7 +220,7 @@
</padding> </padding>
</Button> </Button>
<Button fx:id="btnLogout" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnLogoutClicked" style="-fx-background-color: rgba(255,255,255,0.08); -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="Logout" textFill="#e2e8f0"> <Button fx:id="btnLogout" alignment="CENTER_LEFT" maxWidth="Infinity" mnemonicParsing="false" onAction="#btnLogoutClicked" style="-fx-background-color: rgba(255,255,255,0.08); -fx-background-radius: 8; -fx-cursor: hand; -fx-focus-color: transparent; -fx-faint-focus-color: transparent;" text="🚪 Logout" textFill="#e2e8f0">
<font> <font>
<Font name="System" size="12.0" /> <Font name="System" size="12.0" />
</font> </font>