web: implemented Server State (Schmackofatz)

This commit is contained in:
Sphereso 2024-07-10 20:38:10 +02:00
parent b7fc25b3da
commit 613b6a9314
8 changed files with 67 additions and 33 deletions

1
web/.env.example Normal file
View file

@ -0,0 +1 @@
VITE_BACKEND_URL=

1
web/.gitignore vendored
View file

@ -6,6 +6,7 @@ components.d.ts
# local env files # local env files
.env.local .env.local
.env.*.local .env.*.local
.env
# Log files # Log files
npm-debug.log* npm-debug.log*

View file

@ -5,7 +5,7 @@
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Welcome to Vuetify 3</title> <title>From TURBOMANN™ & Konsorten</title>
</head> </head>
<body> <body>

View file

@ -1,22 +1,14 @@
<template> <template>
<div class="root"> <div class="root">
<h2>{{ props.licenseGroupName }}:</h2> <h2>{{ props.licenseGroupName }}:</h2>
<li> <li v-for="license in licenses" :key="license.id">
<ListViewElement <ListViewElement
licenseName="Jetbrains Ultimate 2024.2.1" :licenseName="license.name"
licenseKey="321z8321789" :licenseKey="license.key"
startDate="12.12.2020" startDate="license.start"
endDate="13.12.2021" endDate="license.end"
:amount=undefined :amount=license.amount
notes="No notes" notes="license.notes"
/>
<ListViewElement
licenseName="Mockup 2"
licenseKey="XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX"
startDate=""
endDate=""
:amount=1
notes="No notes"
/> />
</li> </li>
<!-- <ListViewElement <!-- <ListViewElement
@ -35,10 +27,16 @@
<script setup lang="ts"> <script setup lang="ts">
import ListViewElement from './ListViewElement.vue' import ListViewElement from './ListViewElement.vue'
const props = defineProps({ interface License {
licenseGroupName: String name: string;
id: string;
start?: Date,
end?: Date,
key: string,
amount?: number,
}
}) const props = defineProps<{ licenseGroupName: string, licenses: License[]}>()
</script> </script>

View file

@ -1,4 +1,4 @@
<template> <template>
<div> <div>
<v-toolbar color="main" dark prominent> <v-toolbar color="main" dark prominent>
<img src="../assets/turbologo.svg" alt="logo" class="logo" width="75" /> <img src="../assets/turbologo.svg" alt="logo" class="logo" width="75" />
@ -150,7 +150,7 @@ import {
function handlelogout() { function handlelogout() {
console.log("logout"); console.log("logout");
store.setToken(null); store.setToken(null);
} }
async function submit(event: SubmitEventPromise) { async function submit(event: SubmitEventPromise) {
const result = await event; const result = await event;

View file

@ -2,11 +2,13 @@
<div> <div>
<HeaderBar /> <HeaderBar />
<div class="ma-8"> <div class="ma-8">
<li> <div v-if="isPending">Loading...</div>
<CategoryContainer licenseGroupName="Jetbrains Ultimate" /> <div v-else-if="isError">Error: {{ error?.message }}</div>
<CategoryContainer licenseGroupName="Microsoft" /> <ul v-else-if="data">
<CategoryContainer licenseGroupName="Willy Wonker Online Movie" /> <li v-for="group in data" :key="group.id">
</li> <CategoryContainer :licenseGroupName="group.name" :licenses="group.licenses" />
</li>
</ul>
</div> </div>
</div> </div>
</template> </template>
@ -14,10 +16,40 @@
<script setup lang="ts"> <script setup lang="ts">
import HeaderBar from "./HeaderBar.vue"; import HeaderBar from "./HeaderBar.vue";
import CategoryContainer from "./CategoryContainer.vue"; import CategoryContainer from "./CategoryContainer.vue";
import { useQuery } from "@tanstack/vue-query";
import axios from "axios";
import { store } from "@/store";
interface LicenseGroup {
id: string,
name: string,
licenses: License[]
}
interface License {
name: string;
id: string;
start?: Date,
end?: Date,
key: string,
amount?: number,
}
const {isPending, isError, data, error} = useQuery({
queryKey: ["licenses"],
queryFn: async () => {
const res = await axios.get<LicenseGroup[]>(import.meta.env.VITE_BACKEND_URL + "/licenses", {
headers: {
Authorization: `Bearer ${store.token}`
}
})
return res.data
}
})
</script> </script>
<style scoped> <style scoped>
li { li, ul {
list-style-type: none; list-style-type: none;
} }
</style> </style>

View file

@ -41,12 +41,12 @@ const password = ref("");
async function login() { async function login() {
try { try {
const response = await axios.post<string>( const response = await axios.post<string>(
"http://localhost:8080/api/v1/auth/login", import.meta.env.VITE_BACKEND_URL + "/auth/login",
{ email: email.value, password: password.value } { email: email.value, password: password.value }
); );
if (response.status === 200) { if (response.status === 200) {
store.setToken(response.data); store.setToken(response.data);
} else { } else {
alert("Invalid Credentials"); alert("Invalid Credentials");
} }
} catch (err) { } catch (err) {

View file

@ -5,11 +5,13 @@
*/ */
// Plugins // Plugins
import vuetify from './vuetify' import { VueQueryPlugin } from "@tanstack/vue-query";
import vuetify from "./vuetify";
// Types // Types
import type { App } from 'vue' import type { App } from "vue";
export function registerPlugins (app: App) { export function registerPlugins(app: App) {
app.use(vuetify) app.use(vuetify);
app.use(VueQueryPlugin);
} }