mirror of
https://github.com/notherealmarco/WASAPhoto.git
synced 2025-05-06 12:49:37 +02:00
First webui commit
This commit is contained in:
parent
e38f5d08ab
commit
c4611b92f8
2011 changed files with 30382 additions and 1874 deletions
|
@ -8,7 +8,7 @@ export default {}
|
|||
<template>
|
||||
|
||||
<header class="navbar navbar-dark sticky-top bg-dark flex-md-nowrap p-0 shadow">
|
||||
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="#/">Example App</a>
|
||||
<a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="#/">WASAPhoto</a>
|
||||
<button class="navbar-toggler position-absolute d-md-none collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#sidebarMenu" aria-controls="sidebarMenu" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
|
|
@ -7,7 +7,7 @@ export default {
|
|||
<template>
|
||||
<div v-if="loading">
|
||||
<div style="text-align: center">
|
||||
<div class="spinner-border" role="status">
|
||||
<div class="spinner-grow" role="status">
|
||||
<span class="visually-hidden">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
|
|
90
webui/src/components/PostCard.vue
Normal file
90
webui/src/components/PostCard.vue
Normal file
|
@ -0,0 +1,90 @@
|
|||
<script>
|
||||
|
||||
export default {
|
||||
props: ["user_id", "name", "date", "comments", "likes", "photo_id", "liked", "my_id"],
|
||||
data: function() {
|
||||
return {
|
||||
imageSrc: "",
|
||||
errorMsg: null,
|
||||
post_liked: this.liked,
|
||||
post_like_cnt: this.likes,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
like() {
|
||||
this.$axios.put("/users/" + this.user_id + "/photos/" + this.photo_id + "/likes/" + this.my_id).then(response => {
|
||||
this.post_liked = true;
|
||||
this.post_like_cnt++;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
this.errorMsg = error.toString();
|
||||
});
|
||||
},
|
||||
unlike() {
|
||||
this.$axios.delete("/users/" + this.user_id + "/photos/" + this.photo_id + "/likes/" + this.my_id).then(response => {
|
||||
this.post_liked = false;
|
||||
this.post_like_cnt--;
|
||||
}).catch(error => {
|
||||
console.log(error);
|
||||
this.errorMsg = error.toString();
|
||||
});
|
||||
},
|
||||
},
|
||||
|
||||
created() {
|
||||
this.$axios.get("/users/" + this.user_id + "/photos/" + this.photo_id, {
|
||||
responseType: 'arraybuffer'
|
||||
}).then(response => {
|
||||
const img = document.createElement('img');
|
||||
img.src = URL.createObjectURL(new Blob([response.data]));
|
||||
img.classList.add("card-img-top");
|
||||
this.$refs.imageContainer.appendChild(img);
|
||||
});
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="card mb-5">
|
||||
<!--<img v-auth-img="imageSrc" class="card-img-top" alt="Chicago Skyscrapers"/>-->
|
||||
<div ref="imageContainer"></div>
|
||||
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-10">
|
||||
<div class="card-body">
|
||||
<h5 class="card-title">{{ name }}</h5>
|
||||
<p class="card-text">{{ new Date(Date.parse(date)) }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-2">
|
||||
<div class="card-body d-flex justify-content-end" style="display: inline-flex"> <!-- not quite sure flex is the right property, but it works -->
|
||||
<a><h5><i class="card-title bi bi-chat-right pe-1"></i></h5></a>
|
||||
<h6 class="card-text d-flex align-items-end text-muted">{{ comments }}</h6>
|
||||
<a v-if="!post_liked" @click="like"><h5><i class="card-title bi bi-suit-heart ps-2 pe-1 like-icon"></i></h5></a>
|
||||
<a v-if="post_liked" @click="unlike"><h5><i class="card-title bi bi-heart-fill ps-2 pe-1 like-icon like-red"></i></h5></a>
|
||||
<h6 class="card-text d-flex align-items-end text-muted">{{ post_like_cnt }}</h6>
|
||||
<h5></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!--<ul class="list-group list-group-light list-group-small">
|
||||
<li class="list-group-item px-4">Cras justo odio</li>
|
||||
<li class="list-group-item px-4">Dapibus ac facilisis in</li>
|
||||
<li class="list-group-item px-4">Vestibulum at eros</li>
|
||||
</ul>-->
|
||||
</div>
|
||||
<ErrorMsg v-if="errormsg" :msg="errormsg"></ErrorMsg>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
.like-icon:hover {
|
||||
color: #ff0000;
|
||||
}
|
||||
.like-red {
|
||||
color: #ff0000;
|
||||
}
|
||||
</style>
|
|
@ -1,16 +1,20 @@
|
|||
import {createApp, reactive} from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import axios from './services/axios.js';
|
||||
import { axios, updateToken as axiosUpdate } from './services/axios.js';
|
||||
import ErrorMsg from './components/ErrorMsg.vue'
|
||||
import LoadingSpinner from './components/LoadingSpinner.vue'
|
||||
import PostCard from './components/PostCard.vue'
|
||||
import 'bootstrap-icons/font/bootstrap-icons.css'
|
||||
|
||||
import './assets/dashboard.css'
|
||||
import './assets/main.css'
|
||||
|
||||
const app = createApp(App)
|
||||
app.config.globalProperties.$axios = axios;
|
||||
app.config.globalProperties.$axiosUpdate = axiosUpdate;
|
||||
app.component("ErrorMsg", ErrorMsg);
|
||||
app.component("LoadingSpinner", LoadingSpinner);
|
||||
app.component("PostCard", PostCard);
|
||||
app.use(router)
|
||||
app.mount('#app')
|
||||
app.mount('#app')
|
|
@ -1,10 +1,12 @@
|
|||
import {createRouter, createWebHashHistory} from 'vue-router'
|
||||
import HomeView from '../views/HomeView.vue'
|
||||
import LoginView from '../views/LoginView.vue'
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(import.meta.env.BASE_URL),
|
||||
routes: [
|
||||
{path: '/', component: HomeView},
|
||||
{path: '/login', component: LoginView},
|
||||
{path: '/link1', component: HomeView},
|
||||
{path: '/link2', component: HomeView},
|
||||
{path: '/some/:id/link', component: HomeView},
|
||||
|
|
|
@ -5,4 +5,18 @@ const instance = axios.create({
|
|||
timeout: 1000 * 5
|
||||
});
|
||||
|
||||
export default instance;
|
||||
//axios.interceptors.request.use(function (config) {
|
||||
// const token = sessionStorage.getItem('token');
|
||||
// if (!token) return config;
|
||||
// config.headers.Authorization = "Bearer " + token;
|
||||
// return config;
|
||||
//});
|
||||
|
||||
const updateToken = () => {
|
||||
instance.defaults.headers.common['Authorization'] = 'Bearer ' + sessionStorage.getItem('token');
|
||||
}
|
||||
|
||||
export {
|
||||
instance as axios,
|
||||
updateToken as updateToken,
|
||||
}
|
||||
|
|
|
@ -4,7 +4,8 @@ export default {
|
|||
return {
|
||||
errormsg: null,
|
||||
loading: false,
|
||||
some_data: null,
|
||||
stream_data: null,
|
||||
my_id: sessionStorage.getItem("token"),
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -12,12 +13,16 @@ export default {
|
|||
this.loading = true;
|
||||
this.errormsg = null;
|
||||
try {
|
||||
let response = await this.$axios.get("/");
|
||||
this.some_data = response.data;
|
||||
let response = await this.$axios.get("/stream");
|
||||
this.stream_data = response.data;
|
||||
this.errormsg = this.stream_data; // TODO: temporary
|
||||
this.loading = false;
|
||||
} catch (e) {
|
||||
if (e.response.status == 401) {
|
||||
this.$router.push({ path: "/login" });
|
||||
}
|
||||
this.errormsg = e.toString();
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
|
@ -48,7 +53,28 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<ErrorMsg v-if="errormsg" :msg="errormsg"></ErrorMsg>
|
||||
<div class="container">
|
||||
<div class="row justify-content-md-center">
|
||||
<div class="col-xl-6 col-lg-9">
|
||||
|
||||
<ErrorMsg v-if="errormsg" :msg="errormsg"></ErrorMsg>
|
||||
|
||||
<div id="main-content" v-for="item of stream_data">
|
||||
<PostCard :user_id="item.user_id"
|
||||
:photo_id="item.photo_id"
|
||||
:name="item.name"
|
||||
:date="item.date"
|
||||
:comments="item.comments"
|
||||
:likes="item.likes"
|
||||
:liked="item.liked"
|
||||
:my_id="my_id" />
|
||||
</div>
|
||||
|
||||
<LoadingSpinner :loading="loading" /><br />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
105
webui/src/views/LoginView.vue
Normal file
105
webui/src/views/LoginView.vue
Normal file
|
@ -0,0 +1,105 @@
|
|||
<script>
|
||||
import LoadingSpinner from '../components/LoadingSpinner.vue';
|
||||
|
||||
export default {
|
||||
data: function () {
|
||||
return {
|
||||
errormsg: null,
|
||||
loading: false,
|
||||
some_data: null,
|
||||
field_username: "",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
async login() {
|
||||
this.loading = true;
|
||||
this.errormsg = null;
|
||||
try {
|
||||
let response = await this.$axios.post("/session", {
|
||||
name: this.field_username,
|
||||
});
|
||||
//this.$router.push({ name: "home" });
|
||||
if (response.status == 201 || response.status == 200) {
|
||||
// Save the token in the session storage
|
||||
sessionStorage.setItem("token", response.data["user_id"]);
|
||||
|
||||
// Update the header
|
||||
this.$axiosUpdate();
|
||||
|
||||
this.$router.push({ path: "/" });
|
||||
}
|
||||
else {
|
||||
this.errormsg = response.data["error"];
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
this.errormsg = e.toString();
|
||||
}
|
||||
this.loading = false;
|
||||
},
|
||||
async refresh() {
|
||||
//this.loading = true;
|
||||
//this.errormsg = null;
|
||||
//try {
|
||||
// let response = await this.$axios.get("/");
|
||||
// this.some_data = response.data;
|
||||
//} catch (e) {
|
||||
// this.errormsg = e.toString();
|
||||
//}
|
||||
this.loading = false;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.refresh();
|
||||
},
|
||||
components: { LoadingSpinner }
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="vh-100 container py-5 h-100">
|
||||
<div class="row d-flex justify-content-center align-items-center h-100">
|
||||
<!--<div class="col-sm"><h2>* immagina un logo carino *</h2></div>-->
|
||||
<div class="col-12 col-md-8 col-lg-6 col-xl-5">
|
||||
<div class="card" style="border-radius: 1rem">
|
||||
<div class="card-body p-4">
|
||||
|
||||
<h1 class="h2 pb-4 text-center">WASAPhoto</h1>
|
||||
|
||||
<form>
|
||||
<!-- Email input -->
|
||||
<div class="form-floating mb-4">
|
||||
<input v-model="field_username" type="email" id="formUsername" class="form-control" placeholder="name@example.com"/>
|
||||
<label class="form-label" for="formUsername">Username</label>
|
||||
</div>
|
||||
|
||||
<!-- Password input -->
|
||||
<div class="form-floating mb-4">
|
||||
<input disabled type="password" id="formPassword" class="form-control" placeholder="gattina12"/>
|
||||
<label class="form-label" for="formPassword">Password</label>
|
||||
</div>
|
||||
|
||||
<!-- 2 column grid layout for inline styling -->
|
||||
<div class="row mb-4">
|
||||
<div class="col d-flex justify-content-center">
|
||||
<!-- Checkbox -->
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" value="" id="form2Example31" checked />
|
||||
<label class="form-check-label" for="form2Example31">Remember me</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Submit button -->
|
||||
<button style="width: 100%" type="button" class="btn btn-primary btn-block mb-4" @click="login">Sign in</button>
|
||||
<ErrorMsg v-if="errormsg" :msg="errormsg"></ErrorMsg>
|
||||
<LoadingSpinner :loading="loading" />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style>
|
||||
</style>
|
Loading…
Add table
Add a link
Reference in a new issue