bugfix product options and variants

This commit is contained in:
nomad 2025-06-12 23:13:57 +03:00
parent a362c9a7ce
commit befb0c7fdb

View file

@ -1,21 +1,62 @@
<script lang="ts">
import { cart } from '$lib/stores/cart';
import type { MedusaProduct, MedusaVariant } from '$lib/types/medusa';
import type { MedusaProduct, MedusaVariant, MedusaOptionValue } from '$lib/types/medusa';
export let product: MedusaProduct;
let selectedVariant: MedusaVariant = product.variants[0];
let currentImageIndex = 0;
let cartButton: HTMLDivElement;
let isSticky = false;
let selectedOptions = new Map<string, string>();
// Initialize selected options from the first variant
$: if (product.variants.length > 0) {
selectedOptions = new Map(
product.variants[0].options.map(opt => [opt.option_id, opt.value])
);
}
function handleScroll() {
if (!cartButton) return;
isSticky = window.scrollY + window.innerHeight < cartButton.offsetTop;
}
function handleVariantChange(variantId: string) {
const variant = product.variants.find((v: MedusaVariant) => v.id === variantId);
if (variant) selectedVariant = variant;
function handleOptionChange(optionId: string, value: string) {
selectedOptions.set(optionId, value);
// Find the variant that matches all selected options
const matchingVariant = product.variants.find(variant =>
variant.options.every(opt =>
selectedOptions.get(opt.option_id) === opt.value
)
);
if (matchingVariant) {
selectedVariant = matchingVariant;
}
}
// Get available values for an option based on other selected options
function getAvailableValues(optionId: string) {
const otherSelectedOptions = new Map(selectedOptions);
otherSelectedOptions.delete(optionId);
return product.options
.find(opt => opt.id === optionId)
?.values.filter(value => {
// Check if this value is available in any variant with current selections
return product.variants.some(variant =>
variant.options.some(opt =>
opt.option_id === optionId &&
opt.value === value.value &&
// Check if other selected options match
variant.options.every(opt =>
opt.option_id === optionId ||
otherSelectedOptions.get(opt.option_id) === opt.value
)
)
);
}) || [];
}
</script>
@ -52,17 +93,17 @@
{#each product.options as option}
<div>
<label class="label" for={`option-${option.title}`}>
<label class="label" for={`option-${option.id}`}>
<span class="label-text">{option.title}</span>
</label>
<select
id={`option-${option.title}`}
id={`option-${option.id}`}
class="select select-bordered w-full"
value={selectedVariant.id}
on:change={(e) => handleVariantChange((e.target as HTMLSelectElement).value)}
value={selectedOptions.get(option.id)}
on:change={(e) => handleOptionChange(option.id, (e.target as HTMLSelectElement).value)}
>
{#each option.values as value}
<option value={product.variants.find(v => v.options[0].value === value.value)?.id}>
{#each getAvailableValues(option.id) as value}
<option value={value.value}>
{value.value}
</option>
{/each}