From 20c214e6274861ee10500efe84ceccb31f36f780 Mon Sep 17 00:00:00 2001 From: Nicholas Gallimore Date: Fri, 8 Aug 2025 21:12:41 -0400 Subject: [PATCH 1/5] NFG-86 fix tsconfig --- .github/workflows/ci.yaml | 2 +- tsconfig.app.json | 2 +- tsconfig.spec.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 471b557..d61aeda 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -95,4 +95,4 @@ jobs: action: 'upload' app_location: '/' # App source code path api_location: '' # Api source code path - optional - output_location: 'dist/' # Built app content directory - adjust to match your app’s dist folder + output_location: './dist' # Built app content directory - adjust to match your app’s dist folder diff --git a/tsconfig.app.json b/tsconfig.app.json index ce051b1..5debb86 100644 --- a/tsconfig.app.json +++ b/tsconfig.app.json @@ -2,7 +2,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "./dist/app", + "outDir": "./dist", "types": [] }, "files": ["src/main.ts"], diff --git a/tsconfig.spec.json b/tsconfig.spec.json index a0e8507..5421241 100644 --- a/tsconfig.spec.json +++ b/tsconfig.spec.json @@ -1,7 +1,7 @@ { "extends": "./tsconfig.json", "compilerOptions": { - "outDir": "./out-tsc/spec", + "outDir": "./spec", "module": "CommonJs", "types": ["jest", "node"] }, From 85bd3d5f897f4317dcb2c039feef15cf6bad88ae Mon Sep 17 00:00:00 2001 From: Nicholas Gallimore Date: Fri, 10 Apr 2026 14:54:47 -0400 Subject: [PATCH 2/5] NFG-86 Add default-product image --- .../inventory-items-table.component.ts | 30 +++++++++--------- src/assets/default-product.png | Bin 0 -> 37004 bytes 2 files changed, 15 insertions(+), 15 deletions(-) create mode 100644 src/assets/default-product.png diff --git a/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.ts b/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.ts index 97b5ac8..3c6b1bb 100644 --- a/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.ts +++ b/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.ts @@ -23,7 +23,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { // Sample Table Data rawMaterials = [ { - picture: 'assets/ascorbicAcid.png', + picture: 'assets/default-product.png', materialId: 'RM001', name: 'Ascorbic Acid (Vitamin C)', supplier: 'HealthPro Labs', @@ -46,7 +46,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { priceLastUpdated: new Date('2024-01-25'), }, { - picture: 'assets/manganeseSulfate.png', + picture: 'assets/default-product.png', materialId: 'RM002', name: 'Manganese Sulfate (Manganese)', supplier: 'Mineral Essentials Co.', @@ -69,7 +69,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { priceLastUpdated: new Date('2024-01-05'), }, { - picture: 'assets/riboflavin.png', + picture: 'assets/default-product.png', materialId: 'RM003', name: 'Riboflavin (Vitamin B2)', supplier: 'VitalSource Pharma', @@ -92,7 +92,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { priceLastUpdated: new Date('2024-02-01'), }, { - picture: 'assets/calciferol.png', + picture: 'assets/default-product.png', materialId: 'RM004', name: 'Ergocalciferol (Vitamin D2)', supplier: 'Sunshine Extracts', @@ -117,7 +117,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { ]; components = [ { - picture: 'assets/bottleCap.png', + picture: 'assets/default-product.png', componentId: 'CMP001', name: 'Plastic Bottle Cap', supplier: 'CapIt Industries', @@ -138,7 +138,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'In Stock', }, { - picture: 'assets/labels.png', + picture: 'assets/default-product.png', componentId: 'CMP002', name: 'Pill Bottle Labels', supplier: 'LabelPro Supplies', @@ -159,7 +159,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'Backordered', }, { - picture: 'assets/silicaGel.png', + picture: 'assets/default-product.png', componentId: 'CMP003', name: 'Silica Gel Packets', supplier: 'DryGuard Corp', @@ -180,7 +180,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'In Stock', }, { - picture: 'assets/cottonBalls.png', + picture: 'assets/default-product.png', componentId: 'CMP004', name: 'Cotton Balls', supplier: 'PureSoft Materials', @@ -201,7 +201,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'In Stock', }, { - picture: 'assets/bottles.png', + picture: 'assets/default-product.png', componentId: 'CMP005', name: 'Plastic Pill Bottles', supplier: 'PharmaContainer Ltd.', @@ -225,7 +225,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { wips = [ { - picture: 'assets/probioticCapsules.png', // Path to image + picture: 'assets/default-product.png', // Path to image wipId: 'WIP001', productName: 'Probiotic Capsules', sku: 'PROB-CAP-001', @@ -246,7 +246,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'In Progress', }, { - picture: 'assets/vitaminDPowder.png', // Path to image + picture: 'assets/default-product.png', // Path to image wipId: 'WIP002', productName: 'Vitamin D Powder', sku: 'VITD-PWD-001', @@ -267,7 +267,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'Delayed', }, { - picture: 'assets/fishOilLiquid.png', // Path to image + picture: 'assets/default-product.png', // Path to image wipId: 'WIP003', productName: 'Omega-3 Fish Oil', sku: 'FISH-OIL-001', @@ -290,7 +290,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { ]; finishedGoods = [ { - picture: 'assets/probioticCapsules.png', // Path to image + picture: 'assets/default-product.png', // Path to image productName: 'Probiotic Capsules', sku: 'PROB-CAP-001', batchIds: 'BATCHC123, BATCHC124', @@ -309,7 +309,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'In Stock', }, { - picture: 'assets/vitaminDPowder.png', // Path to image + picture: 'assets/default-product.png', // Path to image productName: 'Vitamin D Powder', sku: 'VITD-PWD-001', batchIds: 'BATCHD456', @@ -328,7 +328,7 @@ export class InventoryItemsTableComponent implements OnInit, AfterViewInit { status: 'Backordered', }, { - picture: 'assets/fishOilLiquid.png', // Path to image + picture: 'assets/default-product.png', // Path to image productName: 'Omega-3 Fish Oil', sku: 'FISH-OIL-001', batchIds: 'BATCHF789', diff --git a/src/assets/default-product.png b/src/assets/default-product.png new file mode 100644 index 0000000000000000000000000000000000000000..98065672eaa9b6b2dc1d36eedecf4061cd23fd88 GIT binary patch literal 37004 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

