start ui with login

This commit is contained in:
2021-11-03 14:10:03 +01:00
commit e3f2e12df4
20 changed files with 28460 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

24
README.md Normal file
View File

@@ -0,0 +1,24 @@
# noscomptes
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Lints and fixes files
```
npm run lint
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

5
babel.config.js Normal file
View File

@@ -0,0 +1,5 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

0
database.vuerd Normal file
View File

27737
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

48
package.json Normal file
View File

@@ -0,0 +1,48 @@
{
"name": "noscomptes",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"axios": "^0.21.1",
"bootstrap": "^5.1.3",
"bootstrap-vue": "^2.21.2",
"core-js": "^3.6.5",
"vue": "^2.6.14",
"vue-axios": "^3.2.4",
"vue-router": "^3.5.1",
"vuex": "^3.6.2"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~4.5.0",
"@vue/cli-plugin-eslint": "~4.5.0",
"@vue/cli-service": "~4.5.0",
"babel-eslint": "^10.1.0",
"eslint": "^6.7.2",
"eslint-plugin-vue": "^6.2.2",
"vue-template-compiler": "^2.6.11"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/essential",
"eslint:recommended"
],
"parserOptions": {
"parser": "babel-eslint"
},
"rules": {}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

17
public/index.html Normal file
View File

@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<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">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

14
src/App.vue Normal file
View File

@@ -0,0 +1,14 @@
<template>
<div id="app">
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'vue_signup'
}
</script>
<style>
</style>

170
src/assets/css/style.css Normal file
View File

@@ -0,0 +1,170 @@
body {
font-family: Arial, Helvetica, sans-serif;
font-size: 14px;
background: #0069ff;
}
/* Style the tab */
.tab {
overflow: hidden;
border: 1px solid #ccc;
background-color: #f1f1f1;
}
/* Style the buttons inside the tab */
.tab a {
background-color: inherit;
float: right;
cursor: pointer;
padding: 14px 16px;
transition: 0.3s;
font-size: 17px;
text-decoration: none;
border: 1px solid;
}
/* Change background color of buttons on hover */
.tab a:hover {
background-color: #ddd;
}
/* Create an active/current tablink class */
.tab a.active {
background-color: #ccc;
}
/* Style the tab content */
.tabcontent {
display: none;
padding: 6px 12px;
border: 1px solid #ccc;
border-top: none;
}
.loginsuccess-container {
padding: 20px;
margin: 0 auto;
width: 80%;
box-shadow: beige;
border: 1px solid #ccc;
border-radius: 5px;
background: #fff;
word-break: break-all;
}
.main-container {
margin-top: 10%;
}
.box-container {
padding: 20px;
margin: 0 auto;
width: 400px;
box-shadow: beige;
border: 1px solid #ccc;
border-radius: 5px;
background: #fff;
}
.heading {
text-align: center;
font-weight: 300;
color: #444;
margin: 0 auto 45px;
font-size: 35px;
line-height: 38px;
text-transform: none;
letter-spacing: 0;
}
.form-fields, .form-fields button {
width: 100%;
margin: 5px 0;
line-height: 28px;
border-radius: 5px;
}
.form-fields input {
width: 100%;
line-height: 40px;
border-radius: 5px;
border-radius: 5px;
border: 1px solid #f1f1f1;
background: #fff;
padding: 0 5px;
font-size: 14px;
}
.signIn {
padding: 10px 32px;
color: white;
font-size: 16px;
font-weight: 400;
background: #15CD72;
text-align: center;
cursor: pointer;
height: auto;
-webkit-appearance: none;
}
.createaccount {
padding: 15px;
background-color: #0069ff;
border: none;
color: #fff;
font-size: 16px;
font-weight: 400;
height: 48px;
line-height: 48px;
padding: 0 32px;
text-align: center;
border-radius: 5px;
}
.center {
text-align: center
}
.login-choice span {
color: #5b6987;
display: -ms-grid;
display: grid;
font-size: 16px;
width: 100%;
line-height: 40px;
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
text-align: center;
-ms-grid-columns: minmax(20px,1fr) auto minmax(20px,1fr);
grid-template-columns: minmax(20px,1fr) auto minmax(20px,1fr);
grid-gap: 19px;
}
.login-choice span:after, .login-choice span:before {
content: "";
border-top: 1px solid #e5e8ed;
}
.signup-buttons {
margin-top: 15px;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
-webkit-box-pack: justify;
-ms-flex-pack: justify;
justify-content: center;
position: relative;
}
.facebook-signup, .google-signup {
color: #031b4e;
background: #f2f8ff;
border: 1px solid rgba(0,105,255,.2);
-webkit-box-sizing: border-box;
box-sizing: border-box;
border-radius: 3px;
display: inline-block;
margin-top: 0;
width: 47.5%;
padding: 15px;
text-align: center;
position: inherit;
}
.signup-buttons a {
vertical-align: middle;
text-decoration: none;
}
.signup-buttons svg {
left: 16px;
position: absolute;
top: 50%;
-webkit-transform: translateY(-50%);
transform: translateY(-50%);
}
.footer, .footer a {
text-align: center;
color: #fff
}

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@@ -0,0 +1,40 @@
<template>
<div class="signup-buttons">
<a href="#" class="google-signup" @click.prevent="loginWithGoogle">
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18" aria-hidden="true"><title>Google</title><g fill="none" fill-rule="evenodd"><path fill="#4285F4" d="M17.64 9.2045c0-.6381-.0573-1.2518-.1636-1.8409H9v3.4814h4.8436c-.2086 1.125-.8427 2.0782-1.7959 2.7164v2.2581h2.9087c1.7018-1.5668 2.6836-3.874 2.6836-6.615z"></path><path fill="#34A853" d="M9 18c2.43 0 4.4673-.806 5.9564-2.1805l-2.9087-2.2581c-.8059.54-1.8368.859-3.0477.859-2.344 0-4.3282-1.5831-5.036-3.7104H.9574v2.3318C2.4382 15.9832 5.4818 18 9 18z"></path><path fill="#FBBC05" d="M3.964 10.71c-.18-.54-.2822-1.1168-.2822-1.71s.1023-1.17.2823-1.71V4.9582H.9573A8.9965 8.9965 0 0 0 0 9c0 1.4523.3477 2.8268.9573 4.0418L3.964 10.71z"></path><path fill="#EA4335" d="M9 3.5795c1.3214 0 2.5077.4541 3.4405 1.346l2.5813-2.5814C13.4632.8918 11.426 0 9 0 5.4818 0 2.4382 2.0168.9573 4.9582L3.964 7.29C4.6718 5.1627 6.6559 3.5795 9 3.5795z"></path></g></svg>
Google
</a>
</div>
</template>
<script>
import router from '@/router/router'
import {logWithGoogle} from '@/config/noscomptes'
export default {
name: 'login_signup_social',
mounted () {
},
methods: {
loginWithGoogle () {
this.$gAuth
.signIn()
.then(GoogleUser => {
logWithGoogle(GoogleUser.getAuthResponse().id_token)
// on success do something
console.log('GoogleUser', GoogleUser)
let userInfoMapped = {
googleId: GoogleUser.wa,
firstName: GoogleUser.mt.Re,
email: GoogleUser.mt.Xt,
oauth_token: GoogleUser.Zb.access_token,
}
this.$store.commit('setLoginUser', userInfoMapped)
router.push('/')
})
.catch(error => {
console.log('error', error)
})
},
}
}
</script>

146
src/config/google_oAuth.js Normal file
View File

@@ -0,0 +1,146 @@
var googleAuth = (function () {
function installClient () {
var apiUrl = 'https://apis.google.com/js/api.js'
return new Promise((resolve) => {
var script = document.createElement('script')
script.src = apiUrl
script.onreadystatechange = script.onload = function () {
if (!script.readyState || /loaded|complete/.test(script.readyState)) {
setTimeout(function () {
resolve()
}, 500)
}
}
document.getElementsByTagName('head')[0].appendChild(script)
})
}
function initClient (config) {
return new Promise((resolve) => {
window.gapi.load('auth2', () => {
window.gapi.auth2.init(config)
.then(() => {
resolve(window.gapi)
})
})
})
}
function Auth () {
if (!(this instanceof Auth))
return new Auth()
this.GoogleAuth = null /* window.gapi.auth2.getAuthInstance() */
this.isAuthorized = false
this.isInit = false
this.prompt = null
this.isLoaded = function () {
/* eslint-disable */
console.warn('isLoaded() will be deprecated. You can use "this.$gAuth.isInit"')
return !!this.GoogleAuth
}
this.load = (config, prompt) => {
installClient()
.then(() => {
return initClient(config)
})
.then((gapi) => {
this.GoogleAuth = gapi.auth2.getAuthInstance()
this.isInit = true
this.prompt = prompt
this.isAuthorized = this.GoogleAuth.isSignedIn.get()
})
}
this.signIn = (successCallback, errorCallback) => {
return new Promise((resolve, reject) => {
if (!this.GoogleAuth) {
if (typeof errorCallback === 'function') errorCallback(false)
reject(false)
return
}
this.GoogleAuth.signIn()
.then(googleUser => {
if (typeof successCallback === 'function') successCallback(googleUser)
this.isAuthorized = this.GoogleAuth.isSignedIn.get()
resolve(googleUser)
})
.catch(error => {
if (typeof errorCallback === 'function') errorCallback(error)
reject(error)
})
})
}
this.getAuthCode = (successCallback, errorCallback) => {
return new Promise((resolve, reject) => {
if (!this.GoogleAuth) {
if (typeof errorCallback === 'function') errorCallback(false)
reject(false)
return
}
this.GoogleAuth.grantOfflineAccess({ prompt: this.prompt })
.then(function (resp) {
if (typeof successCallback === 'function') successCallback(resp.code)
resolve(resp.code)
})
.catch(function (error) {
if (typeof errorCallback === 'function') errorCallback(error)
reject(error)
})
})
}
this.signOut = (successCallback, errorCallback) => {
return new Promise((resolve, reject) => {
if (!this.GoogleAuth) {
if (typeof errorCallback === 'function') errorCallback(false)
reject(false)
return
}
this.GoogleAuth.signOut()
.then(() => {
if (typeof successCallback === 'function') successCallback()
this.isAuthorized = false
resolve(true)
})
.catch(error => {
if (typeof errorCallback === 'function') errorCallback(error)
reject(error)
})
})
}
}
return new Auth()
})()
function installGoogleAuthPlugin(Vue, options) {
//set config
let GoogleAuthConfig = null
let GoogleAuthDefaultConfig = { scope: 'profile email', discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest'] }
let prompt = 'select_account'
if (typeof options === 'object') {
GoogleAuthConfig = Object.assign(GoogleAuthDefaultConfig, options)
if (options.scope) GoogleAuthConfig.scope = options.scope
if (options.prompt) prompt = options.prompt
if (!options.clientId) {
console.warn('clientId is required')
}
} else {
console.warn('invalid option type. Object type accepted only')
}
//Install Vue plugin
Vue.gAuth = googleAuth
Object.defineProperties(Vue.prototype, {
$gAuth: {
get: function () {
return Vue.gAuth
}
}
})
Vue.gAuth.load(GoogleAuthConfig, prompt)
}
export default installGoogleAuthPlugin

15
src/config/noscomptes.js Normal file
View File

@@ -0,0 +1,15 @@
import Vue from 'vue'
export const logWithGoogle = (oauthToken) => {
const headers = {
"Authorization": "Bearer "+oauthToken
};
return Vue.axios.post("http://localhost:8081/users", "{}",{headers})
}
export const getUserInformation = (oauthToken) => {
const headers = {
"Authorization": "Bearer "+oauthToken
};
return Vue.axios.get("http://localhost:8081/configuration", {headers})
}

25
src/config/utils.js Normal file
View File

@@ -0,0 +1,25 @@
/**
* Set localStorage
*/
export const setStore = (name, content) => {
if (!name) return
if (typeof content !== 'string') {
content = JSON.stringify(content)
}
return window.localStorage.setItem(name, content)
}
/**
* Get localStorage
*/
export const getStore = (name) => {
if (!name) return
return JSON.parse(window.localStorage.getItem(name))
}
/**
* Clear localStorage
*/
export const removeItem = (name) => {
console.log(name)
if (!name) return
return window.localStorage.removeItem(name)
}

35
src/main.js Normal file
View File

@@ -0,0 +1,35 @@
import Vue from 'vue'
import App from './App.vue'
import router from './router/router'
import store from './store/store'
import axios from 'axios'
import VueAxios from 'vue-axios'
import '@/assets/css/style.css'
import GoogleAuth from '@/config/google_oAuth.js'
import { BootstrapVue, IconsPlugin } from 'bootstrap-vue'
// Import Bootstrap an BootstrapVue CSS files (order is important)
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'
const gauthOption = {
clientId: '61386079886-2k3g6793pgt5pha4rhdojpvgrkuccfj7.apps.googleusercontent.com',
scope: 'profile email',
prompt: 'select_account'
}
Vue.use(VueAxios, axios)
Vue.use(GoogleAuth, gauthOption)
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
// Make BootstrapVue available throughout your project
Vue.use(BootstrapVue)
// Optionally install the BootstrapVue icon components plugin
Vue.use(IconsPlugin)

47
src/router/router.js Normal file
View File

@@ -0,0 +1,47 @@
import Vue from 'vue'
import Router from 'vue-router'
import Home from '@/views/Home'
import Login from '@/views/Login'
import store from "../store/store";
Vue.use(Router)
let baseRoutes = [
{
path: '/',
name: 'Home',
component: Home,
},
{
path: '/home',
name: 'Home',
component: Home,
},
{
path: '/login',
name: 'Login',
component: Login
}
]
const router = new Router({
mode: 'history',
linkExactActiveClass: 'active',
base: process.env.BASE_URL,
routes: baseRoutes
})
router.beforeEach((to, from, next) => {
// redirect to login page if not logged in and trying to access a restricted page
const publicPages = ['/login']
const authRequired = !publicPages.includes(to.path)
const loggedIn = store.state.loggedUser
console.log(authRequired)
console.log(store.state.loggedUser)
if (authRequired && !loggedIn) {
console.log("Redirected")
return next('/login')
}
next()
})
export default router

33
src/store/store.js Normal file
View File

@@ -0,0 +1,33 @@
import Vue from 'vue'
import Vuex from 'vuex'
import { setStore, getStore } from '@/config/utils'
import {removeItem} from "../config/utils";
Vue.use(Vuex)
const user = getStore('user')
export default new Vuex.Store({
state: {
loggedUser: user
},
mutations: {
setLoginUser(state, user) {
state.loggedUser = user
setStore('user', user)
},
deleteLoginUser(state) {
console.log("delete user")
state.loggedUser = undefined
removeItem('user')
}
},
actions: {
},
getters: {
getLoginUserInfo(state) {
return state.loginUser
}
}
})

59
src/views/Home.vue Normal file
View File

@@ -0,0 +1,59 @@
<template>
<div>
<b-navbar toggleable="lg" type="dark" variant="info" fixed="fixed">
<!-- Right aligned nav items -->
<b-navbar-nav >
<b-nav-item href="#">Mes comptes</b-nav-item>
<b-nav-item href="#">Nos comptes</b-nav-item>
</b-navbar-nav>
<b-navbar-nav align="end" class="right-element">
<b-nav-item-dropdown left dropleft>
<!-- Using 'button-content' slot -->
<template #button-content>
<em>{{ $store.state.loggedUser.firstName}}</em>
</template>
<b-dropdown-item href="#">Profile</b-dropdown-item>
<b-dropdown-item @click="signOut" href="/">Sign Out</b-dropdown-item>
</b-nav-item-dropdown>
</b-navbar-nav>
</b-navbar>
</div>
</template>
<script>
import router from '@/router/router'
import {BDropdownItem, BNavbar, BNavbarNav, BNavItem, BNavItemDropdown} from "bootstrap-vue";
export default {
name: 'home',
components: {
BNavbar,
BNavbarNav,
BNavItem,
BNavItemDropdown,
BDropdownItem
},
methods: {
signOut() {
this.$gAuth
.signOut()
.then( () => {
this.$store.commit("deleteLoginUser")
router.push("/login")
})
},
},
}
</script>
<style>
.right-element {
margin-left: auto;
padding-right: 10px;
}
.right-element .dropdown-menu {
right: 0px;
}
</style>

22
src/views/Login.vue Normal file
View File

@@ -0,0 +1,22 @@
<template>
<div class="main-container">
<form>
<div class="box-container">
<h2 class="heading">Sign In with</h2>
<SocialLogin />
</div>
</form>
<div class="footer">
</div>
</div>
</template>
<script>
import SocialLogin from '@/components/SocialLogin'
export default {
name: 'login',
components: {
SocialLogin
}
}
</script>