Compare commits
No commits in common. "059b0fa9f20078744f6995d66c8140e324fa6558" and "2176c6c3cf39f54298f0eabb92f683b4dfdb659c" have entirely different histories.
059b0fa9f2
...
2176c6c3cf
23 changed files with 66 additions and 1934 deletions
File diff suppressed because it is too large
Load diff
Binary file not shown.
Before Width: | Height: | Size: 647 KiB After Width: | Height: | Size: 641 KiB |
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 11 MiB After Width: | Height: | Size: 10 MiB |
|
@ -2,7 +2,7 @@
|
||||||
<header class="flex flex-row h-16 min-h-16 justify-between p-3 md:px-5 bg-white shadow-sm">
|
<header class="flex flex-row h-16 min-h-16 justify-between p-3 md:px-5 bg-white shadow-sm">
|
||||||
<RouterLink to="/" class="flex flex-row gap-2 align-bottom w-fit h-full">
|
<RouterLink to="/" class="flex flex-row gap-2 align-bottom w-fit h-full">
|
||||||
<img src="/Logo.png" alt="LOGO" class="h-full w-auto" />
|
<img src="/Logo.png" alt="LOGO" class="h-full w-auto" />
|
||||||
<h1 v-if="false" class="font-bold text-3xl w-fit whitespace-nowrap">FF Admin</h1>
|
<h1 v-if="false" class="font-bold text-3xl w-fit whitespace-nowrap">Mitgliederverwaltung</h1>
|
||||||
</RouterLink>
|
</RouterLink>
|
||||||
<div class="flex flex-row gap-2 items-center">
|
<div class="flex flex-row gap-2 items-center">
|
||||||
<div v-if="authCheck" class="hidden md:flex flex-row gap-2 h-full align-middle">
|
<div v-if="authCheck" class="hidden md:flex flex-row gap-2 h-full align-middle">
|
||||||
|
|
|
@ -136,7 +136,7 @@ export default defineComponent({
|
||||||
preferred: formData.preferred.checked,
|
preferred: formData.preferred.checked,
|
||||||
mobile: formData.mobile?.value,
|
mobile: formData.mobile?.value,
|
||||||
email: formData.email?.value,
|
email: formData.email?.value,
|
||||||
postalCode: formData.postalCode?.value,
|
postalCode: formData.postalCode.value,
|
||||||
city: formData.city?.value,
|
city: formData.city?.value,
|
||||||
street: formData.street?.value,
|
street: formData.street?.value,
|
||||||
streetNumber: formData.streetNumber?.value,
|
streetNumber: formData.streetNumber?.value,
|
||||||
|
|
|
@ -80,13 +80,15 @@ export default defineComponent({
|
||||||
this.createInvite(createInvite)
|
this.createInvite(createInvite)
|
||||||
.then((result) => {
|
.then((result) => {
|
||||||
this.status = { status: "success" };
|
this.status = { status: "success" };
|
||||||
setTimeout(() => {
|
|
||||||
this.closeModal();
|
|
||||||
}, 2000);
|
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
this.status = { status: "failed", reason: err.response.data };
|
this.status = { status: "failed", reason: err.response.data };
|
||||||
})
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.closeModal();
|
||||||
|
}, 2000);
|
||||||
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
|
<div class="bg-primary p-2 text-white flex flex-row justify-between items-center">
|
||||||
<p>
|
<p>
|
||||||
{{ user.firstname }} {{ user.lastname }} <small v-if="user.permissions_total.admin">(Admin)</small
|
{{ user.firstname }} {{ user.lastname }} <small v-if="user.permissions_total.admin">(Admin)</small
|
||||||
><small v-if="user.isOwner"> (Owner)</small>
|
><small v-if="isOwner"> (Owner)</small>
|
||||||
</p>
|
</p>
|
||||||
<div class="flex flex-row">
|
<div class="flex flex-row">
|
||||||
<RouterLink
|
<RouterLink
|
||||||
|
@ -65,7 +65,7 @@ export default defineComponent({
|
||||||
user: { type: Object as PropType<UserViewModel>, default: {} },
|
user: { type: Object as PropType<UserViewModel>, default: {} },
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useAbilityStore, ["can"]),
|
...mapState(useAbilityStore, ["can", "isOwner"]),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useModalStore, ["openModal"]),
|
...mapActions(useModalStore, ["openModal"]),
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="max-w-md w-full space-y-8 pb-20">
|
<div class="max-w-md w-full space-y-8 pb-20">
|
||||||
<div class="flex flex-col items-center gap-4">
|
<div class="flex flex-col items-center gap-4">
|
||||||
<img src="/Logo.png" alt="LOGO" class="h-36" />
|
<img src="/Logo.png" alt="LOGO" class="h-36" />
|
||||||
<h2 class="text-center text-4xl font-extrabold text-gray-900">FF Admin</h2>
|
<h2 class="text-center text-4xl font-extrabold text-gray-900">Mitgliederverwaltung</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form class="flex flex-col gap-2" @submit.prevent="login">
|
<form class="flex flex-col gap-2" @submit.prevent="login">
|
||||||
|
|
|
@ -10,7 +10,16 @@
|
||||||
<div class="flex flex-col gap-2">
|
<div class="flex flex-col gap-2">
|
||||||
<img :src="image" alt="totp" class="w-56 h-56 self-center" />
|
<img :src="image" alt="totp" class="w-56 h-56 self-center" />
|
||||||
|
|
||||||
<TextCopy :copyText="otp" />
|
<div class="flex relative">
|
||||||
|
<input type="text" :value="otp" />
|
||||||
|
<ClipboardIcon
|
||||||
|
class="w-5 h-5 p-2 box-content absolute right-1 top-1/2 -translate-y-1/2 bg-white cursor-pointer"
|
||||||
|
@click="copyToClipboard"
|
||||||
|
/>
|
||||||
|
<div v-if="copySuccess" class="absolute w-5 h-5 right-3 top-[10px]">
|
||||||
|
<SuccessCheckmark />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<form class="flex flex-col gap-2" @submit.prevent="verify">
|
<form class="flex flex-col gap-2" @submit.prevent="verify">
|
||||||
<div class="-space-y-px">
|
<div class="-space-y-px">
|
||||||
|
@ -35,13 +44,13 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { defineComponent } from "vue";
|
import { defineComponent, markRaw, defineAsyncComponent } from "vue";
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import MainTemplate from "@/templates/Main.vue";
|
import MainTemplate from "@/templates/Main.vue";
|
||||||
import Spinner from "@/components/Spinner.vue";
|
import Spinner from "@/components/Spinner.vue";
|
||||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
import TextCopy from "@/components/TextCopy.vue";
|
import { ClipboardIcon } from "@heroicons/vue/24/outline";
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -53,6 +62,8 @@ export default defineComponent({
|
||||||
otp: undefined as undefined | string,
|
otp: undefined as undefined | string,
|
||||||
verifyStatus: undefined as undefined | "loading" | "success" | "failed",
|
verifyStatus: undefined as undefined | "loading" | "success" | "failed",
|
||||||
verifyError: "" as string,
|
verifyError: "" as string,
|
||||||
|
copySuccess: false,
|
||||||
|
timeoutCopy: undefined as any,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -89,6 +100,13 @@ export default defineComponent({
|
||||||
}, 2000);
|
}, 2000);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
copyToClipboard() {
|
||||||
|
navigator.clipboard.writeText(this.otp ?? "");
|
||||||
|
this.copySuccess = true;
|
||||||
|
this.timeoutCopy = setTimeout(() => {
|
||||||
|
this.copySuccess = false;
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<SidebarLayout>
|
<SidebarLayout>
|
||||||
<template #sidebar>
|
<template #sidebar>
|
||||||
<SidebarTemplate mainTitle="Mein Account" topTitle="FF Admin" :showTopList="isOwner">
|
<SidebarTemplate mainTitle="Mein Account" topTitle="Mitgliederverwaltung" :showTopList="isOwner">
|
||||||
<template v-if="isOwner" #topList>
|
<template v-if="isOwner" #topList>
|
||||||
<RoutingLink
|
<RoutingLink
|
||||||
title="Administration"
|
title="Administration"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<AwardListItem v-for="award in awards" :key="award.id" :award="award" />
|
<AwardListItem v-for="award in awards" :key="award.id" :award="award" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<CalendarTypeListItem
|
<CalendarTypeListItem
|
||||||
v-for="calendarType in calendarTypes"
|
v-for="calendarType in calendarTypes"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<CommunicationTypeListItem
|
<CommunicationTypeListItem
|
||||||
v-for="communicationType in communicationTypes"
|
v-for="communicationType in communicationTypes"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<ExecutivePositionListItem
|
<ExecutivePositionListItem
|
||||||
v-for="executivePosition in executivePositions"
|
v-for="executivePosition in executivePositions"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<MembershipStatusListItem v-for="status in membershipStatus" :key="status.id" :membershipStatus="status" />
|
<MembershipStatusListItem v-for="status in membershipStatus" :key="status.id" :membershipStatus="status" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<QualificationListItem
|
<QualificationListItem
|
||||||
v-for="qualification in qualifications"
|
v-for="qualification in qualifications"
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<QueryStoreListItem v-for="query in queries" :key="query.id" :queryItem="query" />
|
<QueryStoreListItem v-for="query in queries" :key="query.id" :queryItem="query" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<TemplateListItem v-for="template in templates" :key="template.id" :template="template" />
|
<TemplateListItem v-for="template in templates" :key="template.id" :template="template" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<RoleListItem v-for="role in roles" :key="role.id" :role="role" />
|
<RoleListItem v-for="role in roles" :key="role.id" :role="role" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #diffMain>
|
<template #diffMain>
|
||||||
<div class="flex flex-col gap-4 h-full pl-7">
|
<div class="flex flex-col gap-4 grow pl-7">
|
||||||
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
<div class="flex flex-col gap-2 grow overflow-y-scroll pr-7">
|
||||||
<UserListItem v-for="user in users" :key="user.id" :user="user" />
|
<UserListItem v-for="user in users" :key="user.id" :user="user" />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -47,6 +47,8 @@ import { defineComponent } from "vue";
|
||||||
import Spinner from "@/components/Spinner.vue";
|
import Spinner from "@/components/Spinner.vue";
|
||||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
|
import { RouterLink } from "vue-router";
|
||||||
|
import { ClipboardIcon } from "@heroicons/vue/24/outline";
|
||||||
import FormBottomBar from "@/components/FormBottomBar.vue";
|
import FormBottomBar from "@/components/FormBottomBar.vue";
|
||||||
import TextCopy from "@/components/TextCopy.vue";
|
import TextCopy from "@/components/TextCopy.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -47,6 +47,7 @@ import Spinner from "@/components/Spinner.vue";
|
||||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
import { RouterLink } from "vue-router";
|
import { RouterLink } from "vue-router";
|
||||||
|
import { ClipboardIcon } from "@heroicons/vue/24/outline";
|
||||||
import FormBottomBar from "@/components/FormBottomBar.vue";
|
import FormBottomBar from "@/components/FormBottomBar.vue";
|
||||||
import TextCopy from "@/components/TextCopy.vue";
|
import TextCopy from "@/components/TextCopy.vue";
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -17,7 +17,16 @@
|
||||||
<form v-else class="flex flex-col gap-2" @submit.prevent="setup">
|
<form v-else class="flex flex-col gap-2" @submit.prevent="setup">
|
||||||
<img :src="image" alt="totp" class="w-56 h-56 self-center" />
|
<img :src="image" alt="totp" class="w-56 h-56 self-center" />
|
||||||
|
|
||||||
<TextCopy :copyText="otp" />
|
<div class="flex relative">
|
||||||
|
<input type="text" :value="otp" />
|
||||||
|
<ClipboardIcon
|
||||||
|
class="w-5 h-5 p-2 box-content absolute right-1 top-1/2 -translate-y-1/2 bg-white cursor-pointer"
|
||||||
|
@click="copyToClipboard"
|
||||||
|
/>
|
||||||
|
<div v-if="copySuccess" class="absolute w-5 h-5 right-3 top-[10px]">
|
||||||
|
<SuccessCheckmark />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="-space-y-px">
|
<div class="-space-y-px">
|
||||||
<div>
|
<div>
|
||||||
|
@ -48,8 +57,8 @@ import Spinner from "@/components/Spinner.vue";
|
||||||
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
|
||||||
import FailureXMark from "@/components/FailureXMark.vue";
|
import FailureXMark from "@/components/FailureXMark.vue";
|
||||||
import { RouterLink } from "vue-router";
|
import { RouterLink } from "vue-router";
|
||||||
|
import { ClipboardIcon } from "@heroicons/vue/24/outline";
|
||||||
import FormBottomBar from "@/components/FormBottomBar.vue";
|
import FormBottomBar from "@/components/FormBottomBar.vue";
|
||||||
import TextCopy from "@/components/TextCopy.vue";
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -65,6 +74,8 @@ export default defineComponent({
|
||||||
otp: undefined as undefined | string,
|
otp: undefined as undefined | string,
|
||||||
setupStatus: undefined as undefined | "loading" | "success" | "failed",
|
setupStatus: undefined as undefined | "loading" | "success" | "failed",
|
||||||
setupError: "" as string,
|
setupError: "" as string,
|
||||||
|
copySuccess: false,
|
||||||
|
timputCopy: undefined as any,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -110,6 +121,13 @@ export default defineComponent({
|
||||||
this.setupError = err.response.data;
|
this.setupError = err.response.data;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
copyToClipboard() {
|
||||||
|
navigator.clipboard.writeText(this.otp ?? "");
|
||||||
|
this.copySuccess = true;
|
||||||
|
this.timputCopy = setTimeout(() => {
|
||||||
|
this.copySuccess = false;
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Reference in a new issue