From 3751379f1e9a4c215fb6eb898b4ccc67659b9ace Mon Sep 17 00:00:00 2001 From: stephanchrst Date: Tue, 10 May 2022 21:51:50 +0700 Subject: initial commit 2 --- addons/website_event/static/description/icon.png | Bin 0 -> 10337 bytes addons/website_event/static/description/icon.svg | 1 + .../website_event/static/src/img/event_cover_0.jpg | Bin 0 -> 253769 bytes .../website_event/static/src/img/event_cover_1.jpg | Bin 0 -> 83045 bytes .../website_event/static/src/img/event_cover_2.jpg | Bin 0 -> 179264 bytes .../website_event/static/src/img/event_cover_3.jpg | Bin 0 -> 219399 bytes .../website_event/static/src/img/event_cover_4.jpg | Bin 0 -> 218507 bytes .../website_event/static/src/img/event_cover_5.jpg | Bin 0 -> 153787 bytes .../website_event/static/src/img/event_cover_7.jpg | Bin 0 -> 63219 bytes .../website_event/static/src/img/event_past_0.jpg | Bin 0 -> 321421 bytes .../static/src/img/event_training_0.jpg | Bin 0 -> 267426 bytes .../src/img/openerp_enterprise_of_the_year.png | Bin 0 -> 22408 bytes .../src/img/snippets_thumbs/s_country_events.svg | 52 +++++ .../src/img/snippets_thumbs/s_speaker_bio.svg | 62 +++++ addons/website_event/static/src/img/speaker.png | Bin 0 -> 2215 bytes addons/website_event/static/src/img/training.jpg | Bin 0 -> 48464 bytes .../static/src/js/display_timer_widget.js | 111 +++++++++ .../static/src/js/register_toaster_widget.js | 31 +++ .../static/src/js/tours/event_tour.js | 61 +++++ .../static/src/js/tours/website_event.js | 49 ++++ .../static/src/js/website_event.editor.js | 49 ++++ .../website_event/static/src/js/website_event.js | 93 ++++++++ .../src/js/website_event_set_customize_options.js | 122 ++++++++++ .../static/src/js/website_event_ticket_details.js | 55 +++++ .../static/src/js/website_geolocation.js | 41 ++++ .../static/src/scss/website_event.scss | 254 +++++++++++++++++++++ .../static/src/scss/website_event_templates.scss | 161 +++++++++++++ .../static/src/xml/customize_options.xml | 15 ++ 28 files changed, 1157 insertions(+) create mode 100644 addons/website_event/static/description/icon.png create mode 100644 addons/website_event/static/description/icon.svg create mode 100644 addons/website_event/static/src/img/event_cover_0.jpg create mode 100644 addons/website_event/static/src/img/event_cover_1.jpg create mode 100644 addons/website_event/static/src/img/event_cover_2.jpg create mode 100644 addons/website_event/static/src/img/event_cover_3.jpg create mode 100644 addons/website_event/static/src/img/event_cover_4.jpg create mode 100644 addons/website_event/static/src/img/event_cover_5.jpg create mode 100644 addons/website_event/static/src/img/event_cover_7.jpg create mode 100644 addons/website_event/static/src/img/event_past_0.jpg create mode 100644 addons/website_event/static/src/img/event_training_0.jpg create mode 100644 addons/website_event/static/src/img/openerp_enterprise_of_the_year.png create mode 100644 addons/website_event/static/src/img/snippets_thumbs/s_country_events.svg create mode 100644 addons/website_event/static/src/img/snippets_thumbs/s_speaker_bio.svg create mode 100644 addons/website_event/static/src/img/speaker.png create mode 100644 addons/website_event/static/src/img/training.jpg create mode 100644 addons/website_event/static/src/js/display_timer_widget.js create mode 100644 addons/website_event/static/src/js/register_toaster_widget.js create mode 100644 addons/website_event/static/src/js/tours/event_tour.js create mode 100644 addons/website_event/static/src/js/tours/website_event.js create mode 100644 addons/website_event/static/src/js/website_event.editor.js create mode 100644 addons/website_event/static/src/js/website_event.js create mode 100644 addons/website_event/static/src/js/website_event_set_customize_options.js create mode 100644 addons/website_event/static/src/js/website_event_ticket_details.js create mode 100644 addons/website_event/static/src/js/website_geolocation.js create mode 100644 addons/website_event/static/src/scss/website_event.scss create mode 100644 addons/website_event/static/src/scss/website_event_templates.scss create mode 100644 addons/website_event/static/src/xml/customize_options.xml (limited to 'addons/website_event/static') diff --git a/addons/website_event/static/description/icon.png b/addons/website_event/static/description/icon.png new file mode 100644 index 00000000..6d64c761 Binary files /dev/null and b/addons/website_event/static/description/icon.png differ diff --git a/addons/website_event/static/description/icon.svg b/addons/website_event/static/description/icon.svg new file mode 100644 index 00000000..b3f72c43 --- /dev/null +++ b/addons/website_event/static/description/icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/addons/website_event/static/src/img/event_cover_0.jpg b/addons/website_event/static/src/img/event_cover_0.jpg new file mode 100644 index 00000000..c77c47f2 Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_0.jpg differ diff --git a/addons/website_event/static/src/img/event_cover_1.jpg b/addons/website_event/static/src/img/event_cover_1.jpg new file mode 100644 index 00000000..0dc8960e Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_1.jpg differ diff --git a/addons/website_event/static/src/img/event_cover_2.jpg b/addons/website_event/static/src/img/event_cover_2.jpg new file mode 100644 index 00000000..6fda12d4 Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_2.jpg differ diff --git a/addons/website_event/static/src/img/event_cover_3.jpg b/addons/website_event/static/src/img/event_cover_3.jpg new file mode 100644 index 00000000..4ccf99f2 Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_3.jpg differ diff --git a/addons/website_event/static/src/img/event_cover_4.jpg b/addons/website_event/static/src/img/event_cover_4.jpg new file mode 100644 index 00000000..157a101a Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_4.jpg differ diff --git a/addons/website_event/static/src/img/event_cover_5.jpg b/addons/website_event/static/src/img/event_cover_5.jpg new file mode 100644 index 00000000..89070a4f Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_5.jpg differ diff --git a/addons/website_event/static/src/img/event_cover_7.jpg b/addons/website_event/static/src/img/event_cover_7.jpg new file mode 100644 index 00000000..9914bdf2 Binary files /dev/null and b/addons/website_event/static/src/img/event_cover_7.jpg differ diff --git a/addons/website_event/static/src/img/event_past_0.jpg b/addons/website_event/static/src/img/event_past_0.jpg new file mode 100644 index 00000000..0c070fbe Binary files /dev/null and b/addons/website_event/static/src/img/event_past_0.jpg differ diff --git a/addons/website_event/static/src/img/event_training_0.jpg b/addons/website_event/static/src/img/event_training_0.jpg new file mode 100644 index 00000000..2a2897f8 Binary files /dev/null and b/addons/website_event/static/src/img/event_training_0.jpg differ diff --git a/addons/website_event/static/src/img/openerp_enterprise_of_the_year.png b/addons/website_event/static/src/img/openerp_enterprise_of_the_year.png new file mode 100644 index 00000000..71d8f5b5 Binary files /dev/null and b/addons/website_event/static/src/img/openerp_enterprise_of_the_year.png differ diff --git a/addons/website_event/static/src/img/snippets_thumbs/s_country_events.svg b/addons/website_event/static/src/img/snippets_thumbs/s_country_events.svg new file mode 100644 index 00000000..d8eb58a0 --- /dev/null +++ b/addons/website_event/static/src/img/snippets_thumbs/s_country_events.svg @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/website_event/static/src/img/snippets_thumbs/s_speaker_bio.svg b/addons/website_event/static/src/img/snippets_thumbs/s_speaker_bio.svg new file mode 100644 index 00000000..7bc92057 --- /dev/null +++ b/addons/website_event/static/src/img/snippets_thumbs/s_speaker_bio.svg @@ -0,0 +1,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/website_event/static/src/img/speaker.png b/addons/website_event/static/src/img/speaker.png new file mode 100644 index 00000000..b1921736 Binary files /dev/null and b/addons/website_event/static/src/img/speaker.png differ diff --git a/addons/website_event/static/src/img/training.jpg b/addons/website_event/static/src/img/training.jpg new file mode 100644 index 00000000..05ab1082 Binary files /dev/null and b/addons/website_event/static/src/img/training.jpg differ diff --git a/addons/website_event/static/src/js/display_timer_widget.js b/addons/website_event/static/src/js/display_timer_widget.js new file mode 100644 index 00000000..5f612736 --- /dev/null +++ b/addons/website_event/static/src/js/display_timer_widget.js @@ -0,0 +1,111 @@ +odoo.define('website_event.display_timer_widget', function (require) { +'use strict'; + +var core = require('web.core'); +var _t = core._t; +var publicWidget = require('web.public.widget'); + +publicWidget.registry.displayTimerWidget = publicWidget.Widget.extend({ + selector: '.o_display_timer', + + /** + * This widget allows to display a dom element at the end of a certain time laps. + * There are 2 timers available: + * - The main-timer: display the DOM element (using the displayClass) at the end of this timer. + * - The pre-timer: additional timer to display the main-timer. This pre-timer can be invisible or visible, + * depending of the startCountdownDisplay option. Once the pre-timer is over, + the main-timer is displayed. + * @override + */ + start: function () { + var self = this; + return this._super.apply(this, arguments).then(function () { + self.options = self.$target.data(); + self.preCountdownDisplay = self.options["preCountdownDisplay"]; + self.preCountdownTime = self.options["preCountdownTime"]; + self.preCountdownText = self.options["preCountdownText"]; + + self.mainCountdownTime = self.options["mainCountdownTime"]; + self.mainCountdownText = self.options["mainCountdownText"]; + self.mainCountdownDisplay = self.options["mainCountdownDisplay"]; + + self.displayClass = self.options["displayClass"]; + + if (self.preCountdownDisplay) { + $(self.$el).parent().removeClass('d-none'); + } + + self._checkTimer(); + self.interval = setInterval(function () { self._checkTimer(); }, 1000); + }); + }, + + /** + * This method removes 1 second to the current timer (pre-timer or main-timer) + * and call the method to update the DOM, unless main-timer is over. In that last case, + * the DOM element to show is displayed. + * + * @private + */ + _checkTimer: function () { + var now = new Date(); + + var remainingPreSeconds = this.preCountdownTime - (now.getTime()/1000); + if (remainingPreSeconds <= 1) { + this.$('.o_countdown_text').text(this.mainCountdownText); + if (this.mainCountdownDisplay) { + $(this.$el).parent().removeClass('d-none'); + } + var remainingMainSeconds = this.mainCountdownTime - (now.getTime()/1000); + if (remainingMainSeconds <= 1) { + clearInterval(this.interval); + $(this.displayClass).removeClass('d-none'); + $(this.$el).parent().addClass('d-none'); + } else { + this._updateCountdown(remainingMainSeconds); + } + } else { + this._updateCountdown(remainingPreSeconds); + } + }, + + /** + * This method update the DOM to display the remaining time. + * from seconds, the method extract the number of days, hours, minutes and seconds and + * override the different DOM elements values. + * + * @private + */ + _updateCountdown: function (remainingTime) { + var remainingSeconds = remainingTime; + var days = Math.floor(remainingSeconds / 86400); + + remainingSeconds = remainingSeconds % 86400; + var hours = Math.floor(remainingSeconds / 3600); + + remainingSeconds = remainingSeconds % 3600; + var minutes = Math.floor(remainingSeconds / 60); + + remainingSeconds = Math.floor(remainingSeconds % 60); + + this.$("span.o_timer_days").text(days); + this.$("span.o_timer_hours").text(this._zeroPad(hours, 2)); + this.$("span.o_timer_minutes").text(this._zeroPad(minutes, 2)); + this.$("span.o_timer_seconds").text(this._zeroPad(remainingSeconds, 2)); + }, + + /** + * Small tool to add leading zéros to the given number, in function of the needed number of leading zéros. + * + * @private + */ + _zeroPad: function (num, places) { + var zero = places - num.toString().length + 1; + return new Array(+(zero > 0 && zero)).join("0") + num; + }, + +}); + +return publicWidget.registry.countdownWidget; + +}); diff --git a/addons/website_event/static/src/js/register_toaster_widget.js b/addons/website_event/static/src/js/register_toaster_widget.js new file mode 100644 index 00000000..891f6155 --- /dev/null +++ b/addons/website_event/static/src/js/register_toaster_widget.js @@ -0,0 +1,31 @@ +odoo.define('website_event.register_toaster_widget', function (require) { +'use strict'; + +let core = require('web.core'); +let _t = core._t; +let publicWidget = require('web.public.widget'); + +publicWidget.registry.RegisterToasterWidget = publicWidget.Widget.extend({ + selector: '.o_wevent_register_toaster', + + /** + * This widget allows to display a toast message on the page. + * + * @override + */ + start: function () { + const message = this.$el.data('message'); + if (message && message.length) { + this.displayNotification({ + title: _t("Register"), + message: message, + type: 'info' + }); + } + return this._super.apply(this, arguments); + }, +}); + +return publicWidget.registry.RegisterToasterWidget; + +}); diff --git a/addons/website_event/static/src/js/tours/event_tour.js b/addons/website_event/static/src/js/tours/event_tour.js new file mode 100644 index 00000000..421146c1 --- /dev/null +++ b/addons/website_event/static/src/js/tours/event_tour.js @@ -0,0 +1,61 @@ +odoo.define('website_event.event_steps', function (require) { +"use strict"; + +var core = require('web.core'); +var _t = core._t; + +var EventAdditionalTourSteps = require('event.event_steps'); + +EventAdditionalTourSteps.include({ + + init: function() { + this._super.apply(this, arguments); + }, + + _get_website_event_steps: function () { + this._super.apply(this, arguments); + return [{ + trigger: '.o_event_form_view button[name="is_published"]', + content: _t("Use this shortcut to easily access your event web page."), + position: 'bottom', + }, { + trigger: 'li#edit-page-menu a', + extra_trigger: '.o_wevent_event', + content: _t("With the Edit button, you can customize the web page visitors will see when registering."), + position: 'bottom', + }, { + trigger: 'div[name="Image - Text"] .oe_snippet_thumbnail', + extra_trigger: '.o_wevent_event', + content: _t("Drag and Drop this snippet below the event title."), + position: 'bottom', + run: 'drag_and_drop #o_wevent_event_main_col', + }, { + trigger: 'button[data-action="save"]', + extra_trigger: '.o_wevent_event', + content: _t("Don't forget to click save when you're done."), + position: 'bottom', + }, { + trigger: 'label.js_publish_btn', + extra_trigger: '.o_wevent_event', + content: _t("Looking great! Let's now publish this page so that it becomes visible on your website!"), + position: 'bottom', + }, { + trigger: 'a.css_edit_dynamic', + extra_trigger: '.js_publish_management[data-object="event.event"] .js_publish_btn .css_unpublish:visible', + content: _t("Want to change your event configuration? Let's go back to the event form."), + position: 'bottom', + run: function (actions) { + actions.click('div.dropdown-menu a#edit-in-backend'); + }, + }, { + trigger: 'a#edit-in-backend', + extra_trigger: '.o_wevent_event', + content: _t("This shortcut will bring you right back to the event form."), + position: 'bottom' + }]; + } +}); + +return EventAdditionalTourSteps; + +}); diff --git a/addons/website_event/static/src/js/tours/website_event.js b/addons/website_event/static/src/js/tours/website_event.js new file mode 100644 index 00000000..b07c83a3 --- /dev/null +++ b/addons/website_event/static/src/js/tours/website_event.js @@ -0,0 +1,49 @@ +odoo.define("website_event.tour", function (require) { + "use strict"; + + var core = require("web.core"); + var tour = require("web_tour.tour"); + + var _t = core._t; + + tour.register("event", { + url: "/", + }, [{ + content: _t("Click here to add new content to your website."), + trigger: '#new-content-menu > a', + position: 'bottom', + }, { + trigger: "a[data-action=new_event]", + content: _t("Click here to create a new event."), + position: "bottom", + }, { + trigger: '.modal-dialog #editor_new_event input[type=text]', + content: _t("Create a name for your new event and click \"Continue\". e.g: Technical Training"), + position: "left", + }, { + trigger: '.modal-footer button.btn-primary.btn-continue', + extra_trigger: '#editor_new_event input[type=text][value!=""]', + content: _t("Click Continue to create the event."), + position: "right", + }, { + trigger: "#snippet_structure .oe_snippet:eq(2) .oe_snippet_thumbnail", + content: _t("Drag this block and drop it in your page."), + position: "bottom", + run: "drag_and_drop", + }, { + trigger: "button[data-action=save]", + content: _t("Once you click on save, your event is updated."), + position: "bottom", + extra_trigger: ".o_dirty", + }, { + trigger: ".js_publish_management .js_publish_btn", + extra_trigger: "body:not(.editor_enable)", + content: _t("Click to publish your event."), + position: "top", + }, { + trigger: ".css_edit_dynamic", + extra_trigger: ".js_publish_management .js_publish_btn .css_unpublish:visible", + content: _t("Click here to customize your event further."), + position: "bottom", + }]); +}); diff --git a/addons/website_event/static/src/js/website_event.editor.js b/addons/website_event/static/src/js/website_event.editor.js new file mode 100644 index 00000000..48f3a995 --- /dev/null +++ b/addons/website_event/static/src/js/website_event.editor.js @@ -0,0 +1,49 @@ +odoo.define('website_event.editor', function (require) { +"use strict"; + +var core = require('web.core'); +var wUtils = require('website.utils'); +var WebsiteNewMenu = require('website.newMenu'); + +var _t = core._t; + +WebsiteNewMenu.include({ + actions: _.extend({}, WebsiteNewMenu.prototype.actions || {}, { + new_event: '_createNewEvent', + }), + + //-------------------------------------------------------------------------- + // Actions + //-------------------------------------------------------------------------- + + /** + * Asks the user information about a new event to create, then creates it + * and redirects the user to this new event. + * + * @private + * @returns {Promise} Unresolved if there is a redirection + */ + _createNewEvent: function () { + var self = this; + return wUtils.prompt({ + id: "editor_new_event", + window_title: _t("New Event"), + input: _t("Event Name"), + }).then(function (result) { + var eventName = result.val; + if (!eventName) { + return; + } + return self._rpc({ + route: '/event/add_event', + params: { + event_name: eventName, + }, + }).then(function (url) { + window.location.href = url; + return new Promise(function () {}); + }); + }); + }, +}); +}); diff --git a/addons/website_event/static/src/js/website_event.js b/addons/website_event/static/src/js/website_event.js new file mode 100644 index 00000000..11990e97 --- /dev/null +++ b/addons/website_event/static/src/js/website_event.js @@ -0,0 +1,93 @@ +odoo.define('website_event.website_event', function (require) { + +var ajax = require('web.ajax'); +var core = require('web.core'); +var Widget = require('web.Widget'); +var publicWidget = require('web.public.widget'); + +var _t = core._t; + +// Catch registration form event, because of JS for attendee details +var EventRegistrationForm = Widget.extend({ + + /** + * @override + */ + start: function () { + var self = this; + var res = this._super.apply(this.arguments).then(function () { + $('#registration_form .a-submit') + .off('click') + .click(function (ev) { + self.on_click(ev); + }); + }); + return res; + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {Event} ev + */ + on_click: function (ev) { + ev.preventDefault(); + ev.stopPropagation(); + var $form = $(ev.currentTarget).closest('form'); + var $button = $(ev.currentTarget).closest('[type="submit"]'); + var post = {}; + $('#registration_form table').siblings('.alert').remove(); + $('#registration_form select').each(function () { + post[$(this).attr('name')] = $(this).val(); + }); + var tickets_ordered = _.some(_.map(post, function (value, key) { return parseInt(value); })); + if (!tickets_ordered) { + $('
') + .text(_t('Please select at least one ticket.')) + .insertAfter('#registration_form table'); + return new Promise(function () {}); + } else { + $button.attr('disabled', true); + return ajax.jsonRpc($form.attr('action'), 'call', post).then(function (modal) { + var $modal = $(modal); + $modal.modal({backdrop: 'static', keyboard: false}); + $modal.find('.modal-body > div').removeClass('container'); // retrocompatibility - REMOVE ME in master / saas-19 + $modal.appendTo('body').modal(); + $modal.on('click', '.js_goto_event', function () { + $modal.modal('hide'); + $button.prop('disabled', false); + }); + $modal.on('click', '.close', function () { + $button.prop('disabled', false); + }); + }); + } + }, +}); + +publicWidget.registry.EventRegistrationFormInstance = publicWidget.Widget.extend({ + selector: '#registration_form', + + /** + * @override + */ + start: function () { + var def = this._super.apply(this, arguments); + this.instance = new EventRegistrationForm(this); + return Promise.all([def, this.instance.attachTo(this.$el)]); + }, + /** + * @override + */ + destroy: function () { + this.instance.setElement(null); + this._super.apply(this, arguments); + this.instance.setElement(this.$el); + }, +}); + +return EventRegistrationForm; +}); diff --git a/addons/website_event/static/src/js/website_event_set_customize_options.js b/addons/website_event/static/src/js/website_event_set_customize_options.js new file mode 100644 index 00000000..a6d9f749 --- /dev/null +++ b/addons/website_event/static/src/js/website_event_set_customize_options.js @@ -0,0 +1,122 @@ +odoo.define('website_event.set_customize_options', function (require) { +"use strict"; + +var CustomizeMenu = require('website.customizeMenu'); +var publicWidget = require('web.public.widget'); + +var EventSpecificOptions = publicWidget.Widget.extend({ + template: 'website_event.customize_options', + xmlDependencies: ['/website_event/static/src/xml/customize_options.xml'], + events: { + 'change #display-website-menu': '_onDisplaySubmenuChange', + }, + + /** + * @override + */ + start: function () { + this.$submenuInput = this.$('#display-website-menu'); + this.modelName = this._getEventObject().model; + this.eventId = this._getEventObject().id; + this._initCheckbox(); + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + _onDisplaySubmenuChange: function (ev) { + var checkboxValue = this.$submenuInput.is(':checked'); + this._toggleSubmenuDisplay(checkboxValue); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + _getCheckboxFields: function () { + return ['website_menu', 'website_url']; + }, + + _getCheckboxFieldMatch: function (checkboxField) { + if (checkboxField === 'website_menu') { + return this.$submenuInput; + } + }, + + _getEventObject: function() { + var repr = $('html').data('main-object'); + var m = repr.match(/(.+)\((\d+),(.*)\)/); + return { + model: m[1], + id: m[2] | 0, + }; + }, + + _initCheckbox: function () { + var self = this; + this._rpc({ + model: this.modelName, + method: 'read', + args: [ + [this.eventId], + this._getCheckboxFields() + ], + }).then((data) => { + self._initCheckboxCallback(data); + }); + }, + + _initCheckboxCallback: function (rpcData) { + if (rpcData[0]['website_menu']) { + var submenuInput = this._getCheckboxFieldMatch('website_menu'); + submenuInput.attr('checked', 'checked'); + } + this.eventUrl = rpcData[0]['website_url']; + }, + + _reloadEventPage: function () { + window.location = this.eventUrl; + }, + + _toggleSubmenuDisplay: function (val) { + var self = this; + this._rpc({ + model: this.modelName, + method: 'toggle_website_menu', + args: [[this.eventId], val], + }).then(function () { + self._reloadEventPage(); + }); + }, + +}); + +CustomizeMenu.include({ + _getEventObject: function() { + var repr = $('html').data('main-object'); + var m = repr.match(/(.+)\((\d+),(.*)\)/); + return { + model: m[1], + id: m[2] | 0, + }; + }, + + _loadCustomizeOptions: function () { + var self = this; + var def = this._super.apply(this, arguments); + return def.then(function () { + if (!self.__eventOptionsLoaded && self._getEventObject().model === 'event.event') { + self.__eventOptionsLoaded = true; + self.eventOptions = new EventSpecificOptions(self); + self.eventOptions.insertAfter(self.$el.find('.dropdown-divider:first()')); + } + }); + }, +}); + +return { + EventSpecificOptions: EventSpecificOptions, +}; + +}); diff --git a/addons/website_event/static/src/js/website_event_ticket_details.js b/addons/website_event/static/src/js/website_event_ticket_details.js new file mode 100644 index 00000000..8ad2e307 --- /dev/null +++ b/addons/website_event/static/src/js/website_event_ticket_details.js @@ -0,0 +1,55 @@ +odoo.define('website_event.ticket_details', function (require) { + var publicWidget = require('web.public.widget'); + + publicWidget.registry.ticketDetailsWidget = publicWidget.Widget.extend({ + selector: '.o_wevent_js_ticket_details', + events: { + 'click .o_wevent_registration_btn': '_onTicketDetailsClick', + 'change .custom-select': '_onTicketQuantityChange' + }, + start: function (){ + this.foldedByDefault = this.$el.data('foldedByDefault') === 1; + return this._super.apply(this, arguments); + }, + + //-------------------------------------------------------------------------- + // Private + //-------------------------------------------------------------------------- + + /** + * @private + */ + _getTotalTicketCount: function (){ + var ticketCount = 0; + this.$('.custom-select').each(function (){ + ticketCount += parseInt($(this).val()); + }); + return ticketCount; + }, + + //-------------------------------------------------------------------------- + // Handlers + //-------------------------------------------------------------------------- + + /** + * @private + * @param {*} ev + */ + _onTicketDetailsClick: function (ev){ + ev.preventDefault(); + if (this.foldedByDefault){ + $(ev.currentTarget).toggleClass('btn-primary text-left pl-0'); + $(ev.currentTarget).siblings().toggleClass('d-none'); + this.$('.close').toggleClass('d-none'); + } + }, + /** + * @private + */ + _onTicketQuantityChange: function (){ + this.$('button.btn-primary').attr('disabled', this._getTotalTicketCount() === 0); + } + }); + +return publicWidget.registry.ticketDetailsWidget; +}); diff --git a/addons/website_event/static/src/js/website_geolocation.js b/addons/website_event/static/src/js/website_geolocation.js new file mode 100644 index 00000000..0c93dbbb --- /dev/null +++ b/addons/website_event/static/src/js/website_geolocation.js @@ -0,0 +1,41 @@ +odoo.define('website_event.geolocation', function (require) { +'use strict'; + +var publicWidget = require('web.public.widget'); + +publicWidget.registry.visitor = publicWidget.Widget.extend({ + selector: ".oe_country_events, .country_events", + disabledInEditableMode: false, + + /** + * @override + */ + start: function () { + var defs = [this._super.apply(this, arguments)]; + var self = this; + var $eventList = this.$('.country_events_list'); + this._originalContent = $eventList[0].outerHTML; + defs.push(this._rpc({route: '/event/get_country_event_list'}).then(function (data) { + if (data) { + self._$loadedContent = $(data); + + self._$loadedContent.attr('contentEditable', false); + self._$loadedContent.addClass('o_temp_auto_element'); + self._$loadedContent.attr('data-temp-auto-element-original-content', self._originalContent); + + $eventList.replaceWith(self._$loadedContent); + } + })); + return Promise.all(defs); + }, + /** + * @override + */ + destroy: function () { + this._super.apply(this, arguments); + if (this._$loadedContent) { + this._$loadedContent.replaceWith(this._originalContent); + } + }, +}); +}); diff --git a/addons/website_event/static/src/scss/website_event.scss b/addons/website_event/static/src/scss/website_event.scss new file mode 100644 index 00000000..4cb8bbb9 --- /dev/null +++ b/addons/website_event/static/src/scss/website_event.scss @@ -0,0 +1,254 @@ +.o_wevent_index_topbar_filters { + .dropdown-toggle { + border: $border-width solid gray('400'); + @include o-bg-color(gray('white'), $with-extras: false); + @include border-radius($dropdown-border-radius); + @include hover-focus { + border-color: theme-color('primary'); + color: theme-color('primary'); + text-decoration: none; + } + &:after { + margin-left: 1.2em; + } + .fa { + margin-right: .4em; + color: theme-color('primary'); + } + } + .dropdown-menu { + margin-top: $navbar-padding-y; + min-width: 12rem; + } + .dropdown-item { + &.active .badge { // Invert badge display when the item is active + background-color: color-yiq(theme-color('primary')); + color: theme-color('primary'); + } + } +} + +.o_wevent_social_link { + $o_link_size: 3em; + display: inline-flex; + align-items: center; + justify-content: center; + @include size($o_link_size); + margin: 0 ($spacer * .25) ($spacer * .5) ($spacer * .25); + line-height: $o_link_size; + background-color: gray('100'); + border: $border-width solid $border-color; + border-radius: 50%; + text-align: center; + @include hover-focus { + background-color: gray('300'); + } +} + +.o_wevent_badge { + padding: ($spacer * .5) $spacer; + border-radius: 10rem; + font-weight: $font-weight-normal; +} + +// Index +.o_wevent_index { + // Events List + .o_wevent_events_list { + header { + a { + transition: all .25s ease-in-out; + @include hover-focus { + transform: scale(1.05); + } + } + } + &.opt_event_list_cards_bg { + @if (color('body') == $o-portal-default-body-bg) { + @extend .bg-200; + } + } + .opt_events_list_columns { + header { + height: 200px; + } + } + .opt_events_list_rows { + @include media-breakpoint-down(sm) { + header { + height: 200px; + } + } + } + .o_wevent_badge_event { + @include o-position-absolute($top: 0, $left: 0); + @include border-left-radius(0); + padding: ($spacer * .5) $card-spacer-x; + transform: translateY(-50%); + } + .o_wevent_event_date { + top: $card-spacer-x; + right: $card-spacer-x; + display: flex; + flex-direction: column; + justify-content: center; + @include size(4rem); + border-radius: 50%; + text-align: center; + + .o_wevent_event_day { + font-size: 1.125rem; + font-weight: 300; + line-height: 1; + } + .o_wevent_event_month { + font-size: 0.75rem; + font-weight: $font-weight-bold; + text-transform: uppercase; + } + } + .o_wevent_participating, + .o_wevent_unpublished { + position: absolute; + bottom: 0; + width: 100%; + padding: $card-spacer-y $card-spacer-x; + text-align: right; + } + .card-title { + color: $body-color; + } + } + .o_wevent_sidebar_title { + margin: 0 0 ($spacer * 1.5) 0; + border-bottom: $border-width solid $border-color; + padding: 0 0 ($spacer * .5) 0; + font-weight: $font-weight-bold; + text-transform: uppercase; + } + .o_wevent_sidebar_block { + margin: 0 0 ($spacer * 2.5) 0; + } + .o_wevent_sidebar_figure { + position: relative; + + .figure-img { + margin-bottom: 0; + } + .figure-caption { + @include o-position-absolute($left: 0, $bottom: 0); + width: 100%; + padding: $spacer; + background-color: rgba($color: #000, $alpha: 0.5); + @include border-bottom-radius($border-radius); + color: #fff; + } + } + #o_wevent_index_main_col .form-inline { + width: 100%; + } +} + +.o_wevent_event { + // Multi-line event title, even in mobile mode + nav > div > a.navbar-brand { + text-overflow: revert; + white-space: normal; + overflow: hidden; + max-width: calc(100% - 80px); + } + + // Ensure menu labels are not split + #o_wevent_event_submenu { + li.nav-item { + white-space: nowrap; + } + } + + .o_wevent_event_title { + margin: 3rem 0; + + .o_wevent_event_name { + font-weight: $display4-weight; + line-height: $display-line-height; + @include font-size($display4-size); + } + .o_wevent_event_subtitle { + font-weight: $lead-font-weight; + @include font-size($lead-font-size); + } + } + + .o_wevent_registration_single { + .o_wevent_nowrap { + white-space: nowrap; + } + } + + .o_wevent_registration_btn { + flex: 0 0 100%; + + &.collapsed { + flex: 0 0 33%; + + .close { + display: none; + } + } + .close { + display: block; + } + &:not(.collapsed) { + box-shadow: none; + font-weight: $font-weight-bold; + text-transform: uppercase; + transition: none; + } + } + + .o_wevent_sidebar_title { + margin-bottom: $spacer; + opacity: .5; + text-transform: uppercase; + } + + .o_wevent_sidebar_block { + padding: $spacer * 3; + border-bottom: $border-width solid $border-color; + + &:last-child { + border-bottom: 0; + } + } +} + +.o_wevent_event { + .o_record_cover_container { + overflow: hidden; + z-index: 0; + + .o_record_cover_component { + z-index: -1; + } + &.o_record_has_cover { + .o_record_cover_image { + background-attachment: fixed; + + &::after { + content: ""; + display: block; + @include o-position-absolute(0,0,50%,0); + } + } + .o_wevent_event_title { + color: white; + } + } + } +} + +.modal-open { + > .modal-backdrop { + z-index: $zindex-dropdown - 1; + } +} diff --git a/addons/website_event/static/src/scss/website_event_templates.scss b/addons/website_event/static/src/scss/website_event_templates.scss new file mode 100644 index 00000000..49a9f8ae --- /dev/null +++ b/addons/website_event/static/src/scss/website_event_templates.scss @@ -0,0 +1,161 @@ +// Color tags according to assigned background color. + +.o_wevent_index, .o_wevent_event { + + // Simple colored tags according to assigned background color + @for $size from 1 through length($o-colors) { + .o_tag_color_#{$size - 1} { + @if $size == 1 { + & { + background-color: white; + color: nth($o-colors, $size); + box-shadow: inset 0 0 0 2px nth($o-colors, $size); + } + &::after { + background-color: nth($o-colors, $size); + } + } @else { + &, &::after { + background-color: nth($o-colors, $size); + color: $white; + } + } + } + } + + // Complex colored tags according to assigned background color with hover effect + @for $size from 1 through length($o-colors) { + .o_tag_color_hovered_#{$size - 1} { + $background-color: white; + // no color selected + @if $size == 1 { + & { + color: black; + background-color: $background-color; + box-shadow: inset 0 0 0 1px nth($o-colors, $size); + } + } @else { + $background-color: nth($o-colors, $size); + & { + color: white; + background-color: $background-color; + } + } + @at-root a#{&} { + &:hover { + background-color: darken($background-color, 20%); + } + } + } + } + + /* + * COMMON TO ALL ONLINE-* PAGES + */ + + .o_wevent_online { + // unpublished badge: put opacity to distinguish form other badges + .o_wevent_online_badge_unpublished{ + opacity: 0.4; + } + + &.o_wevent_online_bg { + @if (color('body') == $o-portal-default-body-bg) { + @extend .bg-100; + } + } + + // background color-based for new styling + .event_color_0 { + // bg-100 background but DO NOT extend bg-100 as it messes with text-muted colors + background-color: #F8F9FA; + } + .event_color_1 { + background-color: rgba(240, 96, 80, 0.2); + } + .event_color_2 { + background-color: rgba(244, 164, 96, 0.2); + } + .event_color_3 { + background-color: rgba(247, 205, 31, 0.2); + } + .event_color_4 { + background-color: rgba(108,193,237,0.2); + } + .event_color_5 { + background-color: rgba(129,73,104,0.2); + } + .event_color_6 { + background-color: rgba(235,126,127,0.2); + } + .event_color_7 { + background-color: rgba(44,131,151,0.2); + } + .event_color_8 { + background-color: rgba(71,85,119,0.2); + } + .event_color_9 { + background-color: rgba(214,20,95,0.2); + } + .event_color_10 { + background-color: rgba(48,195,129,0.2); + } + .event_color_11 { + background-color: rgba(147,101,184,0.2); + } + + .o_wevent_online_page_container { + // Widescreen mode + @include media-breakpoint-up(md) { + &:not(.container) { + padding-left: 0.5rem; + padding-right: 0.5rem; + } + } + + // Main panel + .o_wevent_online_page_main { + border: 1px solid $border-color; + + @include media-breakpoint-up(md) { + border-top-width: 0; + } + + .o_wevent_online_page_avatar { + min-width: 64px; + + img { + max-width: 96px; + } + } + } + + // Left panel + .o_wevent_online_page_aside { + + // Left panel: content display + .o_wevent_online_page_aside_content { + border: 1px solid $border-color; + + @include media-breakpoint-up(md) { + border-top-width: 0; + } + + li:not(.nav-item) { + border-bottom: 1px solid $border-color; + &:first-child { + border-top: 1px solid $border-color; + } + &:last-child { + border-bottom: 0px; + } + } + + .o_wevent_online_page_aside_collapse:not(.collapsed) { + transform: rotate(180deg); + } + } + } + } + } +} diff --git a/addons/website_event/static/src/xml/customize_options.xml b/addons/website_event/static/src/xml/customize_options.xml new file mode 100644 index 00000000..539a3ef0 --- /dev/null +++ b/addons/website_event/static/src/xml/customize_options.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + -- cgit v1.2.3