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"> <script lang="ts">
import { cart } from '$lib/stores/cart'; 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; export let product: MedusaProduct;
let selectedVariant: MedusaVariant = product.variants[0]; let selectedVariant: MedusaVariant = product.variants[0];
let currentImageIndex = 0; let currentImageIndex = 0;
let cartButton: HTMLDivElement; let cartButton: HTMLDivElement;
let isSticky = false; 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() { function handleScroll() {
if (!cartButton) return; if (!cartButton) return;
isSticky = window.scrollY + window.innerHeight < cartButton.offsetTop; isSticky = window.scrollY + window.innerHeight < cartButton.offsetTop;
} }
function handleVariantChange(variantId: string) { function handleOptionChange(optionId: string, value: string) {
const variant = product.variants.find((v: MedusaVariant) => v.id === variantId); selectedOptions.set(optionId, value);
if (variant) selectedVariant = variant;
// 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> </script>
@ -52,17 +93,17 @@
{#each product.options as option} {#each product.options as option}
<div> <div>
<label class="label" for={`option-${option.title}`}> <label class="label" for={`option-${option.id}`}>
<span class="label-text">{option.title}</span> <span class="label-text">{option.title}</span>
</label> </label>
<select <select
id={`option-${option.title}`} id={`option-${option.id}`}
class="select select-bordered w-full" class="select select-bordered w-full"
value={selectedVariant.id} value={selectedOptions.get(option.id)}
on:change={(e) => handleVariantChange((e.target as HTMLSelectElement).value)} on:change={(e) => handleOptionChange(option.id, (e.target as HTMLSelectElement).value)}
> >
{#each option.values as value} {#each getAvailableValues(option.id) as value}
<option value={product.variants.find(v => v.options[0].value === value.value)?.id}> <option value={value.value}>
{value.value} {value.value}
</option> </option>
{/each} {/each}