?fln$@5#TBRFGBb;?5Nxhh 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 Hx5R$|T-!7% literal 0 HcmV?d00001 From 261e0660297f1ab2bbb04bc0df029a2e39ce317b Mon Sep 17 00:00:00 2001 From: Nicholas Gallimore Date: Fri, 10 Apr 2026 15:09:13 -0400 Subject: [PATCH 3/5] NFG-86 Add auth fix, stylize the add new inventory item button --- src/app/components/auth/auth.interceptor.ts | 5 +- src/app/components/auth/auth.service.ts | 3 +- .../inventory-items-table.component.html | 10 ---- .../pages/inventory/inventory.component.scss | 50 +++++++++++++++++-- .../pages/inventory/inventory.component.ts | 4 +- 5 files changed, 53 insertions(+), 19 deletions(-) diff --git a/src/app/components/auth/auth.interceptor.ts b/src/app/components/auth/auth.interceptor.ts index 03b46c3..77b8c87 100644 --- a/src/app/components/auth/auth.interceptor.ts +++ b/src/app/components/auth/auth.interceptor.ts @@ -16,8 +16,9 @@ export class AuthInterceptor implements HttpInterceptor { next: HttpHandler ): Observable> { // Retrieve the token from local storage - const authdata = JSON.parse(localStorage.getItem('authData') || '{}'); - const token = authdata?.token; + const authDataStr = localStorage.getItem('authData'); + const authdata = authDataStr ? JSON.parse(authDataStr) : {}; + const token = authdata?.accessToken; if (token) { // Clone the request to add the new header diff --git a/src/app/components/auth/auth.service.ts b/src/app/components/auth/auth.service.ts index 2a1a62f..13855c0 100644 --- a/src/app/components/auth/auth.service.ts +++ b/src/app/components/auth/auth.service.ts @@ -25,8 +25,7 @@ export class AuthService { return this.http.post(registerUrl, form).pipe( tap((response: AuthResponse) => { // Store authentication data in local storage - const authData = JSON.stringify(response); - localStorage.setItem('authData', authData); + localStorage.setItem('authData', JSON.stringify(response)); this.userRoleSubject.next(response.user.role); // Update user role this.isAuthenticated.next(true); this.router.navigate(['/dashboard']); diff --git a/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.html b/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.html index 7bf0246..656fcb8 100644 --- a/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.html +++ b/src/app/pages/inventory/components/inventory-items-table/inventory-items-table.component.html @@ -1,13 +1,3 @@ - -

