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
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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'
|
2021-11-10 22:47:05 +00:00
|
|
|
let notify = true
|
2021-06-01 21:33:49 +00:00
|
|
|
|
2021-10-28 17:59:19 +00:00
|
|
|
const site = window.site
|
2021-11-10 22:47:05 +00:00
|
|
|
const fail = response.fail()
|
2021-06-01 21:33:49 +00:00
|
|
|
|
2021-11-10 22:47:05 +00:00
|
|
|
switch (fail.name) {
|
2021-06-01 21:33:49 +00:00
|
|
|
case 'MisconfigurationError':
|
2021-11-10 22:47:05 +00:00
|
|
|
data.content = fail.message
|
2021-06-01 21:33:49 +00:00
|
|
|
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
|
2021-11-10 22:47:05 +00:00
|
|
|
if (fail.serverResponse.status === 404) {
|
2021-06-01 21:33:49 +00:00
|
|
|
template = 'recover_order'
|
|
|
|
data.content = site.i18n.alerts.recover_order
|
|
|
|
} else {
|
|
|
|
data.content = response.fail().summary
|
|
|
|
}
|
|
|
|
|
|
|
|
break
|
|
|
|
case 'ExpandedSpreeError':
|
2021-11-10 22:47:05 +00:00
|
|
|
const content = []
|
|
|
|
// XXX: La API devuelve los mensajes de error tal cual en la
|
|
|
|
// llave `error` pero el cliente solo nos da acceso a `errors`.
|
|
|
|
for (const field of Object.keys(fail.errors)) {
|
|
|
|
if (!site.i18n.errors?.fields[field]) {
|
|
|
|
console.error('El campo no tiene traducción', field)
|
|
|
|
}
|
|
|
|
|
|
|
|
content.push(`${site.i18n.errors?.fields[field]}: ${fail.errors[field].join(', ')}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
data.content = content.join('. ')
|
|
|
|
notify = false
|
2021-06-01 21:33:49 +00:00
|
|
|
|
|
|
|
break
|
|
|
|
default:
|
2021-11-10 22:47:05 +00:00
|
|
|
data.content = fail.message
|
2021-06-01 21:33:49 +00:00
|
|
|
}
|
|
|
|
|
2021-11-10 22:47:05 +00:00
|
|
|
if (notify) console.error(fail.name, data.content)
|
2021-06-01 21:33:49 +00:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|