refactor: Refactor frontend views and components
This commit is contained in:
parent
9c763c4b3b
commit
517f79c9f9
8 changed files with 104 additions and 169 deletions
19
src/App.vue
19
src/App.vue
|
@ -1,16 +1,25 @@
|
||||||
<template>
|
<template>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
<Navbar />
|
<navbar />
|
||||||
<router-view />
|
<section class="container">
|
||||||
|
<div class="columns is-centered">
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Vue } from "vue-property-decorator";
|
import { Component, Vue } from "vue-property-decorator";
|
||||||
import Navbar from "@/components/Navbar.vue";
|
import Navbar from "@/components/Navbar.vue";
|
||||||
|
import { user } from "@/api";
|
||||||
|
|
||||||
@Component({ components: { Navbar } })
|
@Component({ components: { Navbar } })
|
||||||
export default class App extends Vue {}
|
export default class App extends Vue {
|
||||||
|
public async created(): Promise<void> {
|
||||||
|
if (!user.isAuthenticated && this.$route.name !== "login") {
|
||||||
|
this.$router.push({ name: "login" });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss"></style>
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
import Vue from "vue";
|
||||||
|
|
||||||
type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH";
|
type HTTPMethod = "GET" | "POST" | "PUT" | "PATCH";
|
||||||
|
|
||||||
|
@ -95,3 +96,5 @@ export class User {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const user = Vue.observable(new User());
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<template>
|
|
||||||
<div style="display: flex">
|
|
||||||
<b-input v-if="isEditing" v-model="editorValue" />
|
|
||||||
<span v-else>{{ value }}</span>
|
|
||||||
<b-button @click="toggleEditor" style="margin-left: auto">{{
|
|
||||||
isEditing ? "Speichern" : "Bearbeiten"
|
|
||||||
}}</b-button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { Component, Prop, Vue } from "vue-property-decorator";
|
|
||||||
|
|
||||||
@Component
|
|
||||||
export default class InlineEditor extends Vue {
|
|
||||||
@Prop() private value: string | undefined;
|
|
||||||
|
|
||||||
private editorValue = "";
|
|
||||||
private isEditing = false;
|
|
||||||
|
|
||||||
private created() {
|
|
||||||
this.editorValue = this.value || "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private toggleEditor() {
|
|
||||||
this.isEditing = !this.isEditing;
|
|
||||||
this.$emit("input", this.editorValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,74 +0,0 @@
|
||||||
<template>
|
|
||||||
<form class="box" @submit.prevent="doAction">
|
|
||||||
<div v-if="errorMessage" class="notification is-danger">
|
|
||||||
{{ errorMessage }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<b-field label="Benutzername">
|
|
||||||
<b-input type="text" v-model="user.username" />
|
|
||||||
</b-field>
|
|
||||||
<b-field label="Kennwort">
|
|
||||||
<b-input type="password" v-model="user.password" />
|
|
||||||
</b-field>
|
|
||||||
<b-field v-if="mode === 'signup'" label="Kennwort wiederholen">
|
|
||||||
<b-input type="password" v-model="password2" />
|
|
||||||
</b-field>
|
|
||||||
|
|
||||||
<div class="buttons">
|
|
||||||
<b-button native-type="submit" type="is-primary">
|
|
||||||
{{ mode === "login" ? "Anmelden" : "Konto anlegen" }}
|
|
||||||
</b-button>
|
|
||||||
<router-link v-if="mode === 'login'" to="/signup"
|
|
||||||
>Konto anlegen</router-link
|
|
||||||
>
|
|
||||||
<router-link v-else to="/login">Anmelden</router-link>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { Component, Prop, Watch } from "vue-property-decorator";
|
|
||||||
import { mixins } from "vue-class-component";
|
|
||||||
import { User } from "@/api";
|
|
||||||
import { Route } from "vue-router";
|
|
||||||
import { NotifyMixin } from "@/mixins";
|
|
||||||
|
|
||||||
@Component
|
|
||||||
export default class LoginForm extends mixins(NotifyMixin) {
|
|
||||||
@Prop() private user!: User;
|
|
||||||
|
|
||||||
private mode: "login" | "signup" = "login";
|
|
||||||
private password2 = "";
|
|
||||||
private errorMessage = "";
|
|
||||||
|
|
||||||
public created(): void {
|
|
||||||
if (this.$route.name === "signup") this.mode = "signup";
|
|
||||||
}
|
|
||||||
|
|
||||||
@Watch("$route")
|
|
||||||
public routeChanged(to: Route): void {
|
|
||||||
if (to.name === "signup") {
|
|
||||||
this.mode = "signup";
|
|
||||||
} else {
|
|
||||||
this.mode = "login";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async doAction() {
|
|
||||||
try {
|
|
||||||
if (this.mode === "login") {
|
|
||||||
await this.user.login();
|
|
||||||
if (this.$route.name !== "home") this.$router.push({ name: "home" });
|
|
||||||
} else {
|
|
||||||
await this.user.signup();
|
|
||||||
this.$router.push({ name: "login" });
|
|
||||||
this.showSuccess("Du kannst dich nun anmelden.");
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
this.errorMessage = "Fehler";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss"></style>
|
|
|
@ -1,29 +1,25 @@
|
||||||
import Vue from "vue";
|
import Vue from "vue";
|
||||||
import VueRouter, { RouteConfig } from "vue-router";
|
import VueRouter, { RouteConfig } from "vue-router";
|
||||||
import MainPage from "../views/MainPage.vue";
|
import LoginView from "../views/Login.vue";
|
||||||
|
import UserView from "../views/User.vue";
|
||||||
|
|
||||||
Vue.use(VueRouter);
|
Vue.use(VueRouter);
|
||||||
|
|
||||||
const routes: Array<RouteConfig> = [
|
const routes: Array<RouteConfig> = [
|
||||||
{
|
{
|
||||||
path: "/",
|
path: "/",
|
||||||
name: "home",
|
name: "index",
|
||||||
component: MainPage,
|
component: UserView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/login",
|
path: "/login",
|
||||||
name: "login",
|
name: "login",
|
||||||
component: MainPage,
|
component: LoginView,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: "/signup",
|
path: "/signup",
|
||||||
name: "signup",
|
name: "signup",
|
||||||
component: MainPage,
|
component: LoginView,
|
||||||
},
|
|
||||||
{
|
|
||||||
path: "/confirm/:uid/:token",
|
|
||||||
name: "confirm",
|
|
||||||
component: MainPage,
|
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
73
src/views/Login.vue
Normal file
73
src/views/Login.vue
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
<template>
|
||||||
|
<div class="column is-3-widescreen is-4-desktop is-5-tablet">
|
||||||
|
<form class="box" @submit.prevent="doAction">
|
||||||
|
<div v-if="errorMessage" class="notification is-danger">
|
||||||
|
{{ errorMessage }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<b-field label="Benutzername">
|
||||||
|
<b-input type="text" v-model="user.username" />
|
||||||
|
</b-field>
|
||||||
|
<b-field label="Kennwort">
|
||||||
|
<b-input type="password" v-model="user.password" />
|
||||||
|
</b-field>
|
||||||
|
<b-field v-if="mode === 'signup'" label="Kennwort wiederholen">
|
||||||
|
<b-input type="password" v-model="password2" />
|
||||||
|
</b-field>
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
<b-button native-type="submit" type="is-primary">
|
||||||
|
{{ mode === "login" ? "Anmelden" : "Konto anlegen" }}
|
||||||
|
</b-button>
|
||||||
|
<router-link v-if="mode === 'login'" to="/signup"
|
||||||
|
>Konto anlegen</router-link
|
||||||
|
>
|
||||||
|
<router-link v-else to="/login">Anmelden</router-link>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Component, Watch } from "vue-property-decorator";
|
||||||
|
import { user } from "@/api";
|
||||||
|
import { NotifyMixin } from "@/mixins";
|
||||||
|
import { mixins } from "vue-class-component";
|
||||||
|
import { Route } from "vue-router";
|
||||||
|
|
||||||
|
@Component
|
||||||
|
export default class Login extends mixins(NotifyMixin) {
|
||||||
|
user = user;
|
||||||
|
private mode: "login" | "signup" = "login";
|
||||||
|
private password2 = "";
|
||||||
|
private errorMessage = "";
|
||||||
|
|
||||||
|
public created(): void {
|
||||||
|
if (this.$route.name === "signup") this.mode = "signup";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch("$route")
|
||||||
|
public routeChanged(to: Route): void {
|
||||||
|
if (to.name === "signup") {
|
||||||
|
this.mode = "signup";
|
||||||
|
} else {
|
||||||
|
this.mode = "login";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async doAction() {
|
||||||
|
try {
|
||||||
|
if (this.mode === "login") {
|
||||||
|
await this.user.login();
|
||||||
|
if (this.$route.name !== "home") this.$router.push({ name: "home" });
|
||||||
|
} else {
|
||||||
|
await this.user.signup();
|
||||||
|
this.$router.push({ name: "login" });
|
||||||
|
this.showSuccess("Du kannst dich nun anmelden.");
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
this.errorMessage = "Fehler";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -1,35 +0,0 @@
|
||||||
<template>
|
|
||||||
<section class="container">
|
|
||||||
<div class="columns is-centered">
|
|
||||||
<div
|
|
||||||
v-if="user.isAuthenticated"
|
|
||||||
class="column is-5-fullhd is-6-widescreen is-7-desktop is-7-tablet"
|
|
||||||
>
|
|
||||||
<UserTable :user="user" />
|
|
||||||
</div>
|
|
||||||
<div v-else class="column is-3-widescreen is-4-desktop is-5-tablet">
|
|
||||||
<LoginForm :user="user" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { Component } from "vue-property-decorator";
|
|
||||||
import LoginForm from "@/components/LoginForm.vue";
|
|
||||||
import { mixins } from "vue-class-component";
|
|
||||||
import { User } from "@/api";
|
|
||||||
import UserTable from "@/components/UserTable.vue";
|
|
||||||
import { NotifyMixin } from "@/mixins";
|
|
||||||
|
|
||||||
@Component({ components: { UserTable, LoginForm } })
|
|
||||||
export default class Home extends mixins(NotifyMixin) {
|
|
||||||
private user = new User();
|
|
||||||
|
|
||||||
public async created(): Promise<void> {
|
|
||||||
if (!this.user.isAuthenticated && this.$route.name !== "login") {
|
|
||||||
this.$router.push({ name: "login" });
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div class="column is-5-fullhd is-6-widescreen is-7-desktop is-7-tablet">
|
||||||
<b-notification type="is-info" aria-close-label="Close notification">
|
<b-notification type="is-info" aria-close-label="Close notification">
|
||||||
Dein Konto ist noch nicht aktiv.
|
Dein Konto ist noch nicht aktiv.
|
||||||
<a v-if="user.isTrusted" @click="activate()">Jetzt aktivieren</a>
|
<a v-if="user.isTrusted" @click="activate()">Jetzt aktivieren</a>
|
||||||
|
@ -12,15 +12,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Benutzername</td>
|
<td>Benutzername</td>
|
||||||
<td>
|
<td>{{ user.username }}</td>
|
||||||
<InlineEditor v-model="user.username" @input="user.save()" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Vertrauensperson</td>
|
<td>Vertrauensperson</td>
|
||||||
<td>
|
<td></td>
|
||||||
<inline-editor v-model="user.confidantEmail" @input="user.save()" />
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
@ -28,15 +24,12 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Component, Prop, Vue } from "vue-property-decorator";
|
import { Component, Vue } from "vue-property-decorator";
|
||||||
import { User } from "@/api";
|
import { user } from "@/api";
|
||||||
import InlineEditor from "@/components/InlineEditor.vue";
|
|
||||||
|
|
||||||
@Component({
|
@Component
|
||||||
components: { InlineEditor },
|
export default class Home extends Vue {
|
||||||
})
|
user = user;
|
||||||
export default class UserTable extends Vue {
|
|
||||||
@Prop() private user!: User;
|
|
||||||
|
|
||||||
async activate(): Promise<void> {
|
async activate(): Promise<void> {
|
||||||
await this.user.activate();
|
await this.user.activate();
|
Reference in a new issue