dynamic region selection
This commit is contained in:
parent
68eee09cf3
commit
9342518a85
7 changed files with 173 additions and 6 deletions
|
@ -1,3 +1,7 @@
|
|||
<script>
|
||||
import RegionSelector from './RegionSelector.svelte';
|
||||
</script>
|
||||
|
||||
<footer class="footer p-10 bg-neutral text-neutral-content">
|
||||
<div>
|
||||
<span class="footer-title">Standard Marine GCC</span>
|
||||
|
@ -17,6 +21,10 @@
|
|||
<p>Email: info@standardmarinegcc.com</p>
|
||||
<p>Working Hours: 24/7</p>
|
||||
</div>
|
||||
<div>
|
||||
<span class="footer-title">Region Settings</span>
|
||||
<RegionSelector />
|
||||
</div>
|
||||
<div>
|
||||
<span class="footer-title">Social</span>
|
||||
<div class="grid grid-flow-col gap-4">
|
||||
|
|
73
src/lib/components/RegionSelector.svelte
Normal file
73
src/lib/components/RegionSelector.svelte
Normal file
|
@ -0,0 +1,73 @@
|
|||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { region } from '$lib/stores/region';
|
||||
import type { Region } from '$lib/stores/region';
|
||||
import { PUBLIC_MEDUSA_KEY } from '$env/static/public';
|
||||
|
||||
let regions: Region[] = [];
|
||||
let selectedRegion: Region;
|
||||
let loading = true;
|
||||
|
||||
onMount(async () => {
|
||||
try {
|
||||
const response = await fetch('http://localhost:9000/store/regions', {
|
||||
headers: {
|
||||
'x-publishable-api-key': PUBLIC_MEDUSA_KEY,
|
||||
}
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to fetch regions');
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
console.log(data);
|
||||
regions = data.regions;
|
||||
|
||||
// Set the selected region from the store
|
||||
selectedRegion = $region;
|
||||
} catch (error) {
|
||||
console.error('Error fetching regions:', error);
|
||||
} finally {
|
||||
loading = false;
|
||||
}
|
||||
});
|
||||
|
||||
function handleRegionChange(event: Event) {
|
||||
const select = event.target as HTMLSelectElement;
|
||||
const newRegion = regions.find(r => r.id === select.value);
|
||||
if (newRegion) {
|
||||
region.setRegion(newRegion);
|
||||
selectedRegion = newRegion;
|
||||
|
||||
// Set cookie for server-side access
|
||||
document.cookie = `selectedRegion=${newRegion.id}; path=/; max-age=31536000`; // 1 year expiry
|
||||
|
||||
// Reload the page to fetch products with new region
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="form-control w-full">
|
||||
<label class="label" for="region-select">
|
||||
<span class="label-text text-neutral-content">Region</span>
|
||||
</label>
|
||||
<select
|
||||
id="region-select"
|
||||
class="select select-bordered w-full bg-neutral text-neutral-content border-neutral-content/20"
|
||||
value={selectedRegion?.id}
|
||||
on:change={handleRegionChange}
|
||||
disabled={loading}
|
||||
>
|
||||
{#if loading}
|
||||
<option value="">Loading regions...</option>
|
||||
{:else}
|
||||
{#each regions as region}
|
||||
<option value={region.id}>
|
||||
{region.name} ({region.currency_code.toUpperCase()})
|
||||
</option>
|
||||
{/each}
|
||||
{/if}
|
||||
</select>
|
||||
</div>
|
|
@ -38,7 +38,7 @@
|
|||
}}
|
||||
>
|
||||
{#each product.variants as variant}
|
||||
<option value={variant.id}>{variant.title} {variant.calculated_price.calculated_amount} €</option>
|
||||
<option value={variant.id}>{variant.title} {variant.calculated_price.calculated_amount} {variant.calculated_price.currency_code}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<button
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<div class="space-y-6">
|
||||
<div>
|
||||
<h1 class="text-3xl font-bold">{product.title}</h1>
|
||||
<h1 class="text-3xl font-bold">{selectedVariant.calculated_price.calculated_amount} €</h1>
|
||||
<h1 class="text-3xl font-bold">{selectedVariant.calculated_price.calculated_amount} {selectedVariant.calculated_price.currency_code}</h1>
|
||||
</div>
|
||||
|
||||
{#each product.options as option}
|
||||
|
|
82
src/lib/stores/region.ts
Normal file
82
src/lib/stores/region.ts
Normal file
|
@ -0,0 +1,82 @@
|
|||
import { writable } from 'svelte/store';
|
||||
|
||||
export interface Region {
|
||||
id: string;
|
||||
name: string;
|
||||
currency_code: string;
|
||||
tax_rate: number;
|
||||
tax_code: string | null;
|
||||
countries: {
|
||||
id: number;
|
||||
iso_2: string;
|
||||
iso_3: string;
|
||||
name: string;
|
||||
display_name: string;
|
||||
region_id: string | null;
|
||||
num_iso: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
function createRegionStore() {
|
||||
// Initialize with default region
|
||||
const defaultRegion = {
|
||||
id: 'reg_01JXB17SNW6VA5WJVV8QPHKAY3',
|
||||
name: 'EU',
|
||||
currency_code: 'eur',
|
||||
tax_rate: 0,
|
||||
tax_code: null,
|
||||
countries: []
|
||||
};
|
||||
|
||||
let initialRegion = defaultRegion;
|
||||
|
||||
// Only try to get from localStorage if we're in the browser
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedRegion = localStorage.getItem('selectedRegion');
|
||||
if (savedRegion) {
|
||||
try {
|
||||
const parsed = JSON.parse(savedRegion);
|
||||
if (parsed && typeof parsed === 'object' && 'id' in parsed) {
|
||||
initialRegion = parsed;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to parse stored region, using default', e);
|
||||
localStorage.removeItem('selectedRegion'); // Clear invalid data
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const { subscribe, set, update } = writable<Region>(initialRegion);
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
setRegion: (region: Region) => {
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
localStorage.setItem('selectedRegion', JSON.stringify(region));
|
||||
} catch (e) {
|
||||
console.error('Failed to save region to localStorage', e);
|
||||
}
|
||||
}
|
||||
set(region);
|
||||
},
|
||||
getRegion: () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const savedRegion = localStorage.getItem('selectedRegion');
|
||||
if (savedRegion) {
|
||||
try {
|
||||
const parsed = JSON.parse(savedRegion);
|
||||
if (parsed && typeof parsed === 'object' && 'id' in parsed) {
|
||||
return parsed;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn('Failed to parse stored region, using default', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return defaultRegion;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const region = createRegionStore();
|
|
@ -1,8 +1,10 @@
|
|||
import { PUBLIC_MEDUSA_KEY } from '$env/static/public';
|
||||
|
||||
export async function load() {
|
||||
export async function load({ cookies }) {
|
||||
const regionId = cookies.get('selectedRegion');
|
||||
|
||||
const res = await fetch(
|
||||
`http://localhost:9000/store/products?region_id=reg_01JXB17SNW6VA5WJVV8QPHKAY3`,
|
||||
`http://localhost:9000/store/products?region_id=${regionId}`,
|
||||
{
|
||||
headers: {
|
||||
'x-publishable-api-key': PUBLIC_MEDUSA_KEY,
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
import type { PageServerLoad } from './$types';
|
||||
import { PUBLIC_MEDUSA_KEY } from '$env/static/public';
|
||||
|
||||
export const load = (async ({ params }) => {
|
||||
export const load = (async ({ params, cookies }) => {
|
||||
const regionId = cookies.get('selectedRegion');
|
||||
|
||||
const res = await fetch(
|
||||
`http://localhost:9000/store/products/${params.id}?region_id=reg_01JXB17SNW6VA5WJVV8QPHKAY3`,
|
||||
`http://localhost:9000/store/products/${params.id}?region_id=${regionId}`,
|
||||
{
|
||||
headers: {
|
||||
'x-publishable-api-key': PUBLIC_MEDUSA_KEY,
|
||||
|
|
Loading…
Reference in a new issue