web: implemented login

This commit is contained in:
Mika 2024-07-09 11:19:09 +02:00
parent 129b0224e9
commit ae222173b1
12 changed files with 170 additions and 34 deletions

1
package.json Normal file
View file

@ -0,0 +1 @@
{}

9
pnpm-lock.yaml generated Normal file
View file

@ -0,0 +1,9 @@
lockfileVersion: '9.0'
settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
importers:
.: {}

1
web/components.d.ts vendored
View file

@ -12,6 +12,7 @@ declare module 'vue' {
HeaderBar: typeof import('./src/components/HeaderBar.vue')['default']
ListViewElement: typeof import('./src/components/ListViewElement.vue')['default']
ListViewTemplate: typeof import('./src/components/ListViewTemplate.vue')['default']
LoginPage: typeof import('./src/components/loginPage.vue')['default']
SearchElement: typeof import('./src/components/SearchElement.vue')['default']
StartPage: typeof import('./src/components/StartPage.vue')['default']
TurboLogo: typeof import('./src/components/turboLogo.vue')['default']

View file

@ -8,6 +8,7 @@
},
"dependencies": {
"@mdi/font": "6.2.95",
"axios": "^1.7.2",
"lucide-vue-next": "^0.402.0",
"roboto-fontface": "*",
"vue": "^3.4.21",

73
web/pnpm-lock.yaml generated
View file

@ -11,6 +11,9 @@ importers:
'@mdi/font':
specifier: 6.2.95
version: 6.2.95
axios:
specifier: ^1.7.2
version: 1.7.2
lucide-vue-next:
specifier: ^0.402.0
version: 0.402.0(vue@3.4.31(typescript@5.5.3))
@ -393,6 +396,12 @@ packages:
resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
engines: {node: '>= 8'}
asynckit@0.4.0:
resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
axios@1.7.2:
resolution: {integrity: sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==}
balanced-match@1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
@ -411,6 +420,10 @@ packages:
resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
engines: {node: '>= 8.10.0'}
combined-stream@1.0.8:
resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
engines: {node: '>= 0.8'}
computeds@0.0.1:
resolution: {integrity: sha512-7CEBgcMjVmitjYo5q8JTJVra6X5mQ20uTThdK+0kR7UEaDrAWEQcRiBtWJzga4eRpP6afNwwLsX2SET2JhVB1Q==}
@ -429,6 +442,10 @@ packages:
supports-color:
optional: true
delayed-stream@1.0.0:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
entities@4.5.0:
resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
engines: {node: '>=0.12'}
@ -452,6 +469,19 @@ packages:
resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
engines: {node: '>=8'}
follow-redirects@1.15.6:
resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
form-data@4.0.0:
resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
engines: {node: '>= 6'}
fsevents@2.3.3:
resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
@ -515,6 +545,14 @@ packages:
resolution: {integrity: sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==}
engines: {node: '>=8.6'}
mime-db@1.52.0:
resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
engines: {node: '>= 0.6'}
mime-types@2.1.35:
resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
engines: {node: '>= 0.6'}
minimatch@9.0.5:
resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
engines: {node: '>=16 || 14 >=14.17'}
@ -551,6 +589,9 @@ packages:
resolution: {integrity: sha512-0vzE+lAiG7hZl1/9I8yzKLx3aR9Xbof3fBHKunvMfOCYAtMhrsnccJY2iTURb9EZd5+pLuiNV9/c/GZJOHsgIw==}
engines: {node: ^10 || ^12 || >=14}
proxy-from-env@1.1.0:
resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
queue-microtask@1.2.3:
resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
@ -985,6 +1026,16 @@ snapshots:
normalize-path: 3.0.0
picomatch: 2.3.1
asynckit@0.4.0: {}
axios@1.7.2:
dependencies:
follow-redirects: 1.15.6
form-data: 4.0.0
proxy-from-env: 1.1.0
transitivePeerDependencies:
- debug
balanced-match@1.0.2: {}
binary-extensions@2.3.0: {}
@ -1009,6 +1060,10 @@ snapshots:
optionalDependencies:
fsevents: 2.3.3
combined-stream@1.0.8:
dependencies:
delayed-stream: 1.0.0
computeds@0.0.1: {}
csstype@3.1.3: {}
@ -1019,6 +1074,8 @@ snapshots:
dependencies:
ms: 2.1.2
delayed-stream@1.0.0: {}
entities@4.5.0: {}
esbuild@0.21.5:
@ -1065,6 +1122,14 @@ snapshots:
dependencies:
to-regex-range: 5.0.1
follow-redirects@1.15.6: {}
form-data@4.0.0:
dependencies:
asynckit: 0.4.0
combined-stream: 1.0.8
mime-types: 2.1.35
fsevents@2.3.3:
optional: true
@ -1116,6 +1181,12 @@ snapshots:
braces: 3.0.3
picomatch: 2.3.1
mime-db@1.52.0: {}
mime-types@2.1.35:
dependencies:
mime-db: 1.52.0
minimatch@9.0.5:
dependencies:
brace-expansion: 2.0.1
@ -1142,6 +1213,8 @@ snapshots:
picocolors: 1.0.1
source-map-js: 1.2.0
proxy-from-env@1.1.0: {}
queue-microtask@1.2.3: {}
readdirp@3.6.0:

View file

@ -1,13 +1,18 @@
<template>
<v-app>
<v-main>
<HeaderBar />
<div class="ma-8">
<actionToolbar />
<li>
<CategoryContainer licenseGroupName="Jetbrains Ultimate"/>
<CategoryContainer licenseGroupName="Microsoft"/>
</li>
<div v-if="store.token === null">
<loginPage />
</div>
<div v-else>
<HeaderBar />
<div class="ma-8">
<actionToolbar />
<li>
<CategoryContainer licenseGroupName="Jetbrains Ultimate"/>
<CategoryContainer licenseGroupName="Microsoft"/>
</li>
</div>
</div>
</v-main>
@ -18,6 +23,8 @@
import HeaderBar from './components/HeaderBar.vue';
import CategoryContainer from './components/CategoryContainer.vue';
import actionToolbar from './components/actionToolbar.vue';
import { store } from './store';
</script>

View file

@ -6,8 +6,7 @@
licenseKey="321z8321789"
startDate="12.12.2020"
endDate="13.12.2021"
amount="1"
tags=""
:amount=1
notes="No notes"
/>
<!-- <ListViewElement

View file

@ -29,6 +29,10 @@
</script>
<style scoped>
.logo {
margin-right: 20%;
margin-left: 10px;
}
.compact-form {
transform: scale(0.7);

View file

@ -48,7 +48,6 @@
startDate: String,
endDate: String,
amount: Number,
tags: Array,
notes: String,
})

