sutty-base-jekyll-theme/_packs/controllers/cart_base_controller.js

250 lines
5.4 KiB
JavaScript
Raw Normal View History

2021-06-01 21:33:49 +00:00
import { Controller } from 'stimulus'
import { Liquid } from 'liquidjs'
/*
* Base controller, shared methods go here and other classes extend from
* this.
*/
export class CartBaseController extends Controller {
get spree () {
return window.spree
}
/*
* Gets all products from storage
*
* @return [Array]
*/
get products () {
if (!this.cart) return []
return this.cart.data.relationships.variants.data.map(x => JSON.parse(this.storage.getItem(`cart:item:${x.id}`))).filter(x => x !== null)
}
/*
* The storage
*/
get storage () {
return window.localStorage
}
/*
* Temporary storage
*/
get storageTemp () {
return window.sessionStorage
}
get cart () {
return JSON.parse(this.storage.getItem('cart'))
}
set cart (response) {
this.storage.setItem('cart', JSON.stringify(response.success()))
}
get email () {
return this.storageTemp.getItem('email')
}
set email (email) {
this.storageTemp.setItem('email', email)
}
/*
* The orderToken
*
* @return [String]
*/
get token () {
return this.storage.getItem('token')
}
/*
* The bearerToken
*
* @return [String]
*/
get bearerToken () {
return this.storageTemp.getItem('bearerToken')
}
set bearerToken (token) {
this.storageTemp.setItem('bearerToken', token)
}
/*
* Liquid renderer
*
* @return Liquid
*/
get engine () {
if (!window.liquid) window.liquid = new Liquid()
return window.liquid
}
/*
* Site config (actually just translation strings)
*
* @return [Object]
*/
async site () {
if (!window.site) {
const data = await fetch('assets/data/site.json')
window.site = await data.json()
}
return window.site
}
/*
* Updates the item counter
*/
counterUpdate () {
const item_count = this.cart.data.attributes.item_count
window.dispatchEvent(new CustomEvent('cart:counter', { detail: { item_count }}))
this.storage.setItem('cart:counter', item_count)
}
/*
* Removes the brackets from the name or returns the name
*
* @return [String]
*/
idFromInputName (input) {
const matches = input.name.match(/\[([^\]]+)\]$/)
return (matches === null) ? input.name : matches[1]
}
async handleFailure (response) {
const data = { type: 'primary' }
let template = 'alert'
console.error(response.fail())
2021-06-01 21:33:49 +00:00
const site = await this.site()
switch (response.fail().name) {
case 'MisconfigurationError':
data.content = response.fail().message
break
case 'NoResponseError':
data.content = site.i18n.alerts.no_response_error
break
case 'SpreeError':
data.content = site.i18n.alerts.spree_error
break
case 'BasicSpreeError':
// XXX: The order is missing, we need to start a new one
if (response.fail().serverResponse.status === 404) {
template = 'recover_order'
data.content = site.i18n.alerts.recover_order
} else {
data.content = response.fail().summary
}
break
case 'ExpandedSpreeError':
data.content = response.fail().summary
break
default:
data.content = response.fail().message
}
console.error(response.fail().name, data.content)
window.dispatchEvent(new CustomEvent('notification', { detail: { template, data } }))
}
set formDisabled (state) {
if (!this.hasFormTarget) return
this.formTarget.elements.forEach(x => x.disabled = !!state)
}
assignShippingAddress () {
if (!this.bearerToken) return
const bearerToken = this.bearerToken
const orderToken = this.token
this.spree.sutty.assignOrderShippingAddress({ bearerToken }, { orderToken })
}
notify (data = {}) {
window.dispatchEvent(new CustomEvent('notification', { detail: { template: 'alert', data } }))
}
/*
* Visita una página con soporte para Turbolinks
*
* @param [String] URL
*/
visit (url) {
try {
Turbolinks.visit(url)
} catch {
window.location = url
}
}
async firstAddress (bearerToken) {
if (!this._firstAddress) {
const addresses = await this.spree.account.addressesList({ bearerToken })
if (addresses.isFail()) {
this.handleFailure(addresses)
return
}
// XXX: Asumimos que si se registró tiene una dirección que vamos
// a actualizar.
this._firstAddress = addresses.success().data[0]
}
return this._firstAddress
}
async updateAddress(bearerToken, id, address) {
const updateAddress = await this.spree.account.updateAddress({ bearerToken }, id, { address })
if (updateAddress.isFail()) {
this.handleFailure(updateAddress)
return
}
return updateAddress.success()
}
async shippingMethods(orderToken) {
const shippingMethods = await this.spree.checkout.shippingMethods({ orderToken }, { include: 'shipping_rates' })
if (shippingMethods.isFail()) {
this.handleFailure(shippingMethods)
return
}
return shippingMethods.success()
}
fireCajon (state = 'open', cajon = 'cajon') {
window.dispatchEvent(new CustomEvent('cajon', { detail: { cajon, state }}))
}
formDataToObject (formData) {
const object = {}
for (const field of formData) {
if (field[0].startsWith('_ignore_')) continue
object[field[0]] = field[1]
}
return object
}
}