This commit is contained in:
Dan Elbert 2018-04-01 12:17:54 -05:00
parent 97eca6d319
commit 5579876c63
10 changed files with 77 additions and 16 deletions

View File

@ -7,7 +7,7 @@ class UsersController < ApplicationController
def show def show
if current_user if current_user
render json: { id: current_user.id, name: current_user.display_name } render json: { id: current_user.id, name: current_user.display_name, admin: current_user.admin? }
else else
render json: nil render json: nil
end end
@ -20,8 +20,11 @@ class UsersController < ApplicationController
def logout def logout
set_current_user(nil) set_current_user(nil)
session.destroy session.destroy
flash[:notice] = "Logged out"
redirect_to root_path respond_to do |format|
format.html { redirect_to root_path, notice: "Logged out" }
format.json { render json: { success: true } }
end
end end
def verify_login def verify_login
@ -30,7 +33,7 @@ class UsersController < ApplicationController
if user = User.authenticate(params[:username], params[:password]) if user = User.authenticate(params[:username], params[:password])
set_current_user(user) set_current_user(user)
format.html { redirect_to root_path, notice: "Welcome, #{user.display_name}" } format.html { redirect_to root_path, notice: "Welcome, #{user.display_name}" }
format.json { render json: { success: true, user: { id: user.id, name: user.display_name } } } format.json { render json: { success: true, user: { id: user.id, name: user.display_name, admin: user.admin? } } }
else else
format.html { flash[:error] = "Invalid credentials"; render :login } format.html { flash[:error] = "Invalid credentials"; render :login }
format.json { render json: { success: false, message: 'Invalid Credentials', user: nil } } format.json { render json: { success: false, message: 'Invalid Credentials', user: nil } }

View File