-

View Inventory

-
- - - -
-
-
diff --git a/src/app/pages/inventory/inventory.component.scss b/src/app/pages/inventory/inventory.component.scss index 8d82012..6d5ea3c 100644 --- a/src/app/pages/inventory/inventory.component.scss +++ b/src/app/pages/inventory/inventory.component.scss @@ -1,3 +1,4 @@ +/* General Styles for the Inventory Component */ .dashboard { display: flex; flex-direction: column; @@ -10,17 +11,48 @@ margin-bottom: 20px; padding: 20px; border-radius: 8px; + background-color: #ffffff; + border: 1px solid #e0e0e0; h3 { - font-size: 24px; - color: #ffffff; + font-size: 20px; + color: #333; + margin: 0 0 16px 0; + font-weight: 600; + } +} + +/* Mat-Raised-Button Styling */ +::ng-deep .mat-raised-button { + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12); + text-transform: uppercase; + font-weight: 600; + letter-spacing: 0.5px; + transition: all 0.3s ease; + min-width: 120px; + height: 40px; + + &:hover { + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.18); + transform: translateY(-2px); } - button { - margin-top: 10px; + &:active { + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.12); + transform: translateY(0); } } +::ng-deep .mat-raised-button[color='primary'] { + background-color: #1976d2; + color: #ffffff; + + &:hover { + background-color: #1565c0; + } +} + +/* Responsive adjustments */ @media (max-width: 1024px) { .dashboard { flex-direction: column; @@ -38,5 +70,15 @@ .summary-card { padding: 10px; + + h3 { + font-size: 18px; + } + } + + ::ng-deep .mat-raised-button { + min-width: 100px; + height: 36px; + font-size: 12px; } } diff --git a/src/app/pages/inventory/inventory.component.ts b/src/app/pages/inventory/inventory.component.ts index ff687cc..bb3842c 100644 --- a/src/app/pages/inventory/inventory.component.ts +++ b/src/app/pages/inventory/inventory.component.ts @@ -35,7 +35,9 @@ export class InventoryComponent implements OnInit { ngOnInit(): void { this.authService.userRole.subscribe((role: string | null) => { - this.isAdminOrManager = role === 'admin' || role === 'manager'; + // Allow admin, manager, and User roles + this.isAdminOrManager = + role === 'admin' || role === 'manager' || role === 'User'; }); this.refreshInventory(); } From aee82aa86e77be735fa458f12b28237484028395 Mon Sep 17 00:00:00 2001 From: Nicholas Gallimore Date: Fri, 10 Apr 2026 15:27:24 -0400 Subject: [PATCH 4/5] NFG-86 add new inventory dialog style groups --- .../new-inventory-dialog.component.html | 499 ++++++++++-------- .../new-inventory-dialog.component.scss | 294 ++++++++++- .../new-inventory-dialog.component.ts | 86 +-- src/styles.scss | 36 ++ 4 files changed, 635 insertions(+), 280 deletions(-) diff --git a/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.html b/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.html index e9fcb16..d1a87a8 100644 --- a/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.html +++ b/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.html @@ -3,258 +3,321 @@

- -
- Vendor Name is required. -
- Vendor Name - - Vendor - - - - {{ vendor.displayName }} - - - + +
+

Basic Information

- -
- Display Name is required. + + Vendor * + + -- Select Vendor -- + + {{ vendor.displayName }} + + + +
-
- - Display Name - - + Vendor is required. +
- -
- SKU is required. + + Display Name * + + +
-
- - SKU - - + Display Name is required. +
- -
- Description is required. + + SKU * + + +
-
- - Description - - + SKU is required. +
- -
- Inventory Category is required. + + Description * + + +
+ Description is required. +
- - Inventory Category - - Manufacturing - Customer Supplied - Research Lab - Ancillary - - - -
- Type is required. -
- - Type - - Raw Materials - Components - Work in Progress - Finished Goods - - + +
+

Classification

- -
- Lot Code is required. -
- - Lot Code - - +
+ + + Category * + + Manufacturing + Customer Supplied + Research Lab + Ancillary + + - -
- Unit of Measurement is required. + + + Type * + + Raw Materials + Components + Work in Progress + Finished Goods + + +
+
+
+
+ Category is required. +
+
+
+
+ Type is required. +
+
+
- - Unit of Measurement - - kg - g - mg - lb - oz - - - -
- Price Per Unit is required. + +
+

Unit & Lot Details

+ +
+ + + Lot Code * + + + + + + Unit of Measurement * + + kg + g + mg + lb + oz + + +
+
+
+
+ Lot Code is required. +
+
+
+
+ Unit of Measurement is required. +
+
+
- - Price Per Unit - - - -
- - In Stock - - + +
+

Pricing

+ - Minimum Restock Quantity - + Price Per Unit * + + USD -
- - -
- Available Quantity is required. + Price Per Unit is required. +
- - Available Quantity - - -
- On Hold Quantity is required. -
- - On Hold Quantity - - + +
+

Inventory Quantities

-
- Quarantined Quantity is required. +
+ + + In Stock * + + + + + + Minimum Restock * + + +
+ +
+ + + Available Quantity * + + + + + + On Hold Quantity * + + +
+ +
+ + + Quarantined Quantity * + + +
- - Quarantined Quantity - - diff --git a/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.scss b/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.scss index 0af6f06..b188e64 100644 --- a/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.scss +++ b/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.scss @@ -1,12 +1,18 @@ mat-dialog-content { - padding: 20px; + padding: 0; + max-height: 70vh; + overflow-y: auto; display: flex; flex-direction: column; + background-color: #ffffff; + color: #1a1a1a; form { display: flex; flex-direction: column; - gap: 16px; + gap: 0; + padding: 24px; + color: #1a1a1a; .full-width { width: 100%; @@ -14,61 +20,295 @@ mat-dialog-content { mat-form-field { width: 100%; + margin-bottom: 12px; .mat-form-field-infix { - padding: 8px 12px; + padding: 10px 12px; } } mat-label { font-weight: 500; + color: #1a1a1a; + } + + input, + textarea, + select { + color: #1a1a1a; } } +} - table { - width: 100%; - border-collapse: collapse; - margin-top: 16px; +// Form Sections +.form-section { + margin-bottom: 28px; + padding-bottom: 20px; + border-bottom: 2px solid #e0e0e0; - th, - td { - padding: 8px; - text-align: left; - border-bottom: 1px solid #ddd; + &:last-child { + border-bottom: none; + margin-bottom: 0; + padding-bottom: 0; + } + + .section-title { + font-size: 13px; + font-weight: 700; + color: #1a1a1a; + margin: 0 0 16px 0; + text-transform: uppercase; + letter-spacing: 0.5px; + display: flex; + align-items: center; + gap: 10px; + + &::before { + content: ''; + width: 4px; + height: 18px; + background: linear-gradient(180deg, #0d47a1 0%, #1565c0 100%); + border-radius: 2px; + flex-shrink: 0; } + } +} - th { - background-color: #f2f2f2; +// Form Row for Two-Column Layout +.form-row { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 16px; + margin-bottom: 8px; + + @media (max-width: 600px) { + grid-template-columns: 1fr; + } + + mat-form-field { + width: 100%; + margin-bottom: 0; + } + + &.error-row { + gap: 16px; + margin-top: -4px; + + > div { + flex: 1; } } } +// Required indicator +.required { + color: #d32f2f; + font-weight: bold; + margin-left: 2px; +} + +// Error Message Styling .error-message { font-size: 0.8em; - margin-bottom: 5px; + color: #c62828; + margin-top: 4px; + margin-bottom: 8px; + font-weight: 600; + display: flex; + align-items: center; + gap: 6px; + + span { + &::before { + content: '⚠ '; + font-size: 1.1em; + font-weight: bold; + } + } } +// Enhanced field styling for invalid state +::ng-deep { + // Override Material Design theme variables for outline + .mat-mdc-form-field { + --mdc-theme-primary: #1976d2; + --mat-mdc-form-field-bottom-line-color: #9e9e9e; + } + + // Default state - make outline visible grey + .mat-form-field .mdc-notched-outline__leading, + .mat-form-field .mdc-notched-outline__notch, + .mat-form-field .mdc-notched-outline__trailing { + border-color: #9e9e9e !important; + border-top-color: #9e9e9e !important; + } + + .mat-form-field { + .mat-form-field-label { + color: #424242; + } + + .mat-input-element { + color: #1a1a1a; + caret-color: #1976d2; + } + + // Ensure selected value is visible when dropdown is closed + .mat-select-value { + color: #1a1a1a !important; + opacity: 1 !important; + display: flex !important; + align-items: center; + } + + .mat-select-value-text { + color: #1a1a1a !important; + } + + .mat-mdc-select-min-line { + color: #1a1a1a !important; + } + + .mat-select-trigger { + color: #1a1a1a; + } + } + + // Make mat-select options visible - white background + .mat-mdc-option { + background-color: #ffffff !important; + color: #1a1a1a !important; + + &.mat-selected { + background-color: #ffffff !important; + color: #000000 !important; + font-weight: 500; + } + + &:hover { + background-color: #f5f5f5 !important; + } + } + + // Focused state - blue outline + .mat-form-field.mat-focused .mdc-notched-outline__leading, + .mat-form-field.mat-focused .mdc-notched-outline__notch, + .mat-form-field.mat-focused .mdc-notched-outline__trailing { + border-color: #1976d2 !important; + border-top-color: #1976d2 !important; + } + + .mat-form-field.mat-focused { + .mat-form-field-label { + color: #1976d2 !important; + } + } + + // Invalid state - red outline + .mat-form-field.mat-form-field-invalid .mdc-notched-outline__leading, + .mat-form-field.mat-form-field-invalid .mdc-notched-outline__notch, + .mat-form-field.mat-form-field-invalid .mdc-notched-outline__trailing { + border-color: #c62828 !important; + border-top-color: #c62828 !important; + } + + .mat-form-field.mat-form-field-invalid { + .mat-form-field-label { + color: #c62828 !important; + } + + .mat-input-element { + color: #1a1a1a; + } + } + + // Invalid and focused - keep red + .mat-form-field.mat-focused.mat-form-field-invalid + .mdc-notched-outline__leading, + .mat-form-field.mat-focused.mat-form-field-invalid + .mdc-notched-outline__notch, + .mat-form-field.mat-focused.mat-form-field-invalid + .mdc-notched-outline__trailing { + border-color: #c62828 !important; + border-top-color: #c62828 !important; + } + + .mat-form-field.mat-focused.mat-form-field-invalid { + .mat-form-field-label { + color: #c62828 !important; + } + } +} + +// Hint styling +::ng-deep .mat-form-field-hint { + font-size: 0.75rem; + color: rgba(0, 0, 0, 0.6); + margin-top: 4px; +} + +// Textarea styling +::ng-deep textarea.mat-input-element { + font-family: 'Roboto', sans-serif; + resize: vertical; + min-height: 80px; +} + +// Dialog actions styling mat-dialog-actions { - padding: 16px; + padding: 16px 20px; + border-top: 2px solid #e0e0e0; + margin: 24px 0 0 0; + background-color: #fafafa; display: flex; justify-content: flex-end; gap: 8px; + flex-wrap: wrap; + overflow: visible; + width: 100%; + box-sizing: border-box; button { - min-width: 120px; - } + margin-left: 0; + min-width: 90px; + padding: 8px 16px; + font-weight: 500; + text-transform: uppercase; + font-size: 12px; + letter-spacing: 0.5px; + flex-shrink: 0; - button:first-of-type { - background: transparent; - color: #333; - } + &:first-of-type { + background: transparent; + color: #1a1a1a; + border: 2px solid #bdbdbd; + font-weight: 600; - button:last-of-type { - background-color: #3f51b5; - color: #fff; + &:hover { + background-color: #eeeeee; + border-color: #9e9e9e; + } - &:hover { - background-color: #303f9f; + &:active { + background-color: #e0e0e0; + } + } + + &[color='primary'] { + background: linear-gradient(135deg, #1976d2 0%, #1565c0 100%); + color: white; + box-shadow: 0 2px 4px rgba(25, 118, 210, 0.3); + border: none; + + &:hover { + box-shadow: 0 4px 8px rgba(25, 118, 210, 0.4); + transform: translateY(-1px); + } + + &:disabled { + opacity: 0.5; + box-shadow: none; + } } } } diff --git a/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.ts b/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.ts index 8cb93c4..d418135 100644 --- a/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.ts +++ b/src/app/pages/inventory/components/new-inventory-dialog/new-inventory-dialog.component.ts @@ -16,6 +16,45 @@ export class NewInventoryDialogComponent implements OnInit { isSubmitting: boolean = false; filteredVendors: Vendor[] = []; + // Mock vendors for development + mockVendors: Vendor[] = [ + { + _id: 'vendor-001', + displayName: 'Acme Supplies Inc.', + email: 'contact@acmesupplies.com', + phone: '+1-800-123-4567', + address: '123 Industrial Ave, New York, NY', + } as Vendor, + { + _id: 'vendor-002', + displayName: 'Global Materials LLC', + email: 'sales@globalmaterials.com', + phone: '+1-888-555-0123', + address: '456 Commerce St, Los Angeles, CA', + } as Vendor, + { + _id: 'vendor-003', + displayName: 'Premium Components Co.', + email: 'info@premiumcomponents.com', + phone: '+1-866-777-0456', + address: '789 Tech Boulevard, Austin, TX', + } as Vendor, + { + _id: 'vendor-004', + displayName: 'Quality Imports Ltd.', + email: 'ordering@qualityimports.com', + phone: '+1-855-888-0789', + address: '321 Import Blvd, Chicago, IL', + } as Vendor, + { + _id: 'vendor-005', + displayName: 'Direct Wholesale Corp.', + email: 'wholesale@directwholesale.com', + phone: '+1-844-999-0234', + address: '654 Wholesale Pkwy, Houston, TX', + } as Vendor, + ]; + constructor( private dialogRef: MatDialogRef, private fb: FormBuilder, @@ -46,6 +85,18 @@ export class NewInventoryDialogComponent implements OnInit { } ngOnInit() { + // Try to load vendors from service, fall back to mock data + this.vendorService.getVendors().subscribe( + (vendors) => { + this.filteredVendors = + vendors && vendors.length > 0 ? vendors : this.mockVendors; + }, + (error) => { + console.warn('Error loading vendors, using mock data:', error); + this.filteredVendors = this.mockVendors; + } + ); + // If the data has an inventory item, populate the form for editing if (this.data.inventoryItem) { console.log('inventory data: ' + this.data.inventoryItem); @@ -54,41 +105,6 @@ export class NewInventoryDialogComponent implements OnInit { console.log('No Data'); } - // Subscribe to the vendor input value changes - console.log('Value Change'); - this.inventoryForm - .get('vendor') - ?.valueChanges.pipe( - debounceTime(300), - switchMap((searchTerm) => { - if (searchTerm) { - return this.vendorService.getVendors().pipe( - switchMap((response) => { - if (response) { - console.log(response); - // Filter vendors based on the search term - return of( - response.filter((vendor) => - vendor.displayName - .toLowerCase() - .includes(searchTerm.toLowerCase()) - ) - ); - } else { - console.log('No Vendor Data: ' + JSON.stringify(response)); - } - return of([]); - }) - ); - } else { - return of([]); - } - }) - ) - .subscribe((filteredVendors: Vendor[]) => { - this.filteredVendors = filteredVendors; - }); - // Add SKU duplicate check this.inventoryForm .get('sku') diff --git a/src/styles.scss b/src/styles.scss index 4314ebe..ed6c93e 100644 --- a/src/styles.scss +++ b/src/styles.scss @@ -1,5 +1,41 @@ /* You can add global styles to this file, and also import other style files */ +// Material Select value text color +.mat-mdc-select-min-line, +.mat-select-value-text { + color: #1a1a1a !important; +} + +// Material Form Field outline color override +.mat-mdc-form-field { + .mdc-notched-outline__leading, + .mdc-notched-outline__notch, + .mdc-notched-outline__trailing { + border-color: #9e9e9e !important; + border-top-color: #9e9e9e !important; + } +} + +// Focused state - blue outline +.mat-mdc-form-field.mat-focused { + .mdc-notched-outline__leading, + .mdc-notched-outline__notch, + .mdc-notched-outline__trailing { + border-color: #1976d2 !important; + border-top-color: #1976d2 !important; + } +} + +// Invalid state - red outline +.mat-mdc-form-field.mat-form-field-invalid { + .mdc-notched-outline__leading, + .mdc-notched-outline__notch, + .mdc-notched-outline__trailing { + border-color: #c62828 !important; + border-top-color: #c62828 !important; + } +} + body, html { height: 100%; From 76e19a61f224d74d3adac6ff5079af7c5cf738d0 Mon Sep 17 00:00:00 2001 From: Nicholas Gallimore Date: Fri, 10 Apr 2026 15:28:39 -0400 Subject: [PATCH 5/5] NFG-86 update vercel.json file --- vercel.json | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 vercel.json diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..a7b844e --- /dev/null +++ b/vercel.json @@ -0,0 +1,11 @@ +{ + "version": 2, + "buildCommand": "npm run build", + "outputDirectory": "dist/nufacturing", + "routes": [ + { + "src": "^/(?!api).*", + "dest": "index.html" + } + ] +}