Add bulk price editing features and fix quantity update price preservation
- Fix FilamentForm to preserve prices when updating quantities - Add isInitialLoad flag to prevent price override on form load - Only update prices when color is actively changed, not on initial render - Add bulk filament price editor to dashboard - Filter by material and finish - Set refill and/or spool prices for multiple filaments - Preview changes before applying - Update all filtered filaments at once - Add bulk color price editor to colors page - Edit prices for all colors in one interface - Global price application with search filtering - Individual price editing with change tracking - Add auto-kill script for dev server - Kill existing processes on ports 3000/3001 before starting - Prevent "port already in use" errors - Clean start every time npm run dev is executed
This commit is contained in:
@@ -6,6 +6,7 @@ import { filamentService, colorService } from '@/src/services/api';
|
||||
import { Filament } from '@/src/types/filament';
|
||||
import { trackEvent } from '@/src/components/MatomoAnalytics';
|
||||
import { SaleManager } from '@/src/components/SaleManager';
|
||||
import { BulkFilamentPriceEditor } from '@/src/components/BulkFilamentPriceEditor';
|
||||
// Removed unused imports for Bambu Lab color categorization
|
||||
import '@/src/styles/select.css';
|
||||
|
||||
@@ -391,11 +392,15 @@ export default function AdminDashboard() {
|
||||
Obriši izabrane ({selectedFilaments.size})
|
||||
</button>
|
||||
)}
|
||||
<SaleManager
|
||||
<SaleManager
|
||||
filaments={filaments}
|
||||
selectedFilaments={selectedFilaments}
|
||||
onSaleUpdate={fetchFilaments}
|
||||
/>
|
||||
<BulkFilamentPriceEditor
|
||||
filaments={filaments}
|
||||
onUpdate={fetchFilaments}
|
||||
/>
|
||||
<button
|
||||
onClick={() => router.push('/upadaj/colors')}
|
||||
className="flex-1 sm:flex-initial px-3 sm:px-4 py-2 bg-purple-500 text-white rounded hover:bg-purple-600 text-sm sm:text-base"
|
||||
@@ -713,23 +718,26 @@ function FilamentForm({
|
||||
cena_spulna: 0,
|
||||
});
|
||||
|
||||
// Track if this is the initial load to prevent price override
|
||||
const [isInitialLoad, setIsInitialLoad] = useState(true);
|
||||
|
||||
// Update form when filament prop changes
|
||||
useEffect(() => {
|
||||
// Extract prices from the cena field if it exists (format: "3499/3999" or just "3499")
|
||||
let refillPrice = 0;
|
||||
let spulnaPrice = 0;
|
||||
|
||||
|
||||
if (filament.cena) {
|
||||
const prices = filament.cena.split('/');
|
||||
refillPrice = parseInt(prices[0]) || 0;
|
||||
spulnaPrice = prices.length > 1 ? parseInt(prices[1]) || 0 : parseInt(prices[0]) || 0;
|
||||
}
|
||||
|
||||
|
||||
// Get default prices from color
|
||||
const colorData = availableColors.find(c => c.name === filament.boja);
|
||||
if (!refillPrice && colorData?.cena_refill) refillPrice = colorData.cena_refill;
|
||||
if (!spulnaPrice && colorData?.cena_spulna) spulnaPrice = colorData.cena_spulna;
|
||||
|
||||
|
||||
setFormData({
|
||||
tip: filament.tip || (filament.id ? '' : 'PLA'), // Default to PLA for new filaments
|
||||
finish: filament.finish || (filament.id ? '' : 'Basic'), // Default to Basic for new filaments
|
||||
@@ -742,10 +750,19 @@ function FilamentForm({
|
||||
cena_refill: refillPrice || 3499,
|
||||
cena_spulna: spulnaPrice || 3999,
|
||||
});
|
||||
|
||||
// Reset initial load flag when filament changes
|
||||
setIsInitialLoad(true);
|
||||
}, [filament]);
|
||||
|
||||
// Update prices when color selection changes
|
||||
// Update prices when color selection changes (but not on initial load)
|
||||
useEffect(() => {
|
||||
// Skip price update on initial load to preserve existing filament prices
|
||||
if (isInitialLoad) {
|
||||
setIsInitialLoad(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (formData.boja && availableColors.length > 0) {
|
||||
const colorData = availableColors.find(c => c.name === formData.boja);
|
||||
if (colorData) {
|
||||
|
||||
Reference in New Issue
Block a user