This commit is contained in:
Adrian Hopek 2022-02-15 10:30:41 +01:00
parent 166bec1e51
commit 425d7c7608
11 changed files with 99 additions and 162 deletions

View File

@ -29,7 +29,9 @@ class GoogleController extends Controller
} catch (ModelNotFoundException) { } catch (ModelNotFoundException) {
return redirect() return redirect()
->route("login") ->route("login")
->with("error", __("User does not exist.")); ->withErrors([
"oauth" => __("User does not exist."),
]);
} }
$auth->guard()->login($user, true); $auth->guard()->login($user, true);

17
package-lock.json generated
View File

@ -25,7 +25,8 @@
"vue": "^3.2.26", "vue": "^3.2.26",
"vue-echarts": "^6.0.2", "vue-echarts": "^6.0.2",
"vue-flatpickr-component": "^9.0.5", "vue-flatpickr-component": "^9.0.5",
"vue-loader": "^17.0.0" "vue-loader": "^17.0.0",
"vue-toastification": "^2.0.0-rc.5"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.6.0", "eslint": "^8.6.0",
@ -8943,6 +8944,14 @@
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz",
"integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=" "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ="
}, },
"node_modules/vue-toastification": {
"version": "2.0.0-rc.5",
"resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz",
"integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==",
"peerDependencies": {
"vue": "^3.0.2"
}
},
"node_modules/watchpack": { "node_modules/watchpack": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",
@ -16100,6 +16109,12 @@
} }
} }
}, },
"vue-toastification": {
"version": "2.0.0-rc.5",
"resolved": "https://registry.npmjs.org/vue-toastification/-/vue-toastification-2.0.0-rc.5.tgz",
"integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==",
"requires": {}
},
"watchpack": { "watchpack": {
"version": "2.3.1", "version": "2.3.1",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz",

View File

@ -32,7 +32,8 @@
"vue": "^3.2.26", "vue": "^3.2.26",
"vue-echarts": "^6.0.2", "vue-echarts": "^6.0.2",
"vue-flatpickr-component": "^9.0.5", "vue-flatpickr-component": "^9.0.5",
"vue-loader": "^17.0.0" "vue-loader": "^17.0.0",
"vue-toastification": "^2.0.0-rc.5"
}, },
"devDependencies": { "devDependencies": {
"eslint": "^8.6.0", "eslint": "^8.6.0",

View File

@ -1,4 +1,5 @@
@import 'flatpickr/dist/themes/light.css'; @import 'flatpickr/dist/themes/light.css';
@import 'vue-toastification/dist/index.css';
@tailwind base; @tailwind base;
@tailwind components; @tailwind components;

View File

@ -1,5 +1,41 @@
<template> <template>
<InertiaHead title="Zaloguj się" /> <InertiaHead title="Zaloguj się" />
<transition
enter-active-class="transform ease-out duration-300 transition"
enter-from-class="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-2"
enter-to-class="translate-y-0 opacity-100 sm:translate-x-0"
leave-active-class="transition ease-in duration-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
v-if="errors.oauth"
class="absolute inset-x-2 top-2 sm:mx-auto sm:w-full sm:max-w-md bg-red-500 shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden"
>
<div class="p-4">
<div class="flex items-center">
<div class="w-0 flex-1 flex justify-between">
<ExclamationIcon class="h-5 w-5 mr-1 text-white" />
<p class="w-0 flex-1 text-sm font-medium text-white">
{{ errors.oauth }}
</p>
</div>
<div class="ml-4 flex-shrink-0 flex">
<button
class="bg-red-500 rounded-md inline-flex text-red-100 hover:text-red-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-600"
@click="delete errors.oauth"
>
<span class="sr-only">Close</span>
<XIcon
class="h-5 w-5"
aria-hidden="true"
/>
</button>
</div>
</div>
</div>
</div>
</transition>
<div <div
class="sm:mx-auto sm:w-full sm:max-w-md text-white space-y-4 flex flex-col items-center rounded-lg px-4 py-8" class="sm:mx-auto sm:w-full sm:max-w-md text-white space-y-4 flex flex-col items-center rounded-lg px-4 py-8"
dusk="login-link" dusk="login-link"
@ -30,10 +66,21 @@
<script> <script>
import GuestLayout from '@/Shared/Layout/GuestLayout' import GuestLayout from '@/Shared/Layout/GuestLayout'
import {XIcon} from '@heroicons/vue/solid'
import {ExclamationIcon} from '@heroicons/vue/solid'
export default { export default {
name: 'LoginPage', name: 'LoginPage',
components: {
XIcon,
ExclamationIcon,
},
layout: GuestLayout, layout: GuestLayout,
props: {
errors: {
type: Object,
default: () => ({oauth: null}),
},
},
} }
</script> </script>

View File

@ -118,6 +118,7 @@
:href="`/vacation-requests/${request.id}/accept-as-technical`" :href="`/vacation-requests/${request.id}/accept-as-technical`"
method="post" method="post"
as="button" as="button"
preserve-scroll
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
> >
Zaakceptuj wniosek Zaakceptuj wniosek
@ -140,6 +141,7 @@
:href="`/vacation-requests/${request.id}/accept-as-administrative`" :href="`/vacation-requests/${request.id}/accept-as-administrative`"
method="post" method="post"
as="button" as="button"
preserve-scroll
class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500" class="inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-blumilk-600 hover:bg-blumilk-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blumilk-500"
> >
Zaakceptuj wniosek Zaakceptuj wniosek
@ -162,6 +164,7 @@
:href="`/vacation-requests/${request.id}/reject`" :href="`/vacation-requests/${request.id}/reject`"
method="post" method="post"
as="button" as="button"
preserve-scroll
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm" class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
> >
Odrzuć wniosek Odrzuć wniosek
@ -184,6 +187,7 @@
:href="`/vacation-requests/${request.id}/cancel`" :href="`/vacation-requests/${request.id}/cancel`"
method="post" method="post"
as="button" as="button"
preserve-scroll
class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm" class="inline-flex items-center justify-center px-4 py-2 border border-transparent font-medium rounded-md text-red-700 bg-red-100 hover:bg-red-200 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:text-sm"
> >
Anuluj wniosek Anuluj wniosek

View File

@ -1,67 +0,0 @@
<template>
<transition
enter-active-class="transform ease-out duration-300 transition"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition ease-in duration-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
v-if="show"
class="fixed bottom-4 right-0 mx-auto w-full max-w-md bg-red-500 shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden z-50 sm:mr-4"
>
<div class="p-4">
<div class="flex items-center">
<div class="w-0 flex-1 flex justify-between">
<ExclamationIcon class="h-5 w-5 text-white mr-2" />
<p class="w-0 flex-1 text-sm font-medium text-white">
{{ message }}
</p>
</div>
<div class="ml-4 flex-shrink-0 flex">
<button
class="bg-red-500 rounded-md inline-flex text-red-100 hover:text-red-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-600"
@click="show = false"
>
<span class="sr-only">Close</span>
<XIcon
class="h-5 w-5"
aria-hidden="true"
/>
</button>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
import {XIcon} from '@heroicons/vue/outline'
import {ExclamationIcon} from '@heroicons/vue/solid'
import {ref} from 'vue'
export default {
name: 'ErrorAlert',
components: {
ExclamationIcon,
XIcon,
},
props: {
message: {
type: String,
default: () => null,
},
},
setup() {
const show = ref(true)
setTimeout(() => show.value = false, 6000)
return {
show,
}
},
}
</script>

View File

@ -1,67 +0,0 @@
<template>
<transition
enter-active-class="transform ease-out duration-300 transition"
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-active-class="transition ease-in duration-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
v-if="show"
class="fixed bottom-4 right-0 mx-auto w-full max-w-md bg-green-500 shadow-lg rounded-lg pointer-events-auto ring-1 ring-black ring-opacity-5 overflow-hidden z-50 sm:mr-4"
>
<div class="p-4">
<div class="flex items-center">
<div class="w-0 flex-1 flex justify-between">
<CheckCircleIcon class="h-5 w-5 text-white mr-2" />
<p class="w-0 flex-1 text-sm font-medium text-white">
{{ message }}
</p>
</div>
<div class="ml-4 flex-shrink-0 flex">
<button
class="bg-green-500 rounded-md inline-flex text-green-100 hover:text-green-400 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-green-600"
@click="show = false"
>
<span class="sr-only">Close</span>
<XIcon
class="h-5 w-5"
aria-hidden="true"
/>
</button>
</div>
</div>
</div>
</div>
</transition>
</template>
<script>
import {XIcon} from '@heroicons/vue/outline'
import {CheckCircleIcon} from '@heroicons/vue/solid'
import {ref} from 'vue'
export default {
name: 'SuccessAlert',
components: {
CheckCircleIcon,
XIcon,
},
props: {
message: {
type: String,
default: () => '',
},
},
setup() {
const show = ref(true)
setTimeout(() => show.value = false, 6000)
return {
show,
}
},
}
</script>

View File

@ -2,14 +2,6 @@
<div class="min-h-full"> <div class="min-h-full">
<MainMenu /> <MainMenu />
<main class="lg:ml-64 flex flex-col flex-1 py-8"> <main class="lg:ml-64 flex flex-col flex-1 py-8">
<SuccessAlert
v-if="flash.success"
:message="flash.success"
/>
<ErrorAlert
v-if="flash.error"
:message="flash.error"
/>
<div> <div>
<slot /> <slot />
</div> </div>
@ -19,14 +11,12 @@
<script> <script>
import MainMenu from '@/Shared/MainMenu' import MainMenu from '@/Shared/MainMenu'
import SuccessAlert from '@/Shared/Alerts/SuccessAlert' import {useToast} from 'vue-toastification'
import ErrorAlert from '@/Shared/Alerts/ErrorAlert' import {watch} from 'vue'
export default { export default {
name: 'AppLayout', name: 'AppLayout',
components: { components: {
SuccessAlert,
ErrorAlert,
MainMenu, MainMenu,
}, },
props: { props: {
@ -35,5 +25,22 @@ export default {
default: () => null, default: () => null,
}, },
}, },
setup(props) {
const toast = useToast()
watch(() => props.flash, flash => {
if (flash.success) {
toast.success(flash.success)
}
if (flash.error) {
toast.error(flash.error)
}
}, {immediate:true})
return {
toast,
}
},
} }
</script> </script>

View File

@ -1,23 +1,11 @@
<template> <template>
<div class="min-h-screen flex flex-col justify-center py-12 sm:px-6 lg:px-8 bg-blumilk-25"> <div class="min-h-screen flex flex-col justify-center py-12 sm:px-6 lg:px-8 bg-blumilk-25">
<ErrorAlert
v-if="flash.error"
:message="flash.error"
/>
<slot /> <slot />
</div> </div>
</template> </template>
<script> <script>
import ErrorAlert from '@/Shared/Alerts/ErrorAlert'
export default { export default {
name: 'GuestLayout', name: 'GuestLayout',
components: {ErrorAlert},
props: {
flash: {
type: Object,
default: () => null,
},
},
} }
</script> </script>

View File

@ -4,6 +4,7 @@ import {InertiaProgress} from '@inertiajs/progress'
import AppLayout from '@/Shared/Layout/AppLayout' import AppLayout from '@/Shared/Layout/AppLayout'
import Flatpickr from 'flatpickr' import Flatpickr from 'flatpickr'
import { Polish } from 'flatpickr/dist/l10n/pl.js' import { Polish } from 'flatpickr/dist/l10n/pl.js'
import Toast from 'vue-toastification'
createInertiaApp({ createInertiaApp({
resolve: name => { resolve: name => {
@ -16,6 +17,11 @@ createInertiaApp({
setup({el, App, props, plugin}) { setup({el, App, props, plugin}) {
createApp({render: () => h(App, props)}) createApp({render: () => h(App, props)})
.use(plugin) .use(plugin)
.use(Toast, {
position: 'bottom-right',
maxToast: 5,
})
.component('InertiaLink', Link) .component('InertiaLink', Link)
.component('InertiaHead', Head) .component('InertiaHead', Head)
.mount(el) .mount(el)