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
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
render json: nil
end
@ -20,8 +20,11 @@ class UsersController < ApplicationController
def logout
set_current_user(nil)
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
def verify_login
@ -30,7 +33,7 @@ class UsersController < ApplicationController
if user = User.authenticate(params[:username], params[:password])
set_current_user(user)
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
format.html { flash[:error] = "Invalid credentials"; render :login }
format.json { render json: { success: false, message: 'Invalid Credentials', user: nil } }

View File

@ -1,6 +1,6 @@
<template>
<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-card">
<header class="modal-card-head">
@ -21,6 +21,7 @@
<script>
import AppIcon from "./AppIcon";
import { mapState } from "vuex";
export default {
props: {
@ -39,6 +40,12 @@
this.$refs.container.appendChild(this.$refs.modal);
},
computed: {
...mapState([
'error'
])
},
methods: {
close() {
this.$emit("dismiss");

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5899,6 +5899,10 @@ vue@^2.5.16:
version "2.5.16"
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:
version "3.0.1"
resolved "https://registry.yarnpkg.com/vuex/-/vuex-3.0.1.tgz#e761352ebe0af537d4bb755a9b9dc4be3df7efd2"