Skip to content

Commit

Permalink
Merge pull request #45 from Twissi/add-notifications
Browse files Browse the repository at this point in the history
WIP: Add notifications #25
  • Loading branch information
markusphil authored Oct 17, 2019
2 parents b9cd27e + 896e3e7 commit 86fe222
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 51 deletions.
9 changes: 6 additions & 3 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
<template>
<div id="app">
<nav-bar />
<notifications />
<router-view />
<confirmationModal />
<confirmation-modal />
</div>
</template>

<script>
import { auth } from '@/utility/firebase';
import confirmationModal from './components/basic/ConfirmationModal.vue';
import ConfirmationModal from './components/basic/ConfirmationModal.vue';
import NavBar from './components/basic/NavBar.vue';
import Notifications from '@/components/basic/Notifications.vue';
export default {
components: {
confirmationModal,
ConfirmationModal,
NavBar,
Notifications,
},
mounted() {
// this method creates an observer that should be triggered on signIn and signOut
Expand Down
103 changes: 103 additions & 0 deletions src/components/basic/Notifications.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<template>
<div class="notifications">
<article
v-for="notification in notifications"
v-bind:key="notification.id"
v-bind:class="['message', `is-${notification.type}`, { 'fade-out': notification.fade }]"
>
<div class="message-header">
<p>{{ notification.title }}</p>

<button
class="delete"
aria-label="delete"
:disabled="notification.fade"
@click="remove(notification)"
></button>
</div>
<div class="message-body">{{ notification.message }}</div>
</article>
</div>
</template>

<script>
export default {
methods: {
remove(notification) {
this.$store.dispatch('removeNotification', notification);
},
},
computed: {
notifications() {
return this.$store.getters.notifications || [];
},
},
};
</script>

<style scoped lang="scss">
@-webkit-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
.notifications {
padding-top: 20px;
width: 90%;
max-width: 800px;
margin: 0 auto;
}
.message {
-webkit-animation-name: fadeIn;
animation-name: fadeIn;
-webkit-animation-duration: 0.5s;
animation-duration: 0.5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
.fade-out {
-webkit-animation-name: fadeOut;
animation-name: fadeOut;
-webkit-animation-duration: 0.5s;
animation-duration: 0.5s;
-webkit-animation-fill-mode: both;
animation-fill-mode: both;
}
</style>
49 changes: 49 additions & 0 deletions src/store/modules/notifications.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Vue from 'vue';

const notificationsStore = {
state: {
notifications: [],
},
mutations: {
addNotification: (state, { title, message, type }) => {
state.notifications = [
{
id: state.notifications.length++,
title: title,
message: message,
type: type,
},
];
},
removeNotification: (state, id) => {
state.notifications = state.notifications.filter(notification => {
return notification.id !== id;
});
},
fadeNotification: (state, id) => {
state.notifications.map(notification => {
if (notification.id === id) {
Vue.set(notification, 'fade', 'fadeOut');
}
});
},
},
actions: {
addNotification: ({ commit }, notification) => {
commit('addNotification', notification);
},
removeNotification: ({ commit }, notification) => {
commit('fadeNotification', notification.id);
setTimeout(() => {
commit('removeNotification', notification.id);
}, 500);
},
},
getters: {
notifications: state => {
return state.notifications;
},
},
};

export default notificationsStore;
2 changes: 2 additions & 0 deletions src/store/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import templateStore from './modules/templates';
import answerStore from './modules/answers';
import userStore from './modules/user';
import confirmationDialogStore from './modules/confirmationDialog';
import notificationsStore from './modules/notifications';

Vue.use(Vuex);

Expand All @@ -18,5 +19,6 @@ export default new Vuex.Store({
answers: answerStore,
user: userStore,
confirmationDialog: confirmationDialogStore,
notifications: notificationsStore,
},
});
100 changes: 52 additions & 48 deletions src/views/Login.vue
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
<template>
<div class="wrapper">
<FormCard title="Login to continue..." @submit="login" :submitBtn="{ name: 'login', loading }">
<template #body>
<InputUnit v-model="email" :name="'Email'" :type="'email'" />
<InputUnit v-model="password" :name="'Password'" :type="'password'" />
<p>
No account yet?
<router-link to="/signup">Request access here</router-link>
</p>
</template>
</FormCard>
</div>
</template>

<script>
import { auth } from '../utility/firebase';
import FormCard from '../components/basic/FormCard.vue';
import InputUnit from '../components/basic/InputUnit.vue';
export default {
components: {
FormCard,
InputUnit,
},
data() {
return {
email: null,
password: null,
loading: false,
};
},
methods: {
async login() {
console.log('triggered function');
this.loading = true;
try {
await auth.signInWithEmailAndPassword(this.email, this.password);
console.log('successfully logged in');
this.loading = false;
} catch (error) {
console.log(error);
this.loading = false;
}
},
},
};
</script>
<template>
<div class="wrapper">
<FormCard title="Login to continue..." @submit="login" :submitBtn="{ name: 'login', loading }">
<template #body>
<InputUnit v-model="email" :name="'Email'" :type="'email'" />
<InputUnit v-model="password" :name="'Password'" :type="'password'" />
<p>
No account yet?
<router-link to="/signup">Request access here</router-link>
</p>
</template>
</FormCard>
</div>
</template>

<script>
import { auth } from '../utility/firebase';
import FormCard from '../components/basic/FormCard.vue';
import InputUnit from '../components/basic/InputUnit.vue';
export default {
components: {
FormCard,
InputUnit,
},
data() {
return {
email: null,
password: null,
loading: false,
};
},
methods: {
async login() {
console.log('triggered function');
this.loading = true;
try {
await auth.signInWithEmailAndPassword(this.email, this.password);
console.log('successfully logged in');
this.loading = false;
} catch (error) {
this.$store.dispatch('addNotification', {
title: 'Error',
message: error,
type: 'danger',
});
this.loading = false;
}
},
},
};
</script>

0 comments on commit 86fe222

Please sign in to comment.