Commit e0103599 authored by Andres Käver's avatar Andres Käver

api, identity

parent 9a1e9cae
......@@ -1186,6 +1186,11 @@
"integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==",
"dev": true
},
"@types/jwt-decode": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/@types/jwt-decode/-/jwt-decode-2.2.1.tgz",
"integrity": "sha512-aWw2YTtAdT7CskFyxEX2K21/zSDStuf/ikI3yBqmwpwJF0pS+/IX5DWv+1UFffZIbruP6cnT9/LAJV1gFwAT1A=="
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
......@@ -7602,6 +7607,11 @@
"verror": "1.10.0"
}
},
"jwt-decode": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-2.2.0.tgz",
"integrity": "sha1-fYa9VmefWM5qhHBKZX3TkruoGnk="
},
"killable": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz",
......@@ -12009,6 +12019,14 @@
"integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==",
"dev": true
},
"vue-jwt-decode": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/vue-jwt-decode/-/vue-jwt-decode-0.1.0.tgz",
"integrity": "sha512-4iP0NzYHkAF7G13tYPc/nudk4oNpB8GCVZupc7lekxXok1XKEgefNaGTpDT14g7RKe5H9GaMphPduDj4UVfZwQ==",
"requires": {
"vue": "^2.3.3"
}
},
"vue-loader": {
"version": "15.9.1",
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.1.tgz",
......
......@@ -8,14 +8,17 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@types/jwt-decode": "^2.2.1",
"axios": "^0.19.2",
"bootstrap": "^4.4.1",
"core-js": "^3.6.4",
"font-awesome": "^4.7.0",
"jquery": "3.4.1",
"jwt-decode": "^2.2.0",
"popper.js": "^1.16.1",
"vue": "^2.6.11",
"vue-class-component": "^7.2.3",
"vue-jwt-decode": "^0.1.0",
"vue-property-decorator": "^8.4.1",
"vue-router": "^3.1.6",
"vuex": "^3.1.3"
......
......@@ -2,7 +2,7 @@
<ul class="navbar-nav">
<template v-if="isAuthenticated">
<li class="nav-item">
<a class="nav-link text-dark" href>user@user.com</a>
<span class="nav-link text-dark">{{userEmail}}</span>
</li>
<li class="nav-item">
<a @click="logoutOnClick" class="nav-link text-dark" href>Logout</a>
......@@ -15,18 +15,27 @@
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import store from '../store';
import router from '../router';
import store from "../store";
import router from "../router";
import JwtDecode from 'jwt-decode';
@Component
export default class Identity extends Vue {
get isAuthenticated(): boolean {
return store.getters.isAuthenticated
return store.getters.isAuthenticated;
}
get userEmail(): string {
if (store.state.jwt) {
const decoded = JwtDecode(store.state.jwt) as Record<string, string>;
return decoded["http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"];
}
return 'null';
}
logoutOnClick(): void {
store.dispatch('clearJwt');
router.push('/');
store.dispatch("clearJwt");
router.push("/");
}
}
</script>
export interface IGpsSession {
id: string;
name: string;
description: string;
recordedAt: string;
gpsLocationsCount: number;
userFirstLastName: string;
}
import Axios from 'axios';
import { IGpsSession } from '@/domain/IGpsSession';
export abstract class GpsSessionsApi {
private static axios = Axios.create(
{
baseURL: "https://sportmap.akaver.com/api/v1.0/GpsSessions/",
headers: {
common: {
'Content-Type': 'application/json'
}
}
}
)
static async getAll(): Promise<IGpsSession[]> {
const url = "";
try {
const response = await this.axios.get<IGpsSession[]>(url);
console.log('getAll response', response);
if (response.status === 200) {
return response.data;
}
return [];
} catch (error) {
console.log('error: ', (error as Error).message);
return [];
}
}
static async delete(id: string, jwt: string): Promise<void> {
const url = "" + id;
try {
const response = await this.axios.delete<IGpsSession>(url, { headers: { Authorization: 'Bearer ' + jwt } });
console.log('delete response', response);
if (response.status === 200) {
return;
}
return;
} catch (error) {
console.log('error: ', (error as Error).message);
}
}
}
......@@ -2,16 +2,22 @@ import Vue from 'vue'
import Vuex, { Store } from 'vuex'
import { ILoginDTO } from '@/types/ILoginDTO';
import { AccountApi } from '@/services/AccountApi';
import { GpsSessionsApi } from '@/services/GpsSessionApi';
import { IGpsSession } from './../domain/IGpsSession';
Vue.use(Vuex)
export default new Vuex.Store({
state: {
jwt: null as string | null
jwt: null as string | null,
gpsSessions: [] as IGpsSession[]
},
mutations: {
setJwt(state, jwt: string | null) {
state.jwt = jwt;
},
setGpsSessions(state, gpsSessions: IGpsSession[]) {
state.gpsSessions = gpsSessions;
}
},
getters: {
......@@ -27,6 +33,17 @@ export default new Vuex.Store({
const jwt = await AccountApi.getJwt(loginDTO);
context.commit('setJwt', jwt);
return jwt !== null;
},
async getGpsSessions(context): Promise<void> {
const gpsSessions = await GpsSessionsApi.getAll();
context.commit('setGpsSessions', gpsSessions);
},
async deleteGpsSession(context, id: string): Promise<void> {
console.log('deleteGpsSession', context.getters.isAuthenticated);
if (context.getters.isAuthenticated && context.state.jwt) {
await GpsSessionsApi.delete(id, context.state.jwt);
await context.dispatch('getGpsSessions');
}
}
},
modules: {
......
<template>
<div>
<h1>GpsSessions Index</h1>
<router-link :to="urlObject">Details</router-link>
<button class="btn btn-primary" @click="navigateClicked">Navigate</button>
<ul>
<li v-for="session in sessions" :key="session.id">
{{session.userFirstLastName}} - {{session.name}} - {{session.gpsLocationsCount}}
<button
v-if="session.gpsLocationsCount < 50"
@click="deleteOnClick(session)"
type="button"
class="btn btn-danger"
>Delete</button>
</li>
</ul>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import router from "../../router";
import { IGpsSession } from "../../domain/IGpsSession";
import store from "../../store";
@Component
export default class GpsSessionsIndex extends Vue {
private urlObject = {
name: "GpsSessionsDetails",
params: {
id: "tricky"
}
};
get sessions(): IGpsSession[] {
return store.state.gpsSessions;
}
navigateClicked(): void {
console.log('navigateClicked');
router.push(this.urlObject);
deleteOnClick(session: IGpsSession): void {
if (session.gpsLocationsCount < 50) {
store.dispatch('deleteGpsSession', session.id);
}
}
// ============ Lifecycle methods ==========
......@@ -39,6 +48,7 @@ export default class GpsSessionsIndex extends Vue {
mounted(): void {
console.log("mounted");
store.dispatch("getGpsSessions");
}
beforeUpdate(): void {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment