Skip to content

Instantly share code, notes, and snippets.

@JBreit
Created June 10, 2018 03:22
Show Gist options
  • Save JBreit/edc3aba1af1b3746bd433151403e2a36 to your computer and use it in GitHub Desktop.
Save JBreit/edc3aba1af1b3746bd433151403e2a36 to your computer and use it in GitHub Desktop.
// Body
$body-bg: #f5f8fa;
// Typography
$font-family-sans-serif: "Raleway", sans-serif;
$font-size-base: 0.9rem;
$line-height-base: 1.6;
import Vue from 'vue';
import VueRouter from 'vue-router';
import './bootstrap';
import router from './routes';
import store from './store';
window.Vue = Vue;
window.VueRouter = VueRouter;
Vue.use(VueRouter);
router.beforeEach((to, from, next) => {
if (to.matched.some(route => route.meta.requiresAuth) && !store.getters.isAuthenticated) {
next({ name: 'login' });
return;
}
if (to.path === '/login' && store.getters.isAuthenticated) {
next({ name: 'dashboard' });
return;
}
next();
});
const app = new Vue({
el: '#app',
router,
http: {
headers: {
'X-CSRF-Token': axios.defaults.headers.common['X-CSRF-TOKEN'],
}
},
computed: {
isAuthenticated() {
return this.$store.getters.isAuthenticated;
}
},
data() {
return {
};
},
mounted() {
},
store,
});
// Fonts
@import url("https://fonts.googleapis.com/css?family=Raleway:300,400,600");
// Variables
@import "variables";
// Bootstrap
@import '~bootstrap/scss/bootstrap';
.navbar-laravel {
background-color: #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.04);
}
window._ = require('lodash');
window.Popper = require('popper.js').default;
try {
window.$ = window.jQuery = require('jquery');
require('bootstrap');
} catch (e) {}
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
<template>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card card-default">
<div class="card-header">Dashboard Component</div>
<div class="card-body">
{{ data }}
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
data: '',
};
},
mounted() {
axios.get('/api/auth/dashboard', {
headers: {
Authorization: `Bearer ${ localStorage.getItem('token') }`,
}
})
.then(response => {
this.data = response.data.data;
});
}
}
</script>
<template>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card card-default">
<div class="card-header">Home Component</div>
<div class="card-body">
I'm the home component.
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
data: '',
};
},
mounted() {
}
}
</script>
<template>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card card-default">
<div class="card-header">Login</div>
<div class="card-body">
<form
method="POST"
action="/api/login"
v-on:submit.prevent="login">
<input type="hidden" name="_token" :value="csrf">
<div
class="form-group row"
v-bind:class="{ 'has-error': error && errors.email }">
<label
for="email"
class="col-sm-4 col-form-label text-md-right">
E-Mail Address
</label>
<div class="col-md-6">
<input
id="email"
type="email"
class="form-control"
name="email"
value=""
v-model="email"
required
autofocus>
<span
class="invalid-feedback"
v-if="error && errors.email">
{{ errors.email }}
</span>
</div>
</div>
<div
class="form-group row"
v-bind:class="{ 'has-error': error && errors.password }">
<label
for="password"
class="col-md-4 col-form-label text-md-right">
Password
</label>
<div class="col-md-6">
<input
id="password"
type="password"
class="form-control"
name="password"
v-model="password"
required>
<span
class="invalid-feedback"
v-if="error && errors.password">
{{ errors.password }}
</span>
</div>
</div>
<div class="form-group row">
<div class="col-md-6 offset-md-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember"> Remember Me
</label>
</div>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">
Login
</button>
<a class="btn btn-link" href="/password/reset">
Forgot Your Password?
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
csrf: '',
email: '',
error: '',
errors: '',
password: '',
}
},
methods: {
login() {
this.error = false;
axios.post('http://innermind/api/login', { email: this.email, password: this.password })
.then(response => {
this.$store.commit('login');
localStorage.setItem('token', response.data.token);
this.$router.push({ name: 'dashboard' });
})
.catch(error => this.error = true);
}
},
mounted() {
this.csrf = axios.defaults.headers.common['X-CSRF-TOKEN'];
}
}
</script>
<template>
</template>
<script>
export default {
mounted() {
localStorage.removeItem('token');
this.$store.commit('logout');
this.$router.push({ name: 'login' });
}
}
</script>
<template>
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card card-default">
<div class="card-header">Register</div>
<div class="card-body">
<form
method="POST"
action="/api/register">
<input
type="hidden"
name="_token"
:value="csrf">
<div
class="form-group row"
v-bind:class="{ 'has-error': error && errors.name }">
<label
for="name"
class="col-md-4 col-form-label text-md-right">
Name
</label>
<div class="col-md-6">
<input
id="name"
type="text"
class="form-control"
name="name"
value=""
v-model="name"
required
autofocus />
<span
class="invalid-feedback"
v-if="error && errors.name">
{{ errors.name }}
</span>
</div>
</div>
<div
class="form-group row"
v-bind:class="{ 'has-error': error && errors.email }">
<label
for="email"
class="col-md-4 col-form-label text-md-right">
E-Mail Address
</label>
<div class="col-md-6">
<input
id="email"
type="email"
class="form-control"
name="email"
value=""
v-model="email"
required />
<span
class="invalid-feedback"
v-if="error && errors.email">
{{ errors.email }}
</span>
</div>
</div>
<div
class="form-group row"
v-bind:class="{ 'has-error': error && errors.password }">
<label
for="password"
class="col-md-4 col-form-label text-md-right">
Password
</label>
<div class="col-md-6">
<input
id="password"
type="password"
class="form-control"
name="password"
v-model="password"
required />
<span
class="invalid-feedback"
v-if="error && errors.password">
{{ errors.password }}
</span>
</div>
</div>
<div
class="form-group row"
v-bind:class="{ 'has-error': error && errors.password }">
<label
for="password-confirm"
class="col-md-4 col-form-label text-md-right">
Confirm Password
</label>
<div class="col-md-6">
<input
id="password-confirm"
type="password"
class="form-control"
name="password_confirmation"
v-model="password"
required />
<span
class="invalid-feedback"
v-if="error && errors.password">
{{ errors.password }}
</span>
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-6 offset-md-4">
<button type="submit" class="btn btn-primary">
Register
</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
csrf: '',
name: '',
email: '',
password: '',
error: '',
errors: {},
success: '',
}
},
methods: {
register() {
}
},
mounted() {
this.csrf = axios.defaults.headers.common['X-CSRF-TOKEN'];
}
}
</script>
import VueRouter from 'vue-router';
import HomeComponent from './components/Home';
import LoginComponent from './components/Login';
import RegisterComponent from './components/Register';
import DashboardComponent from './components/Dashboard';
import UserComponent from './components/User';
import LogoutComponent from './components/Logout';
let routes = [
{
path: '/',
name: 'home',
component: HomeComponent,
},
{
path: '/login',
name: 'login',
component: LoginComponent,
},
{
path: '/register',
name: 'register',
component: RegisterComponent,
},
{
path: '/auth/dashboard',
name: 'dashboard',
component: DashboardComponent,
meta: { requiresAuth: true },
},
{
path: '/auth/user',
name: 'user',
component: UserComponent,
meta: { requiresAuth: true },
},
{
path: '/auth/logout',
name: 'logout',
component: LogoutComponent,
meta: { requiresAuth: true },
}
];
export default new VueRouter({
mode: 'history',
routes,
});
import Vue from 'vue';
import Vuex from 'vuex';
window.Vuex = Vuex;
Vue.use(Vuex);
const state = {
isLoggedIn: !!localStorage.getItem('token'),
token: localStorage.getItem('token') || '',
};
const getters = {
isAuthenticated: state => !!state.token,
};
const mutations = {
login(state) {
state.token = true;
},
logout(state) {
state.token = false;
}
};
export default new Vuex.Store({
state,
getters,
mutations,
});
<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
<base href="/">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>Laravel</title>
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app" class="flex-center position-ref full-height">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<router-link :to="{ name: 'home' }" class="navbar-brand">Innermind</router-link>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active" v-if="!isAuthenticated">
<router-link :to="{ name: 'home' }" class="nav-link">Home <span class="sr-only">(current)</span></router-link>
</li>
<li class="nav-item" v-if="isAuthenticated">
<router-link :to="{ name: 'dashboard' }" class="nav-link">Dashboard</router-link>
</li>
<li class="nav-item" v-if="isAuthenticated">
<router-link :to="{ name: 'user' }" class="nav-link">User</router-link>
</li>
<li class="nav-item" v-if="!isAuthenticated">
<router-link :to="{ name: 'login' }" class="nav-link">Login</router-link>
</li>
<li class="nav-item" v-if="!isAuthenticated">
<router-link :to="{ name: 'register' }" class="nav-link">Register</router-link>
</li>
<li class="nav-item" v-if="isAuthenticated">
<router-link :to="{ name: 'logout' }" class="nav-link">Logout</router-link>
</li>
</ul>
</div>
</nav>
<router-view class="content"></router-view>
</div>
<script src="{{ asset('js/app.js') }}"></script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment