implemented notification component and logic
This commit is contained in:
24
src/App.vue
24
src/App.vue
@@ -1,15 +1,24 @@
|
||||
<template>
|
||||
<v-app>
|
||||
<v-main>
|
||||
<div class="container shadow p-3 text-center">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
</v-main>
|
||||
</v-app>
|
||||
<v-app>
|
||||
<v-main>
|
||||
<Notification />
|
||||
<div class="container shadow p-3 text-center">
|
||||
<nav class="nav justify-content-center border-bottom mb-4 pb-2">
|
||||
<a href="" class="nav-link">Logout</a>
|
||||
<router-link class="nav-link" to="/">Home</router-link>
|
||||
<router-link to="Login" class="nav-link">Login</router-link>
|
||||
</nav>
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
|
||||
</v-main>
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import Notification from '@/components/Notification.vue';
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
@@ -18,6 +27,5 @@
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
</style>
|
||||
|
||||
41
src/components/Notification.vue
Normal file
41
src/components/Notification.vue
Normal file
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
|
||||
<div class="toast-container position-absolute top-0 start-50 mt-3 translate-middle-x">
|
||||
<transition-group name="fade">
|
||||
<div v-for="(note, index) in notifications" :key="index" data-bs-delay="2000" data-bs-autohide="true" class="show fade toast border-0 text-white" :class="toastClasses(note.type)" role="alert" aria-live="assertive" aria-atomic="true">
|
||||
<div class="d-flex">
|
||||
<div class="toast-body">
|
||||
{{note.text}}
|
||||
</div>
|
||||
<button type="button" @click="destroyAlert(index)" class="btn-close btn-close-white me-2 m-auto" data-bs-dismiss="toast"></button>
|
||||
</div>
|
||||
</div>
|
||||
</transition-group>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useNotifications } from '@/stores/notifications'
|
||||
import { storeToRefs } from 'pinia'
|
||||
|
||||
const notes = useNotifications()
|
||||
const { notifications } = storeToRefs(notes)
|
||||
|
||||
function destroyAlert(index : number) {
|
||||
notes.removeAlert(index)
|
||||
}
|
||||
|
||||
function toastClasses(type : string){
|
||||
return {
|
||||
'bg-danger': type === 'danger',
|
||||
'bg-success' : type === 'success',
|
||||
'bg-warning' : type === 'warning'
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
20
src/stores/notifications.ts
Normal file
20
src/stores/notifications.ts
Normal file
@@ -0,0 +1,20 @@
|
||||
import { defineStore, acceptHMRUpdate } from 'pinia'
|
||||
|
||||
export const useNotifications = defineStore('notifications', {
|
||||
state: () => {
|
||||
return {
|
||||
/**@type {{type: string, text: string}[]} */
|
||||
notifications: new Array<{type: string, text: string}>()
|
||||
}
|
||||
},
|
||||
|
||||
actions: {
|
||||
removeAlert(index : number) : void {
|
||||
this.notifications.splice(index, 1)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
if(import.meta.hot) {
|
||||
import.meta.hot.accept(acceptHMRUpdate(useNotifications, import.meta.hot))
|
||||
}
|
||||
@@ -1,5 +1,22 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { defineStore, storeToRefs } from 'pinia'
|
||||
import axios, {AxiosResponse, AxiosError} from 'axios'
|
||||
import { useNotifications } from './notifications'
|
||||
|
||||
type AuthSuccResult = {
|
||||
notification: {
|
||||
type: string,
|
||||
text: string
|
||||
}
|
||||
user: string,
|
||||
role: string
|
||||
}
|
||||
|
||||
type AuthErrResult = {
|
||||
notification: {
|
||||
text: string,
|
||||
type: string
|
||||
}
|
||||
}
|
||||
|
||||
export const useUser = defineStore('userStore', {
|
||||
state: () => {
|
||||
@@ -12,27 +29,37 @@ export const useUser = defineStore('userStore', {
|
||||
|
||||
actions: {
|
||||
async login(username: string, password: string) : Promise<boolean> {
|
||||
const { notifications } = storeToRefs(useNotifications())
|
||||
|
||||
try {
|
||||
const response: AxiosResponse<{
|
||||
user: string,
|
||||
role: string,
|
||||
Message: string
|
||||
}> = await axios.post('http://localhost:3333/api/v1/login', {
|
||||
const response = await axios.post<AuthSuccResult>('http://localhost:3333/api/v1/login', {
|
||||
username: username,
|
||||
password: password
|
||||
})
|
||||
|
||||
console.log(response.data)
|
||||
this.isLoggedIn = true
|
||||
this.user = response.data.user
|
||||
this.role = response.data.role
|
||||
|
||||
notifications.value.push({
|
||||
type: response.data.notification.type,
|
||||
text: response.data.notification.text,
|
||||
})
|
||||
|
||||
return true
|
||||
} catch(err) {
|
||||
if (axios.isAxiosError(err)){
|
||||
console.log(err.response)
|
||||
} catch(err : unknown) {
|
||||
if (axios.isAxiosError(err) && err.response && err.response.data){
|
||||
|
||||
const data = err.response.data as AuthErrResult
|
||||
|
||||
const note = {
|
||||
type: data.notification.type,
|
||||
text: data.notification.text
|
||||
}
|
||||
|
||||
notifications.value.push(note)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template lang="pug">
|
||||
|
||||
p {{ state }}
|
||||
//- p {{ state }}
|
||||
|
||||
MonthPicker(:selectedMonth="selectedMonth" :selectedYear="selectedYear" @getMonth="selectedMonth = $event" @getYear="selectedYear = $event")
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
<template>
|
||||
|
||||
<br />
|
||||
|
||||
<img src="/src/assets/logo.png">
|
||||
<form class="m-auto">
|
||||
<h1 class="h3 mb-3">Bitte einloggen</h1>
|
||||
@@ -24,22 +27,26 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useUser } from '@/stores/user'
|
||||
import { onMounted, reactive } from 'vue'
|
||||
import { useNotifications } from '@/stores/notifications'
|
||||
import { reactive } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const userStore = useUser()
|
||||
const noteStore = useNotifications()
|
||||
|
||||
const router = useRouter()
|
||||
|
||||
const input = reactive({
|
||||
username: '',
|
||||
password: ''
|
||||
})
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
async function onClick() {
|
||||
|
||||
userStore.login(input.username, input.password)
|
||||
if(await userStore.login(input.username, input.password)) {
|
||||
router.push({name: 'Home'})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user