@ -1,6 +1,6 @@
<template> <template>
<div ref="container"> <div ref="container">
<div ref="modal" :class="['popup', 'modal', { 'is-active': open }]"> <div ref="modal" :class="['popup', 'modal', { 'is-active': open && error === null }]">
<div class="modal-background" @click="close"></div> <div class="modal-background" @click="close"></div>
<div class="modal-card"> <div class="modal-card">
<header class="modal-card-head"> <header class="modal-card-head">
@ -21,6 +21,7 @@
<script> <script>
import AppIcon from "./AppIcon"; import AppIcon from "./AppIcon";
import { mapState } from "vuex";
export default { export default {
props: { props: {
@ -39,6 +40,12 @@
this.$refs.container.appendChild(this.$refs.modal); this.$refs.container.appendChild(this.$refs.modal);
}, },
computed: {
...mapState([
'error'
])
},
methods: { methods: {
close() { close() {
this.$emit("dismiss"); this.$emit("dismiss");

View File

@ -17,8 +17,8 @@
<router-link to="/ingredients" class="navbar-item">Ingredients</router-link> <router-link to="/ingredients" class="navbar-item">Ingredients</router-link>
<router-link to="/calculator" class="navbar-item">Calculator</router-link> <router-link to="/calculator" class="navbar-item">Calculator</router-link>
<router-link to="/about" class="navbar-item">About</router-link> <router-link to="/about" class="navbar-item">About</router-link>
<router-link to="/notes" class="navbar-item">Notes</router-link> <router-link v-if="isLoggedIn" to="/notes" class="navbar-item">Notes</router-link>
<a class="navbar-item" href="/admin/users">Admin</a> <a v-if="isAdmin" class="navbar-item" href="/admin/users">Admin</a>
</div> </div>
<div class="navbar-end"> <div class="navbar-end">
@ -31,9 +31,7 @@
<a class="navbar-item" href="#"> <a class="navbar-item" href="#">
Profile Profile
</a> </a>
<a class="navbar-item" href="#"> <router-link to="/logout" class="navbar-item">Logout</router-link>
Logout
</a>
</div> </div>
</div> </div>
<div v-else> <div v-else>
@ -50,6 +48,7 @@
<script> <script>
import UserLogin from "./UserLogin"; import UserLogin from "./UserLogin";
import { mapState } from "vuex";
export default { export default {
data() { data() {
@ -57,6 +56,24 @@
menuActive: false menuActive: false
}; };
}, },
computed: {
...mapState([
'route',
'user'
])
},
watch: {
route() {
this.menuActive = false;
},
user() {
this.menuActive = false;
}
},
components: { components: {
UserLogin UserLogin
} }

View File

@ -93,6 +93,10 @@ class Api {
return this.post("/login", params); return this.post("/login", params);
} }
getLogout() {
return this.get("/logout");
}
getCurrentUser() { getCurrentUser() {
return this.get("/user") return this.get("/user")
} }

View File

@ -6,7 +6,8 @@ Vue.mixin({
computed: { computed: {
...mapGetters([ ...mapGetters([
"isLoading", "isLoading",
"isLoggedIn" "isLoggedIn",
"isAdmin"
]), ]),
...mapState([ ...mapState([
"user" "user"

View File

@ -1,6 +1,7 @@
import '../styles'; import '../styles';
import Vue from 'vue' import Vue from 'vue'
import { sync } from 'vuex-router-sync';
import config from '../config'; import config from '../config';
import store from '../store'; import store from '../store';
import router from '../router'; import router from '../router';
@ -8,7 +9,7 @@ import '../lib/GlobalMixins';
import App from '../components/App'; import App from '../components/App';
//Vue.use(VueClipboard); //Vue.use(VueClipboard);
//sync(store, router); sync(store, router);
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {

View File

@ -12,8 +12,12 @@ import TheRecipeList from './components/TheRecipeList';
Vue.use(Router); Vue.use(Router);
export default new Router({ const router = new Router({
routes: [ routes: []
});
router.addRoutes(
[
{ {
path: '/', path: '/',
name: 'recipeList', name: 'recipeList',
@ -49,9 +53,20 @@ export default new Router({
name: "notes", name: "notes",
component: TheNotesList component: TheNotesList
}, },
{
path: "/logout",
name: "logout",
beforeEnter: (to, from, next) => {
const $store = router.app.$store;
$store.dispatch("logout")
.then(() => next("/"));
}
},
{ {
path: '*', path: '*',
component: The404Page component: The404Page
} }
] ]
}) );
export default router;

View File

@ -1,6 +1,8 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import api from '../lib/Api';
Vue.use(Vuex); Vue.use(Vuex);
export default new Vuex.Store({ export default new Vuex.Store({
@ -17,6 +19,9 @@ export default new Vuex.Store({
}, },
isLoggedIn(state) { isLoggedIn(state) {
return state.user !== null; return state.user !== null;
},
isAdmin(state) {
return state.user !== null && state.user.admin === true;
} }
}, },
mutations: { mutations: {
@ -34,6 +39,9 @@ export default new Vuex.Store({
} }
}, },
actions: { actions: {
logout({commit}) {
return api.getLogout()
.then(() => commit("setUser", null));
}
} }
}); });

View File

@ -11,6 +11,7 @@
"vue-router": "^3.0.1", "vue-router": "^3.0.1",
"vue-template-compiler": "^2.5.16", "vue-template-compiler": "^2.5.16",
"vuex": "^3.0.1", "vuex": "^3.0.1",
"vuex-router-sync": "^5.0.0",
"webpack": "^3.11.0" "webpack": "^3.11.0"
}, },
"devDependencies": { "devDependencies": {

View File

@ -5899,6 +5899,10 @@ vue@^2.5.16:
version "2.5.16" version "2.5.16"
resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085" resolved "https://registry.yarnpkg.com/vue/-/vue-2.5.16.tgz#07edb75e8412aaeed871ebafa99f4672584a0085"
vuex-router-sync@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/vuex-router-sync/-/vuex-router-sync-5.0.0.tgz#1a225c17a1dd9e2f74af0a1b2c62072e9492b305"
vuex@^3.0.1: vuex@^3.0.1:
version "3.0.1" version "3.0.1"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2" resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"