Initial commit
This commit is contained in:
37
resources/js/plugins/amplitude.js
vendored
Normal file
37
resources/js/plugins/amplitude.js
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
// Log event function used to log event. Can be used when not using the directive.
|
||||
Vue.prototype.$logEvent = function (eventName, eventData) {
|
||||
if (!window.amplitude) return
|
||||
if (eventData && typeof eventData !== 'object') {
|
||||
throw new Error('Amplitude event value must be an object.')
|
||||
}
|
||||
|
||||
if (!window.config.production) {
|
||||
console.log('[DEBUG] Amplitude logged event:', eventName, eventData)
|
||||
} else {
|
||||
window.amplitude.getInstance().logEvent(eventName, eventData)
|
||||
}
|
||||
}
|
||||
|
||||
// Hook function used by event listener
|
||||
function hookLogEvent (binding) {
|
||||
const modifiers = Object.keys(binding.modifiers)
|
||||
if (modifiers.length !== 1) {
|
||||
throw new Error('Amplitude directive takes only one modifier which is the event name.')
|
||||
}
|
||||
const eventName = modifiers[0]
|
||||
|
||||
Vue.prototype.$logEvent(eventName, binding.value)
|
||||
}
|
||||
|
||||
// Register directive to log event
|
||||
const registeredListeners = {}
|
||||
Vue.directive('track', {
|
||||
bind (el, binding, vnode) {
|
||||
registeredListeners[el] = () => {
|
||||
hookLogEvent(binding)
|
||||
}
|
||||
el.addEventListener('click', registeredListeners[el])
|
||||
}
|
||||
})
|
||||
52
resources/js/plugins/axios.js
vendored
Normal file
52
resources/js/plugins/axios.js
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
import axios from 'axios'
|
||||
import store from '~/store'
|
||||
import router from '~/router'
|
||||
import i18n from '~/plugins/i18n'
|
||||
import Cookies from 'js-cookie'
|
||||
|
||||
function addPasswordToFormRequest (request) {
|
||||
const url = request.url
|
||||
if (!url.startsWith('/api/forms/')) return request
|
||||
|
||||
const slug = url.split('/')[3]
|
||||
if (slug !== undefined && slug !== '' && Cookies.get('password-' + slug) !== undefined) {
|
||||
request.headers['form-password'] = Cookies.get('password-' + slug)
|
||||
}
|
||||
|
||||
return request
|
||||
}
|
||||
|
||||
// Request interceptor
|
||||
axios.interceptors.request.use(request => {
|
||||
const token = store.getters['auth/token']
|
||||
if (token) {
|
||||
request.headers.common.Authorization = `Bearer ${token}`
|
||||
}
|
||||
|
||||
const locale = store.getters['lang/locale']
|
||||
if (locale) {
|
||||
request.headers.common['Accept-Language'] = locale
|
||||
}
|
||||
|
||||
// request.headers['X-Socket-Id'] = Echo.socketId()
|
||||
|
||||
request = addPasswordToFormRequest(request)
|
||||
|
||||
return request
|
||||
})
|
||||
|
||||
// Response interceptor
|
||||
axios.interceptors.response.use(response => response, error => {
|
||||
const { status } = error.response
|
||||
if (status >= 500) {
|
||||
console.log(status)
|
||||
}
|
||||
|
||||
if (status === 401 && store.getters['auth/check']) {
|
||||
store.commit('auth/LOGOUT')
|
||||
|
||||
router.push({ name: 'login' })
|
||||
}
|
||||
|
||||
return Promise.reject(error)
|
||||
})
|
||||
19
resources/js/plugins/config/vue-tailwind/datePicker.js
vendored
Normal file
19
resources/js/plugins/config/vue-tailwind/datePicker.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
export const fixedClasses = {
|
||||
input: 'rounded-lg border-transparent flex-1 appearance-none border border-gray-300 w-full py-2 px-4 bg-white text-gray-700 dark:bg-notion-dark-light dark:text-gray-300 dark:placeholder-gray-500 placeholder-gray-400 shadow-sm text-base focus:outline-none focus:ring-1 focus:ring-opacity-100 focus:border-transparent focus:ring-2 ring-blue-500',
|
||||
navigator: 'flex',
|
||||
navigatorViewButton: 'flex items-center',
|
||||
navigatorViewButtonIcon: 'flex-shrink-0 h-5 w-5',
|
||||
navigatorViewButtonBackIcon: 'flex-shrink-0 h-5 w-5',
|
||||
navigatorLabel: 'flex items-center py-1',
|
||||
navigatorPrevButtonIcon: 'h-6 w-6 inline-flex',
|
||||
navigatorNextButtonIcon: 'h-6 w-6 inline-flex',
|
||||
inputWrapper: 'relative',
|
||||
viewGroup: 'inline-flex flex-wrap',
|
||||
view: 'w-64',
|
||||
calendarDaysWrapper: 'grid grid-cols-7',
|
||||
calendarHeaderWrapper: 'grid grid-cols-7',
|
||||
monthWrapper: 'grid grid-cols-4',
|
||||
yearWrapper: 'grid grid-cols-4',
|
||||
clearButton: 'flex flex-shrink-0 items-center justify-center absolute right-0 top-0 m-2 h-6 w-6',
|
||||
clearButtonIcon: 'fill-current h-3 w-3'
|
||||
}
|
||||
30
resources/js/plugins/i18n.js
vendored
Normal file
30
resources/js/plugins/i18n.js
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
import Vue from 'vue'
|
||||
import store from '~/store'
|
||||
import VueI18n from 'vue-i18n'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: 'en',
|
||||
messages: {}
|
||||
})
|
||||
|
||||
/**
|
||||
* @param {String} locale
|
||||
*/
|
||||
export async function loadMessages (locale) {
|
||||
if (Object.keys(i18n.getLocaleMessage(locale)).length === 0) {
|
||||
const messages = await import(/* webpackChunkName: '' */ `~/lang/${locale}`)
|
||||
i18n.setLocaleMessage(locale, messages)
|
||||
}
|
||||
|
||||
if (i18n.locale !== locale) {
|
||||
i18n.locale = locale
|
||||
}
|
||||
}
|
||||
|
||||
;(async function () {
|
||||
await loadMessages(store.getters['lang/locale'])
|
||||
})()
|
||||
|
||||
export default i18n
|
||||
4
resources/js/plugins/index.js
vendored
Normal file
4
resources/js/plugins/index.js
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
import './axios'
|
||||
import './vue-plugins'
|
||||
import './amplitude'
|
||||
import './vapor'
|
||||
58
resources/js/plugins/vapor.js
vendored
Normal file
58
resources/js/plugins/vapor.js
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
import Vue from 'vue'
|
||||
const axios = require('axios')
|
||||
|
||||
const assetUrl = process.env.MIX_VAPOR_ASSET_URL
|
||||
? process.env.MIX_VAPOR_ASSET_URL
|
||||
: ''
|
||||
|
||||
Vue.mixin({
|
||||
methods: {
|
||||
asset (path) {
|
||||
return assetUrl + '/' + path
|
||||
},
|
||||
|
||||
/**
|
||||
* Store a file in S3 and return its UUID, key, and other information.
|
||||
*/
|
||||
async storeFile (file, options = {}) {
|
||||
const response = await axios.post(options.signedStorageUrl ? options.signedStorageUrl : '/vapor/signed-storage-url', {
|
||||
bucket: options.bucket || '',
|
||||
content_type: options.contentType || file.type,
|
||||
expires: options.expires || '',
|
||||
visibility: options.visibility || '',
|
||||
...options.data
|
||||
}, {
|
||||
baseURL: options.baseURL || null,
|
||||
headers: options.headers || {},
|
||||
...options.options
|
||||
})
|
||||
|
||||
const headers = response.data.headers
|
||||
|
||||
if ('Host' in headers) {
|
||||
delete headers.Host
|
||||
}
|
||||
|
||||
if (typeof options.progress === 'undefined') {
|
||||
options.progress = () => {}
|
||||
}
|
||||
|
||||
const cancelToken = options.cancelToken || ''
|
||||
|
||||
// Remove authorization headers
|
||||
const cleanAxios = axios.create()
|
||||
cleanAxios.defaults.headers.common = {}
|
||||
await cleanAxios.put(response.data.url, file, {
|
||||
cancelToken: cancelToken,
|
||||
headers: headers,
|
||||
onUploadProgress: (progressEvent) => {
|
||||
options.progress(progressEvent.loaded / progressEvent.total)
|
||||
}
|
||||
})
|
||||
|
||||
response.data.extension = file.name.split('.').pop()
|
||||
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
})
|
||||
91
resources/js/plugins/vue-plugins.js
vendored
Normal file
91
resources/js/plugins/vue-plugins.js
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
import Vue from 'vue'
|
||||
|
||||
import PortalVue from 'portal-vue'
|
||||
|
||||
import VueTailwind from 'vue-tailwind'
|
||||
import TDatepicker from 'vue-tailwind/dist/t-datepicker'
|
||||
|
||||
Vue.use(PortalVue)
|
||||
const settings = {
|
||||
't-datepicker': {
|
||||
component: TDatepicker,
|
||||
props: {
|
||||
classes: {
|
||||
dropdown: 'origin-top-left absolute rounded shadow bg-white dark:bg-notion-dark dark:border-gray-100 border overflow-hidden mt-1',
|
||||
wrapper: 'flex flex-col',
|
||||
dropdownWrapper: 'relative z-10',
|
||||
enterClass: 'opacity-0 scale-95',
|
||||
enterActiveClass: 'transition transform ease-out duration-100',
|
||||
enterToClass: 'opacity-100 scale-100',
|
||||
leaveClass: 'opacity-100 scale-100',
|
||||
leaveActiveClass: 'transition transform ease-in duration-75',
|
||||
leaveToClass: 'opacity-0 scale-95',
|
||||
inlineWrapper: '',
|
||||
inlineViews: 'rounded bg-white border mt-1 inline-flex',
|
||||
inputWrapper: '',
|
||||
input: 'text-black placeholder-gray-400 border-gray-300',
|
||||
clearButton: 'hover:bg-gray-100 rounded transition duration-100 ease-in-out text-gray-600',
|
||||
clearButtonIcon: '',
|
||||
viewGroup: '',
|
||||
view: '',
|
||||
navigator: 'pt-2 px-3',
|
||||
navigatorViewButton: 'transition ease-in-out duration-100 inline-flex cursor-pointer rounded-full px-2 py-1 -ml-1 hover:bg-gray-100',
|
||||
navigatorViewButtonIcon: 'fill-current text-gray-400',
|
||||
navigatorViewButtonBackIcon: 'fill-current text-gray-400',
|
||||
navigatorViewButtonMonth: 'text-gray-700 font-semibold',
|
||||
navigatorViewButtonYear: 'text-gray-500 ml-1',
|
||||
navigatorViewButtonYearRange: 'text-gray-500 ml-1',
|
||||
navigatorLabel: 'py-1',
|
||||
navigatorLabelMonth: 'text-gray-700 font-semibold',
|
||||
navigatorLabelYear: 'text-gray-500 ml-1',
|
||||
navigatorPrevButton: 'transition ease-in-out duration-100 inline-flex cursor-pointer hover:bg-gray-100 rounded-full p-1 ml-2 ml-auto disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
navigatorNextButton: 'transition ease-in-out duration-100 inline-flex cursor-pointer hover:bg-gray-100 rounded-full p-1 -mr-1 disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
navigatorPrevButtonIcon: 'text-gray-400',
|
||||
navigatorNextButtonIcon: 'text-gray-400',
|
||||
calendarWrapper: 'px-3 pt-2',
|
||||
calendarHeaderWrapper: '',
|
||||
calendarHeaderWeekDay: 'uppercase text-xs text-gray-500 w-8 h-8 flex items-center justify-center',
|
||||
calendarDaysWrapper: '',
|
||||
calendarDaysDayWrapper: 'w-full h-8 flex flex-shrink-0 items-center',
|
||||
otherMonthDay: 'text-sm rounded-full w-8 h-8 mx-auto hover:bg-blue-100 text-gray-400 disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
emptyDay: '',
|
||||
inRangeFirstDay: 'text-sm bg-blue-500 text-white w-full h-8 rounded-l-full',
|
||||
inRangeLastDay: 'text-sm bg-blue-500 text-white w-full h-8 rounded-r-full',
|
||||
inRangeDay: 'text-sm bg-blue-200 w-full h-8 disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
selectedDay: 'text-sm rounded-full w-8 h-8 mx-auto bg-blue-500 text-white disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
activeDay: 'text-sm rounded-full bg-blue-100 w-8 h-8 mx-auto disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
highlightedDay: 'text-sm rounded-full bg-blue-200 w-8 h-8 mx-auto disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
day: 'text-sm rounded-full w-8 h-8 mx-auto hover:bg-blue-100 disabled:opacity-50 disabled:cursor-not-allowed',
|
||||
today: 'text-sm rounded-full w-8 h-8 mx-auto hover:bg-blue-100 disabled:opacity-50 disabled:cursor-not-allowed border border-blue-500',
|
||||
monthWrapper: 'px-3 pt-2',
|
||||
selectedMonth: 'text-sm rounded w-full h-12 mx-auto bg-blue-500 text-white',
|
||||
activeMonth: 'text-sm rounded w-full h-12 mx-auto bg-blue-100',
|
||||
month: 'text-sm rounded w-full h-12 mx-auto hover:bg-blue-100',
|
||||
yearWrapper: 'px-3 pt-2',
|
||||
year: 'text-sm rounded w-full h-12 mx-auto hover:bg-blue-100',
|
||||
selectedYear: 'text-sm rounded w-full h-12 mx-auto bg-blue-500 text-white',
|
||||
activeYear: 'text-sm rounded w-full h-12 mx-auto bg-blue-100',
|
||||
timepickerWrapper: 'flex items-center px-4 py-2 space-x-2',
|
||||
timepickerTimeWrapper: 'flex items-center space-x-2',
|
||||
timepickerTimeFieldsWrapper: 'bg-gray-100 dark:bg-notion-dark-light rounded-md w-full text-right flex items-center border border-gray-100 focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50',
|
||||
timepickerOkButton: 'text-blue-600 text-sm uppercase font-semibold transition duration-100 ease-in-out border border-transparent focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 rounded cursor-pointer',
|
||||
timepickerInput: 'text-center w-8 border-transparent bg-transparent dark:bg-notion-dark-light p-0 h-6 text-sm transition duration-100 ease-in-out border border-transparent focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50 rounded',
|
||||
timepickerTimeLabel: 'flex-grow text-sm text-gray-500',
|
||||
timepickerAmPmWrapper: 'relative inline-flex flex-shrink-0 transition duration-200 ease-in-out bg-gray-100 dark:bg-notion-dark-light border border-transparent rounded cursor-pointer focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50',
|
||||
timepickerAmPmWrapperChecked: 'relative inline-flex flex-shrink-0 transition duration-200 ease-in-out bg-gray-100 dark:bg-notion-dark-light border border-transparent rounded cursor-pointer focus:border-blue-500 focus:ring-2 focus:ring-blue-500 focus:outline-none focus:ring-opacity-50',
|
||||
timepickerAmPmWrapperDisabled: 'relative inline-flex flex-shrink-0 transition duration-200 ease-in-out opacity-50 cursor-not-allowed',
|
||||
timepickerAmPmWrapperCheckedDisabled: 'relative inline-flex flex-shrink-0 transition duration-200 ease-in-out opacity-50 cursor-not-allowed',
|
||||
timepickerAmPmButton: 'absolute flex items-center justify-center w-6 h-6 text-xs text-gray-800 transition duration-200 ease-in-out transform translate-x-0 bg-white rounded shadow',
|
||||
timepickerAmPmButtonChecked: 'absolute flex items-center justify-center w-6 h-6 text-xs text-gray-800 transition duration-200 ease-in-out transform translate-x-full bg-white rounded shadow',
|
||||
timepickerAmPmCheckedPlaceholder: 'flex items-center justify-center w-6 h-6 text-xs text-gray-500 rounded-sm',
|
||||
timepickerAmPmUncheckedPlaceholder: 'flex items-center justify-center w-6 h-6 text-xs text-gray-500 rounded-sm'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vue.use(VueTailwind, settings)
|
||||
|
||||
Vue.prototype.$getCrisp = () => {
|
||||
return window.$crisp
|
||||
}
|
||||
Reference in New Issue
Block a user