feat: fix raw material photo display in Cutting and Purchase pages by adding conversion URLs
This commit is contained in:
parent
ef136bd1e7
commit
6fa9224983
@ -24,10 +24,22 @@ public function getForCutting(): array
|
|||||||
->select(['id', 'name', 'unit', 'is_active'])
|
->select(['id', 'name', 'unit', 'is_active'])
|
||||||
->with([
|
->with([
|
||||||
'rawMaterialPrices:id,raw_material_id,variant,price,stock',
|
'rawMaterialPrices:id,raw_material_id,variant,price,stock',
|
||||||
|
'rawMaterialPrices.media',
|
||||||
])
|
])
|
||||||
->active()
|
->active()
|
||||||
->orderBy('name')
|
->orderBy('name')
|
||||||
->get()
|
->get()
|
||||||
|
->each(function (RawMaterial $rawMaterial) {
|
||||||
|
$rawMaterial->rawMaterialPrices->each(function (RawMaterialPrice $price) {
|
||||||
|
$media = $price->getFirstMedia('images');
|
||||||
|
$price->photo_url = $media
|
||||||
|
? $this->s3Service->getTemporaryUrl($media->getPath())
|
||||||
|
: null;
|
||||||
|
$price->photo_conversion_url = $media
|
||||||
|
? $this->s3Service->getTemporaryUrl($media->getPath('thumb'))
|
||||||
|
: null;
|
||||||
|
});
|
||||||
|
})
|
||||||
->toArray();
|
->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
49
docs/2026-08-15-raw-material-photo-fix.md
Normal file
49
docs/2026-08-15-raw-material-photo-fix.md
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# Fix: Foto Bahan Baku Tidak Muncul di Cutting & Belanja
|
||||||
|
|
||||||
|
## Tujuan
|
||||||
|
Memperbaiki foto bahan baku (raw material) yang tidak muncul di halaman create/edit Cutting dan Belanja (Purchasing). Menampilkan foto conversion (thumbnail) bukan original.
|
||||||
|
|
||||||
|
## File yang Dibaca
|
||||||
|
- `app/Services/Admin/Master/RawMaterial/RawMaterialVariantService.php` → `getForCutting()` method (root cause backend)
|
||||||
|
- `resources/js/pages/admin/manage/cutting/columns.tsx` → `CuttingCreateData` type (root cause frontend)
|
||||||
|
- `resources/js/pages/admin/manage/purchase/columns.tsx` → `PurchaseCreateData` type (root cause frontend)
|
||||||
|
- `resources/js/pages/admin/master/raw-material/columns.tsx` → reference type pattern
|
||||||
|
|
||||||
|
## Root Cause
|
||||||
|
|
||||||
|
### Backend
|
||||||
|
`getForCutting()` tidak load media atau set `photo_url`/`photo_conversion_url` pada `RawMaterialPrice`.
|
||||||
|
|
||||||
|
### Frontend
|
||||||
|
Type `CuttingCreateData` dan `PurchaseCreateData` tidak include `photo_conversion_url` di `raw_material_prices` → TypeScript strip property → frontend tidak bisa akses.
|
||||||
|
|
||||||
|
## Perubahan
|
||||||
|
|
||||||
|
### 1. Backend — `RawMaterialVariantService::getForCutting()`
|
||||||
|
- Tambah eager load `rawMaterialPrices.media`
|
||||||
|
- Iterasi setiap `RawMaterialPrice` untuk set `photo_url` + `photo_conversion_url`
|
||||||
|
|
||||||
|
### 2. Frontend Types — `columns.tsx`
|
||||||
|
- `CuttingCreateData.raw_material_prices` → tambah `photo_conversion_url: string | null`
|
||||||
|
- `PurchaseCreateData.raw_material_prices` → tambah `photo_conversion_url: string | null`
|
||||||
|
|
||||||
|
### 3. Frontend Components — 4 files
|
||||||
|
- Tambah `photo_conversion_url` ke `MaterialState` type (cutting create/edit)
|
||||||
|
- Map `photo_conversion_url` dari backend data
|
||||||
|
- `<img src={price.photo_url}` → `<img src={price.photo_conversion_url ?? price.photo_url}`
|
||||||
|
- `photoUrl: price.photo_url` → `photoUrl: price.photo_conversion_url ?? price.photo_url` (purchase cart items)
|
||||||
|
|
||||||
|
## Files Changed
|
||||||
|
| File | Change |
|
||||||
|
|------|--------|
|
||||||
|
| `RawMaterialVariantService.php` | Load media + set photo_url/photo_conversion_url |
|
||||||
|
| `cutting/columns.tsx` | Add `photo_conversion_url` to type |
|
||||||
|
| `purchase/columns.tsx` | Add `photo_conversion_url` to type |
|
||||||
|
| `cutting/create.tsx` | Type + mapping + img tags |
|
||||||
|
| `cutting/edit.tsx` | Type + mapping + img tags |
|
||||||
|
| `purchase/create.tsx` | Cart photoUrl + img tag |
|
||||||
|
| `purchase/edit.tsx` | Cart photoUrl + img tag |
|
||||||
|
|
||||||
|
## Dampak
|
||||||
|
- Create/Edit Cutting → foto bahan baku muncul (conversion/thumbnail)
|
||||||
|
- Create/Edit Belanja → foto bahan baku muncul (conversion/thumbnail)
|
||||||
@ -105,6 +105,7 @@ export type CuttingCreateData = {
|
|||||||
price: number;
|
price: number;
|
||||||
stock: number;
|
stock: number;
|
||||||
photo_url: string | null;
|
photo_url: string | null;
|
||||||
|
photo_conversion_url: string | null;
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -34,6 +34,7 @@ type MaterialState = {
|
|||||||
material_name: string;
|
material_name: string;
|
||||||
unit: string;
|
unit: string;
|
||||||
photo_url: string | null;
|
photo_url: string | null;
|
||||||
|
photo_conversion_url: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CombinationState = {
|
type CombinationState = {
|
||||||
@ -61,6 +62,7 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
material_name: m.material_name,
|
material_name: m.material_name,
|
||||||
unit: m.unit,
|
unit: m.unit,
|
||||||
photo_url: m.photo_url,
|
photo_url: m.photo_url,
|
||||||
|
photo_conversion_url: m.photo_conversion_url,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +132,7 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
material_name: m.material_name,
|
material_name: m.material_name,
|
||||||
unit: m.unit,
|
unit: m.unit,
|
||||||
photo_url: m.photo_url,
|
photo_url: m.photo_url,
|
||||||
|
photo_conversion_url: m.photo_conversion_url,
|
||||||
})),
|
})),
|
||||||
combinations: combinations.map((c) => ({
|
combinations: combinations.map((c) => ({
|
||||||
material_result: c.material_result,
|
material_result: c.material_result,
|
||||||
@ -192,6 +195,7 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
material_name: rawMaterial.name,
|
material_name: rawMaterial.name,
|
||||||
unit: rawMaterial.unit,
|
unit: rawMaterial.unit,
|
||||||
photo_url: price.photo_url,
|
photo_url: price.photo_url,
|
||||||
|
photo_conversion_url: price.photo_conversion_url,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
@ -242,6 +246,7 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
material_name: foundMaterial?.name ?? '',
|
material_name: foundMaterial?.name ?? '',
|
||||||
unit: foundMaterial?.unit ?? '',
|
unit: foundMaterial?.unit ?? '',
|
||||||
photo_url: foundPrice?.photo_url ?? null,
|
photo_url: foundPrice?.photo_url ?? null,
|
||||||
|
photo_conversion_url: foundPrice?.photo_conversion_url ?? null,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -393,8 +398,8 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img src={price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
<img src={price.photo_conversion_url ?? price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
)}
|
)}
|
||||||
@ -439,8 +444,8 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img src={price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
<img src={price.photo_conversion_url ?? price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
)}
|
)}
|
||||||
@ -623,9 +628,9 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
<div key={cartKey} className="space-y-2">
|
<div key={cartKey} className="space-y-2">
|
||||||
<div className="flex items-start justify-between gap-2">
|
<div className="flex items-start justify-between gap-2">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{m.photo_url ? (
|
{m.photo_conversion_url ?? m.photo_url ? (
|
||||||
<button type="button" onClick={() => setPreviewKey(cartKey)} className="block h-8 w-8 shrink-0 overflow-hidden rounded-md border transition-opacity hover:opacity-80">
|
<button type="button" onClick={() => setPreviewKey(cartKey)} className="block h-8 w-8 shrink-0 overflow-hidden rounded-md border transition-opacity hover:opacity-80">
|
||||||
<img src={m.photo_url} alt={m.variant} className="h-full w-full object-cover" />
|
<img src={m.photo_conversion_url ?? m.photo_url} alt={m.variant} className="h-full w-full object-cover" />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
@ -744,7 +749,7 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
if (p) {
|
if (p) {
|
||||||
variantName = p.variant;
|
variantName = p.variant;
|
||||||
materialName = rm.name;
|
materialName = rm.name;
|
||||||
photoUrl = p.photo_url;
|
photoUrl = p.photo_conversion_url ?? p.photo_url;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -782,8 +787,8 @@ export default function CuttingCreate({ rawMaterials }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div key={price.id} className={`flex items-center justify-between gap-3 rounded-lg border p-3 ${isSelected ? 'border-primary' : ''}`}>
|
<div key={price.id} className={`flex items-center justify-between gap-3 rounded-lg border p-3 ${isSelected ? 'border-primary' : ''}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img src={price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
<img src={price.photo_conversion_url ?? price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -33,6 +33,7 @@ type MaterialState = {
|
|||||||
material_name: string;
|
material_name: string;
|
||||||
unit: string;
|
unit: string;
|
||||||
photo_url: string | null;
|
photo_url: string | null;
|
||||||
|
photo_conversion_url: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
type CombinationState = {
|
type CombinationState = {
|
||||||
@ -73,6 +74,7 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
material_name: rawMaterial?.name ?? '',
|
material_name: rawMaterial?.name ?? '',
|
||||||
unit: rawMaterial?.unit ?? '',
|
unit: rawMaterial?.unit ?? '',
|
||||||
photo_url: price?.photo_url ?? m.photo_url ?? null,
|
photo_url: price?.photo_url ?? m.photo_url ?? null,
|
||||||
|
photo_conversion_url: price?.photo_conversion_url ?? m.photo_conversion_url ?? null,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -175,6 +177,7 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
material_name: rawMaterial.name,
|
material_name: rawMaterial.name,
|
||||||
unit: rawMaterial.unit,
|
unit: rawMaterial.unit,
|
||||||
photo_url: price.photo_url,
|
photo_url: price.photo_url,
|
||||||
|
photo_conversion_url: price.photo_conversion_url,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
@ -225,6 +228,7 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
material_name: foundMaterial?.name ?? '',
|
material_name: foundMaterial?.name ?? '',
|
||||||
unit: foundMaterial?.unit ?? '',
|
unit: foundMaterial?.unit ?? '',
|
||||||
photo_url: foundPrice?.photo_url ?? null,
|
photo_url: foundPrice?.photo_url ?? null,
|
||||||
|
photo_conversion_url: foundPrice?.photo_conversion_url ?? null,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -371,8 +375,8 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img src={price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
<img src={price.photo_conversion_url ?? price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
)}
|
)}
|
||||||
@ -417,8 +421,8 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
<div key={price.id} className={`flex flex-wrap items-center justify-between gap-2 rounded-lg border p-3 ${isAdded ? 'border-primary' : ''}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img src={price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
<img src={price.photo_conversion_url ?? price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
)}
|
)}
|
||||||
@ -601,9 +605,9 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
<div key={cartKey} className="space-y-2">
|
<div key={cartKey} className="space-y-2">
|
||||||
<div className="flex items-start justify-between gap-2">
|
<div className="flex items-start justify-between gap-2">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{m.photo_url ? (
|
{m.photo_conversion_url ?? m.photo_url ? (
|
||||||
<button type="button" onClick={() => setPreviewKey(cartKey)} className="block h-8 w-8 shrink-0 overflow-hidden rounded-md border transition-opacity hover:opacity-80">
|
<button type="button" onClick={() => setPreviewKey(cartKey)} className="block h-8 w-8 shrink-0 overflow-hidden rounded-md border transition-opacity hover:opacity-80">
|
||||||
<img src={m.photo_url} alt={m.variant} className="h-full w-full object-cover" />
|
<img src={m.photo_conversion_url ?? m.photo_url} alt={m.variant} className="h-full w-full object-cover" />
|
||||||
</button>
|
</button>
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-8 w-8 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
@ -722,7 +726,7 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
if (p) {
|
if (p) {
|
||||||
variantName = p.variant;
|
variantName = p.variant;
|
||||||
materialName = rm.name;
|
materialName = rm.name;
|
||||||
photoUrl = p.photo_url;
|
photoUrl = p.photo_conversion_url ?? p.photo_url;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -760,8 +764,8 @@ export default function CuttingEdit({ cutting, rawMaterials }: Props) {
|
|||||||
return (
|
return (
|
||||||
<div key={price.id} className={`flex items-center justify-between gap-3 rounded-lg border p-3 ${isSelected ? 'border-primary' : ''}`}>
|
<div key={price.id} className={`flex items-center justify-between gap-3 rounded-lg border p-3 ${isSelected ? 'border-primary' : ''}`}>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img src={price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
<img src={price.photo_conversion_url ?? price.photo_url} alt={price.variant} className="h-10 w-10 shrink-0 rounded-md object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-muted text-xs text-muted-foreground">N/A</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -98,6 +98,7 @@ export type PurchaseCreateData = {
|
|||||||
price: number;
|
price: number;
|
||||||
stock: number;
|
stock: number;
|
||||||
photo_url: string | null;
|
photo_url: string | null;
|
||||||
|
photo_conversion_url: string | null;
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -354,7 +354,7 @@ export default function PurchaseCreate({ suppliers, rawMaterials }: Props) {
|
|||||||
if (price && material) {
|
if (price && material) {
|
||||||
lines.push({
|
lines.push({
|
||||||
key: `existing-${id}`,
|
key: `existing-${id}`,
|
||||||
photoUrl: price.photo_url,
|
photoUrl: price.photo_conversion_url ?? price.photo_url,
|
||||||
title: `${material.name} — ${price.variant}`,
|
title: `${material.name} — ${price.variant}`,
|
||||||
subtitle: `${formatCurrency(price.price)} / ${material.unit}`,
|
subtitle: `${formatCurrency(price.price)} / ${material.unit}`,
|
||||||
price: price.price,
|
price: price.price,
|
||||||
@ -876,10 +876,10 @@ export default function PurchaseCreate({ suppliers, rawMaterials }: Props) {
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
price.photo_url
|
price.photo_conversion_url ?? price.photo_url
|
||||||
}
|
}
|
||||||
alt={
|
alt={
|
||||||
price.variant
|
price.variant
|
||||||
|
|||||||
@ -166,7 +166,7 @@ export default function PurchaseEdit({
|
|||||||
if (price && material) {
|
if (price && material) {
|
||||||
lines.push({
|
lines.push({
|
||||||
key: `existing-${id}`,
|
key: `existing-${id}`,
|
||||||
photoUrl: price.photo_url,
|
photoUrl: price.photo_conversion_url ?? price.photo_url,
|
||||||
title: `${material.name} — ${price.variant}`,
|
title: `${material.name} — ${price.variant}`,
|
||||||
subtitle: `${formatCurrency(price.price)} / ${material.unit}`,
|
subtitle: `${formatCurrency(price.price)} / ${material.unit}`,
|
||||||
price: price.price,
|
price: price.price,
|
||||||
@ -319,11 +319,11 @@ export default function PurchaseEdit({
|
|||||||
}
|
}
|
||||||
>
|
>
|
||||||
<div className="flex min-w-0 items-center gap-3">
|
<div className="flex min-w-0 items-center gap-3">
|
||||||
{price.photo_url ? (
|
{price.photo_conversion_url ?? price.photo_url ? (
|
||||||
<img
|
<img
|
||||||
src={
|
src={
|
||||||
price.photo_url
|
price.photo_conversion_url ?? price.photo_url
|
||||||
}
|
}
|
||||||
alt={
|
alt={
|
||||||
price.variant
|
price.variant
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user