Refactor notifications + add shadow

This commit is contained in:
Julien Nahum 2024-01-02 14:40:47 +01:00
parent bd27d3a561
commit 2be72e0e8e
3 changed files with 76 additions and 126 deletions

View File

@ -1,112 +1,17 @@
<template> <template>
<div class="fixed top-0 bottom-24 right-0 flex px-4 items-start justify-end z-50 pointer-events-auto">
<NuxtNotifications> <NuxtNotifications>
<template #body="props"> <template #body="props">
<div class="relative"> <div class="p-2">
<div <div
v-if="props.item.type==='success'" class="flex max-w-sm w-full mx-auto bg-white shadow-md rounded-lg overflow-hidden relative"
class="flex max-w-sm w-full mx-auto bg-white shadow-md rounded-lg overflow-hidden mt-4"
> >
<div class="flex justify-center items-center w-12 bg-green-500"> <div class="flex justify-center items-center w-12" :class="notifTypes[props.item.type].background" v-html="notifTypes[props.item.type].svg"/>
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 fill-current text-white" viewBox="0 0 20 20"
fill="currentColor">
<path fill-rule="evenodd"
d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z"
clip-rule="evenodd"/>
</svg>
</div>
<div class="-mx-3 py-2 px-4"> <div class="-mx-3 py-2 px-4">
<div class="mx-3"> <div class="mx-3">
<span class="text-green-500 font-semibold pr-6">{{ props.item.title }}</span> <span :class="notifTypes[props.item.type].text" class="font-semibold pr-6">{{ props.item.title }}</span>
<p class="text-gray-600 text-sm">{{ props.item.text }}</p> <p class="text-gray-600 text-sm">{{ props.item.text }}</p>
</div> <div class="w-full flex gap-2 mt-1" v-if="props.item.type == 'confirm'">
</div>
</div>
<div
v-if="props.item.type==='info'"
class="flex max-w-sm w-full mx-auto bg-white shadow-md rounded-lg overflow-hidden mt-4"
>
<div class="flex justify-center items-center w-12 bg-blue-500">
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 fill-current text-white" viewBox="0 0 20 20"
fill="currentColor">
<path fill-rule="evenodd"
d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z"
clip-rule="evenodd"/>
</svg>
</div>
<div class="-mx-3 py-2 px-4">
<div class="mx-3">
<span class="text-blue-500 font-semibold pr-6">{{ props.item.title }}</span>
<p class="text-gray-600 text-sm">T{{ props.item.text }}</p>
</div>
</div>
</div>
<div
v-if="props.item.type==='error'"
class="flex max-w-sm w-full mx-auto bg-white shadow-md rounded-lg overflow-hidden mt-4"
>
<div class="flex justify-center items-center w-12 bg-red-500">
<svg
class="h-6 w-6 fill-current text-white"
viewBox="0 0 40 40"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM21.6667 28.3333H18.3334V25H21.6667V28.3333ZM21.6667 21.6666H18.3334V11.6666H21.6667V21.6666Z"
/>
</svg>
</div>
<div class="-mx-3 py-2 px-4">
<div class="mx-3">
<span class="text-red-500 font-semibold pr-6">{{ props.item.title }}</span>
<p class="text-gray-600 text-sm">{{ props.item.text }}</p>
</div>
</div>
</div>
<div
class="flex max-w-sm w-full mx-auto bg-white shadow-md rounded-lg overflow-hidden mt-4"
v-if="props.item.type==='warning'"
>
<div class="flex justify-center items-center w-12 bg-yellow-500">
<svg
class="h-6 w-6 fill-current text-white"
viewBox="0 0 40 40"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM21.6667 28.3333H18.3334V25H21.6667V28.3333ZM21.6667 21.6666H18.3334V11.6666H21.6667V21.6666Z"
/>
</svg>
</div>
<div class="-mx-3 py-2 px-4">
<div class="mx-3">
<span class="text-yellow-500 font-semibold pr-6">{{ props.item.title }}</span>
<p class="text-gray-600 text-sm">{{ props.item.text }}</p>
</div>
</div>
</div>
<div
class="flex max-w-sm w-full mx-auto bg-white shadow-md rounded-lg overflow-hidden mt-4"
v-if="props.item.type==='confirm'"
>
<div class="flex justify-center items-center w-12 bg-blue-500">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"
class="w-6 h-6 text-white">
<path fill-rule="evenodd"
d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12zm11.378-3.917c-.89-.777-2.366-.777-3.255 0a.75.75 0 01-.988-1.129c1.454-1.272 3.776-1.272 5.23 0 1.513 1.324 1.513 3.518 0 4.842a3.75 3.75 0 01-.837.552c-.676.328-1.028.774-1.028 1.152v.75a.75.75 0 01-1.5 0v-.75c0-1.279 1.06-2.107 1.875-2.502.182-.088.351-.199.503-.331.83-.727.83-1.857 0-2.584zM12 18a.75.75 0 100-1.5.75.75 0 000 1.5z"
clip-rule="evenodd"/>
</svg>
</div>
<div class="-mx-3 py-2 px-4">
<div class="mx-3">
<span class="text-blue-500 font-semibold pr-6">{{ props.item.title }}</span>
<p class="text-gray-600 text-sm">{{ props.item.text }}</p>
<div class="w-full flex gap-2 mt-1">
<v-button color="blue" size="small" @click.prevent="props.item.data.success();props.close()">Yes <v-button color="blue" size="small" @click.prevent="props.item.data.success();props.close()">Yes
</v-button> </v-button>
<v-button color="white" size="small" <v-button color="white" size="small"
@ -115,7 +20,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<button @click="props.close()" class="absolute top-0 right-0 px-2 py-2 cursor-pointer"> <button @click="props.close()" class="absolute top-0 right-0 px-2 py-2 cursor-pointer">
<svg <svg
class="fill-current h-6 w-6 text-gray-300 hover:text-gray-500" class="fill-current h-6 w-6 text-gray-300 hover:text-gray-500"
@ -130,9 +35,9 @@
</svg> </svg>
</button> </button>
</div> </div>
</div>
</template> </template>
</NuxtNotifications> </NuxtNotifications>
</div>
</template> </template>
<script> <script>
@ -140,14 +45,58 @@ export default {
name: 'Notifications', name: 'Notifications',
data() { data() {
return {} return {
notifTypes: {
success: {
background: 'bg-green-500',
text: 'text-green-500',
svg: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 fill-current text-white" viewBox="0 0 20 20" fill="currentColor">' +
' <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />' +
' </svg>'
}, },
warning: {
computed: {}, background: 'bg-yellow-500',
text: 'text-yellow-500',
mounted() { svg: '<svg' +
' class="h-6 w-6 fill-current text-white"' +
' viewBox="0 0 40 40"' +
' xmlns="http://www.w3.org/2000/svg"' +
' >' +
' <path' +
' d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM21.6667 28.3333H18.3334V25H21.6667V28.3333ZM21.6667 21.6666H18.3334V11.6666H21.6667V21.6666Z"' +
' />' +
' </svg>',
}, },
error: {
background: 'bg-red-500',
text: 'text-red-500',
svg: '<svg' +
' class="h-6 w-6 fill-current text-white"' +
' viewBox="0 0 40 40"' +
' xmlns="http://www.w3.org/2000/svg"' +
' >' +
' <path' +
' d="M20 3.33331C10.8 3.33331 3.33337 10.8 3.33337 20C3.33337 29.2 10.8 36.6666 20 36.6666C29.2 36.6666 36.6667 29.2 36.6667 20C36.6667 10.8 29.2 3.33331 20 3.33331ZM21.6667 28.3333H18.3334V25H21.6667V28.3333ZM21.6667 21.6666H18.3334V11.6666H21.6667V21.6666Z"' +
' />' +
' </svg>'
},
confirm: {
background: 'bg-blue-500',
text: 'text-blue-500',
svg: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 fill-current text-white" viewBox="0 0 20 20" fill="currentColor">' +
' <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />' +
' </svg>'
},
info: {
background: 'bg-blue-500',
text: 'text-blue-500',
svg: '<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 fill-current text-white" viewBox="0 0 20 20" fill="currentColor">' +
' <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />' +
' </svg>'
}
methods: {} }
}
},
} }
</script> </script>

View File

@ -170,6 +170,7 @@ export default {
return return
} }
if (form.busy) return
this.loading = true this.loading = true
// this.closeAlert() // this.closeAlert()
form.post('/forms/' + this.form.slug + '/answer').then((data) => { form.post('/forms/' + this.form.slug + '/answer').then((data) => {
@ -218,8 +219,9 @@ export default {
this.confetti.play() this.confetti.play()
} }
}).catch((error) => { }).catch((error) => {
if (error.response && error.response.data && error.response.data.message) { console.log('here')
useAlert().error(error.response.data.message) if (error.response && error.data && error.data.message) {
useAlert().error(error.data.message)
} }
this.loading = false this.loading = false
onFailure() onFailure()

View File

@ -87,7 +87,6 @@ const passwordEntered = function (password) {
const loadForm = async () => { const loadForm = async () => {
if (formsStore.loading || form.value) return Promise.resolve() if (formsStore.loading || form.value) return Promise.resolve()
console.info('Loading form', slug)
const {data, error} = await formsStore.publicLoad(slug) const {data, error} = await formsStore.publicLoad(slug)
if (error.value) { if (error.value) {
formsStore.stopLoading() formsStore.stopLoading()