mirror of
https://github.com/pretix/pretix.git
synced 2026-05-08 15:44:02 +00:00
fix inconsistencies from automatic migration
This commit is contained in:
@@ -61,11 +61,8 @@ const waitingListUrl = computed(() => {
|
||||
if (store.subevent) {
|
||||
u += `&subevent=${store.subevent}`
|
||||
}
|
||||
const widgetDataJson = JSON.stringify(store.widgetData)
|
||||
u += `&widget_data=${encodeURIComponent(widgetDataJson)}`
|
||||
if (store.widgetData.consent) {
|
||||
u += `&consent=${encodeURIComponent(store.widgetData.consent)}`
|
||||
}
|
||||
u += `&widget_data=${encodeURIComponent(store.widgetDataJson)}`
|
||||
u += store.consentParameter
|
||||
return u
|
||||
})
|
||||
|
||||
|
||||
@@ -16,32 +16,6 @@ const formMethod = computed(() => {
|
||||
return 'post'
|
||||
})
|
||||
|
||||
const formAction = computed(() => store.getFormAction())
|
||||
|
||||
const formTarget = computed(() => {
|
||||
const isFirefox = navigator.userAgent.toLowerCase().includes('firefox')
|
||||
const isAndroid = navigator.userAgent.toLowerCase().includes('android')
|
||||
if (isAndroid && isFirefox) {
|
||||
return '_top'
|
||||
}
|
||||
return '_blank'
|
||||
})
|
||||
|
||||
const consentParameterValue = computed(() => {
|
||||
if (store.widgetData.consent) {
|
||||
return encodeURIComponent(store.widgetData.consent)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const widgetDataJson = computed(() => {
|
||||
const clonedData = { ...store.widgetData }
|
||||
if (clonedData.consent) {
|
||||
delete clonedData.consent
|
||||
}
|
||||
return JSON.stringify(clonedData)
|
||||
})
|
||||
|
||||
function handleBuy (event: Event) {
|
||||
if (form.value) {
|
||||
const formData = new FormData(form.value)
|
||||
@@ -57,13 +31,13 @@ defineExpose({
|
||||
<template lang="pug">
|
||||
.pretix-widget-wrapper
|
||||
.pretix-widget-button-container
|
||||
form(ref="form", :method="formMethod", :action="formAction", :target="formTarget")
|
||||
form(ref="form", :method="formMethod", :action="store.formAction", :target="store.formTarget")
|
||||
input(v-if="store.voucherCode", type="hidden", name="_voucher_code", :value="store.voucherCode")
|
||||
input(v-if="store.voucherCode", type="hidden", name="voucher", :value="store.voucherCode")
|
||||
input(type="hidden", name="subevent", :value="store.subevent")
|
||||
input(type="hidden", name="locale", :value="lang")
|
||||
input(type="hidden", name="widget_data", :value="widgetDataJson")
|
||||
input(v-if="consentParameterValue", type="hidden", name="consent", :value="consentParameterValue")
|
||||
input(type="hidden", name="widget_data", :value="store.widgetDataJson")
|
||||
input(v-if="store.consentParameterValue", type="hidden", name="consent", :value="store.consentParameterValue")
|
||||
input(
|
||||
v-for="item in store.items",
|
||||
:key="item.item",
|
||||
@@ -76,6 +50,5 @@ defineExpose({
|
||||
|
||||
Overlay
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -19,6 +19,5 @@ defineProps<{
|
||||
:category="category"
|
||||
)
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -16,6 +16,7 @@ const calendar = ref<HTMLDivElement>()
|
||||
const displayEventInfo = computed(() => store.displayEventInfo || (store.displayEventInfo === null && store.parentStack.length > 0))
|
||||
|
||||
const monthname = computed(() => {
|
||||
// TODO proper date formatting?
|
||||
if (!store.date) return ''
|
||||
const monthNum = store.date.substr(5, 2)
|
||||
const year = store.date.substr(0, 4)
|
||||
@@ -26,9 +27,8 @@ const id = computed(() => `${store.htmlId}-event-calendar-table`)
|
||||
|
||||
const ariaLabelledby = computed(() => `${store.htmlId}-event-calendar-table-label`)
|
||||
|
||||
const showFilters = computed(() => !store.disableFilters && store.metaFilterFields.length > 0)
|
||||
|
||||
function backToList () {
|
||||
// TODO should be in store
|
||||
store.weeks = null
|
||||
store.view = 'events'
|
||||
store.name = null
|
||||
@@ -63,7 +63,6 @@ function nextmonth () {
|
||||
store.reload({ focus: `#${id.value}` })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
.pretix-widget-event-calendar(ref="calendar")
|
||||
//- Back navigation
|
||||
@@ -80,7 +79,7 @@ function nextmonth () {
|
||||
)
|
||||
|
||||
//- Filter
|
||||
EventListFilterForm(v-if="showFilters")
|
||||
EventListFilterForm(v-if="!store.disableFilters && store.metaFilterFields.length > 0")
|
||||
|
||||
//- Calendar navigation
|
||||
.pretix-widget-event-calendar-head
|
||||
@@ -92,7 +91,7 @@ function nextmonth () {
|
||||
a.pretix-widget-event-calendar-next-month(href="#", @click.prevent.stop="nextmonth")
|
||||
| {{ STRINGS.next_month }} »
|
||||
|
||||
//- Calendar table
|
||||
//- Calendar
|
||||
table.pretix-widget-event-calendar-table(
|
||||
:id="id",
|
||||
tabindex="0",
|
||||
@@ -115,6 +114,5 @@ function nextmonth () {
|
||||
:mobile="mobile"
|
||||
)
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -26,9 +26,10 @@ const tabindex = computed(() => role.value === 'button' ? '0' : '-1')
|
||||
const classObject = computed(() => {
|
||||
const o: Record<string, boolean> = {}
|
||||
if (props.day && props.day.events.length > 0) {
|
||||
o['pretix-widget-has-events'] = true
|
||||
o['pretix-widget-has-events'] = true // TODO static
|
||||
let best = 'red'
|
||||
let allLow = true
|
||||
// TODO decopypasta
|
||||
for (const ev of props.day.events) {
|
||||
if (ev.availability.color === 'green') {
|
||||
best = 'green'
|
||||
@@ -47,11 +48,12 @@ const classObject = computed(() => {
|
||||
return o
|
||||
})
|
||||
|
||||
function selectDay(e: Event) {
|
||||
function selectDay (e: Event) {
|
||||
if (!props.day || !props.day.events.length || !props.mobile) return
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
// TODO decopypasta
|
||||
if (props.day.events.length === 1) {
|
||||
const ev = props.day.events[0]
|
||||
store.parentStack.push(store.targetUrl)
|
||||
@@ -66,22 +68,23 @@ function selectDay(e: Event) {
|
||||
}
|
||||
}
|
||||
|
||||
function onKeyDown(e: KeyboardEvent) {
|
||||
function onKeyDown (e: KeyboardEvent) {
|
||||
const keyDown = e.key ?? e.keyCode
|
||||
if (keyDown === 'Enter' || keyDown === 13 || ['Spacebar', ' '].includes(keyDown as string) || keyDown === 32) {
|
||||
// (prevent default so the page doesn't scroll when pressing space)
|
||||
e.preventDefault()
|
||||
selectDay(e)
|
||||
}
|
||||
}
|
||||
|
||||
function attachListeners() {
|
||||
function attachListeners () {
|
||||
if (role.value === 'button' && cellEl.value) {
|
||||
cellEl.value.addEventListener('click', selectDay)
|
||||
cellEl.value.addEventListener('keydown', onKeyDown)
|
||||
}
|
||||
}
|
||||
|
||||
function detachListeners() {
|
||||
function detachListeners () {
|
||||
if (cellEl.value) {
|
||||
cellEl.value.removeEventListener('click', selectDay)
|
||||
cellEl.value.removeEventListener('keydown', onKeyDown)
|
||||
@@ -92,6 +95,7 @@ onMounted(() => {
|
||||
attachListeners()
|
||||
})
|
||||
|
||||
// TODO why different from old version?
|
||||
watch(role, (newValue, oldValue) => {
|
||||
if (newValue === 'button' && oldValue !== 'button') {
|
||||
attachListeners()
|
||||
@@ -100,7 +104,6 @@ watch(role, (newValue, oldValue) => {
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
td(
|
||||
ref="cellEl",
|
||||
@@ -113,6 +116,5 @@ td(
|
||||
.pretix-widget-event-calendar-events(v-if="day")
|
||||
EventCalendarEvent(v-for="e in day.events", :key="e.event_url", :event="e")
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -21,7 +21,7 @@ const classObject = computed(() => {
|
||||
return o
|
||||
})
|
||||
|
||||
function select() {
|
||||
function select () {
|
||||
store.parentStack.push(store.targetUrl)
|
||||
store.targetUrl = props.event.event_url
|
||||
store.error = null
|
||||
@@ -30,18 +30,16 @@ function select() {
|
||||
store.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
a.pretix-widget-event-calendar-event(
|
||||
href="#",
|
||||
:class="classObject",
|
||||
@click.prevent.stop="select",
|
||||
:aria-describedby="describedby"
|
||||
:aria-describedby="describedby",
|
||||
@click.prevent.stop="select"
|
||||
)
|
||||
strong.pretix-widget-event-calendar-event-name {{ event.name }}
|
||||
.pretix-widget-event-calendar-event-date(v-if="!event.continued && event.time") {{ event.time }}
|
||||
.pretix-widget-event-calendar-event-availability(v-if="!event.continued && event.availability.text") {{ event.availability.text }}
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -7,11 +7,9 @@ defineProps<{
|
||||
mobile: boolean
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
tr
|
||||
EventCalendarCell(v-for="(d, idx) in week", :key="idx", :day="d", :mobile="mobile")
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -11,12 +11,9 @@ const voucherinput = ref<HTMLInputElement>()
|
||||
const isItemsSelected = ref(false)
|
||||
const localVoucher = ref('')
|
||||
|
||||
const displayEventInfo = computed(() => store.displayEventInfo || (store.displayEventInfo === null && (store.events || store.weeks || store.days)))
|
||||
|
||||
const idVoucherInput = computed(() => `${store.htmlId}-voucher-input`)
|
||||
|
||||
const ariaLabelledby = computed(() => `${store.htmlId}-voucher-headline`)
|
||||
|
||||
const displayEventInfo = computed(() => store.displayEventInfo || (store.displayEventInfo === null && (store.events || store.weeks || store.days)))
|
||||
const idCartExistsMsg = computed(() => `${store.htmlId}-cart-exists`)
|
||||
|
||||
const buyLabel = computed(() => {
|
||||
@@ -43,78 +40,16 @@ const hiddenParams = computed(() => {
|
||||
const params = new URL(store.getVoucherFormTarget()).searchParams
|
||||
params.delete('iframe')
|
||||
params.delete('take_cart_id')
|
||||
return Array.from(params.entries())
|
||||
return [...params.entries()]
|
||||
})
|
||||
|
||||
const showVoucherForm = computed(() => store.vouchersExist && !store.disableVouchers && !store.voucherCode)
|
||||
|
||||
const consentParameterValue = computed(() => {
|
||||
if (store.widgetData.consent) {
|
||||
return encodeURIComponent(store.widgetData.consent)
|
||||
}
|
||||
return ''
|
||||
})
|
||||
|
||||
const widgetDataJson = computed(() => {
|
||||
const clonedData = { ...store.widgetData }
|
||||
if (clonedData.consent) {
|
||||
delete clonedData.consent
|
||||
}
|
||||
return JSON.stringify(clonedData)
|
||||
})
|
||||
|
||||
const formAction = computed(() => {
|
||||
const additionalParams = getAdditionalURLParams()
|
||||
let checkoutUrl = `/${store.targetUrl.replace(/^[^\/]+:\/\/([^\/]+)\//, '')}w/${store.widgetId.replace('pretix-widget-', '')}/`
|
||||
if (!store.cartExists) {
|
||||
checkoutUrl += 'checkout/start'
|
||||
}
|
||||
if (additionalParams) {
|
||||
checkoutUrl += `?${additionalParams}`
|
||||
}
|
||||
|
||||
const cookieName = `pretix_widget_${store.targetUrl.replace(/[^a-zA-Z0-9]+/g, '_')}`
|
||||
const cartIdCookie = document.cookie
|
||||
.split('; ')
|
||||
.find((row) => row.startsWith(`${cookieName}=`))
|
||||
?.split('=')[1] || null
|
||||
|
||||
let formTarget = `${store.targetUrl}w/${store.widgetId.replace('pretix-widget-', '')}/cart/add?iframe=1&next=${encodeURIComponent(checkoutUrl)}`
|
||||
if (cartIdCookie) {
|
||||
formTarget += `&take_cart_id=${cartIdCookie}`
|
||||
}
|
||||
if (store.widgetData.consent) {
|
||||
formTarget += `&consent=${encodeURIComponent(store.widgetData.consent)}`
|
||||
}
|
||||
return formTarget
|
||||
})
|
||||
|
||||
const formTarget = computed(() => {
|
||||
const isFirefox = navigator.userAgent.toLowerCase().includes('firefox')
|
||||
const isAndroid = navigator.userAgent.toLowerCase().includes('android')
|
||||
if (isAndroid && isFirefox) {
|
||||
return '_top'
|
||||
}
|
||||
return '_blank'
|
||||
})
|
||||
|
||||
function getAdditionalURLParams (): string {
|
||||
if (!window.location.search.includes('utm_')) {
|
||||
return ''
|
||||
}
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
for (const [key] of params.entries()) {
|
||||
if (!key.startsWith('utm_')) {
|
||||
params.delete(key)
|
||||
}
|
||||
}
|
||||
return params.toString()
|
||||
}
|
||||
|
||||
function backToList () {
|
||||
store.targetUrl = store.parentStack.pop() || store.targetUrl
|
||||
store.error = null
|
||||
if (!store.subevent) {
|
||||
// reset if we are not in a series
|
||||
store.name = null
|
||||
store.frontpageText = null
|
||||
}
|
||||
@@ -123,13 +58,20 @@ function backToList () {
|
||||
store.appendEvents = false
|
||||
store.triggerLoadCallback()
|
||||
|
||||
if (store.events !== null) {
|
||||
if (store.events !== undefined && store.events !== null) {
|
||||
store.view = 'events'
|
||||
} else if (store.days !== null) {
|
||||
} else if (store.days !== undefined && store.days !== null) {
|
||||
store.view = 'days'
|
||||
} else {
|
||||
store.view = 'weeks'
|
||||
}
|
||||
|
||||
// TODO
|
||||
// let $el = this.$root.$el
|
||||
// this.$root.$nextTick(function () {
|
||||
// // wait for redraw, then focus content element for better a11y
|
||||
// $el.focus()
|
||||
// })
|
||||
}
|
||||
|
||||
function calcItemsSelected () {
|
||||
@@ -208,14 +150,14 @@ watch(() => store.overlay?.frameShown, (newValue) => {
|
||||
form(
|
||||
ref="form",
|
||||
method="post",
|
||||
:action="formAction",
|
||||
:target="formTarget",
|
||||
:action="store.formAction",
|
||||
:target="store.formTarget",
|
||||
@submit="handleBuy"
|
||||
)
|
||||
input(v-if="store.voucherCode", type="hidden", name="_voucher_code", :value="store.voucherCode")
|
||||
input(type="hidden", name="subevent", :value="store.subevent")
|
||||
input(type="hidden", name="widget_data", :value="widgetDataJson")
|
||||
input(v-if="consentParameterValue", type="hidden", name="consent", :value="consentParameterValue")
|
||||
input(type="hidden", name="widget_data", :value="store.widgetDataJson")
|
||||
input(v-if="store.consentParameterValue", type="hidden", name="consent", :value="store.consentParameterValue")
|
||||
|
||||
//- Error message
|
||||
.pretix-widget-error-message(v-if="store.error") {{ store.error }}
|
||||
@@ -242,7 +184,7 @@ watch(() => store.overlay?.frameShown, (newValue) => {
|
||||
| {{ STRINGS.waiting_list }}
|
||||
.pretix-widget-clear
|
||||
|
||||
//- Product list
|
||||
//- Actual Product list
|
||||
Category(v-for="category in store.categories", :key="category.id", :category="category")
|
||||
|
||||
//- Buy button
|
||||
@@ -293,6 +235,5 @@ watch(() => store.overlay?.frameShown, (newValue) => {
|
||||
button(@click="handleRedeem") {{ STRINGS.redeem }}
|
||||
.pretix-widget-clear
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -9,11 +9,12 @@ const store = inject(StoreKey)!
|
||||
|
||||
const displayEventInfo = computed(() => store.displayEventInfo || (store.displayEventInfo === null && store.parentStack.length > 0))
|
||||
|
||||
const showBackButton = computed(() => store.weeks || store.parentStack.length > 0)
|
||||
|
||||
const showFilters = computed(() => !store.disableFilters && store.metaFilterFields.length > 0)
|
||||
|
||||
function backToCalendar() {
|
||||
function backToCalendar () {
|
||||
// TODO
|
||||
// make sure to always focus content element
|
||||
// this.$nextTick(function () {
|
||||
// this.$root.$el.focus()
|
||||
// })
|
||||
store.offset = 0
|
||||
store.appendEvents = false
|
||||
|
||||
@@ -30,17 +31,16 @@ function backToCalendar() {
|
||||
}
|
||||
}
|
||||
|
||||
function loadMore() {
|
||||
function loadMore () {
|
||||
store.appendEvents = true
|
||||
store.offset += 50
|
||||
store.loading++
|
||||
store.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
.pretix-widget-event-list
|
||||
.pretix-widget-back(v-if="showBackButton")
|
||||
.pretix-widget-back(v-if="store.weeks || store.parentStack.length > 0")
|
||||
a(href="#", rel="prev", @click.prevent.stop="backToCalendar")
|
||||
| ‹ {{ STRINGS.back }}
|
||||
|
||||
@@ -52,7 +52,7 @@ function loadMore() {
|
||||
v-html="store.frontpageText"
|
||||
)
|
||||
|
||||
EventListFilterForm(v-if="showFilters")
|
||||
EventListFilterForm(v-if="!store.disableFilters && store.metaFilterFields.length > 0")
|
||||
|
||||
EventListEntry(
|
||||
v-for="event in store.events",
|
||||
@@ -63,6 +63,5 @@ function loadMore() {
|
||||
p.pretix-widget-event-list-load-more(v-if="store.hasMoreEvents")
|
||||
button(@click.prevent.stop="loadMore") {{ STRINGS.load_more }}
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -22,7 +22,7 @@ const classObject = computed(() => {
|
||||
|
||||
const location = computed(() => props.event.location.replace(/\s*\n\s*/g, ', '))
|
||||
|
||||
function select() {
|
||||
function select () {
|
||||
store.parentStack.push(store.targetUrl)
|
||||
store.targetUrl = props.event.event_url
|
||||
store.error = null
|
||||
@@ -31,15 +31,14 @@ function select() {
|
||||
store.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
a.pretix-widget-event-list-entry(href="#", :class="classObject", @click.prevent.stop="select")
|
||||
.pretix-widget-event-list-entry-name {{ event.name }}
|
||||
.pretix-widget-event-list-entry-date {{ event.date_range }}
|
||||
//- hidden by css for now, but used by a few people
|
||||
.pretix-widget-event-list-entry-location {{ location }}
|
||||
.pretix-widget-event-list-entry-availability
|
||||
span {{ event.availability.text }}
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -16,13 +16,11 @@ const currentValue = computed(() => {
|
||||
return filterParams.get(props.field.key) || ''
|
||||
})
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
.pretix-widget-event-list-filter-field
|
||||
label(:for="id") {{ field.label }}
|
||||
select(:id="id", :name="field.key", :value="currentValue")
|
||||
option(v-for="choice in field.choices", :key="choice[0]", :value="choice[0]") {{ choice[1] }}
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,7 @@ import EventListFilterField from './EventListFilterField.vue'
|
||||
const store = inject(StoreKey)!
|
||||
const filterform = ref<HTMLFormElement>()
|
||||
|
||||
function onSubmit(e: Event) {
|
||||
function onSubmit (e: Event) {
|
||||
e.preventDefault()
|
||||
if (!filterform.value) return
|
||||
|
||||
@@ -25,7 +25,6 @@ function onSubmit(e: Event) {
|
||||
store.reload()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
form.pretix-widget-event-list-filter-form(ref="filterform", @submit="onSubmit")
|
||||
fieldset.pretix-widget-event-list-filter-fieldset
|
||||
@@ -37,6 +36,5 @@ form.pretix-widget-event-list-filter-form(ref="filterform", @submit="onSubmit")
|
||||
)
|
||||
button {{ STRINGS.filter }}
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -24,16 +24,14 @@ const weekname = computed(() => {
|
||||
|
||||
const id = computed(() => `${store.htmlId}-event-week-table`)
|
||||
|
||||
const showFilters = computed(() => !store.disableFilters && store.metaFilterFields.length > 0)
|
||||
|
||||
function backToList() {
|
||||
function backToList () {
|
||||
store.weeks = null
|
||||
store.name = null
|
||||
store.frontpageText = null
|
||||
store.view = 'events'
|
||||
}
|
||||
|
||||
function prevweek() {
|
||||
function prevweek () {
|
||||
if (!store.week) return
|
||||
let curWeek = store.week[1]
|
||||
let curYear = store.week[0]
|
||||
@@ -47,7 +45,7 @@ function prevweek() {
|
||||
store.reload({ focus: `#${id.value}` })
|
||||
}
|
||||
|
||||
function nextweek() {
|
||||
function nextweek () {
|
||||
if (!store.week) return
|
||||
let curWeek = store.week[1]
|
||||
let curYear = store.week[0]
|
||||
@@ -61,12 +59,11 @@ function nextweek() {
|
||||
store.reload({ focus: `#${id.value}` })
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
.pretix-widget-event-calendar.pretix-widget-event-week-calendar(ref="weekcalendar")
|
||||
//- Back navigation
|
||||
.pretix-widget-back(v-if="store.events !== null")
|
||||
a(href="#", @click.prevent.stop="backToList", role="button")
|
||||
a(href="#", role="button", @click.prevent.stop="backToList")
|
||||
| ‹ {{ STRINGS.back }}
|
||||
|
||||
//- Event header
|
||||
@@ -74,7 +71,7 @@ function nextweek() {
|
||||
strong {{ store.name }}
|
||||
|
||||
//- Filter
|
||||
EventListFilterForm(v-if="showFilters")
|
||||
EventListFilterForm(v-if="!store.disableFilters && store.metaFilterFields.length > 0")
|
||||
|
||||
//- Calendar navigation
|
||||
.pretix-widget-event-description(
|
||||
@@ -82,12 +79,12 @@ function nextweek() {
|
||||
v-html="store.frontpageText"
|
||||
)
|
||||
.pretix-widget-event-calendar-head
|
||||
a.pretix-widget-event-calendar-previous-month(href="#", @click.prevent.stop="prevweek", role="button")
|
||||
a.pretix-widget-event-calendar-previous-month(href="#", role="button", @click.prevent.stop="prevweek")
|
||||
| « {{ STRINGS.previous_week }}
|
||||
|
|
||||
strong {{ weekname }}
|
||||
|
|
||||
a.pretix-widget-event-calendar-next-month(href="#", @click.prevent.stop="nextweek", role="button")
|
||||
a.pretix-widget-event-calendar-next-month(href="#", role="button", @click.prevent.stop="nextweek")
|
||||
| {{ STRINGS.next_week }} »
|
||||
|
||||
//- Actual calendar
|
||||
@@ -95,6 +92,5 @@ function nextweek() {
|
||||
.pretix-widget-event-week-col(v-for="d in store.days", :key="d?.date || ''")
|
||||
EventWeekCell(:day="d", :mobile="mobile")
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -6,7 +6,7 @@ import EventCalendarEvent from './EventCalendarEvent.vue'
|
||||
|
||||
const props = defineProps<{
|
||||
day: DayEntry | null
|
||||
mobile: boolean
|
||||
mobile: boolean // TODO inject?
|
||||
}>()
|
||||
|
||||
const store = inject(StoreKey)!
|
||||
@@ -47,6 +47,7 @@ function selectDay () {
|
||||
|
||||
if (props.day.events.length === 1) {
|
||||
const ev = props.day.events[0]
|
||||
// TODO store mutation bad
|
||||
store.parentStack.push(store.targetUrl)
|
||||
store.targetUrl = ev.event_url
|
||||
store.error = null
|
||||
@@ -59,7 +60,6 @@ function selectDay () {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template lang="pug">
|
||||
div(:class="classObject", @click.prevent.stop="selectDay")
|
||||
.pretix-widget-event-calendar-day(v-if="day", :id="id") {{ dayhead }}
|
||||
@@ -71,6 +71,5 @@ div(:class="classObject", @click.prevent.stop="selectDay")
|
||||
:describedby="id"
|
||||
)
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -69,8 +69,11 @@ function errorClose (e: Event) {
|
||||
store.overlay.errorUrlAfterNewTab = false
|
||||
}
|
||||
|
||||
function close () {
|
||||
function close (e) {
|
||||
if (store.overlay.frameLoading) {
|
||||
// Chrome does not allow blocking dialog.cancel event more than once
|
||||
// => wiggle the loading-element and re-open the modal
|
||||
cancel(e)
|
||||
frameDialog.value?.showModal()
|
||||
return
|
||||
}
|
||||
@@ -82,6 +85,7 @@ function close () {
|
||||
}
|
||||
|
||||
function cancel (e: Event) {
|
||||
// do not allow to cancel while frame is loading as we cannot abort the operation
|
||||
if (store.overlay.frameLoading) {
|
||||
e.preventDefault()
|
||||
const target = e.target as HTMLElement
|
||||
@@ -111,14 +115,14 @@ function triggerCloseCallback () {
|
||||
})
|
||||
}
|
||||
|
||||
// TODO check if watchEffect is better for the following watchers
|
||||
watch(() => store.overlay.lightbox, (newValue, oldValue) => {
|
||||
if (newValue) {
|
||||
if (newValue.image !== oldValue?.image) {
|
||||
newValue.loading = true
|
||||
}
|
||||
if (!oldValue) {
|
||||
lightboxDialog.value?.showModal()
|
||||
}
|
||||
if (!newValue) return
|
||||
if (newValue.image !== oldValue?.image) {
|
||||
newValue.loading = true
|
||||
}
|
||||
if (!oldValue) {
|
||||
lightboxDialog.value?.showModal()
|
||||
}
|
||||
})
|
||||
|
||||
@@ -128,19 +132,19 @@ watch(() => store.overlay.errorMessage, (newValue, oldValue) => {
|
||||
}
|
||||
})
|
||||
|
||||
watch(() => store.overlay.frameShown, (newValue) => {
|
||||
if (newValue) {
|
||||
nextTick(() => {
|
||||
closeButton.value?.focus()
|
||||
})
|
||||
}
|
||||
watch(() => store.overlay.frameShown, async (newValue) => {
|
||||
if (!newValue) return
|
||||
await nextTick()
|
||||
closeButton.value?.focus()
|
||||
})
|
||||
|
||||
watch(() => store.overlay.frameSrc, (newValue, oldValue) => {
|
||||
// show loading spinner only when previously no frame_src was set
|
||||
if (newValue && !oldValue) {
|
||||
store.overlay.frameLoading = true
|
||||
}
|
||||
if (iframe.value) {
|
||||
// to close and unload the iframe, frame_src can be empty -> make it valid HTML with about:blank
|
||||
iframe.value.src = newValue || 'about:blank'
|
||||
}
|
||||
})
|
||||
@@ -151,7 +155,7 @@ watch(() => store.overlay.frameLoading, (newValue) => {
|
||||
frameDialog.value.showModal()
|
||||
}
|
||||
} else {
|
||||
if (!store.overlay.frameSrc && frameDialog.value?.open) {
|
||||
if (!store.overlay.frameSrc && frameDialog.value?.open) { // finished loading, but no iframe to display => close
|
||||
frameDialog.value.close()
|
||||
}
|
||||
}
|
||||
@@ -169,7 +173,6 @@ onUnmounted(() => {
|
||||
<template lang="pug">
|
||||
Teleport(to="body")
|
||||
.pretix-widget-overlay
|
||||
//- Iframe dialog
|
||||
dialog(ref="frameDialog", :class="frameClasses", :aria-label="STRINGS.checkout", @close="close", @cancel="cancel")
|
||||
.pretix-widget-frame-loading(v-show="store.overlay.frameLoading")
|
||||
svg(width="256", height="256", viewBox="0 0 1792 1792", xmlns="http://www.w3.org/2000/svg")
|
||||
@@ -193,8 +196,6 @@ Teleport(to="body")
|
||||
referrerpolicy="origin",
|
||||
@load="iframeLoaded"
|
||||
) Please enable frames in your browser!
|
||||
|
||||
//- Alert dialog
|
||||
dialog(ref="alertDialog", :class="alertClasses", role="alertdialog", :aria-labelledby="errorMessageId", @close="errorClose")
|
||||
form.pretix-widget-alert-box(method="dialog")
|
||||
p(:id="errorMessageId") {{ store.overlay.errorMessage }}
|
||||
@@ -207,7 +208,6 @@ Teleport(to="body")
|
||||
path(style="fill:#ffffff;", d="M 599.86438,303.72882 H 1203.5254 V 1503.4576 H 599.86438 Z")
|
||||
path.pretix-widget-primary-color(d="M896 128q209 0 385.5 103t279.5 279.5 103 385.5-103 385.5-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103zm128 1247v-190q0-14-9-23.5t-22-9.5h-192q-13 0-23 10t-10 23v190q0 13 10 23t23 10h192q13 0 22-9.5t9-23.5zm-2-344l18-621q0-12-10-18-10-8-24-8h-220q-14 0-24 8-10 6-10 18l17 621q0 10 10 17.5t24 7.5h185q14 0 23.5-7.5t10.5-17.5z")
|
||||
|
||||
//- Lightbox dialog
|
||||
dialog(ref="lightboxDialog", :class="lightboxClasses", role="alertdialog", @close="lightboxClose")
|
||||
.pretix-widget-lightbox-loading(v-if="store.overlay.lightbox?.loading")
|
||||
svg(width="256", height="256", viewBox="0 0 1792 1792", xmlns="http://www.w3.org/2000/svg")
|
||||
@@ -227,6 +227,5 @@ Teleport(to="body")
|
||||
)
|
||||
figcaption(v-if="store.overlay.lightbox.description") {{ store.overlay.lightbox.description }}
|
||||
</template>
|
||||
|
||||
<style lang="sass">
|
||||
</style>
|
||||
|
||||
@@ -36,12 +36,14 @@ onMounted(() => {
|
||||
resizeObserver.observe(wrapper.value)
|
||||
}
|
||||
|
||||
store.reload()
|
||||
emit('mounted')
|
||||
store.reload() // TODO call earlier?
|
||||
emit('mounted') // TODO where does this go?
|
||||
})
|
||||
|
||||
watch(() => store.view, (newValue, oldValue) => {
|
||||
if (oldValue && wrapper.value) {
|
||||
// always make sure the widget is scrolled to the top
|
||||
// as we only check top, we do not need to wait for a redraw
|
||||
const rect = wrapper.value.getBoundingClientRect()
|
||||
if (rect.top < 0) {
|
||||
wrapper.value.scrollIntoView()
|
||||
|
||||
@@ -125,22 +125,23 @@ export function createWidgetStore (config: {
|
||||
if ((window as any).crossOriginIsolated === true) return false
|
||||
return !this.disableIframe && (this.skipSsl || /https.*/.test(document.location.protocol))
|
||||
},
|
||||
|
||||
cookieName (): string {
|
||||
return `pretix_widget_${this.targetUrl.replace(/[^a-zA-Z0-9]+/g, '_')}`
|
||||
},
|
||||
|
||||
cartIdFromCookie (): string | null {
|
||||
return getCookie(this.cookieName) ?? null
|
||||
},
|
||||
|
||||
widgetDataJson (): string {
|
||||
const cloned = { ...this.widgetData }
|
||||
delete cloned.consent
|
||||
return JSON.stringify(cloned)
|
||||
},
|
||||
consentParameter (): string {
|
||||
if (this.widgetData.consent) {
|
||||
return `&consent=${encodeURIComponent(this.widgetData.consent)}`
|
||||
}
|
||||
return ''
|
||||
},
|
||||
|
||||
additionalURLParams (): string {
|
||||
if (!window.location.search.includes('utm_')) {
|
||||
return ''
|
||||
@@ -153,12 +154,46 @@ export function createWidgetStore (config: {
|
||||
}
|
||||
return params.toString()
|
||||
},
|
||||
|
||||
newTabTarget (): string {
|
||||
return this.subevent ? `${this.targetUrl}${this.subevent}/` : this.targetUrl
|
||||
},
|
||||
},
|
||||
formTarget (): string {
|
||||
const isFirefox = navigator.userAgent.toLowerCase().includes('firefox')
|
||||
const isAndroid = navigator.userAgent.toLowerCase().includes('android')
|
||||
if (isAndroid && isFirefox) {
|
||||
return '_top'
|
||||
}
|
||||
return '_blank'
|
||||
},
|
||||
consentParameterValue (): string {
|
||||
if (this.widgetData.consent) {
|
||||
return encodeURIComponent(this.widgetData.consent)
|
||||
}
|
||||
return ''
|
||||
},
|
||||
formAction (): string {
|
||||
if (!this.useIframe && this.isButton && this.items.length === 0) {
|
||||
if (this.voucherCode) return `${this.targetUrl}redeem`
|
||||
if (this.subevent) return `${this.targetUrl}${this.subevent}/`
|
||||
return this.targetUrl
|
||||
}
|
||||
|
||||
let checkoutUrl = `/${this.targetUrl.replace(/^[^/]+:\/\/([^/]+)\//, '')}w/${globalWidgetId}/`
|
||||
if (!this.cartExists) {
|
||||
checkoutUrl += 'checkout/start'
|
||||
}
|
||||
if (this.additionalURLParams) {
|
||||
checkoutUrl += `?${this.additionalURLParams}`
|
||||
}
|
||||
|
||||
let formTarget = `${this.targetUrl}w/${globalWidgetId}/cart/add?iframe=1&next=${encodeURIComponent(checkoutUrl)}`
|
||||
if (this.cartIdFromCookie) {
|
||||
formTarget += `&take_cart_id=${this.cartIdFromCookie}`
|
||||
}
|
||||
formTarget += this.consentParameter
|
||||
return formTarget
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
triggerLoadCallback () {
|
||||
nextTick(() => {
|
||||
@@ -167,7 +202,6 @@ export function createWidgetStore (config: {
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
async reload (opt: { focus?: string } = {}) {
|
||||
if (this.isButton) return
|
||||
|
||||
@@ -303,28 +337,6 @@ export function createWidgetStore (config: {
|
||||
}
|
||||
}
|
||||
},
|
||||
getFormAction (): string {
|
||||
if (!this.useIframe && this.isButton && this.items.length === 0) {
|
||||
if (this.voucherCode) return `${this.targetUrl}redeem`
|
||||
if (this.subevent) return `${this.targetUrl}${this.subevent}/`
|
||||
return this.targetUrl
|
||||
}
|
||||
|
||||
let checkoutUrl = `/${this.targetUrl.replace(/^[^/]+:\/\/([^/]+)\//, '')}w/${globalWidgetId}/`
|
||||
if (!this.cartExists) {
|
||||
checkoutUrl += 'checkout/start'
|
||||
}
|
||||
if (this.additionalURLParams) {
|
||||
checkoutUrl += `?${this.additionalURLParams}`
|
||||
}
|
||||
|
||||
let formTarget = `${this.targetUrl}w/${globalWidgetId}/cart/add?iframe=1&next=${encodeURIComponent(checkoutUrl)}`
|
||||
if (this.cartIdFromCookie) {
|
||||
formTarget += `&take_cart_id=${this.cartIdFromCookie}`
|
||||
}
|
||||
formTarget += this.consentParameter
|
||||
return formTarget
|
||||
},
|
||||
getVoucherFormTarget (): string {
|
||||
let formTarget = `${this.targetUrl}w/${globalWidgetId}/redeem?iframe=1&locale=${LANG}`
|
||||
if (this.cartIdFromCookie) {
|
||||
@@ -334,7 +346,7 @@ export function createWidgetStore (config: {
|
||||
formTarget += `&subevent=${this.subevent}`
|
||||
}
|
||||
if (this.widgetData) {
|
||||
formTarget += `&widget_data=${encodeURIComponent(JSON.stringify(this.widgetData))}`
|
||||
formTarget += `&widget_data=${encodeURIComponent(this.widgetDataJson)}`
|
||||
}
|
||||
formTarget += this.consentParameter
|
||||
if (this.additionalURLParams) {
|
||||
@@ -349,12 +361,11 @@ export function createWidgetStore (config: {
|
||||
setCookie(this.cookieName, data.cart_id, 30)
|
||||
}
|
||||
|
||||
let redirectUrl = data.redirect
|
||||
if (redirectUrl.substring(0, 1) === '/') {
|
||||
redirectUrl = `${this.targetUrl.replace(/^([^/]+:\/\/[^/]+)\/.*$/, '$1')}${redirectUrl}`
|
||||
let url = data.redirect
|
||||
if (url.substring(0, 1) === '/') {
|
||||
url = `${this.targetUrl.replace(/^([^/]+:\/\/[^/]+)\/.*$/, '$1')}${url}`
|
||||
}
|
||||
|
||||
let url = redirectUrl
|
||||
if (url.includes('?')) {
|
||||
url = `${url}&iframe=1&locale=${LANG}&take_cart_id=${this.cartId}`
|
||||
} else {
|
||||
@@ -375,9 +386,11 @@ export function createWidgetStore (config: {
|
||||
} else {
|
||||
this.overlay.frameSrc = url
|
||||
}
|
||||
} else if (data.async_id && data.check_url) {
|
||||
} else {
|
||||
this.asyncTaskId = data.async_id
|
||||
this.asyncTaskCheckUrl = `${this.targetUrl.replace(/^([^/]+:\/\/[^/]+)\/.*$/, '$1')}${data.check_url}`
|
||||
if (data.check_url) {
|
||||
this.asyncTaskCheckUrl = `${this.targetUrl.replace(/^([^/]+:\/\/[^/]+)\/.*$/, '$1')}${data.check_url}`
|
||||
}
|
||||
this.asyncTaskTimeout = window.setTimeout(() => this.pollAsyncTask(), this.asyncTaskInterval)
|
||||
this.asyncTaskInterval = 250
|
||||
}
|
||||
@@ -397,11 +410,8 @@ export function createWidgetStore (config: {
|
||||
}
|
||||
},
|
||||
async buy (formData: FormData, event?: Event) {
|
||||
if (this.useIframe) {
|
||||
if (event) event.preventDefault()
|
||||
} else {
|
||||
return
|
||||
}
|
||||
if (!this.useIframe) return
|
||||
if (event) event.preventDefault()
|
||||
|
||||
if (this.isButton && this.items.length === 0) {
|
||||
if (this.voucherCode) {
|
||||
@@ -412,7 +422,7 @@ export function createWidgetStore (config: {
|
||||
return
|
||||
}
|
||||
|
||||
const url = `${this.getFormAction()}&locale=${LANG}&ajax=1`
|
||||
const url = `${this.formAction}&locale=${LANG}&ajax=1`
|
||||
this.overlay.frameLoading = true
|
||||
this.asyncTaskInterval = 100
|
||||
|
||||
@@ -427,25 +437,24 @@ export function createWidgetStore (config: {
|
||||
this.overlay.errorUrlAfter = this.newTabTarget
|
||||
this.overlay.errorUrlAfterNewTab = true
|
||||
} else if (e.status === 405) {
|
||||
// Likely a redirect!
|
||||
this.targetUrl = e.responseUrl.substring(0, e.responseUrl.indexOf('/cart/add') - 18)
|
||||
this.overlay.frameLoading = false
|
||||
} else {
|
||||
this.overlay.errorMessage = STRINGS.cart_error
|
||||
this.overlay.frameLoading = false
|
||||
this.buy(formData)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
this.overlay.errorMessage = STRINGS.cart_error
|
||||
this.overlay.frameLoading = false
|
||||
}
|
||||
this.overlay.errorMessage = STRINGS.cart_error
|
||||
this.overlay.frameLoading = false
|
||||
}
|
||||
},
|
||||
redeem (voucherCode: string, event?: Event) {
|
||||
if (this.useIframe) {
|
||||
if (event) event.preventDefault()
|
||||
this.voucherOpen(voucherCode)
|
||||
}
|
||||
if (!this.useIframe) return
|
||||
if (event) event.preventDefault()
|
||||
this.voucherOpen(voucherCode)
|
||||
},
|
||||
voucherOpen (voucherCode: string) {
|
||||
// TODO just use https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams
|
||||
const redirectUrl = `${this.getVoucherFormTarget()}&voucher=${encodeURIComponent(voucherCode)}`
|
||||
if (this.useIframe) {
|
||||
this.overlay.frameSrc = redirectUrl
|
||||
@@ -456,6 +465,7 @@ export function createWidgetStore (config: {
|
||||
resume () {
|
||||
let redirectUrl = `${this.targetUrl}w/${globalWidgetId}/`
|
||||
if (this.subevent && !this.cartId) {
|
||||
// button with subevent but no items
|
||||
redirectUrl += `${this.subevent}/`
|
||||
}
|
||||
redirectUrl += `?iframe=1&locale=${LANG}`
|
||||
@@ -463,7 +473,7 @@ export function createWidgetStore (config: {
|
||||
redirectUrl += `&take_cart_id=${this.cartId}`
|
||||
}
|
||||
if (this.widgetData) {
|
||||
redirectUrl += `&widget_data=${encodeURIComponent(JSON.stringify(this.widgetData))}`
|
||||
redirectUrl += `&widget_data=${encodeURIComponent(this.widgetDataJson)}`
|
||||
}
|
||||
redirectUrl += this.consentParameter
|
||||
if (this.additionalURLParams) {
|
||||
@@ -502,7 +512,7 @@ export function createWidgetStore (config: {
|
||||
redirectUrl += `&take_cart_id=${this.cartId}`
|
||||
}
|
||||
if (this.widgetData) {
|
||||
redirectUrl += `&widget_data=${encodeURIComponent(JSON.stringify(this.widgetData))}`
|
||||
redirectUrl += `&widget_data=${encodeURIComponent(this.widgetDataJson)}`
|
||||
}
|
||||
redirectUrl += this.consentParameter
|
||||
if (this.additionalURLParams) {
|
||||
|
||||
Reference in New Issue
Block a user