View file

@ -1,24 +0,0 @@
<template>
<div style="display: flex;">
<div style="flex: 30%">
<h1>Start Page</h1>
<p>Welcome to the start page</p>
</div>
<div style="flex: 70%;">
<h1>Start Page</h1>
<p>Welcome to the start page</p>
</div>
</div>
</template>
<script setup lang="ts">
</script>
<style scoped>
</style>

View file

@ -0,0 +1,58 @@
<template>
<v-container>
<v-row justify="center">
<v-col cols="12" sm="8" md="4">
<v-card>
<v-card-title class="text-h5">Login</v-card-title>
<v-card-text>
<v-form>
<v-text-field v-model="email" label="Email" required></v-text-field>
<v-text-field v-model="password" label="Password" type="password" required></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-btn @click="login" color="primary">Login</v-btn>
</v-card-actions>
</v-card>
</v-col>
</v-row>
</v-container>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import axios from 'axios'
import { store } from '@/store';
const email = ref('')
const password = ref('')
async function login() {
try {
const response = await axios.post<string>("http://localhost:8080/api/v1/auth/login", { email: email.value, password: password.value})
if (response.status === 200) {
store.setToken(response.data)
} else {
alert("Invalid Credentials")
}
} catch(err) {
alert("Invalid Credentials")
}
}
/*
setTimeout(() => {
console.log(email.value)
console.log(password.value)
}, 3000);
*/
</script>
<style scoped>
</style>

8
web/src/store.ts Normal file
View file

@ -0,0 +1,8 @@
import { reactive } from 'vue';
export const store = reactive<{token: string | null, setToken: (token: string | null) => void}>({
token: null,
setToken: (token: string | null) => store.token = token
});