Combining Vue.js!!! How exciting!

Adding Vue.js to handle frontend changes, leaving the server only need to response json data. Ditching flask template and hope it can reduce the memory and cpu usage :)
This commit is contained in:
Donald Zou
2023-11-30 09:42:02 -05:00
parent f07508073f
commit 0c0bce9755
15 changed files with 462 additions and 41 deletions

51
src/static/app/app.js Normal file
View File

@@ -0,0 +1,51 @@
const { createApp, ref } = Vue;
import Index from './index.js'
import Signin from './signin/signin.js'
const {createPinia} = Pinia
import {cookie} from "./cookie.js";
const app = createApp({
template: `
<nav class="navbar bg-dark fixed-top" data-bs-theme="dark">
<div class="container-fluid">
<span class="navbar-brand mb-0 h1">WGDashboard</span>
</div>
</nav>
<RouterView></RouterView>
`
});
const pinia = createPinia()
const routes = [
{
path: '/',
component: Index,
meta: {
requiresAuth: true
}
},
{
path: '/signin', component: Signin
}
]
const router = VueRouter.createRouter({
// 4. Provide the history implementation to use. We are using the hash history for simplicity here.
history: VueRouter.createWebHashHistory(),
routes, // short for `routes: routes`
});
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth){
if (cookie.getCookie("auth")){
next()
}else{
next("/signin")
}
}else {
next();
}
});
app.use(router);
app.use(pinia)
app.mount('#app');

9
src/static/app/cookie.js Normal file
View File

@@ -0,0 +1,9 @@
export const cookie = {
//https://stackoverflow.com/a/15724300
getCookie(name) {
const value = `; ${document.cookie}`;
const parts = value.split(`; ${name}=`);
if (parts.length === 2) return parts.pop().split(';').shift();
}
}

5
src/static/app/index.js Normal file
View File

@@ -0,0 +1,5 @@
export default {
template: `
this is idex
`
}

View File

@@ -0,0 +1,28 @@
export const fetchGet = async (url, params=undefined, callback=undefined) => {
const urlSearchParams = new URLSearchParams(params);
await fetch(`${url}?${urlSearchParams.toString()}}`, {
headers: {
"content-type": "application/json"
}
})
.then(x => x.json())
.then(x => callback ? callback(x) : undefined)
.catch(() => {
alert("Error occurred! Check console")
});
}
export const fetchPost = async (url, body, callback) => {
await fetch(`${url}`, {
headers: {
"content-type": "application/json"
},
method: "POST",
body: JSON.stringify(body)
})
.then(x => x.json())
.then(x => callback ? callback(x) : undefined)
// .catch(() => {
// alert("Error occurred! Check console")
// });
}

View File

@@ -0,0 +1,52 @@
import {fetchPost} from "./fetch.js";
export default {
data(){
return {
username: "",
password: ""
}
},
template: `
<div class="container-fluid login-container-fluid h-100 d-flex">
<div class="login-box m-auto" style="width: 500px;">
<h1 class="text-center">Sign in</h1>
<h5 class="text-center">to WGDashboard</h5>
<div class="m-auto">
<div class="alert alert-danger d-none" role="alert" style="margin-top: 1rem; margin-bottom: 0rem;"></div>
<div class="form-group">
<label for="username" class="text-left" style="font-size: 1rem"><i class="bi bi-person-circle"></i></label>
<input type="text" v-model="username" class="form-control" id="username" name="username" placeholder="Username" required>
</div>
<div class="form-group">
<label for="password" class="text-left" style="font-size: 1rem"><i class="bi bi-key-fill"></i></label>
<input type="password" v-model="password" class="form-control" id="password" name="password" placeholder="Password" required>
</div>
<button class="btn btn-dark w-100 mt-4" @click="this.auth()">Sign In</button>
</div>
</div>
</div>
`,
methods: {
async auth(){
if (this.username && this.password){
await fetchPost("/auth", {
username: this.username,
password: this.password
}, (response) => {
console.log(response)
})
}else{
document.querySelectorAll("input[required]").forEach(x => {
if (x.value.length === 0){
x.classList.remove("is-valid")
x.classList.add("is-invalid")
}else{
x.classList.remove("is-invalid")
x.classList.add("is-valid")
}
})
}
}
}
}

5
src/static/app/store.js Normal file
View File

@@ -0,0 +1,5 @@
import { defineStore } from 'pinia'
export const wgdStore = defineStore('WGDashboardStore', {
})

View File

@@ -89,8 +89,8 @@ body {
padding-top: .75rem;
padding-bottom: .75rem;
font-size: 1rem;
background-color: rgba(0, 0, 0, .25);
box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);
/*background-color: rgba(0, 0, 0, .25);*/
/*box-shadow: inset -1px 0 0 rgba(0, 0, 0, .25);*/
}
.navbar .navbar-toggler {
@@ -468,7 +468,7 @@ main {
.login-box label[for="password"] {
font-size: 1rem;
margin: 0 !important;
transform: translateY(30px) translateX(16px);
transform: translateY(2.1rem) translateX(1rem);
padding: 0;
}