standard pricing with suppliers fixes
CI / build (push) Has been skipped
CI / deploy (push) Successful in 45s

This commit is contained in:
2026-03-18 18:04:39 -05:00
parent 6780d80d10
commit 74e859ef71
2 changed files with 28 additions and 30 deletions
+2 -1
View File
@@ -172,7 +172,8 @@ export const appStore = {
async loadSuppliers() { async loadSuppliers() {
try { try {
const records = await pb.collection(COLLECTIONS.STANDARD_PRICES).getFullList({ const records = await pb.collection(COLLECTIONS.STANDARD_PRICES).getFullList({
fields: 'supplier' fields: 'supplier',
requestKey: null
}); });
const unique = [...new Set(records.map(r => r.supplier).filter(Boolean))].sort() as string[]; const unique = [...new Set(records.map(r => r.supplier).filter(Boolean))].sort() as string[];
setSuppliers(unique); setSuppliers(unique);
+26 -29
View File
@@ -1,4 +1,4 @@
import { createSignal, onMount, For, createMemo } from 'solid-js'; import { createSignal, onMount, For, createMemo, createResource } from 'solid-js';
import type { Component } from 'solid-js'; import type { Component } from 'solid-js';
import { Trash2, Plus, RefreshCw, Edit2, Save, X, ChevronDown } from 'lucide-solid'; import { Trash2, Plus, RefreshCw, Edit2, Save, X, ChevronDown } from 'lucide-solid';
import { pb, COLLECTIONS } from '../utils/db'; import { pb, COLLECTIONS } from '../utils/db';
@@ -6,8 +6,15 @@ import type { StandardPrice } from '../types';
import { appStore } from '../store/appStore'; import { appStore } from '../store/appStore';
const StandardPricing: Component = () => { const StandardPricing: Component = () => {
const [prices, setPrices] = createSignal<StandardPrice[]>([]); const fetchPrices = async () => {
const [isLoading, setIsLoading] = createSignal(true); const records = await pb.collection(COLLECTIONS.STANDARD_PRICES).getFullList({
sort: 'category,name',
requestKey: null
});
return records as unknown as StandardPrice[];
};
const [prices, { refetch }] = createResource(fetchPrices);
const [newCategory, setNewCategory] = createSignal(''); const [newCategory, setNewCategory] = createSignal('');
const [newName, setNewName] = createSignal(''); const [newName, setNewName] = createSignal('');
@@ -21,29 +28,14 @@ const StandardPricing: Component = () => {
const [editSupplier, setEditSupplier] = createSignal(''); const [editSupplier, setEditSupplier] = createSignal('');
const categories = createMemo(() => { const categories = createMemo(() => {
return [...new Set(prices().map(p => p.category))].sort(); return [...new Set((prices() || []).map(p => p.category))].sort();
}); });
const itemNames = createMemo(() => { const itemNames = createMemo(() => {
return [...new Set(prices().map(p => p.name))].sort(); return [...new Set((prices() || []).map(p => p.name))].sort();
}); });
const loadPrices = async () => {
setIsLoading(true);
try {
const records = await pb.collection(COLLECTIONS.STANDARD_PRICES).getFullList({
sort: 'category,name'
});
setPrices(records as unknown as StandardPrice[]);
} catch (error) {
console.error('Error loading standard prices:', error);
} finally {
setIsLoading(false);
}
};
onMount(() => { onMount(() => {
loadPrices();
appStore.loadSuppliers(); appStore.loadSuppliers();
}); });
@@ -57,8 +49,8 @@ const StandardPricing: Component = () => {
price: newPrice(), price: newPrice(),
supplier: newSupplier() supplier: newSupplier()
}; };
const added = await pb.collection(COLLECTIONS.STANDARD_PRICES).create(record); await pb.collection(COLLECTIONS.STANDARD_PRICES).create(record);
setPrices([...prices(), added as unknown as StandardPrice]); refetch();
appStore.loadSuppliers(); // Refresh global list appStore.loadSuppliers(); // Refresh global list
// Reset fields // Reset fields
@@ -96,7 +88,7 @@ const StandardPricing: Component = () => {
supplier: editSupplier() supplier: editSupplier()
}; };
await pb.collection(COLLECTIONS.STANDARD_PRICES).update(id, updates); await pb.collection(COLLECTIONS.STANDARD_PRICES).update(id, updates);
setPrices(prices().map(p => p.id === id ? { ...p, ...updates } : p)); refetch();
setEditingId(null); setEditingId(null);
appStore.loadSuppliers(); // Refresh global list appStore.loadSuppliers(); // Refresh global list
} catch (error) { } catch (error) {
@@ -109,7 +101,7 @@ const StandardPricing: Component = () => {
if (!confirm('Are you sure you want to delete this standard price?')) return; if (!confirm('Are you sure you want to delete this standard price?')) return;
try { try {
await pb.collection(COLLECTIONS.STANDARD_PRICES).delete(id); await pb.collection(COLLECTIONS.STANDARD_PRICES).delete(id);
setPrices(prices().filter(p => p.id !== id)); refetch();
appStore.loadSuppliers(); // Refresh global list appStore.loadSuppliers(); // Refresh global list
} catch (error) { } catch (error) {
console.error('Error deleting price:', error); console.error('Error deleting price:', error);
@@ -127,10 +119,10 @@ const StandardPricing: Component = () => {
</div> </div>
<button <button
onClick={loadPrices} onClick={refetch}
class="flex items-center gap-2 px-4 py-2 text-sm font-bold text-gray-700 bg-gray-50 border border-gray-200 rounded-xl hover:bg-gray-100 transition-all" class="flex items-center gap-2 px-4 py-2 text-sm font-bold text-gray-700 bg-gray-50 border border-gray-200 rounded-xl hover:bg-gray-100 transition-all"
> >
<RefreshCw class={`w-4 h-4 ${isLoading() ? 'animate-spin' : ''}`} /> <RefreshCw class={`w-4 h-4 ${prices.loading ? 'animate-spin' : ''}`} />
Refresh Refresh
</button> </button>
</div> </div>
@@ -205,14 +197,19 @@ const StandardPricing: Component = () => {
<div> <div>
<h3 class="text-sm font-bold text-gray-800 mb-4 uppercase tracking-wider">Existing Prices</h3> <h3 class="text-sm font-bold text-gray-800 mb-4 uppercase tracking-wider">Existing Prices</h3>
{isLoading() ? ( {prices.loading && !prices() ? (
<div class="py-12 text-center text-gray-500">Loading...</div> <div class="py-12 text-center text-gray-500">Loading...</div>
) : prices().length === 0 ? ( ) : (prices()?.length || 0) === 0 ? (
<div class="py-12 text-center text-gray-500 border-2 border-dashed border-gray-200 rounded-xl"> <div class="py-12 text-center text-gray-500 border-2 border-dashed border-gray-200 rounded-xl">
No standard prices added yet. No standard prices added yet.
</div> </div>
) : ( ) : (
<div class="border border-gray-200 rounded-xl overflow-hidden"> <div class="border border-gray-200 rounded-xl overflow-hidden relative">
{prices.loading && (
<div class="absolute inset-0 bg-white/50 backdrop-blur-[1px] flex items-center justify-center z-10 transition-opacity">
<RefreshCw class="w-8 h-8 text-blue-500 animate-spin" />
</div>
)}
<table class="w-full text-left border-collapse"> <table class="w-full text-left border-collapse">
<thead> <thead>
<tr class="bg-gray-50 border-b border-gray-200 text-xs text-gray-500 uppercase tracking-wider font-bold"> <tr class="bg-gray-50 border-b border-gray-200 text-xs text-gray-500 uppercase tracking-wider font-bold">