Last active
July 16, 2024 14:06
-
-
Save gijsbotje/cb631ff6e59095d142f875c0eab7a6e3 to your computer and use it in GitHub Desktop.
Afosto 2.0 storefront scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- twig/layouts/storefrontScripts.twig --> | |
<!-- Styling voor de error meldingen d.m.v. toastify-js --> | |
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/toastify-js/src/toastify.min.css"> | |
<script type="module"> | |
import 'https://esm.sh/preact/debug'; | |
import { h, render, Fragment } from 'https://esm.sh/preact'; | |
import { useEffect, useState, useRef } from 'https://esm.sh/preact/hooks'; | |
import { html } from 'https://esm.sh/htm/preact'; | |
import Toastify from 'https://esm.sh/toastify-js'; | |
import { createStorefrontClient } from 'https://esm.sh/@afosto/storefront@3'; | |
const getErrorMessage = error => { | |
const errorResponse = error?.response || {}; | |
const errorResponseData = errorResponse?.data || {}; | |
const errorResponseError = errorResponseData?.error || {}; | |
const gqlResponseErrors = errorResponse?.errors || []; | |
const [firstGqlError] = gqlResponseErrors || []; | |
const gqlErrorExtensions = firstGqlError?.extensions || {}; | |
const pointers = errorResponseError?.details?.pointers || firstGqlError?.extensions?.pointers; | |
const [firstPointer] = pointers || []; | |
return ( | |
firstPointer?.message || | |
errorResponseError?.message || | |
errorResponseData?.message || | |
firstGqlError?.message | |
); | |
}; | |
const formatPrice = (value) => { | |
const intl = Intl.NumberFormat(`${document.documentElement.lang}-${document.documentElement.lang.toUpperCase()}`, { | |
style: 'currency', | |
currency: document.body.dataset.afCurrencyIso, | |
}); | |
const decimal = intl.formatToParts(value / 100).find(part => part.type === 'decimal').value; | |
return intl.format(value / 100).replace(`${decimal}00`, `${decimal}-`); | |
}; | |
const CouponForm = ({ coupons }) => { | |
const [value, setValue] = useState(''); | |
const [errorMessage, setErrorMessage] = useState(null); | |
const [isSubmitting, setIsSubmitting] = useState(false); | |
const handleAddCouponToCart = async e => { | |
e.preventDefault(); | |
try { | |
setIsSubmitting(true); | |
const updatedCart = await window.Storefront.addCouponToCart(value); | |
if (!!updatedCart) { | |
setValue(''); | |
$('body').trigger('cart:updated', updatedCart); | |
} else { | |
alert('something went wrong'); | |
} | |
} catch (error) { | |
$("#add-response-modal .modal-header .modal-title").html($("#add-response-modal").data("error-title")); | |
$("#add-response-modal .modal-body").addClass('text-center'); | |
$("#add-response-modal .modal-body").html('<span class="fa-stack fa-3x text-warning"><i class="far fa-circle fa-stack-2x"></i><i class="fas fa-exclamation fa-stack-1x"></i></span><p class="lead mt-15">' + getErrorMessage(error) + '</p>'); | |
$("#add-response-modal").modal('show'); | |
} finally { | |
setIsSubmitting(false); | |
} | |
}; | |
const handleRemoveCouponToCart = async code => { | |
try { | |
setIsSubmitting(true); | |
const updatedCart = await window.Storefront.removeCouponFromCart(code); | |
$('body').trigger('cart:updated', updatedCart); | |
} catch (error) { | |
$("#add-response-modal .modal-header .modal-title").html($("#add-response-modal").data("error-title")); | |
$("#add-response-modal .modal-body").addClass('text-center'); | |
$("#add-response-modal .modal-body").html('<span class="fa-stack fa-3x text-warning"><i class="far fa-circle fa-stack-2x"></i><i class="fas fa-exclamation fa-stack-1x"></i></span><p class="lead mt-15">' + getErrorMessage(error) + '</p>'); | |
$("#add-response-modal").modal('show'); | |
} finally { | |
setIsSubmitting(false); | |
} | |
}; | |
const handleChange = e => { | |
setValue(e.target.value); | |
}; | |
const handleInput = () => { | |
setErrorMessage(null); | |
}; | |
return html` | |
<form onSubmit="${handleAddCouponToCart}"> | |
<div class=""> | |
${(coupons || []).map(({ code }, index) => html` | |
<div class="panel panel-default d-flex justify-content-between align-items-center"> | |
<div class="py-4 px-12"> | |
${code || null} | |
</div> | |
<button class="btn btn-danger btn-sm" type="button" onClick="${() => handleRemoveCouponToCart(code)}"> | |
<i class="fal fa-times" /> | |
</button> | |
</div> | |
`)} | |
</div> | |
<div class="input-group"> | |
<input class="form-control" placeholder="Coupon code toevoegen" onChange="${handleChange}" onInput="${handleInput}" value="${value}" /> | |
<span class="input-group-btn"> | |
<button type="submit" class="btn btn-primary" disabled="${isSubmitting}"> | |
<i class="fal fa-angle-right" /> | |
</button> | |
</span> | |
</div> | |
${errorMessage && errorMessage} | |
</form> | |
`; | |
}; | |
const CopyCartLink = ({ id }) => { | |
const handleShowShareDialog = () => { | |
$('#share-cart-dialog').modal('show'); | |
}; | |
const handleCopyLink = () => { | |
const cartLink = `${window.location.origin}/cart?hash=${id}`; | |
navigator.clipboard.writeText(cartLink); | |
}; | |
useEffect(() => { | |
if (id) { | |
const cartLink = `${window.location.origin}/cart?hash=${id}`; | |
const dialog = document.getElementById('share-cart-dialog'); | |
dialog.innerHTML = dialog.innerHTML.replace(/\{url\}/g, cartLink); | |
$('[data-toggle="tooltip"]').tooltip(); | |
$('.copy-to-clipboard').tooltip({ | |
container: '.input-group-btn', | |
trigger: 'click' | |
}).on('mouseout', function(){ | |
$(this).tooltip('hide'); | |
}); | |
new Clipboard('.copy-to-clipboard'); | |
// new Clipboard('#copy-field'); | |
$('input[data-clipboard-text]').on('click, focus', function() { | |
$(this).select(); | |
}); | |
} | |
}, [id]); | |
return html` | |
<button class="btn btn-link btn-block" data-toggle="modal" data-target="#share-cart-dialog">Winkelwagen delen</button> | |
`; | |
}; | |
const CartPageSummary = ({ cart, checkoutUrl, isLoading }) => { | |
const { subtotal, total, totalExcludingVat, vat, adjustments, services, coupons, id } = cart || {}; | |
return html` | |
<div class="cost-summary px-15"> | |
<div class="cost-summary-inner"> | |
<strong class="h4"> | |
{{'Checkout'|t}} | |
</strong> | |
<div class="d-flex justify-content-between align-items-center"> | |
<span class="h6 my-5 text-muted"> | |
{{'Subtotaal'|t}} | |
</span> | |
<span class="h5 my-5 text-uppercase${isLoading ? 'text-muted' : ''}"> | |
${isLoading ? '-' : formatPrice(subtotal || 0)} | |
</span> | |
</div> | |
${(adjustments || []).map(({ description, amount, isDiscount, isPercentage, outcome }, index) => html` | |
<div class="d-flex justify-content-between align-items-center${index > 0 ? ' mt-20' : ''}"> | |
<span class="h6 my-5 text-muted"> | |
${description}${isPercentage ? ` (${amount}%)` : ''} | |
</span> | |
<span class="h5 my-5"> | |
${formatPrice((outcome.amount || 0) * (isDiscount ? -1 : 1) )} | |
</span> | |
</div> | |
`)} | |
<div class="d-flex justify-content-between align-items-center"> | |
<span class="h6 my-5 text-muted"> | |
{{'Totaal excl. BTW'|t}} | |
</span> | |
<span class="h5 my-5${isLoading ? 'text-muted' : ''}"> | |
${isLoading ? '-' : formatPrice(totalExcludingVat || 0)} | |
</span> | |
</div> | |
${(vat || []).map(({ rate, amount }, index) => html` | |
<div class="d-flex justify-content-between align-items-center${index > 0 ? ' mt-20' : ''}"> | |
<span class="h6 my-5 text-muted"> | |
BTW ${rate || 0}% | |
</span> | |
<span class="h5 my-5"> | |
${formatPrice(amount || 0)} | |
</span> | |
</div> | |
`)} | |
<hr /> | |
<div class="d-flex justify-content-between align-items-center mb-32"> | |
<span class="h6 my-0 text-muted"> | |
{{'Totaal'|t}} | |
</span> | |
<span class="h4 my-0${isLoading ? 'text-muted' : ''}"> | |
${isLoading ? '-' : formatPrice(total || 0)} | |
</span> | |
</div> | |
<${CouponForm} coupons="${coupons}" /> | |
// <${PayPalButton} options="${paypalOptions}" /> | |
<a class="btn btn-success btn-block mt-16" href="${checkoutUrl}" title="{{'Verder met bestellen'|t}}"> | |
{{'Verder met bestellen'|t}} | |
</a> | |
<${CopyCartLink} id="${id}" /> | |
</div> | |
</div> | |
`; | |
}; | |
const ItemsGrid = ({ items, onRemove, onChangeQuantity, isLoading }) => { | |
const increaseQuantity = item => onChangeQuantity(item, item.quantity + 1); | |
const decreaseQuantity = item => onChangeQuantity(item, item.quantity - 1); | |
return html` | |
<div class="cart-grid px-15 d-flex flex-column"> | |
<div class="cart-grid-header"> | |
<div class="cart-grid-header-action"></div> | |
<div class="cart-grid-header-information"> | |
<span> | |
{{'Informatie'|t}} | |
</span> | |
</div> | |
<div class="cart-grid-header-single-price"> | |
<span> | |
{{'Stuksprijs'|t}} | |
</span> | |
</div> | |
<div class="cart-grid-header-quantity"> | |
<span> | |
{{'Aantal'|t}} | |
</span> | |
</div> | |
<div class="cart-grid-header-subtotal"> | |
<span> | |
{{'Subtotaal'|t}} | |
</span> | |
</div> | |
</div> | |
${!isLoading ? items.map(item => { | |
const { label, sku, total, subtotal, quantity, ids, details, image } = item || {}; | |
const unitPrice = details[0] && details[0].pricing && details[0].pricing.amount || 0; | |
return html` | |
<div class="cart-grid-item-container" key="${sku}"> | |
<div class="cart-grid-item"> | |
<div class="cart-grid-item-action hidden-xs hidden-sm"> | |
<button | |
type="button" | |
class="btn btn-link text-danger btn-block btn-icon p-10" | |
onClick="${() => onRemove(ids)}" | |
> | |
<i class="fa fa-times"></i> | |
</button> | |
</div> | |
<div class="cart-grid-item-information"> | |
<div class="cart-grid-item-information-image"> | |
<a href="{{cartItem.url}}" title="${label || sku}"> | |
<div class="lazyload-wrapper lazyload-square"> | |
<img loading="lazy" src="${image}" alt="${'{{'Afbeelding van [name]'|t}}'.replace('[name]', label || sku) }" class="lazyload-cover" /> | |
</div> | |
</a> | |
</div> | |
<div class="cart-grid-item-information-inner"> | |
<strong class="h5 cart-grid-item-product-name"> | |
${label || sku} | |
</strong> | |
<div class="visible-xs visible-sm"> | |
<div class="d-flex"> | |
<div class="flex-100 d-flex align-items-center"> | |
<label class="h6 text-muted d-block mr-10"> | |
{{'Aantal'|t}} | |
</label> | |
<div class="quantity-counter"> | |
<button | |
type="button" | |
class="btn" | |
onClick="${() => decreaseQuantity(item)}" | |
> | |
<i class="fa fa-minus"></i> | |
</button> | |
<div class="mx-10"> | |
${quantity} | |
</div> | |
<button | |
type="button" | |
class="btn" | |
onClick="${() => increaseQuantity(item)}" | |
> | |
<i class="fa fa-plus"></i> | |
</button> | |
</div> | |
</div> | |
</div> | |
<hr class="light my-10"/> | |
<div class="d-flex align-items-center"> | |
<span class="h6 my-0 text-muted mr-10"> | |
{{'Subtotal'|t}} | |
</span> | |
<span class="h6 my-0"> | |
${formatPrice(subtotal)} | |
</span> | |
<button | |
type="button" | |
class="btn btn-link btn-sm text-danger btn-icon p-5 ml-auto" | |
onClick="${() => onRemove(ids)}" | |
> | |
<i class="fa fa-times"></i> | |
<span> | |
{{'Verwijderen'|t}} | |
</span> | |
</button> | |
</div> | |
</div> | |
</div> | |
<div class="cart-grid-item-single-price hidden-xs hidden-sm text-right"> | |
<div class="h5"> | |
${formatPrice(unitPrice)} | |
</div> | |
</div> | |
<div class="cart-grid-item-quantity hidden-xs hidden-sm"> | |
<div class="quantity-counter"> | |
<button | |
type="button" | |
class="btn" | |
onClick="${() => decreaseQuantity(item)}" | |
> | |
<i class="fa fa-minus fa-sm"></i> | |
</button> | |
<div class="mx-10"> | |
${quantity} | |
</div> | |
<button | |
type="button" | |
class="btn" | |
onClick="${() => increaseQuantity(item)}" | |
> | |
<i class="fa fa-plus fa-sm"></i> | |
</button> | |
</div> | |
</div> | |
<div class="cart-grid-item-subtotal hidden-xs hidden-sm text-right"> | |
<span class="h5"> | |
${formatPrice(subtotal)} | |
</span> | |
</div> | |
</div> | |
</div> | |
</div> | |
`; | |
}) : ''} | |
</div> | |
`; | |
}; | |
const CartPage = () => { | |
const [cart, setCart] = useState({}); | |
const [isLoadingCart, setIsLoadingCart] = useState(true); | |
const [error, setError] = useState(null); | |
const checkoutUrl = cart && cart.checkout && cart.checkout.url || ''; | |
const handleRemoveItems = async ids => { | |
const updatedCart = await window.Storefront.removeCartItems(ids); | |
$('body').trigger('cart:updated', updatedCart); | |
}; | |
const handleChangeQuantity = async (item, quantity) => { | |
try { | |
if (!quantity || quantity === item.quantity) { | |
return; | |
} | |
let cartResponse; | |
if (quantity > item.quantity) { | |
cartResponse = await window.Storefront.addCartItems([ | |
{ | |
sku: item.sku, | |
quantity: quantity - item.quantity, | |
}, | |
]); | |
} else { | |
const difference = item.quantity - quantity; | |
const ids = [...(item.ids || [])].reverse().slice(0, difference); | |
cartResponse = await window.Storefront.removeCartItems(ids); | |
} | |
$('body').trigger('cart:updated', cartResponse); | |
} catch(error) { | |
$("#add-response-modal .modal-header .modal-title").html($("#add-response-modal").data("error-title")); | |
$("#add-response-modal .modal-body").addClass('text-center'); | |
$("#add-response-modal .modal-body").html('<span class="fa-stack fa-3x text-warning"><i class="far fa-circle fa-stack-2x"></i><i class="fas fa-exclamation fa-stack-1x"></i></span><p class="lead mt-15">' + getErrorMessage(error) + '</p>'); | |
$("#add-response-modal").modal('show'); | |
} | |
}; | |
useEffect(() => { | |
const updateCart = (event, val) => { | |
setCart(val); | |
if (isLoadingCart) { | |
setIsLoadingCart(false); | |
} | |
}; | |
$('body').on('cart:updated', updateCart); | |
return () => { | |
$('body').off('cart:updated', updateCart); | |
} | |
}, []); | |
return html` | |
<section id="contentcart" class="container mb-20 cart-version-flex${isLoadingCart ? ' loading-ajax' : ''}"> | |
<div class="mb-15"> | |
<div class="cart-header d-flex align-items-center justify-content-between"> | |
<h1 class="my-0 cart-title"> | |
{{'Winkelwagen'|t}} | |
</h1> | |
${(cart && cart.items && cart.items.length > 0) && !isLoadingCart && html` | |
<a class="btn btn-success visible-sm visible-xs" href="${checkoutUrl}"> | |
{{'Afrekenen'|t}} | |
</a>`} | |
</div> | |
<div class="clearfix"></div> | |
</div> | |
${error && html` | |
<div class="alert alert-warning">${error}</div> | |
`} | |
${(cart && cart.items && cart.items.length > 0) || isLoadingCart ? html` | |
<div class="d-flex flex-wrap flex-md-nowrap mx-n15"> | |
<${ItemsGrid} isLoading="${isLoadingCart}" items="${cart.items || []}" onRemove="${handleRemoveItems}" onChangeQuantity="${handleChangeQuantity}" /> | |
<${CartPageSummary} isLoading="${isLoadingCart}" cart="${cart}" checkoutUrl="${checkoutUrl}" /> | |
</div> | |
` : html` | |
<h3 class="text-center text-warning"> | |
{{'Uw winkelwagen is leeg.'|t}} | |
<br /> | |
<br /> | |
<a class="center btn btn-primary" href="{{home_url}}">{{'Bekijk onze producten'|t}}</a> | |
</h3> | |
`} | |
</section> | |
`; | |
}; | |
const CartDrawerItem = ({ item, onRemove, onChangeQuantity }) => { | |
const { label, sku, image, ids, quantity, subtotal, total } = item; | |
const increaseQuantity = item => onChangeQuantity(item, item.quantity + 1); | |
const decreaseQuantity = item => onChangeQuantity(item, item.quantity - 1); | |
return html` | |
<div class="cart-overview-item"> | |
<div class="cart-overview-item-inner d-flex gap-8"> | |
<div class="cart-overview-item-delete align-self-center"> | |
<a class="text-primary" onClick="${() => onRemove(ids)}"> | |
<i class="fa fa-times text-danger fa-sm"></i> | |
</a> | |
</div> | |
<div class="cart-overview-item-image px-5"> | |
<div class="d-block icon-75"> | |
<div class="lazyload-wrapper lazyload-square"> | |
<img class="lazyload lazyload-cover" data-src="${image}" alt="${'{{'Afbeelding van [name]'|t}}'.replace('[name]', label || sku) }"/> | |
</div> | |
</div> | |
</div> | |
<div class="cart-overview-item-group d-flex flex-column justify-content-between flex-fill"> | |
<div class="cart-overview-item-name"> | |
${label || sku} | |
</div> | |
<div class="d-flex justify-content-between"> | |
<div class="cart-overview-item-quantity align-self-end"> | |
<div class="quantity-counter"> | |
<button | |
type="button" | |
class="btn" | |
aria-label="{{'aantal min 1'|t}}" | |
onClick="${() => decreaseQuantity(item)}" | |
> | |
<i class="fa fa-minus fa-sm"></i> | |
</button> | |
<div class="mx-10"> | |
${quantity} | |
</div> | |
<button | |
type="button" | |
class="btn" | |
aria-label="{{'aantal plus 1'|t}}" | |
onClick="${() => increaseQuantity(item)}" | |
> | |
<i class="fa fa-plus fa-sm"></i> | |
</button> | |
</div> | |
</div> | |
<div class="cart-overview-item-price text-right"> | |
<strong> | |
${formatPrice(subtotal)} | |
</strong> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
`; | |
}; | |
const CartDrawer = () => { | |
const [cart, setCart] = useState(null); | |
const [isLoadingCart, setIsLoadingCart] = useState(false); | |
const drawerRef = useRef(null); | |
const handleRemoveItems = async ids => { | |
const updatedCart = await window.Storefront.removeCartItems(ids); | |
setCart(updatedCart); | |
$('body').trigger('cart:updated', updatedCart); | |
}; | |
const handleChangeQuantity = async (item, quantity) => { | |
try { | |
if (!quantity || quantity === item.quantity) { | |
return; | |
} | |
let cartResponse; | |
if (quantity > item.quantity) { | |
cartResponse = await window.Storefront.addCartItems([ | |
{ | |
sku: item.sku, | |
quantity: quantity - item.quantity, | |
}, | |
]); | |
} else { | |
const difference = item.quantity - quantity; | |
const ids = [...(item.ids || [])].reverse().slice(0, difference); | |
cartResponse = await window.Storefront.removeCartItems(ids); | |
} | |
setCart(cartResponse); | |
$('body').trigger('cart:updated', cartResponse); | |
} catch(error) { | |
$("#add-response-modal .modal-header .modal-title").html($("#add-response-modal").data("error-title")); | |
$("#add-response-modal .modal-body").addClass('text-center'); | |
$("#add-response-modal .modal-body").html('<span class="fa-stack fa-3x text-warning"><i class="far fa-circle fa-stack-2x"></i><i class="fas fa-exclamation fa-stack-1x"></i></span><p class="lead mt-15">' + getErrorMessage(error) + '</p>'); | |
$("#add-response-modal").modal('show'); | |
} | |
}; | |
const getCartData = async () => { | |
setIsLoadingCart(true); | |
let tokenIsValid = true; | |
const { search = '', pathname } = window?.location || {}; | |
const params = new URLSearchParams(search); | |
const cartToken = params.get('hash'); | |
const isCartPage = pathname === '/cart'; | |
const intent = isCartPage ? 'VIEW_CART' : null; | |
const cartResponse = await window.Storefront.getCart(cartToken, intent).catch(() => { | |
if (cartToken) { | |
tokenIsValid = false; | |
return window.Storefront.getCart(null, intent); | |
} | |
return Promise.reject(new Error('Cart not found')); | |
}); | |
if (cartResponse && tokenIsValid && cartToken) { | |
await window.Storefront.storeCartTokenInStorage(cartToken); | |
} | |
// window.Storefront.getCart().then(response => { | |
setIsLoadingCart(false); | |
$('body').trigger('cart:updated', cartResponse); | |
// }); | |
}; | |
useEffect(() => { | |
getCartData(); | |
}, []); | |
useEffect(() => { | |
const updateCart = (event, val) => { | |
if(!!val) { | |
setCart(val); | |
} | |
if (isLoadingCart) { | |
setIsLoadingCart(false); | |
} | |
}; | |
$('body').on('cart:updated', updateCart); | |
return () => { | |
$('body').off('cart:updated', updateCart); | |
} | |
}, []); | |
return html` | |
<div class="drawer drawer-right" id="cart-drawer" ref="${drawerRef}"> | |
<div class="drawer-header"> | |
<div class="h4 m-0 fw-700"> | |
{{"Winkelwagen"|t}} | |
</div> | |
<button class="btn btn-link m-4 p-0 icon-40 mr-n12" type="button" data-dismiss="drawer" aria-label="{{'Sluit winkelwagen'|t}}"> | |
<i class="fa fa-times icon-size-20 text-black"></i> | |
</button> | |
</div> | |
<div class="drawer-body configurator-drawer-inner p-0"> | |
${((cart && cart.items) || []).length === 0 ? html` | |
<div class="text-center"> | |
<i class="fa fa-cart-plus text-primary fa-4x mt-40 mb-40"></i> | |
<span class="h4 mb-12">{{"Uw winkelwagen is leeg"|t}}</span> | |
<p class=" mb-40">{{"Bekijk het aanbod op onze website en voeg producten toe aan je winkelwagen."|t}}</p> | |
<button type="button" class="btn btn-primary" data-dismiss="drawer"> | |
{{'Verder winkelen'|t}} | |
</button> | |
</div> | |
` : html` | |
<div class="cart-preview-items py-8"> | |
${((cart && cart.items) || []).map(item => html` | |
<${CartDrawerItem} key="${item.sku}" item="${item}" onRemove="${handleRemoveItems}" onChangeQuantity="${handleChangeQuantity}" /> | |
`)} | |
</div> | |
`} | |
</div> | |
${((cart && cart.items) || []).length ? html` | |
<div class="drawer-footer drawer-footer-sticky pb-32 px-32"> | |
<hr class="m-0" /> | |
<div class="d-flex justify-content-between py-20"> | |
<span> | |
{{'Totaal'|t}} | |
</span> | |
<span> | |
${formatPrice(cart.total)} | |
</span> | |
</div> | |
<hr class="mt-0 mb-32" /> | |
<a class="btn btn-primary btn-block" href="{{cart_url}}"> | |
{{'Afrekenen'|t}} | |
</a> | |
</div> | |
` : ''} | |
</div> | |
`; | |
}; | |
const AccountMenu = () => { | |
const [channel, setChannel] = useState(null); | |
const accountLink = channel?.links?.find(({ type }) => type === 'MY_ACCOUNT')?.value; | |
const [account, setAccount] = useState(window.Storefront.getUser()); | |
const getChannelData = async () => { | |
const channelResponse = await window.Storefront.getChannel(); | |
setChannel(channelResponse); | |
}; | |
const handleSignOut = () => { | |
window.Storefront.signOut(); | |
setAccount(window.Storefront.getUser()); | |
}; | |
useEffect(() => { | |
getChannelData(); | |
}, []); | |
$('[data-toggle="tooltip"]').tooltip(); | |
if (account) { | |
return html` | |
<a data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |
<i class="fa fa-user-check"></i> | |
<br /> | |
<span class="hidden-xs account-link-label">${account.givenName}</span> | |
</a> | |
<ul class="dropdown-menu"> | |
<li> | |
<a href="${accountLink}/account/orders"> | |
{{"Mijn bestellingen"|t}} | |
</a> | |
</li> | |
<li> | |
<a href="${accountLink}/account/details"> | |
{{"Mijn gegevens"|t}} | |
</a> | |
</li> | |
<li> | |
<a href="${accountLink}/account/addresses"> | |
{{"Mijn adressen"|t}} | |
</a> | |
</li> | |
<li> | |
<a href="${accountLink}/account/preferences"> | |
{{"Mijn voorkeuren"|t}} | |
</a> | |
</li> | |
<li role="separator" class="divider" /> | |
<li> | |
<a onClick="${handleSignOut}">{{"Uitloggen"|t}}</a> | |
</li> | |
</ul> | |
`; | |
} | |
return html` | |
<a href="${accountLink}" data-toggle="tooltip" data-placement="bottom" title="Inloggen"> | |
<i class="fa fa-user-times"></i> | |
<br /> | |
<span class="hidden-xs account-link-label">{{"Inloggen"|t}}</span> | |
</a> | |
`; | |
}; | |
const setupStorefront = () => { | |
const client = createStorefrontClient({ | |
domain: window.location.host, | |
storefrontToken: '{{pluginData.orm.storefront}}', | |
graphQLClientOptions: { | |
headers: { | |
"Accept-Language": document.documentElement.lang, | |
} | |
} | |
}); | |
if (window.visitor_id) { | |
client.setSessionID(window.visitor_id); | |
} | |
const renderCartDrawer = () => { | |
if (document.getElementById('cart-drawer-container')) { | |
return render(html`<${CartDrawer} />`, document.getElementById('cart-drawer-container')); | |
} | |
console.warn('[Afosto Storefront] No element fount with id "cart-drawer-container" to mount the CartDrawer on. Add the id to an element or check your storefrontScripts.twig file.') | |
}; | |
const renderCartPage = () => { | |
if (document.getElementById('cart-container')) { | |
return render(html`<${CartPage} />`, document.getElementById('cart-container')); | |
} | |
console.warn('[Afosto Storefront] No element fount with id "cart-container" to mount the CartPage on. Add the id to an element or check your storefrontScripts.twig file.') | |
}; | |
const renderAccountMenu = () => { | |
if (document.getElementById('account-display')) { | |
return render(html`<${AccountMenu} />`, document.getElementById('account-display')); | |
} | |
console.warn('[Afosto Storefront] No element fount with id "account-display" to mount the AccountMenu on. Add the id to an element or check your storefrontScripts.twig file.') | |
}; | |
return { | |
...client, | |
client, | |
renderCartDrawer, | |
renderCartPage, | |
renderAccountMenu, | |
}; | |
}; | |
const afostoStorefront = setupStorefront(); | |
window.Storefront = afostoStorefront; | |
const initializeCart = async () => { | |
afostoStorefront.renderCartDrawer(); | |
afostoStorefront.renderAccountMenu(); | |
if ("{{ type }}" === 'cart') { | |
afostoStorefront.renderCartPage(); | |
} | |
}; | |
document.addEventListener("readystatechange", (event) => { | |
if (document.readyState === 'complete') { | |
initializeCart().catch(() => { | |
// Do nothing. | |
}) | |
} | |
}); | |
</script> | |
<div class="modal fade" tabindex="-1" role="dialog" id="share-cart-dialog"> | |
<div class="modal-dialog" role="document"> | |
<div class="modal-content"> | |
<div class="modal-header"> | |
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button> | |
<h4 class="modal-title">{{'Winkelwagen delen'|t}}</h4> | |
</div> | |
<div class="modal-body text-center"> | |
<div class="row"> | |
<div class="col-md-4 col-xs-3"> | |
<a class="text-black" href="https://www.facebook.com/sharer/sharer.php?u={url}&t=" rel="noopener noreferrer" target="_blank" title="{{"Share on Facebook"|t}}" > | |
<i class="fab fa-3x fa-facebook"></i> | |
</a> | |
</div> | |
<div class="col-md-4 visible-xs visible-sm col-xs-3"> | |
<a class="text-black" href="whatsapp://send?text={url}"> | |
<i class="fab fa-3x fa-whatsapp"></i> | |
</a> | |
</div> | |
<div class="col-md-4 col-xs-3"> | |
<a class="text-black" href="mailto:?subject=&body={url}" rel="noopener noreferrer" target="_self" title="{{"Send email"|t}}"> | |
<i class="fas fa-3x fa-envelope"></i> | |
</a> | |
</div> | |
</div> | |
</div> | |
<div class="modal-footer text-left"> | |
<p class="text-center"> | |
{{' Kopieer deze link om op je website te plaatsen of om te gebruiken in een bericht'|t}} | |
</p> | |
<div class="form-group"> | |
<div class="input-group"> | |
<input class="form-control" value="{url}" id="copy-cart-url-field" data-clipboard-text="{url}"> | |
<div class="input-group-btn"> | |
<button type="button" class="copy-to-clipboard btn btn-secondary" data-clipboard-target="#copy-cart-url-field" data-toggle="tooltip" data-placement="bottom" title="{{'Gekopieerd!'|t}}">{{'Kopieer'|t}}</button> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div><!-- /.modal-content --> | |
</div><!-- /.modal-dialog --> | |
</div><!-- /.modal --> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment