diff --git a/front/package.json b/front/package.json index e4355926877f4c633ba0298e2a1ec8341ea16da9..4dd9ba87e7e81fa7a7b374866bfe8d2235a4b4bc 100644 --- a/front/package.json +++ b/front/package.json @@ -8,8 +8,10 @@ "lint": "vue-cli-service lint" }, "dependencies": { + "axios": "^0.18.0", "pug": "^2.0.3", "register-service-worker": "^1.5.2", + "semantic-ui-vue": "^0.7.0", "vue": "^2.5.22", "vue-router": "^3.0.1", "vuex": "^3.0.1" diff --git a/front/public/img/wallpaper.jpg b/front/public/img/wallpaper.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8c175c8dab03ba5ffdf4338e6c08addc4fadabee Binary files /dev/null and b/front/public/img/wallpaper.jpg differ diff --git a/front/public/index.html b/front/public/index.html index 5514f8289d3904c9eb922fe1cbc7fe46c3a1d637..35239811aa290bb59e428c968efb3c5e1fcd110f 100644 --- a/front/public/index.html +++ b/front/public/index.html @@ -5,9 +5,11 @@ <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width,initial-scale=1.0"> <link rel="icon" href="<%= BASE_URL %>favicon.ico"> + <link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.3.0/semantic.min.css"> <title>front</title> </head> <body> + <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script> <noscript> <strong>We're sorry but front doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> </noscript> diff --git a/front/src/App.vue b/front/src/App.vue index ab8fe3c0a0586e85f4430d14ed127a1e7fcb87d6..913958c12c9e304327080cff49d1006fd02c8183 100644 --- a/front/src/App.vue +++ b/front/src/App.vue @@ -1,31 +1,25 @@ -<template> - <div id="app"> - <div id="nav"> - <router-link to="/">Home</router-link> | - <router-link to="/about">About</router-link> - </div> - <router-view /> - </div> +<template lang="pug"> + .app + NavBar + .ui.grid + .three.wide.column + .ten.wide.column + router-view + .three.wide.column + //- notifications </template> -<style> -#app { - font-family: "Avenir", Helvetica, Arial, sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - text-align: center; - color: #2c3e50; -} -#nav { - padding: 30px; +<script> +import NavBar from "@/components/NavBar.vue"; +export default { + name: "App", + components: { + NavBar, + }, } +</script> -#nav a { - font-weight: bold; - color: #2c3e50; -} -#nav a.router-link-exact-active { - color: #42b983; -} +<style> + </style> diff --git a/front/src/components/NavBar.vue b/front/src/components/NavBar.vue new file mode 100644 index 0000000000000000000000000000000000000000..21c0fc56253cfbe2bab575ec82a2e7eec7e1b2ae --- /dev/null +++ b/front/src/components/NavBar.vue @@ -0,0 +1,49 @@ +<template lang="pug"> + sui-menu(pointing) + router-link(is="sui-menu-item", to="/") Home + router-link(v-if="user", is="sui-menu-item", to="/characters") Characters + sui-menu-menu(v-if="!user", position="right") + sui-menu-item + sui-input(transparent, type="text", placeholder="username", v-model="username") + sui-input(transparent, type="password", placeholder="password", v-model="password") + sui-button(@click="login") Login + sui-menu-menu(v-else, position="right") + sui-menu-item {{ user.username }} + sui-menu-item + sui-button(@click="logout") Logout +</template> + +<script> +export default { + name: "NavBar", + data() { + return { + username: "", + password: "", + } + }, + computed: { + user() { + return this.$store.state.user; + } + }, + created() { + this.$store.dispatch("login"); + }, + methods: { + login() { + this.$store.dispatch("authRequest", { + username: this.username, + password: this.password + }); + }, + logout() { + this.$store.dispatch("logout"); + } + } +} +</script> + +<style scoped> + +</style> diff --git a/front/src/http.js b/front/src/http.js new file mode 100644 index 0000000000000000000000000000000000000000..1b9024fa048047ba493fb2b498a768b83d98408d --- /dev/null +++ b/front/src/http.js @@ -0,0 +1,12 @@ +import axios from "axios"; + +export default function() { + return axios.create({ + baseUrl: "http://localhost:3000/", + timeout: 1000, + headers: { + Authorization: localStorage.getItem("token"), + "Content-Type": "application/json" + } + }); +} diff --git a/front/src/main.js b/front/src/main.js index 9466dcc769bed98c9fd9c1d761638576262251ba..014159cef83c8f0608734bde846bc031869d2326 100644 --- a/front/src/main.js +++ b/front/src/main.js @@ -3,8 +3,10 @@ import App from "./App.vue"; import router from "./router"; import store from "./store"; import "./registerServiceWorker"; +import SuiVue from "semantic-ui-vue"; Vue.config.productionTip = false; +Vue.use(SuiVue); new Vue({ router, diff --git a/front/src/store.js b/front/src/store.js index bb02ce2d2c3ace184b1b4d9f5e98b67d9973b3d8..b0e6bcc28539f2afc023768bae4ac71dd8aca903 100644 --- a/front/src/store.js +++ b/front/src/store.js @@ -1,10 +1,53 @@ import Vue from "vue"; import Vuex from "vuex"; +import http from "@/http"; Vue.use(Vuex); export default new Vuex.Store({ - state: {}, - mutations: {}, - actions: {} + state: { + status: "", + user: null + }, + getters: { + isAuthenticated: state => !!localStorage.getItem("token") && !!state.user, + authStatus: state => state.status, + user: state => state.user + }, + mutations: { + ["AUTH_REQUEST"]: state => (state.status = "loading"), + ["AUTH_SUCCESS"]: (state, user) => { + state.status = "success"; + state.user = user; + }, + ["AUTH_ERROR"]: state => (state.status = "error"), + ["LOGOUT"]: state => { + state.user = null; + state.status = "success"; + } + }, + actions: { + authRequest: ({ commit }, credentials) => { + commit("AUTH_REQUEST"); + http() + .post("http://localhost:3000/users/authenticate", credentials) + .then(res => { + localStorage.setItem("token", res.data.token); + commit("AUTH_SUCCESS", res.data); + }) + .catch(() => commit("AUTH_ERROR")); + }, + logout: ({ commit }) => { + localStorage.removeItem("token"); + commit("LOGOUT"); + }, + login: ({ commit }) => { + if (localStorage.getItem("token")) { + http() + .get("http://localhost:3000/users/me") + .then(res => commit("AUTH_SUCCESS", res.data)) + .catch(() => commit("AUTH_ERROR")); + } + } + } });