Merge branch 'monterail_vue3_migration' of github.com:gradido/gradido into monterail_vue3_migration

This commit is contained in:
Kamila 2024-08-09 08:59:49 +02:00
commit 4c04543194
35 changed files with 599 additions and 1775 deletions

View File

@ -1 +1 @@
lts/gallium
v18.20

View File

@ -89,13 +89,16 @@ declare module 'vue' {
IBiCheck: typeof import('~icons/bi/check')['default']
IBiEye: typeof import('~icons/bi/eye')['default']
IBiEyeSlash: typeof import('~icons/bi/eye-slash')['default']
IBiFacebook: typeof import('~icons/bi/facebook')['default']
IBiLayers: typeof import('~icons/bi/layers')['default']
IBiPencil: typeof import('~icons/bi/pencil')['default']
IBiPeople: typeof import('~icons/bi/people')['default']
IBiQuestion: typeof import('~icons/bi/question')['default']
IBiShieldCheck: typeof import('~icons/bi/shield-check')['default']
IBiTrash: typeof import('~icons/bi/trash')['default']
IBiTwitterX: typeof import('~icons/bi/twitter-x')['default']
IBiXCircle: typeof import('~icons/bi/x-circle')['default']
IBiYoutube: typeof import('~icons/bi/youtube')['default']
InputAmount: typeof import('./src/components/Inputs/InputAmount.vue')['default']
InputEmail: typeof import('./src/components/Inputs/InputEmail.vue')['default']
InputHour: typeof import('./src/components/Inputs/InputHour.vue')['default']

View File

@ -98,7 +98,8 @@
"stylelint-config-standard-scss": "13.1.0",
"unplugin-icons": "^0.19.1",
"unplugin-vue-components": "^0.27.3",
"vue-html-webpack-plugin": "^3.2.2"
"vue-html-webpack-plugin": "^3.2.2",
"vite-plugin-environment": "^1.1.3"
},
"postcss": {
"plugins": {

View File

@ -5,30 +5,33 @@
<div
class="d-flex justify-content-center justify-content-md-center justify-content-lg-start ml-3"
>
<b-nav class="nav-footer">
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/impressum/`" target="_blank">
<BNav class="nav-footer">
<BNavItem :href="`https://gradido.net/${$i18n.locale}/impressum/`" target="_blank">
{{ $t('footer.imprint') }}
</b-nav-item>
<b-nav-item :href="`https://gradido.net/${$i18n.locale}/datenschutz/`" target="_blank">
</BNavItem>
<BNavItem :href="`https://gradido.net/${$i18n.locale}/datenschutz/`" target="_blank">
{{ $t('footer.privacy_policy') }}
</b-nav-item>
</b-nav>
</BNavItem>
</BNav>
</div>
</BCol>
<BCol class="col-12 col-md-12 col-lg-6 mt-4 mb-4 mt-lg-0 mb-lg-0">
<div class="text-center ml-3 ml-lg-0 text-lg-right pt-1">
{{ $t('followUs') }}
<b-link href="https://www.facebook.com/groups/Gradido/" target="_blank">
<b-icon-facebook class="ml-3 mr-3 c-grey" font-scale="1"></b-icon-facebook>
</b-link>
<b-link href="https://twitter.com/gradido" target="_blank">
<b-icon-twitter class="mr-3 c-grey" font-scale="1"></b-icon-twitter>
</b-link>
<b-link href="https://www.youtube.com/c/GradidoNet" target="_blank">
<b-icon-youtube class="mr-3 c-grey" font-scale="1"></b-icon-youtube>
</b-link>
<BLink href="https://www.facebook.com/groups/Gradido/" target="_blank">
<!-- <b-icon-facebook class="ml-3 mr-3 c-grey" font-scale="1"></b-icon-facebook>-->
<IBiFacebook class="ml-3 mr-3 c-grey" />
</BLink>
<BLink href="https://twitter.com/gradido" target="_blank">
<!-- <b-icon-twitter class="mr-3 c-grey" font-scale="1"></b-icon-twitter>-->
<IBiTwitterX class="mr-3 c-grey" font-scale="1" />
</BLink>
<BLink href="https://www.youtube.com/c/GradidoNet" target="_blank">
<!-- <b-icon-youtube class="mr-3 c-grey" font-scale="1"></b-icon-youtube>-->
<IBiYoutube class="mr-3 c-grey" font-scale="1" />
</BLink>
<b-link href="https://t.me/Gradido" target="_blank">
<BLink href="https://t.me/Gradido" target="_blank">
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
@ -41,7 +44,7 @@
d="M16 8A8 8 0 1 1 0 8a8 8 0 0 1 16 0zM8.287 5.906c-.778.324-2.334.994-4.666 2.01-.378.15-.577.298-.595.442-.03.243.275.339.69.47l.175.055c.408.133.958.288 1.243.294.26.006.549-.1.868-.32 2.179-1.471 3.304-2.214 3.374-2.23.05-.012.12-.026.166.016.047.041.042.12.037.141-.03.129-1.227 1.241-1.846 1.817-.193.18-.33.307-.358.336a8.154 8.154 0 0 1-.188.186c-.38.366-.664.64.015 1.088.327.216.589.393.85.571.284.194.568.387.936.629.093.06.183.125.27.187.331.236.63.448.997.414.214-.02.435-.22.547-.82.265-1.417.786-4.486.906-5.751a1.426 1.426 0 0 0-.013-.315.337.337 0 0 0-.114-.217.526.526 0 0 0-.31-.093c-.3.005-.763.166-2.984 1.09z"
/>
</svg>
</b-link>
</BLink>
</div>
</BCol>
</BRow>

View File

@ -3,39 +3,28 @@
<BNavbar :toggleable="false" :container="false" class="d-flex">
<BNavbarBrand class="d-none d-lg-block">
<BImg class="position-absolute ml--3 mt-lg--2 p-2" :src="logo" width="200" alt="Logo" />
<BImg
class="mt--3 ml--3"
:src="background_header"
width="230"
alt="Background Image"
></BImg>
<BImg class="mt--3 ml--3" :src="backgroundHeader" width="230" alt="Background Image"></BImg>
</BNavbarBrand>
<BImg class="sheet-img position-absolute d-block d-lg-none zindex1000" :src="sheet"></BImg>
<BCollapse id="nav-collapse" is-nav>
<BNavbarNav class="ml-auto d-none d-lg-flex" right>
<BNavItem :to="register" class="auth-navbar ml-lg-5">{{ $t('signup') }}</BNavItem>
<BNavItem :to="register()" class="auth-navbar ml-lg-5">{{ $t('signup') }}</BNavItem>
<span class="d-none d-lg-block mt-1">{{ $t('math.pipe') }}</span>
<BNavItem :to="login" class="auth-navbar">{{ $t('signin') }}</BNavItem>
<BNavItem :to="login()" class="auth-navbar">{{ $t('signin') }}</BNavItem>
</BNavbarNav>
</BCollapse>
</BNavbar>
</div>
</template>
<script>
import { authLinks } from '@/mixins/authLinks'
<script setup>
import { useAuthLinks } from '@/composables/useAuthLinks'
export default {
name: 'AuthNavbar',
mixins: [authLinks],
data() {
return {
background_header: '/img/template/gradido_background_header.png',
logo: '/img/brand/gradido-logo.png',
sheet: '/img/template/Blaetter.png',
}
},
}
const { login, register } = useAuthLinks()
const backgroundHeader = '/img/template/gradido_background_header.png'
const logo = '/img/brand/gradido-logo.png'
const sheet = '/img/template/Blaetter.png'
</script>
<style scoped lang="scss">

View File

@ -1,22 +1,19 @@
<template>
<div class="navbar-small">
<b-navbar class="navi">
<b-navbar-nav>
<b-nav-item :to="register" class="auth-navbar">{{ $t('signup') }}</b-nav-item>
<BNavbar class="navi">
<BNavbarNav>
<BNavItem :to="register()" class="auth-navbar">{{ $t('signup') }}</BNavItem>
<span class="mt-1">{{ $t('math.pipe') }}</span>
<b-nav-item :to="login" class="auth-navbar">{{ $t('signin') }}</b-nav-item>
</b-navbar-nav>
</b-navbar>
<BNavItem :to="login()" class="auth-navbar">{{ $t('signin') }}</BNavItem>
</BNavbarNav>
</BNavbar>
</div>
</template>
<script>
import { authLinks } from '@/mixins/authLinks'
<script setup>
import { useAuthLinks } from '@/composables/useAuthLinks'
export default {
name: 'AuthNavbarSmall',
mixins: [authLinks],
}
const { login, register } = useAuthLinks()
</script>
<style scoped>
.navi {

View File

@ -26,10 +26,10 @@
>
{{ linkText }}
<div>
<b-button class="p-4">
<BButton class="p-4">
<IBiLink45deg />
<!-- <b-icon icon="link45deg"></b-icon>-->
</b-button>
</BButton>
</div>
</div>
</div>
@ -40,13 +40,19 @@
</div>
</div>
</template>
<script>
import { copyLinks } from '../mixins/copyLinks'
export default {
name: 'ClipboardCopy',
mixins: [copyLinks],
}
<script setup>
import { useCopyLinks } from '@/composables/useCopyLinks'
const props = defineProps({
link: { type: String, required: true },
amount: { type: String, required: true },
memo: { type: String, required: true },
validUntil: { type: String, required: true },
})
const { copyLink, copyLinkWithText, linkText, canCopyLink } = useCopyLinks({ ...props })
</script>
<style>
.svg {
filter: brightness(0) invert(1);

View File

@ -24,59 +24,6 @@
</div>
</div>
</template>
<!--<script>-->
<!--import { createContributionMessage } from '../../graphql/mutations.js'-->
<!--export default {-->
<!-- name: 'ContributionMessagesFormular',-->
<!-- props: {-->
<!-- contributionId: {-->
<!-- type: Number,-->
<!-- required: true,-->
<!-- },-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- form: {-->
<!-- text: '',-->
<!-- },-->
<!-- isSubmitting: false,-->
<!-- }-->
<!-- },-->
<!-- computed: {-->
<!-- disabled() {-->
<!-- return this.form.text === '' || this.isSubmitting-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- onSubmit() {-->
<!-- this.isSubmitting = true-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: createContributionMessage,-->
<!-- variables: {-->
<!-- contributionId: this.contributionId,-->
<!-- message: this.form.text,-->
<!-- },-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.$emit('get-list-contribution-messages', false)-->
<!-- this.$emit('update-status', this.contributionId)-->
<!-- this.form.text = ''-->
<!-- this.toastSuccess(this.$t('message.reply'))-->
<!-- this.isSubmitting = false-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.toastError(error.message)-->
<!-- this.isSubmitting = false-->
<!-- })-->
<!-- },-->
<!-- onReset() {-->
<!-- this.form.text = ''-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, computed } from 'vue'

View File

@ -107,7 +107,7 @@
</BCol>
</BRow>
<div v-else class="pb-3"></div>
<BCollapse :id="collapsId" :model-value="visible" class="mt-2">
<BCollapse :id="collapseId" :model-value="visible" class="mt-2">
<contribution-messages-list
:messages="messagesGet"
:status="status"
@ -119,169 +119,13 @@
</div>
</div>
</template>
<!--<script>-->
<!--import Avatar from 'vue-avatar'-->
<!--import CollapseIcon from '../TransactionRows/CollapseIcon'-->
<!--import ContributionMessagesList from '@/components/ContributionMessages/ContributionMessagesList'-->
<!--import { listContributionMessages } from '../../graphql/queries.js'-->
<!--export default {-->
<!-- name: 'ContributionListItem',-->
<!-- components: {-->
<!-- Avatar,-->
<!-- CollapseIcon,-->
<!-- ContributionMessagesList,-->
<!-- },-->
<!-- props: {-->
<!-- id: {-->
<!-- type: Number,-->
<!-- },-->
<!-- amount: {-->
<!-- type: String,-->
<!-- },-->
<!-- memo: {-->
<!-- type: String,-->
<!-- },-->
<!-- firstName: {-->
<!-- type: String,-->
<!-- required: false,-->
<!-- },-->
<!-- lastName: {-->
<!-- type: String,-->
<!-- required: false,-->
<!-- },-->
<!-- createdAt: {-->
<!-- type: String,-->
<!-- },-->
<!-- contributionDate: {-->
<!-- type: String,-->
<!-- },-->
<!-- deletedAt: {-->
<!-- type: String,-->
<!-- required: false,-->
<!-- },-->
<!-- confirmedBy: {-->
<!-- type: Number,-->
<!-- required: false,-->
<!-- },-->
<!-- confirmedAt: {-->
<!-- type: String,-->
<!-- required: false,-->
<!-- },-->
<!-- deniedBy: {-->
<!-- type: Number,-->
<!-- required: false,-->
<!-- },-->
<!-- deniedAt: {-->
<!-- type: String,-->
<!-- required: false,-->
<!-- },-->
<!-- updatedBy: {-->
<!-- type: Number,-->
<!-- required: false,-->
<!-- },-->
<!-- status: {-->
<!-- type: String,-->
<!-- required: false,-->
<!-- default: '',-->
<!-- },-->
<!-- messagesCount: {-->
<!-- type: Number,-->
<!-- required: false,-->
<!-- },-->
<!-- contributionId: {-->
<!-- type: Number,-->
<!-- required: true,-->
<!-- },-->
<!-- allContribution: {-->
<!-- type: Boolean,-->
<!-- required: false,-->
<!-- default: false,-->
<!-- },-->
<!-- moderatorId: {-->
<!-- type: Number,-->
<!-- required: false,-->
<!-- default: 0,-->
<!-- },-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- inProcess: true,-->
<!-- messages_get: [],-->
<!-- visible: false,-->
<!-- }-->
<!-- },-->
<!-- computed: {-->
<!-- icon() {-->
<!-- if (this.deletedAt) return 'trash'-->
<!-- if (this.deniedAt) return 'x-circle'-->
<!-- if (this.confirmedAt) return 'check'-->
<!-- if (this.status === 'IN_PROGRESS') return 'question'-->
<!-- return `<IBiBellFill />`-->
<!-- },-->
<!-- variant() {-->
<!-- if (this.deletedAt) return 'danger'-->
<!-- if (this.deniedAt) return 'warning'-->
<!-- if (this.confirmedAt) return 'success'-->
<!-- if (this.status === 'IN_PROGRESS') return '205'-->
<!-- return 'primary'-->
<!-- },-->
<!-- date() {-->
<!-- return this.createdAt-->
<!-- },-->
<!-- collapsId() {-->
<!-- return 'collapse' + String(this.id)-->
<!-- },-->
<!-- username() {-->
<!-- return {-->
<!-- username: `${this.firstName} ${this.lastName}`,-->
<!-- initials: `${this.firstName[0]}${this.lastName[0]}`,-->
<!-- }-->
<!-- },-->
<!-- },-->
<!-- watch: {-->
<!-- visible() {-->
<!-- if (this.visible) this.getListContributionMessages()-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- deleteContribution(item) {-->
<!-- this.$bvModal.msgBoxConfirm(this.$t('contribution.delete')).then(async (value) => {-->
<!-- if (value) this.$emit('delete-contribution', item)-->
<!-- })-->
<!-- },-->
<!-- getListContributionMessages(closeCollapse = true) {-->
<!-- if (closeCollapse) {-->
<!-- this.$emit('closeAllOpenCollapse')-->
<!-- }-->
<!-- this.$apollo-->
<!-- .query({-->
<!-- query: listContributionMessages,-->
<!-- variables: {-->
<!-- contributionId: this.contributionId,-->
<!-- },-->
<!-- fetchPolicy: 'no-cache',-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.messages_get = result.data.listContributionMessages.messages-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.toastError(error.message)-->
<!-- })-->
<!-- },-->
<!-- updateStatus(id) {-->
<!-- this.$emit('update-status', id)-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, computed, watch } from 'vue'
import Avatar from 'vue-avatar'
import CollapseIcon from '../TransactionRows/CollapseIcon'
import ContributionMessagesList from '@/components/ContributionMessages/ContributionMessagesList'
import { listContributionMessages } from '../../graphql/queries.js'
import { listContributionMessages } from '@/graphql/queries'
import { useAppToast } from '@/composables/useToast'
import { useI18n } from 'vue-i18n'
import { useQuery } from '@vue/apollo-composable'
@ -366,14 +210,6 @@ const inProcess = ref(true)
const messagesGet = ref([])
const visible = ref(false)
const icon = computed(() => {
if (props.deletedAt) return 'trash'
if (props.deniedAt) return 'x-circle'
if (props.confirmedAt) return 'check'
if (props.status === 'IN_PROGRESS') return 'question'
return `<IBiBellFill />`
})
const variant = computed(() => {
if (props.deletedAt) return 'danger'
if (props.deniedAt) return 'warning'
@ -384,7 +220,7 @@ const variant = computed(() => {
const date = computed(() => props.createdAt)
const collapsId = computed(() => 'collapse' + String(props.id))
const collapseId = computed(() => 'collapse' + String(props.id))
const username = computed(() => ({
username: `${props.firstName} ${props.lastName}`,

View File

@ -5,9 +5,9 @@
v-for="lang in locales"
:key="lang.code"
class="pointer"
:class="$store.state.language === lang.code ? 'c-grey' : 'c-blau'"
:class="store.state.language === lang.code ? 'c-grey' : 'c-blau'"
>
<span v-if="lang.code === $store.state.language" class="locales mr-1">
<span v-if="lang.code === store.state.language" class="locales mr-1">
{{ lang.name }}
</span>
</span>
@ -19,15 +19,15 @@
v-for="(lang, index) in locales"
:key="lang.code"
class="pointer"
:class="$store.state.language === lang.code ? 'c-grey' : 'c-blau'"
:class="store.state.language === lang.code ? 'c-grey' : 'c-blau'"
@click.prevent="saveLocale(lang.code)"
>
<span v-if="lang.code !== $store.state.language" v-b-toggle.collapse-1 class="locales">
<span v-if="lang.code !== store.state.language" v-b-toggle.collapse-1 class="locales">
{{ lang.name }}
</span>
<span
v-if="
lang.code !== $store.state.language &&
lang.code !== store.state.language &&
(indexOfSelectedLocale !== indexOfLastLocale ||
(indexOfSelectedLocale === indexOfLastLocale && index !== indexOfSecondLastLocale))
"
@ -40,86 +40,14 @@
</div>
</template>
<!--<script>-->
<!--import locales from '@/locales/'-->
<!--import { updateUserInfos } from '@/graphql/mutations'-->
<!--export default {-->
<!-- name: 'LanguageSwitch',-->
<!-- data() {-->
<!-- return {-->
<!-- locales: locales,-->
<!-- currentLanguage: {},-->
<!-- }-->
<!-- },-->
<!-- methods: {-->
<!-- setLocale(locale) {-->
<!-- this.$store.commit('language', locale)-->
<!-- this.currentLanguage = this.getLocaleObject(locale)-->
<!-- },-->
<!-- async saveLocale(locale) {-->
<!-- if (this.$i18n.locale === locale) return-->
<!-- this.setLocale(locale)-->
<!-- if (this.$store.state.gradidoID) {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: updateUserInfos,-->
<!-- variables: {-->
<!-- locale: locale,-->
<!-- },-->
<!-- })-->
<!-- .then(() => {-->
<!-- this.toastSuccess(this.$t('settings.language.success'))-->
<!-- })-->
<!-- .catch(() => {-->
<!-- this.toastSuccess(this.$t('error'))-->
<!-- })-->
<!-- }-->
<!-- },-->
<!-- getLocaleObject(code) {-->
<!-- return this.locales.find((l) => l.code === code)-->
<!-- },-->
<!-- getNavigatorLanguage() {-->
<!-- const lang = navigator.language-->
<!-- if (lang) return lang.split('-')[0]-->
<!-- return lang-->
<!-- },-->
<!-- setCurrentLanguage() {-->
<!-- let locale = this.$store.state.language || this.getNavigatorLanguage() || 'en'-->
<!-- let object = this.getLocaleObject(locale)-->
<!-- if (!object) {-->
<!-- locale = 'en'-->
<!-- object = this.getLocaleObject(locale)-->
<!-- }-->
<!-- this.setLocale(locale)-->
<!-- this.currentLanguage = object-->
<!-- },-->
<!-- },-->
<!-- computed: {-->
<!-- indexOfSelectedLocale() {-->
<!-- return this.locales.findIndex((element) => element.code === this.$store.state.language)-->
<!-- },-->
<!-- indexOfSecondLastLocale() {-->
<!-- return this.locales.length - 2-->
<!-- },-->
<!-- indexOfLastLocale() {-->
<!-- return this.locales.length - 1-->
<!-- },-->
<!-- },-->
<!-- created() {-->
<!-- this.setCurrentLanguage()-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { useStore } from 'vuex'
import { useI18n } from 'vue-i18n'
import { useMutation } from '@vue/apollo-composable'
import { useAppToast } from '../composables/useToast'
import { useAppToast } from '@/composables/useToast'
import locales from '@/locales/'
import { onMounted, ref, computed } from 'vue'
import { updateUserInfos } from '../graphql/mutations'
import { updateUserInfos } from '@/graphql/mutations'
const store = useStore()
const { t, locale } = useI18n()

View File

@ -1,6 +1,6 @@
<template>
<div class="redeem-information">
<b-jumbotron bg-variant="muted" text-variant="dark" border-variant="info">
<BCard bg-variant="muted" text-variant="dark" border-variant="info">
<h1 v-if="amount === ''">{{ $t('gdd_per_link.redeemlink-error') }}</h1>
<h1 v-if="isContributionLink && amount !== ''">
{{ CONFIG.COMMUNITY_NAME }}
@ -11,7 +11,7 @@
{{ $t('transaction-link.send_you') }} {{ $filters.GDD(amount) }}
</h1>
<b>{{ memo }}</b>
</b-jumbotron>
</BCard>
</div>
</template>
<script>

View File

@ -2,7 +2,7 @@
<div class="redeem-logged-out">
<redeem-information v-bind="linkData" :is-contribution-link="isContributionLink" />
<b-jumbotron>
<BCard>
<div class="mb-2">
<h2>{{ $t('gdd_per_link.redeem') }}</h2>
</div>
@ -10,16 +10,16 @@
<BRow>
<BCol sm="12" md="6">
<p>{{ $t('gdd_per_link.no-account') }}</p>
<b-button variant="primary" :to="register">
<BButton variant="primary" :to="register">
{{ $t('gdd_per_link.to-register') }}
</b-button>
</BButton>
</BCol>
<BCol sm="12" md="6" class="mt-4 mt-lg-0">
<p>{{ $t('gdd_per_link.has-account') }}</p>
<b-button variant="gradido" :to="login">{{ $t('gdd_per_link.to-login') }}</b-button>
<BButton variant="gradido" :to="login">{{ $t('gdd_per_link.to-login') }}</BButton>
</BCol>
</BRow>
</b-jumbotron>
</BCard>
</div>
</template>
<script>

View File

@ -2,16 +2,16 @@
<div class="redeem-self-creator">
<redeem-information v-bind="linkData" :is-contribution-link="isContributionLink" />
<b-jumbotron>
<BCard>
<div class="mb-3 text-center">
<div class="mt-3">
{{ $t('gdd_per_link.no-redeem') }}
<b-link to="/transactions">
<BLink to="/transactions">
<b>{{ $t('gdd_per_link.link-overview') }}</b>
</b-link>
</BLink>
</div>
</div>
</b-jumbotron>
</BCard>
</div>
</template>
<script>

View File

@ -1,18 +1,18 @@
<template>
<div class="redeem-valid">
<redeem-information v-bind="linkData" :is-contribution-link="isContributionLink" />
<b-jumbotron>
<BCard>
<div class="mb-3 text-center">
<b-button
<BButton
variant="gradido"
size="lg"
:disabled="!validLink"
@click="$emit('mutation-link', linkData.amount)"
>
{{ $t('gdd_per_link.redeem') }}
</b-button>
</BButton>
</div>
</b-jumbotron>
</BCard>
</div>
</template>
<script>

View File

@ -1,13 +1,13 @@
<template>
<div class="redeemed-text-box">
<b-jumbotron bg-variant="muted" text-variant="dark" border-variant="info">
<BCard bg-variant="muted" text-variant="dark" border-variant="info">
<h1>
{{ text }}
</h1>
</b-jumbotron>
</BCard>
<div class="text-center">
<b-button to="/overview">{{ $t('back') }}</b-button>
<BButton to="/overview">{{ $t('back') }}</BButton>
</div>
</div>
</template>

View File

@ -1,9 +1,9 @@
<template>
<div class="navbar-component">
<div class="navbar-element">
<b-navbar toggleable="lg" class="pr-4">
<b-navbar-brand>
<b-img
<BNavbar toggleable="lg" class="pr-4">
<BNavbarBrand>
<BImg
class="mt-lg--2 mt-3 mb-3 d-none d-lg-block zindex10"
:src="logo"
width="200"
@ -12,11 +12,11 @@
<div v-b-toggle.sidebar-mobile variant="link" class="d-block d-lg-none">
<span class="navbar-toggler-icon h2"></span>
</div>
</b-navbar-brand>
</BNavbarBrand>
<b-img class="sheet-img position-absolute zindex-1" :src="sheet"></b-img>
<BImg class="sheet-img position-absolute zindex-1" :src="sheet"></BImg>
<b-navbar-nav class="ml-auto" right>
<BNavbarNav class="ml-auto" right>
<router-link to="/settings">
<div class="d-flex align-items-center">
<div class="mr-3">
@ -33,8 +33,8 @@
</div>
</div>
</router-link>
</b-navbar-nav>
</b-navbar>
</BNavbarNav>
</BNavbar>
<!-- <div class="alert-box">
<b-alert show dismissible variant="light" class="nav-alert text-dark">
<small>{{ $t('1000thanks') }}</small>

View File

@ -1,33 +1,53 @@
<template>
<div>
<b-sidebar
id="sidebar-mobile"
sidebar-class="sidebar-radius"
width="220px"
:backdrop="true"
bg-variant="white"
no-header-close
>
<b-img src="img/svg/lines.png" />
<div class="py-2">
<sidebar :shadow="false" @admin="$emit('admin')" @logout="$emit('logout')" />
</div>
</b-sidebar>
</div>
<BCollapse
id="sidebar-mobile"
sidebar-class="sidebar-radius"
:backdrop="true"
bg-variant="white"
no-header-close
horizontal
skip-animation
>
<div class="mobile-sidebar-wrapper py-2">
<BImg src="img/svg/lines.png" />
<sidebar :shadow="false" @admin="emit('admin')" @logout="emit('logout')" />
</div>
<div v-b-toggle.sidebar-mobile class="simple-overlay" />
</BCollapse>
</template>
<script>
import Sidebar from '@/components/Menu/Sidebar'
export default {
name: 'MobileSidebar',
components: {
Sidebar,
},
}
<script setup>
const emit = defineEmits(['admin', 'logout'])
</script>
<style>
.sidebar-radius {
.mobile-sidebar-wrapper {
width: 220px;
background-color: #fff;
z-index: 10;
position: absolute;
border-bottom-right-radius: 26px;
border-top-right-radius: 26px;
top: 0;
bottom: 0;
}
#sidebar-mobile {
width: 220px;
position: absolute;
left: 0;
top: 0;
bottom: 0;
}
.simple-overlay {
position: absolute;
left: 200px;
top: 0;
bottom: 0;
background-color: #212529;
z-index: 9;
opacity: 0.6;
width: calc(100vw - 200px);
}
</style>

View File

@ -51,46 +51,6 @@
</div>
</div>
</template>
<!--<script>-->
<!--import { updateUserInfos } from '@/graphql/mutations'-->
<!--export default {-->
<!-- name: 'GddAmount',-->
<!-- props: {-->
<!-- path: { type: String, required: false, default: '' },-->
<!-- balance: { type: Number, required: true },-->
<!-- badgeShow: { type: Boolean, default: true },-->
<!-- showStatus: { type: Boolean, default: false },-->
<!-- },-->
<!-- computed: {-->
<!-- hideAmount() {-->
<!-- return this.$store.state.hideAmountGDD-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- async updateHideAmountGDD() {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: updateUserInfos,-->
<!-- variables: {-->
<!-- hideAmountGDD: !this.hideAmount,-->
<!-- },-->
<!-- })-->
<!-- .then(() => {-->
<!-- this.$store.commit('hideAmountGDD', !this.hideAmount)-->
<!-- if (!this.hideAmount) {-->
<!-- this.toastSuccess(this.$t('settings.showAmountGDD'))-->
<!-- } else {-->
<!-- this.toastSuccess(this.$t('settings.hideAmountGDD'))-->
<!-- }-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.toastError(error.message)-->
<!-- })-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { computed } from 'vue'

View File

@ -46,45 +46,6 @@
</div>
</div>
</template>
<!--<script>-->
<!--import { updateUserInfos } from '@/graphql/mutations'-->
<!--export default {-->
<!-- name: 'GdtAmount',-->
<!-- props: {-->
<!-- GdtBalance: { type: Number, required: true },-->
<!-- badgeShow: { type: Boolean, default: true },-->
<!-- showStatus: { type: Boolean, default: false },-->
<!-- },-->
<!-- computed: {-->
<!-- hideAmount() {-->
<!-- return this.$store.state.hideAmountGDT-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- async updateHideAmountGDT() {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: updateUserInfos,-->
<!-- variables: {-->
<!-- hideAmountGDT: !this.hideAmount,-->
<!-- },-->
<!-- })-->
<!-- .then(() => {-->
<!-- this.$store.commit('hideAmountGDT', !this.hideAmount)-->
<!-- if (!this.hideAmount) {-->
<!-- this.toastSuccess(this.$t('settings.showAmountGDT'))-->
<!-- } else {-->
<!-- this.toastSuccess(this.$t('settings.hideAmountGDT'))-->
<!-- }-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.toastError(error.message)-->
<!-- })-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { computed } from 'vue'

View File

@ -18,7 +18,7 @@
<IBiThreeDotsVertical />
</template>
<BDropdownItem v-if="validLink" class="test-copy-link" @click="copyLink">
<BDropdownItem v-if="validLink" class="test-copy-link" @click="copyToClipboard">
<IBiClipboard />
{{ $t('gdd_per_link.copy-link') }}
</BDropdownItem>
@ -31,7 +31,7 @@
class="pt-3 pb-3 test-qr-code"
@click="$bvModal.show('modalPopover-' + id)"
>
<b-img src="img/svg/qr-code.svg" width="18" class="filter"></b-img>
<BImg src="img/svg/qr-code.svg" width="18" class="filter"></BImg>
{{ $t('qrCode') }}
</BDropdownItem>
<BDropdownItem class="test-delete-link" @click="deleteLink()">
@ -64,62 +64,7 @@
</BModal>
</div>
</template>
<!--<script>-->
<!--import { deleteTransactionLink } from '@/graphql/mutations'-->
<!--import TypeIcon from '../TransactionRows/TypeIcon'-->
<!--import AmountAndNameRow from '../TransactionRows/AmountAndNameRow'-->
<!--import MemoRow from '../TransactionRows/MemoRow'-->
<!--import DateRow from '../TransactionRows/DateRow'-->
<!--import DecayRow from '../TransactionRows/DecayRow'-->
<!--import FigureQrCode from '@/components/QrCode/FigureQrCode'-->
<!--import { copyLinks } from '../../mixins/copyLinks'-->
<!--export default {-->
<!-- name: 'TransactionLink',-->
<!-- mixins: [copyLinks],-->
<!-- components: {-->
<!-- TypeIcon,-->
<!-- AmountAndNameRow,-->
<!-- MemoRow,-->
<!-- DateRow,-->
<!-- DecayRow,-->
<!-- FigureQrCode,-->
<!-- },-->
<!-- props: {-->
<!-- holdAvailableAmount: { type: String, required: true },-->
<!-- id: { type: Number, required: true },-->
<!-- },-->
<!-- methods: {-->
<!-- deleteLink() {-->
<!-- this.$bvModal.msgBoxConfirm(this.$t('gdd_per_link.delete-the-link')).then(async (value) => {-->
<!-- if (value)-->
<!-- await this.$apollo-->
<!-- .mutate({-->
<!-- mutation: deleteTransactionLink,-->
<!-- variables: {-->
<!-- id: this.id,-->
<!-- },-->
<!-- })-->
<!-- .then(() => {-->
<!-- this.toastSuccess(this.$t('gdd_per_link.deleted'))-->
<!-- this.$emit('reset-transaction-link-list')-->
<!-- })-->
<!-- .catch((err) => {-->
<!-- this.toastError(err.message)-->
<!-- })-->
<!-- })-->
<!-- },-->
<!-- },-->
<!-- computed: {-->
<!-- decay() {-->
<!-- return `${this.amount - this.holdAvailableAmount}`-->
<!-- },-->
<!-- validLink() {-->
<!-- return new Date(this.validUntil) > new Date()-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { computed } from 'vue'
import { useMutation } from '@vue/apollo-composable'
@ -148,7 +93,7 @@ const emit = defineEmits(['reset-transaction-link-list'])
const { t } = useI18n()
const { toastSuccess, toastError } = useAppToast()
const { copyToClipboard } = useCopyLinks({
const { copyToClipboard, copyLinkWithText } = useCopyLinks({
amount: props.amount,
validUntil: props.validUntil,
link: props.link,

View File

@ -2,7 +2,7 @@
<div class="transaction-slot-link" @click="showTransactionLinks()">
<BRow class="align-items-center">
<BCol cols="3" lg="2" md="2">
<b-avatar icon="link" variant="light" :size="42"></b-avatar>
<BAvatar icon="link" variant="light" :size="42"></BAvatar>
</BCol>
<BCol>
<div>{{ $t('gdd_per_link.links_sum') }}</div>
@ -27,87 +27,84 @@
</BCollapse>
</div>
</template>
<script>
<script setup>
import { ref, watch } from 'vue'
import { useQuery } from '@vue/apollo-composable'
import CollapseIcon from '../TransactionRows/CollapseIcon'
import CollapseLinksList from '../DecayInformations/CollapseLinksList'
import { useAppToast } from '@/composables/useToast'
import { listTransactionLinks } from '@/graphql/queries'
export default {
name: 'TransactionSlotLink',
components: {
CollapseIcon,
CollapseLinksList,
const props = defineProps({
amount: {
type: String,
required: true,
},
props: {
amount: {
type: String,
required: true,
},
decay: {
type: Object,
required: true,
},
transactionLinkCount: {
type: Number,
required: true,
},
decay: {
type: Object,
required: true,
},
data() {
return {
visible: false,
transactionLinks: [],
currentPage: 1,
pageSize: 5,
pending: false,
transactionLinkCount: {
type: Number,
required: true,
},
})
const emit = defineEmits(['update-transactions'])
const { toastError } = useAppToast()
const visible = ref(false)
const transactionLinks = ref([])
const currentPage = ref(1)
const pageSize = ref(5)
const pending = ref(false)
const { refetch, loading, error } = useQuery(
listTransactionLinks,
() => ({
currentPage: currentPage.value,
}),
{ enabled: false },
)
watch(currentPage, () => {
updateListTransactionLinks()
})
function showTransactionLinks() {
if (visible.value) {
visible.value = false
} else {
transactionLinks.value = []
if (currentPage.value === 1) {
updateListTransactionLinks()
} else {
currentPage.value = 1
}
},
watch: {
currentPage() {
this.updateListTransactionLinks()
},
},
methods: {
showTransactionLinks() {
if (this.visible) {
this.visible = false
} else {
this.transactionLinks = []
if (this.currentPage === 1) {
this.updateListTransactionLinks()
} else {
this.currentPage = 1
}
this.visible = true
}
},
async updateListTransactionLinks() {
if (this.currentPage === 0) {
this.transactionLinks = []
this.currentPage = 1
} else {
this.pending = true
this.$apollo
.query({
query: listTransactionLinks,
variables: {
currentPage: this.currentPage,
},
fetchPolicy: 'network-only',
})
.then((result) => {
this.transactionLinks = [
...this.transactionLinks,
...result.data.listTransactionLinks.links,
]
this.$emit('update-transactions')
this.pending = false
})
.catch((err) => {
this.toastError(err.message)
this.pending = false
})
}
},
},
visible.value = true
}
}
async function updateListTransactionLinks() {
if (currentPage.value === 0) {
transactionLinks.value = []
currentPage.value = 1
} else {
pending.value = true
try {
const result = await refetch()
transactionLinks.value = [
...transactionLinks.value,
...result.data.listTransactionLinks.links,
]
emit('update-transactions')
} catch (err) {
toastError(err.message)
} finally {
pending.value = false
}
}
}
</script>

View File

@ -10,8 +10,7 @@
<navbar class="main-navbar" :balance="balance"></navbar>
</BCol>
</BRow>
<!-- TODO mobile sidebar needs new component to be fixed-->
<!-- <mobile-sidebar @admin="admin" @logout="logout" />-->
<mobile-sidebar @admin="admin" @logout="logoutUser" />
<!-- Breadcrumb -->
<BRow class="breadcrumb">
@ -23,7 +22,7 @@
<BRow fluid class="d-flex">
<!-- Sidebar left -->
<BCol cols="2" class="d-none d-lg-block">
<sidebar class="main-sidebar" @admin="admin" @logout="logout" />
<sidebar class="main-sidebar" @admin="admin" @logout="logoutUser" />
</BCol>
<!-- ContentHeader && Content -->
<BCol>
@ -182,149 +181,17 @@
<content-footer v-if="!$route.meta.hideFooter"></content-footer>
</BCol>
</BRow>
<session-logout-timeout @logout="logout"></session-logout-timeout>
<session-logout-timeout @logout="logoutUser"></session-logout-timeout>
</div>
</div>
<!-- <h1>TEST</h1>-->
</template>
<!--<script>-->
<!--import ContentHeader from '@/layouts/templates/ContentHeader'-->
<!--import CommunityTemplate from '@/layouts/templates/CommunityTemplate'-->
<!--import Breadcrumb from '@/components/Breadcrumb/breadcrumb'-->
<!--import RightSide from '@/layouts/templates/RightSide'-->
<!--import SkeletonOverview from '@/components/skeleton/Overview'-->
<!--import Navbar from '@/components/Menu/Navbar'-->
<!--import Sidebar from '@/components/Menu/Sidebar'-->
<!--import MobileSidebar from '@/components/MobileSidebar/MobileSidebar'-->
<!--import SessionLogoutTimeout from '@/components/SessionLogoutTimeout'-->
<!--import { transactionsQuery, communityStatistics } from '@/graphql/queries'-->
<!--import { logout } from '@/graphql/mutations'-->
<!--import ContentFooter from '@/components/ContentFooter'-->
<!--import { FadeTransition } from 'vue2-transitions'-->
<!--import CONFIG from '@/config'-->
<!--import GddAmount from '@/components/Template/ContentHeader/GddAmount'-->
<!--import GdtAmount from '@/components/Template/ContentHeader/GdtAmount'-->
<!--import CommunityMember from '@/components/Template/ContentHeader/CommunityMember'-->
<!--import NavCommunity from '@/components/Template/ContentHeader/NavCommunity'-->
<!--import LastTransactions from '@/components/Template/RightSide/LastTransactions'-->
<!--export default {-->
<!-- name: 'DashboardLayout',-->
<!-- components: {-->
<!-- SkeletonOverview,-->
<!-- ContentHeader,-->
<!-- RightSide,-->
<!-- Navbar,-->
<!-- Sidebar,-->
<!-- MobileSidebar,-->
<!-- SessionLogoutTimeout,-->
<!-- ContentFooter,-->
<!-- FadeTransition,-->
<!-- Breadcrumb,-->
<!-- GddAmount,-->
<!-- GdtAmount,-->
<!-- CommunityMember,-->
<!-- NavCommunity,-->
<!-- LastTransactions,-->
<!-- CommunityTemplate,-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- balance: 0,-->
<!-- GdtBalance: 0,-->
<!-- transactions: [],-->
<!-- transactionCount: 0,-->
<!-- transactionLinkCount: 0,-->
<!-- pending: true,-->
<!-- visible: false,-->
<!-- hamburger: true,-->
<!-- darkMode: false,-->
<!-- skeleton: true,-->
<!-- totalUsers: null,-->
<!-- }-->
<!-- },-->
<!-- created() {-->
<!-- this.updateTransactions(0)-->
<!-- this.getCommunityStatistics()-->
<!-- setTimeout(() => {-->
<!-- this.skeleton = false-->
<!-- }, 1500)-->
<!-- },-->
<!-- methods: {-->
<!-- async logout() {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: logout,-->
<!-- })-->
<!-- .then(() => {-->
<!-- this.$store.dispatch('logout')-->
<!-- this.$router.push('/login')-->
<!-- })-->
<!-- .catch(() => {-->
<!-- this.$store.dispatch('logout')-->
<!-- if (this.$router.currentRoute.path !== '/login') this.$router.push('/login')-->
<!-- })-->
<!-- },-->
<!-- async updateTransactions(pagination) {-->
<!-- this.pending = true-->
<!-- this.$apollo-->
<!-- .query({-->
<!-- query: transactionsQuery,-->
<!-- variables: {-->
<!-- currentPage: pagination.currentPage,-->
<!-- pageSize: pagination.pageSize,-->
<!-- },-->
<!-- fetchPolicy: 'network-only',-->
<!-- })-->
<!-- .then((result) => {-->
<!-- const {-->
<!-- data: { transactionList },-->
<!-- } = result-->
<!-- this.GdtBalance =-->
<!-- transactionList.balance.balanceGDT === null-->
<!-- ? 0-->
<!-- : Number(transactionList.balance.balanceGDT)-->
<!-- this.transactions = transactionList.transactions-->
<!-- this.balance = Number(transactionList.balance.balance)-->
<!-- this.transactionCount = transactionList.balance.count-->
<!-- this.transactionLinkCount = transactionList.balance.linkCount-->
<!-- this.pending = false-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.pending = true-->
<!-- this.transactionCount = -1-->
<!-- this.toastError(error.message)-->
<!-- // what to do when loading balance fails?-->
<!-- })-->
<!-- },-->
<!-- async getCommunityStatistics() {-->
<!-- this.$apollo-->
<!-- .query({-->
<!-- query: communityStatistics,-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.totalUsers = result.data.communityStatistics.totalUsers-->
<!-- })-->
<!-- .catch(() => {-->
<!-- this.toastError('communityStatistics has no result, use default data')-->
<!-- })-->
<!-- },-->
<!-- admin() {-->
<!-- window.location.assign(CONFIG.ADMIN_AUTH_URL.replace('{token}', this.$store.state.token))-->
<!-- this.$store.dispatch('logout') // logout without redirect-->
<!-- },-->
<!-- setVisible(bool) {-->
<!-- this.visible = bool-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, onMounted, watch } from 'vue'
import { ref, onMounted } from 'vue'
import { useStore } from 'vuex'
import { useRouter } from 'vue-router'
import { useLazyQuery, useMutation, useQuery } from '@vue/apollo-composable'
import { useLazyQuery, useMutation } from '@vue/apollo-composable'
import { useI18n } from 'vue-i18n'
import ContentHeader from '@/layouts/templates/ContentHeader'
import CommunityTemplate from '@/layouts/templates/CommunityTemplate'

View File

@ -1,7 +1,5 @@
import { createApp } from 'vue'
// import '@/assets/scss/gradido.scss'
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue-next/dist/bootstrap-vue-next.css'
@ -46,18 +44,13 @@ app.use(FlatPickr)
app.use(() => apolloProvider)
// app.use(VueTimers)
// app.mixin(toasters)
const filters = createFilters(i18n)
app.config.globalProperties.$filters = {
amount: filters.amount,
GDD: filters.GDD,
}
// TODO it will be used in future
// app.config.globalProperties.$filters = {
// GDD: filters.GDD,
// amount: filters.amount,
// }
loadAllRules(i18n.global, apolloProvider.defaultClient)
loadAllRules(i18n.global, apolloProvider.defaultClient)

View File

@ -31,47 +31,6 @@
</BContainer>
</div>
</template>
<!--<script>-->
<!--import { authenticateHumhubAutoLogin } from '@/graphql/queries'-->
<!--export default {-->
<!-- name: 'Circles',-->
<!-- data() {-->
<!-- return {-->
<!-- enableButton: false,-->
<!-- humhubUri: '',-->
<!-- }-->
<!-- },-->
<!-- computed: {-->
<!-- humhubAllowed() {-->
<!-- return this.$store.state.humhubAllowed-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- async authenticateHumhubAutoLogin() {-->
<!-- this.enableButton = false-->
<!-- this.humhubUri = null-->
<!-- this.$apollo-->
<!-- .query({-->
<!-- query: authenticateHumhubAutoLogin,-->
<!-- fetchPolicy: 'network-only',-->
<!-- })-->
<!-- .then(async (result) => {-->
<!-- this.humhubUri = result.data.authenticateHumhubAutoLogin-->
<!-- this.enableButton = true-->
<!-- })-->
<!-- .catch(() => {-->
<!-- this.enableButton = true-->
<!-- this.humhubUri = ''-->
<!-- // something went wrong with login link so we disable humhub-->
<!-- this.$store.commit('humhubAllowed', false)-->
<!-- })-->
<!-- },-->
<!-- },-->
<!-- created() {-->
<!-- this.authenticateHumhubAutoLogin()-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, computed, onMounted } from 'vue'

View File

@ -58,250 +58,6 @@
</div>
</div>
</template>
<!--<script>-->
<!--import OpenCreationsAmount from '@/components/Contributions/OpenCreationsAmount'-->
<!--import ContributionForm from '@/components/Contributions/ContributionForm'-->
<!--import ContributionList from '@/components/Contributions/ContributionList'-->
<!--import { createContribution, updateContribution, deleteContribution } from '@/graphql/mutations'-->
<!--import { listContributions, listAllContributions, openCreations } from '@/graphql/queries'-->
<!--const COMMUNITY_TABS = ['contribute', 'contributions', 'community']-->
<!--export default {-->
<!-- name: 'Community',-->
<!-- components: {-->
<!-- ContributionForm,-->
<!-- ContributionList,-->
<!-- OpenCreationsAmount,-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- tabIndex: 0,-->
<!-- items: [],-->
<!-- itemsAll: [],-->
<!-- currentPage: 1,-->
<!-- pageSize: 25,-->
<!-- currentPageAll: 1,-->
<!-- pageSizeAll: 25,-->
<!-- contributionCount: 0,-->
<!-- contributionCountAll: 0,-->
<!-- form: {-->
<!-- id: null,-->
<!-- date: '',-->
<!-- memo: '',-->
<!-- hours: 0,-->
<!-- amount: '',-->
<!-- },-->
<!-- originalContributionDate: '',-->
<!-- updateAmount: '',-->
<!-- maximalDate: new Date(),-->
<!-- openCreations: [],-->
<!-- }-->
<!-- },-->
<!-- mounted() {-->
<!-- this.updateTabIndex()-->
<!-- },-->
<!-- apollo: {-->
<!-- OpenCreations: {-->
<!-- query() {-->
<!-- return openCreations-->
<!-- },-->
<!-- fetchPolicy: 'network-only',-->
<!-- variables() {-->
<!-- return {}-->
<!-- },-->
<!-- update({ openCreations }) {-->
<!-- this.openCreations = openCreations-->
<!-- },-->
<!-- error({ message }) {-->
<!-- this.toastError(message)-->
<!-- },-->
<!-- },-->
<!-- ListAllContributions: {-->
<!-- query() {-->
<!-- return listAllContributions-->
<!-- },-->
<!-- variables() {-->
<!-- return {-->
<!-- currentPage: this.currentPageAll,-->
<!-- pageSize: this.pageSizeAll,-->
<!-- }-->
<!-- },-->
<!-- fetchPolicy: 'no-cache',-->
<!-- update({ listAllContributions }) {-->
<!-- this.contributionCountAll = listAllContributions.contributionCount-->
<!-- this.itemsAll = listAllContributions.contributionList-->
<!-- },-->
<!-- error({ message }) {-->
<!-- this.toastError(message)-->
<!-- },-->
<!-- },-->
<!-- ListContributions: {-->
<!-- query() {-->
<!-- return listContributions-->
<!-- },-->
<!-- fetchPolicy: 'network-only',-->
<!-- variables() {-->
<!-- return {-->
<!-- currentPage: this.currentPage,-->
<!-- pageSize: this.pageSize,-->
<!-- }-->
<!-- },-->
<!-- update({ listContributions }) {-->
<!-- this.contributionCount = listContributions.contributionCount-->
<!-- this.items = listContributions.contributionList-->
<!-- if (this.items.find((item) => item.status === 'IN_PROGRESS')) {-->
<!-- this.tabIndex = 1-->
<!-- if (this.$route.params.tab !== 'contributions')-->
<!-- this.$router.push({ params: { tab: 'contributions' } })-->
<!-- this.toastInfo(this.$t('contribution.alert.answerQuestionToast'))-->
<!-- }-->
<!-- },-->
<!-- error({ message }) {-->
<!-- this.toastError(message)-->
<!-- },-->
<!-- },-->
<!-- },-->
<!-- watch: {-->
<!-- '$route.params.tab'() {-->
<!-- this.updateTabIndex()-->
<!-- },-->
<!-- },-->
<!-- computed: {-->
<!-- minimalDate() {-->
<!-- const date = new Date(this.maximalDate)-->
<!-- return new Date(date.setMonth(date.getMonth() - 1, 1))-->
<!-- },-->
<!-- isThisMonth() {-->
<!-- const formDate = new Date(this.form.date)-->
<!-- return (-->
<!-- formDate.getFullYear() === this.maximalDate.getFullYear() &&-->
<!-- formDate.getMonth() === this.maximalDate.getMonth()-->
<!-- )-->
<!-- },-->
<!-- amountToAdd() {-->
<!-- // when existing contribution is edited, the amount is added back on top of the amount-->
<!-- if (this.form.id) return parseInt(this.updateAmount)-->
<!-- return 0-->
<!-- },-->
<!-- maxForMonths() {-->
<!-- const originalContributionDate = new Date(this.originalContributionDate)-->
<!-- if (this.openCreations && this.openCreations.length)-->
<!-- return this.openCreations.slice(1).map((creation) => {-->
<!-- if (-->
<!-- creation.year === originalContributionDate.getFullYear() &&-->
<!-- creation.month === originalContributionDate.getMonth()-->
<!-- )-->
<!-- return parseInt(creation.amount) + this.amountToAdd-->
<!-- return parseInt(creation.amount)-->
<!-- })-->
<!-- return [0, 0]-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- updateTabIndex() {-->
<!-- const index = COMMUNITY_TABS.indexOf(this.$route.params.tab)-->
<!-- this.$nextTick(() => {-->
<!-- this.tabIndex = index > -1 ? index : 0-->
<!-- })-->
<!-- this.closeAllOpenCollapse()-->
<!-- },-->
<!-- closeAllOpenCollapse() {-->
<!-- this.$el.querySelectorAll('.collapse.show').forEach((value) => {-->
<!-- this.$root.$emit('bv::toggle::collapse', value.id)-->
<!-- })-->
<!-- },-->
<!-- refetchData() {-->
<!-- this.$apollo.queries.ListAllContributions.refetch()-->
<!-- this.$apollo.queries.ListContributions.refetch()-->
<!-- this.$apollo.queries.OpenCreations.refetch()-->
<!-- },-->
<!-- saveContribution(data) {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- fetchPolicy: 'no-cache',-->
<!-- mutation: createContribution,-->
<!-- variables: {-->
<!-- creationDate: data.date,-->
<!-- memo: data.memo,-->
<!-- amount: data.amount,-->
<!-- },-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.toastSuccess(this.$t('contribution.submitted'))-->
<!-- this.refetchData()-->
<!-- })-->
<!-- .catch((err) => {-->
<!-- this.toastError(err.message)-->
<!-- })-->
<!-- },-->
<!-- updateContribution(data) {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- fetchPolicy: 'no-cache',-->
<!-- mutation: updateContribution,-->
<!-- variables: {-->
<!-- contributionId: data.id,-->
<!-- creationDate: data.date,-->
<!-- memo: data.memo,-->
<!-- amount: data.amount,-->
<!-- },-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.toastSuccess(this.$t('contribution.updated'))-->
<!-- this.refetchData()-->
<!-- })-->
<!-- .catch((err) => {-->
<!-- this.toastError(err.message)-->
<!-- })-->
<!-- },-->
<!-- deleteContribution(data) {-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- fetchPolicy: 'no-cache',-->
<!-- mutation: deleteContribution,-->
<!-- variables: {-->
<!-- id: data.id,-->
<!-- },-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.toastSuccess(this.$t('contribution.deleted'))-->
<!-- this.refetchData()-->
<!-- })-->
<!-- .catch((err) => {-->
<!-- this.toastError(err.message)-->
<!-- })-->
<!-- },-->
<!-- updateListAllContributions(pagination) {-->
<!-- this.currentPageAll = pagination.currentPage-->
<!-- this.pageSizeAll = pagination.pageSize-->
<!-- this.$apollo.queries.ListAllContributions.refetch()-->
<!-- },-->
<!-- updateListContributions(pagination) {-->
<!-- this.currentPage = pagination.currentPage-->
<!-- this.pageSize = pagination.pageSize-->
<!-- this.$apollo.queries.ListContributions.refetch()-->
<!-- },-->
<!-- updateContributionForm(item) {-->
<!-- this.form.id = item.id-->
<!-- this.form.date = item.contributionDate-->
<!-- this.originalContributionDate = item.contributionDate-->
<!-- this.form.memo = item.memo-->
<!-- this.form.amount = item.amount-->
<!-- this.form.hours = item.amount / 20-->
<!-- this.updateAmount = item.amount-->
<!-- this.tabIndex = 0-->
<!-- this.$router.push({ params: { tab: 'contribute' } })-->
<!-- },-->
<!-- updateTransactions(pagination) {-->
<!-- this.$emit('update-transactions', pagination)-->
<!-- },-->
<!-- updateStatus(id) {-->
<!-- this.items.find((item) => item.id === id).status = 'PENDING'-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, computed, watch, onMounted } from 'vue'
@ -325,7 +81,6 @@ const router = useRouter()
const { toastError, toastSuccess, toastInfo } = useAppToast()
const { t } = useI18n()
// Reactive state
const tabIndex = ref(0)
const items = ref([])
const itemsAll = ref([])
@ -347,7 +102,6 @@ const updateAmount = ref('')
const maximalDate = ref(new Date())
const openCreationsData = ref([])
// Computed properties
const minimalDate = computed(() => {
const date = new Date(maximalDate.value)
return new Date(date.setMonth(date.getMonth() - 1, 1))
@ -383,7 +137,6 @@ const computedKeyFromForm = computed(() => {
return `${form.value.id}_${form.value.date}_${form.value.memo}_${form.value.amount}_${form.value.hours}`
})
// Queries
const { onResult: onOpenCreationsResult, refetch: refetchOpenCreations } = useQuery(openCreations)
const { onResult: onListAllContributionsResult, refetch: refetchAllContributions } = useQuery(
listAllContributions,
@ -402,12 +155,10 @@ const { onResult: onListContributionsResult, refetch: refetchContributions } = u
{ fetchPolicy: 'network-only' },
)
// Mutations
const { mutate: createContributionMutation } = useMutation(createContribution)
const { mutate: updateContributionMutation } = useMutation(updateContribution)
const { mutate: deleteContributionMutation } = useMutation(deleteContribution)
// Query results
onOpenCreationsResult(({ data }) => {
if (data) {
openCreationsData.value = data.openCreations
@ -441,7 +192,6 @@ onListContributionsResult(({ data }) => {
}
})
// Methods
const updateTabIndex = () => {
const index = COMMUNITY_TABS.indexOf(route.params.tab)
tabIndex.value = index > -1 ? index : 0
@ -450,7 +200,6 @@ const updateTabIndex = () => {
const closeAllOpenCollapse = () => {
document.querySelectorAll('.collapse.show').forEach((el) => {
// Assuming you're using bootstrap-vue, adjust if using a different library
el.classList.remove('show')
})
}
@ -539,10 +288,8 @@ const updateStatus = (id) => {
}
}
// Watchers
watch(() => route.params.tab, updateTabIndex)
// Lifecycle hooks
onMounted(updateTabIndex)
</script>
<style scoped>

View File

@ -1,36 +1,29 @@
<!-- eslint-disable prettier/prettier -->
<template>
<div class="forgot-password">
<b-container v-if="enterData">
<BContainer v-if="enterData">
<div class="pb-5">{{ $t('site.forgotPassword.heading') }}</div>
<BRow class="justify-content-center">
<BCol>
<validation-observer ref="observer" v-slot="{ handleSubmit, valid }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
<input-email
v-model="form.email"
:name="$t('form.email')"
:label="$t('form.email')"
:placeholder="$t('form.email')"
></input-email>
<BRow>
<BCol cols="12" lg="6">
<b-button
type="submit"
:variant="valid ? 'gradido' : 'gradido-disable'"
block
:disabled="!valid"
>
{{ $t('settings.password.send_now') }}
</b-button>
</BCol>
</BRow>
</b-form>
</validation-observer>
<BForm role="form" @submit.prevent="onSubmit">
<input-email name="email" :label="$t('form.email')" :placeholder="$t('form.email')" />
<BRow>
<BCol cols="12" lg="6">
<BButton
type="submit"
:variant="formMeta.valid ? 'gradido' : 'gradido-disable'"
block
:disabled="!formMeta.valid"
>
{{ $t('settings.password.send_now') }}
</BButton>
</BCol>
</BRow>
</BForm>
</BCol>
</BRow>
</b-container>
<b-container v-else>
</BContainer>
<BContainer v-else>
<message
:headline="success ? $t('message.title') : $t('message.errorTitle')"
:subtitle="success ? $t('message.email') : $t('error.email-already-sent')"
@ -38,70 +31,64 @@
:button-text="$t('login')"
link-to="/login"
/>
</b-container>
</BContainer>
</div>
</template>
<script>
import { forgotPassword } from '@/graphql/mutations'
<script setup>
import { ref, computed } from 'vue'
import { useMutation } from '@vue/apollo-composable'
import InputEmail from '@/components/Inputs/InputEmail'
import Message from '@/components/Message/Message'
import { useAppToast } from '@/composables/useToast'
import { forgotPassword } from '@/graphql/mutations'
import { useRoute } from 'vue-router'
import { useForm } from 'vee-validate'
import { useI18n } from 'vue-i18n'
export default {
name: 'ForgotPassword',
components: {
InputEmail,
Message,
},
data() {
return {
form: {
email: '',
},
subtitle: 'settings.password.subtitle',
showPageMessage: false,
success: null,
}
},
computed: {
enterData() {
return !this.showPageMessage
},
},
created() {
if (this.$route.params.comingFrom) {
this.subtitle = 'settings.password.resend_subtitle'
}
},
methods: {
async onSubmit() {
this.$apollo
.mutate({
mutation: forgotPassword,
variables: {
email: this.form.email,
},
})
.then(() => {
this.showPageMessage = true
this.success = true
})
.catch(() => {
this.showPageMessage = true
this.success = false
this.toastError(this.$t('error.email-already-sent'))
})
},
},
const { toastError } = useAppToast()
const subtitle = ref('settings.password.subtitle')
const showPageMessage = ref(false)
const success = ref(null)
const { params } = useRoute()
const { t } = useI18n()
if (params.comingFrom) {
subtitle.value = 'settings.password.resend_subtitle'
}
const { mutate } = useMutation(forgotPassword)
const { meta: formMeta, values: formValues } = useForm()
const enterData = computed(() => {
return !showPageMessage.value
})
async function onSubmit() {
try {
await mutate({
email: formValues.email,
})
showPageMessage.value = true
success.value = true
} catch (err) {
showPageMessage.value = true
success.value = false
toastError(t('error.email-already-sent'))
}
}
</script>
<style scoped>
.btn-gradido {
:deep(.btn-gradido) {
padding-right: 0;
padding-left: 0;
}
.btn-gradido-disable {
:deep(.btn-gradido-disable) {
padding-right: 0;
padding-left: 0;
}

View File

@ -100,87 +100,6 @@
</div>
</template>
<!--<script>-->
<!--import InputPassword from '@/components/Inputs/InputPassword'-->
<!--import InputEmail from '@/components/Inputs/InputEmail'-->
<!--import Message from '@/components/Message/Message'-->
<!--import { login } from '@/graphql/mutations'-->
<!--export default {-->
<!-- name: 'Login',-->
<!-- components: {-->
<!-- InputPassword,-->
<!-- InputEmail,-->
<!-- Message,-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- form: {-->
<!-- email: '',-->
<!-- password: '',-->
<!-- },-->
<!-- passwordVisible: false,-->
<!-- showPageMessage: false,-->
<!-- errorReason: null,-->
<!-- errorSubtitle: '',-->
<!-- errorLinkTo: '',-->
<!-- }-->
<!-- },-->
<!-- methods: {-->
<!-- async onSubmit() {-->
<!-- const loader = this.$loading.show({-->
<!-- container: this.$refs.submitButton,-->
<!-- })-->
<!-- this.$root.$bvToast.hide()-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: login,-->
<!-- variables: {-->
<!-- email: this.form.email,-->
<!-- password: this.form.password,-->
<!-- publisherId: this.$store.state.publisherId,-->
<!-- },-->
<!-- })-->
<!-- .then(async (result) => {-->
<!-- const {-->
<!-- data: { login },-->
<!-- } = result-->
<!-- this.$store.dispatch('login', login)-->
<!-- this.$store.commit('email', this.form.email)-->
<!-- await loader.hide()-->
<!-- if (this.$route.params.code) {-->
<!-- this.$router.push(`/redeem/${this.$route.params.code}`)-->
<!-- } else {-->
<!-- this.$router.push(this.$store.state.redirectPath)-->
<!-- }-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- if (error.message.includes('User email not validated')) {-->
<!-- this.showPageMessage = true-->
<!-- this.errorSubtitle = this.$t('message.activateEmail')-->
<!-- this.errorLinkTo = '/forgot-password'-->
<!-- this.toastError(this.$t('error.no-account'))-->
<!-- } else if (error.message.includes('User has no password set yet')) {-->
<!-- this.showPageMessage = true-->
<!-- this.errorSubtitle = this.$t('message.unsetPassword')-->
<!-- this.errorLinkTo = '/reset-password/login'-->
<!-- this.toastError(this.$t('error.no-account'))-->
<!-- } else if (error.message.includes('No user with this credentials')) {-->
<!-- this.toastError(this.$t('error.no-user'))-->
<!-- } else {-->
<!-- this.toastError(this.$t('error.unknown-error') + error.message)-->
<!-- }-->
<!-- loader.hide()-->
<!-- })-->
<!-- },-->
<!-- },-->
<!-- computed: {-->
<!-- enterData() {-->
<!-- return !this.showPageMessage-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import InputPassword from '@/components/Inputs/InputPassword'
import InputEmail from '@/components/Inputs/InputEmail'

View File

@ -1,186 +1,154 @@
<template>
<div id="registerform">
<b-container v-if="enterData">
<BContainer v-if="enterData">
<div class="pb-5" align="center">{{ $t('gdd_per_link.isFree') }}</div>
<validation-observer ref="observer" v-slot="{ handleSubmit }">
<b-form role="form" @submit.prevent="handleSubmit(onSubmit)">
<BRow>
<BCol sm="12" md="6">
<validation-provider
v-slot="validationContext"
:name="$t('form.firstname')"
:rules="{ required: true, min: 3 }"
>
<b-form-group
class="mb-3"
:label="$t('form.firstname')"
label-for="registerFirstname"
>
<b-form-input
id="registerFirstname"
v-model="form.firstname"
:name="$t('form.firstname')"
:placeholder="$t('form.firstname')"
:state="getValidationState(validationContext)"
aria-describedby="registerFirstnameLiveFeedback"
></b-form-input>
<BForm role="form" @submit.prevent="onSubmit">
<BRow>
<BCol sm="12" md="6">
<BFormGroup class="mb-3" :label="$t('form.firstname')" label-for="registerFirstname">
<BFormInput
id="registerFirstname"
:model-value="firstname"
name="firstname"
:placeholder="$t('form.firstname')"
:state="firstnameMeta.valid"
aria-describedby="registerFirstnameLiveFeedback"
@update:model-value="firstname = $event"
/>
<b-form-invalid-feedback id="registerFirstnameLiveFeedback">
{{ validationContext.errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</validation-provider>
</BCol>
<BCol sm="12" md="6">
<validation-provider
v-slot="validationContext"
:name="$t('form.lastname')"
:rules="{ required: true, min: 2 }"
>
<b-form-group
class="mb-3"
:label="$t('form.lastname')"
label-for="registerLastname"
>
<b-form-input
id="registerLastname"
v-model="form.lastname"
:name="$t('form.lastname')"
:placeholder="$t('form.lastname')"
:state="getValidationState(validationContext)"
aria-describedby="registerLastnameLiveFeedback"
></b-form-input>
<BFormInvalidFeedback v-if="firstnameError" id="registerFirstnameLiveFeedback">
{{ firstnameError }}
</BFormInvalidFeedback>
</BFormGroup>
</BCol>
<BCol sm="12" md="6">
<BFormGroup class="mb-3" :label="$t('form.lastname')" label-for="registerLastname">
<BFormInput
id="registerLastname"
:model-value="lastname"
name="lastname"
:placeholder="$t('form.lastname')"
:state="lastnameMeta.valid"
aria-describedby="registerLastnameLiveFeedback"
@update:model-value="lastname = $event"
/>
<b-form-invalid-feedback id="registerLastnameLiveFeedback">
{{ validationContext.errors[0] }}
</b-form-invalid-feedback>
</b-form-group>
</validation-provider>
</BCol>
</BRow>
<BRow>
<BCol>
<input-email
v-model="form.email"
:name="$t('form.email')"
:label="$t('form.email')"
:placeholder="$t('form.email')"
></input-email>
</BCol>
</BRow>
<BRow>
<BCol cols="12" class="my-4">
<b-form-checkbox
id="registerCheckbox"
v-model="form.agree"
:name="$t('site.signup.agree')"
>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
</b-form-checkbox>
</BCol>
</BRow>
<BRow>
<BCol cols="12" lg="6">
<b-button
block
type="submit"
:disabled="disabled"
:variant="disabled ? 'gradido-disable' : 'gradido'"
>
{{ $t('signup') }}
</b-button>
</BCol>
</BRow>
</b-form>
</validation-observer>
</b-container>
<b-container v-else>
<BFormInvalidFeedback v-if="lastnameError" id="registerLastnameLiveFeedback">
{{ lastnameError }}
</BFormInvalidFeedback>
</BFormGroup>
</BCol>
</BRow>
<BRow>
<BCol>
<input-email name="email" :label="$t('form.email')" :placeholder="$t('form.email')" />
</BCol>
</BRow>
<BRow>
<BCol cols="12" class="my-4">
<BFormCheckbox
id="registerCheckbox"
name="agree"
:model-value="agree"
:state="(agreeMeta.valid && agreeMeta.dirty) || undefined"
@update:model-value="agree = $event"
>
<!-- eslint-disable-next-line @intlify/vue-i18n/no-v-html -->
<span class="text-muted" v-html="$t('site.signup.agree')"></span>
</BFormCheckbox>
</BCol>
</BRow>
<BRow>
<BCol cols="12" lg="6">
<BButton
block
type="submit"
:disabled="!formMeta.valid"
:variant="!formMeta.valid ? 'gradido-disable' : 'gradido'"
>
{{ $t('signup') }}
</BButton>
</BCol>
</BRow>
</BForm>
</BContainer>
<BContainer v-else>
<message :headline="$t('message.title')" :subtitle="$t('message.register')" />
</b-container>
</BContainer>
</div>
</template>
<script>
import { createUser } from '@/graphql/mutations'
import CONFIG from '@/config'
<script setup>
import { ref, computed } from 'vue'
import { useMutation } from '@vue/apollo-composable'
import InputEmail from '@/components/Inputs/InputEmail'
import Message from '@/components/Message/Message'
import { useAppToast } from '@/composables/useToast'
import { useField, useForm } from 'vee-validate'
import { createUser } from '@/graphql/mutations'
import { useI18n } from 'vue-i18n'
import { useStore } from 'vuex'
import { useRoute } from 'vue-router'
export default {
name: 'Register',
components: {
InputEmail,
Message,
},
data() {
return {
form: {
firstname: '',
lastname: '',
email: '',
agree: false,
},
showPageMessage: false,
submitted: false,
publisherId: this.$store.state.publisherId,
redeemCode: this.$route.params.code,
CONFIG,
}
},
computed: {
namesFilled() {
return (
this.form.firstname !== '' &&
this.form.firstname.length > 2 &&
this.form.lastname !== '' &&
this.form.lastname.length > 1
)
},
emailFilled() {
return this.form.email !== ''
},
disabled() {
return !(this.namesFilled && this.emailFilled && this.form.agree)
},
enterData() {
return !this.showPageMessage
},
},
methods: {
getValidationState({ dirty, validated, valid = null }) {
return dirty || validated ? valid : null
},
async onSubmit() {
this.$apollo
.mutate({
mutation: createUser,
variables: {
email: this.form.email,
firstName: this.form.firstname,
lastName: this.form.lastname,
language: this.$store.state.language,
publisherId: this.$store.state.publisherId,
redeemCode: this.redeemCode,
},
})
.then(() => {
this.showPageMessage = true
})
.catch((error) => {
this.toastError(this.$t('error.unknown-error') + error.message)
})
},
},
const { toastError } = useAppToast()
const { mutate } = useMutation(createUser)
const { values: formValues, meta: formMeta, defineField, handleSubmit } = useForm()
const [firstname, firstnameProps] = defineField('firstname')
const { meta: firstnameMeta, errorMessage: firstnameError } = useField('firstname', {
required: true,
min: 3,
})
const [lastname, lastnameProps] = defineField('lastname')
const { meta: lastnameMeta, errorMessage: lastnameError } = useField('lastname', {
required: true,
min: 2,
})
const [agree, agreeProps] = defineField('agree')
const { meta: agreeMeta } = useField('agree', 'required')
const { t } = useI18n()
const store = useStore()
const { params } = useRoute()
const showPageMessage = ref(false)
const submitted = ref(false)
const publisherId = ref(store.state.publisherId)
const redeemCode = ref(params.code)
const CONFIG = window.config
const enterData = computed(() => {
return !showPageMessage.value
})
async function onSubmit() {
try {
await mutate({
email: formValues.email,
firstName: formValues.firstname,
lastName: formValues.lastname,
language: store.state.language,
publisherId: publisherId.value,
redeemCode: redeemCode.value,
})
showPageMessage.value = true
} catch (error) {
toastError(`${t('error.unknown-error')} ${error.message}`)
}
}
</script>
<style scoped>
.btn-gradido {
:deep(.btn-gradido) {
padding-right: 0;
padding-left: 0;
}
.btn-gradido-disable {
:deep(.btn-gradido-disable) {
padding-right: 0;
padding-left: 0;
}

View File

@ -2,7 +2,7 @@
<div id="register-community">
<!-- Header -->
<div class="p-3">
<b-container>
<BContainer>
<div class="text-center mb-7 header">
<BRow class="justify-content-center">
<BCol xl="5" lg="6" md="8" class="px-2">
@ -18,9 +18,9 @@
<BRow>
<BCol class="text-center">
<router-link to="/register">
<b-button variant="outline-secondary">
<BButton variant="outline-secondary">
{{ $t('community.continue-to-registration') }}
</b-button>
</BButton>
</router-link>
</BCol>
</BRow>
@ -29,9 +29,9 @@
<BRow>
<BCol class="text-center">
<router-link to="/select-community">
<b-button variant="outline-secondary">
<BButton variant="outline-secondary">
{{ $t('community.choose-another-community') }}
</b-button>
</BButton>
</router-link>
</BCol>
</BRow>
@ -39,12 +39,12 @@
<BRow>
<BCol class="text-center">
<router-link to="/login">
<b-button variant="outline-secondary">{{ $t('back') }}</b-button>
<BButton variant="outline-secondary">{{ $t('back') }}</BButton>
</router-link>
</BCol>
</BRow>
</div>
</b-container>
</BContainer>
</div>
</div>
</template>

View File

@ -49,144 +49,6 @@
</gdd-send>
</div>
</template>
<!--<script>-->
<!--import GddSend, { TRANSACTION_STEPS } from '@/components/GddSend'-->
<!--import TransactionForm from '@/components/GddSend/TransactionForm'-->
<!--import TransactionConfirmationSend from '@/components/GddSend/TransactionConfirmationSend'-->
<!--import TransactionConfirmationLink from '@/components/GddSend/TransactionConfirmationLink'-->
<!--import TransactionResultSendSuccess from '@/components/GddSend/TransactionResultSendSuccess'-->
<!--import TransactionResultSendError from '@/components/GddSend/TransactionResultSendError'-->
<!--import TransactionResultLink from '@/components/GddSend/TransactionResultLink'-->
<!--import { sendCoins, createTransactionLink } from '@/graphql/mutations.js'-->
<!--const EMPTY_TRANSACTION_DATA = {-->
<!-- identifier: '',-->
<!-- amount: 0,-->
<!-- memo: '',-->
<!--}-->
<!--export const SEND_TYPES = {-->
<!-- send: 'send',-->
<!-- link: 'link',-->
<!--}-->
<!--export default {-->
<!-- name: 'Send',-->
<!-- components: {-->
<!-- GddSend,-->
<!-- TransactionForm,-->
<!-- TransactionConfirmationSend,-->
<!-- TransactionConfirmationLink,-->
<!-- TransactionResultSendSuccess,-->
<!-- TransactionResultSendError,-->
<!-- TransactionResultLink,-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- transactionData: { ...EMPTY_TRANSACTION_DATA },-->
<!-- error: false,-->
<!-- errorResult: '',-->
<!-- currentTransactionStep: TRANSACTION_STEPS.transactionForm,-->
<!-- loading: false,-->
<!-- link: null,-->
<!-- }-->
<!-- },-->
<!-- props: {-->
<!-- balance: { type: Number, default: 0 },-->
<!-- GdtBalance: { type: Number, default: 0 },-->
<!-- transactions: {-->
<!-- default: () => [],-->
<!-- },-->
<!-- pending: {-->
<!-- type: Boolean,-->
<!-- default: true,-->
<!-- },-->
<!-- },-->
<!-- methods: {-->
<!-- setTransaction(data) {-->
<!-- this.transactionData = { ...data }-->
<!-- switch (data.selected) {-->
<!-- case SEND_TYPES.send:-->
<!-- this.currentTransactionStep = TRANSACTION_STEPS.transactionConfirmationSend-->
<!-- break-->
<!-- case SEND_TYPES.link:-->
<!-- this.currentTransactionStep = TRANSACTION_STEPS.transactionConfirmationLink-->
<!-- break-->
<!-- }-->
<!-- },-->
<!-- async sendTransaction() {-->
<!-- this.loading = true-->
<!-- this.error = false-->
<!-- switch (this.transactionData.selected) {-->
<!-- case SEND_TYPES.send:-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: sendCoins,-->
<!-- variables: {-->
<!-- // from target community we need only the uuid-->
<!-- recipientCommunityIdentifier: this.transactionData.targetCommunity.uuid,-->
<!-- recipientIdentifier: this.transactionData.identifier,-->
<!-- amount: this.transactionData.amount,-->
<!-- memo: this.transactionData.memo,-->
<!-- },-->
<!-- })-->
<!-- .then(() => {-->
<!-- this.error = false-->
<!-- this.$emit('set-tunneled-email', null)-->
<!-- this.updateTransactions({})-->
<!-- this.transactionData = { ...EMPTY_TRANSACTION_DATA }-->
<!-- this.currentTransactionStep = TRANSACTION_STEPS.transactionResultSendSuccess-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.errorResult = error.message-->
<!-- this.error = true-->
<!-- this.currentTransactionStep = TRANSACTION_STEPS.transactionResultSendError-->
<!-- })-->
<!-- break-->
<!-- case SEND_TYPES.link:-->
<!-- this.$apollo-->
<!-- .mutate({-->
<!-- mutation: createTransactionLink,-->
<!-- variables: { amount: this.transactionData.amount, memo: this.transactionData.memo },-->
<!-- })-->
<!-- .then((result) => {-->
<!-- this.$emit('set-tunneled-email', null)-->
<!-- const {-->
<!-- data: {-->
<!-- createTransactionLink: { link, amount, memo, validUntil },-->
<!-- },-->
<!-- } = result-->
<!-- this.link = link-->
<!-- this.amount = amount-->
<!-- this.memo = memo-->
<!-- this.validUntil = validUntil-->
<!-- this.transactionData = { ...EMPTY_TRANSACTION_DATA }-->
<!-- this.currentTransactionStep = TRANSACTION_STEPS.transactionResultLink-->
<!-- this.updateTransactions({})-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.toastError(error.message)-->
<!-- })-->
<!-- break-->
<!-- default:-->
<!-- throw new Error(`undefined transactionData.selected : ${this.transactionData.selected}`)-->
<!-- }-->
<!-- this.loading = false-->
<!-- this.$router.push({ path: '/send' })-->
<!-- },-->
<!-- onBack() {-->
<!-- this.currentTransactionStep = TRANSACTION_STEPS.transactionForm-->
<!-- this.$mount()-->
<!-- },-->
<!-- updateTransactions(pagination) {-->
<!-- this.$emit('update-transactions', pagination)-->
<!-- },-->
<!-- },-->
<!-- created() {-->
<!-- this.updateTransactions({})-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, reactive } from 'vue'
@ -313,21 +175,4 @@ function updateTransactions(pagination) {
// Equivalent to created hook
updateTransactions({})
// Expose necessary methods and reactive variables
// defineExpose({
// setTransaction,
// sendTransaction,
// onBack,
// updateTransactions,
// transactionData,
// error,
// errorResult,
// currentTransactionStep,
// loading,
// link,
// amount,
// memo,
// validUntil,
// })
</script>

View File

@ -1,7 +1,7 @@
<template>
<div class="show-transaction-link-informations">
<div class="mt-4">
<transaction-link-item :type="itemType">
<transaction-link-item :type="itemTypeExt">
<template #LOGGED_OUT>
<redeem-logged-out :link-data="linkData" :is-contribution-link="isContributionLink" />
</template>
@ -26,139 +26,140 @@
</div>
</div>
</template>
<script>
<script setup>
import { ref, computed, onMounted, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { useStore } from 'vuex'
import { useQuery, useMutation } from '@vue/apollo-composable'
import TransactionLinkItem from '@/components/TransactionLinkItem'
import RedeemLoggedOut from '@/components/LinkInformations/RedeemLoggedOut'
import RedeemSelfCreator from '@/components/LinkInformations/RedeemSelfCreator'
import RedeemValid from '@/components/LinkInformations/RedeemValid'
import RedeemedTextBox from '@/components/LinkInformations/RedeemedTextBox'
import { useAppToast } from '@/composables/useToast'
import { queryTransactionLink } from '@/graphql/queries'
import { redeemTransactionLink } from '@/graphql/mutations'
import { useI18n } from 'vue-i18n'
export default {
name: 'TransactionLink',
components: {
TransactionLinkItem,
RedeemLoggedOut,
RedeemSelfCreator,
RedeemValid,
RedeemedTextBox,
const { toastError, toastSuccess } = useAppToast()
const router = useRouter()
const { params } = useRoute()
const store = useStore()
const { d, t } = useI18n()
const linkData = ref({
__typename: 'TransactionLink',
amount: '',
memo: '',
user: {
firstName: '',
},
emits: ['set-mobile-start'],
data() {
return {
linkData: {
__typename: 'TransactionLink',
amount: '',
memo: '',
user: {
firstName: '',
},
deletedAt: null,
validLink: false,
},
}
},
computed: {
isContributionLink() {
return this.$route.params.code.search(/^CL-/) === 0
},
tokenExpiresInSeconds() {
const remainingSecs = Math.floor(
(new Date(this.$store.state.tokenTime * 1000).getTime() - new Date().getTime()) / 1000,
)
return remainingSecs <= 0 ? 0 : remainingSecs
},
itemType() {
// link is deleted: at, from
if (this.linkData.deletedAt) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.redeemedBoxText = this.$t('gdd_per_link.link-deleted', {
date: this.$d(new Date(this.linkData.deletedAt), 'long'),
})
return `TEXT`
}
// link ist abgelaufen, nicht gelöscht
if (new Date(this.linkData.validUntil) < new Date()) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.redeemedBoxText = this.$t('gdd_per_link.link-expired', {
date: this.$d(new Date(this.linkData.validUntil), 'long'),
})
return `TEXT`
deletedAt: null,
validLink: false,
})
const redeemedBoxText = ref('')
const { result, loading, error } = useQuery(queryTransactionLink, {
code: params.code,
})
const {
mutate: redeemMutate,
loading: redeemLoading,
error: redeemError,
} = useMutation(redeemTransactionLink)
const isContributionLink = computed(() => {
return params.code.search(/^CL-/) === 0
})
const tokenExpiresInSeconds = computed(() => {
const remainingSecs = Math.floor(
(new Date(store.state.tokenTime * 1000).getTime() - new Date().getTime()) / 1000,
)
return remainingSecs <= 0 ? 0 : remainingSecs
})
const itemType = computed(() => {
if (linkData.value.deletedAt) return 'TEXT_DELETED'
if (new Date(linkData.value.validUntil) < new Date()) return 'TEXT_EXPIRED'
if (linkData.value.redeemedAt) return 'TEXT_REDEEMED'
if (store.state.token && store.state.tokenTime) {
if (tokenExpiresInSeconds.value < 5) return 'LOGGED_OUT'
if (linkData.value.user && store.state.gradidoID === linkData.value.user.gradidoID)
return 'SELF_CREATOR'
if (!linkData.value.redeemedAt && !linkData.value.deletedAt) return 'VALID'
}
return 'LOGGED_OUT'
})
const itemTypeExt = computed(() => {
if (itemType.value.startsWith('TEXT')) {
return 'TEXT'
}
return itemType.value
})
watch(itemType, (newItemType) => {
updateRedeemedBoxText(newItemType)
})
function updateRedeemedBoxText(type) {
switch (type) {
case 'TEXT_DELETED':
redeemedBoxText.value = t('gdd_per_link.link-deleted', {
date: d(new Date(linkData.value.deletedAt), 'long'),
})
break
case 'TEXT_EXPIRED':
redeemedBoxText.value = t('gdd_per_link.link-expired', {
date: d(new Date(linkData.value.validUntil), 'long'),
})
break
case 'TEXT_REDEEMED':
redeemedBoxText.value = t('gdd_per_link.redeemed-at', {
date: d(new Date(linkData.value.redeemedAt), 'long'),
})
break
default:
redeemedBoxText.value = ''
}
}
const emit = defineEmits(['set-mobile-start'])
onMounted(() => {
setTransactionLinkInformation()
emit('set-mobile-start', false)
})
function setTransactionLinkInformation() {
result.value
.then((data) => {
linkData.value = data.queryTransactionLink
if (linkData.value.__typename === 'ContributionLink' && store.state.token) {
mutationLink(linkData.value.amount)
}
})
.catch(() => {
toastError(t('gdd_per_link.redeemlink-error'))
})
}
// der link wurde eingelöst, nicht gelöscht
if (this.linkData.redeemedAt) {
// eslint-disable-next-line vue/no-side-effects-in-computed-properties
this.redeemedBoxText = this.$t('gdd_per_link.redeemed-at', {
date: this.$d(new Date(this.linkData.redeemedAt), 'long'),
})
return `TEXT`
}
if (this.$store.state.token && this.$store.state.tokenTime) {
if (this.tokenExpiresInSeconds < 5) return `LOGGED_OUT`
// logged in, nicht berechtigt einzulösen, eigener link
if (this.linkData.user && this.$store.state.gradidoID === this.linkData.user.gradidoID) {
return `SELF_CREATOR`
}
// logged in und berechtigt einzulösen
if (!this.linkData.redeemedAt && !this.linkData.deletedAt) {
return `VALID`
}
}
return `LOGGED_OUT`
},
},
created() {
this.setTransactionLinkInformation()
this.$emit('set-mobile-start', false)
},
methods: {
setTransactionLinkInformation() {
this.$apollo
.query({
fetchPolicy: 'no-cache',
query: queryTransactionLink,
variables: {
code: this.$route.params.code,
},
})
.then((result) => {
this.validLink = true
this.linkData = result.data.queryTransactionLink
if (this.linkData.__typename === 'ContributionLink' && this.$store.state.token) {
this.mutationLink(this.linkData.amount)
}
})
.catch(() => {
this.toastError(this.$t('gdd_per_link.redeemlink-error'))
})
},
mutationLink(amount) {
this.$apollo
.mutate({
mutation: redeemTransactionLink,
variables: {
code: this.$route.params.code,
},
})
.then(() => {
this.toastSuccess(
this.$t('gdd_per_link.redeemed', {
n: amount,
}),
)
this.$router.push('/overview')
})
.catch((err) => {
this.toastError(err.message)
this.$router.push('/overview')
})
},
},
async function mutationLink(amount) {
try {
await redeemMutate({
code: params.code,
})
toastSuccess(t('gdd_per_link.redeemed', { n: amount }))
await router.push('/overview')
} catch (err) {
toastError(err.message)
await router.push('/overview')
}
}
</script>

View File

@ -21,84 +21,7 @@
</div>
</div>
</template>
<!--<script>-->
<!--import GddTransactionList from '@/components/GddTransactionList'-->
<!--import GdtTransactionList from '@/components/GdtTransactionList'-->
<!--import { listGDTEntriesQuery } from '@/graphql/queries'-->
<!--export default {-->
<!-- name: 'Transactions',-->
<!-- components: {-->
<!-- GddTransactionList,-->
<!-- GdtTransactionList,-->
<!-- },-->
<!-- props: {-->
<!-- gdt: { type: Boolean, default: false },-->
<!-- transactions: {-->
<!-- default: () => [],-->
<!-- },-->
<!-- transactionCount: { type: Number, default: 0 },-->
<!-- transactionLinkCount: { type: Number, default: 0 },-->
<!-- },-->
<!-- data() {-->
<!-- return {-->
<!-- timestamp: Date.now(),-->
<!-- transactionsGdt: [],-->
<!-- transactionGdtCount: 0,-->
<!-- currentPage: 1,-->
<!-- pageSize: 25,-->
<!-- tabIndex: 0,-->
<!-- }-->
<!-- },-->
<!-- methods: {-->
<!-- async updateGdt() {-->
<!-- this.$apollo-->
<!-- .query({-->
<!-- query: listGDTEntriesQuery,-->
<!-- variables: {-->
<!-- currentPage: this.currentPage,-->
<!-- pageSize: this.pageSize,-->
<!-- },-->
<!-- fetchPolicy: 'network-only',-->
<!-- })-->
<!-- .then((result) => {-->
<!-- const {-->
<!-- data: { listGDTEntries },-->
<!-- } = result-->
<!-- this.transactionsGdt = listGDTEntries.gdtEntries-->
<!-- this.transactionGdtCount = listGDTEntries.count-->
<!-- window.scrollTo(0, 0)-->
<!-- // eslint-disable-next-line no-unused-expressions-->
<!-- this.$route.path === '/transactions' ? this.$router.replace('/gdt') : ''-->
<!-- })-->
<!-- .catch((error) => {-->
<!-- this.transactionGdtCount = -1-->
<!-- this.toastError(error.message)-->
<!-- })-->
<!-- },-->
<!-- updateTransactions(pagination) {-->
<!-- this.$emit('update-transactions', pagination)-->
<!-- },-->
<!-- },-->
<!-- created() {-->
<!-- if (this.gdt) {-->
<!-- this.updateGdt()-->
<!-- }-->
<!-- },-->
<!-- watch: {-->
<!-- currentPage() {-->
<!-- if (this.gdt) {-->
<!-- this.updateGdt()-->
<!-- }-->
<!-- },-->
<!-- gdt() {-->
<!-- if (this.gdt) {-->
<!-- this.updateGdt()-->
<!-- }-->
<!-- },-->
<!-- },-->
<!--}-->
<!--</script>-->
<script setup>
import { ref, watch, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'

View File

@ -20,34 +20,24 @@
</b-container>
</div>
</template>
<script>
<script setup>
import { ref } from 'vue'
import { useQuery } from '@vue/apollo-composable'
import { useAppToast } from '@/composables/useToast'
import { authenticateGmsUserSearch } from '@/graphql/queries'
export default {
name: 'UserSearch',
data() {
return {
gmsUri: 'not initialized',
}
},
created() {
this.authenticateGmsUserPlayground()
},
methods: {
async authenticateGmsUserPlayground() {
this.$apollo
.query({
query: authenticateGmsUserSearch,
})
.then(async (result) => {
this.gmsUri =
result.data.authenticateGmsUserSearch.url +
'?accesstoken=' +
result.data.authenticateGmsUserSearch.token
})
.catch(() => {
this.toastError('authenticateGmsUserSearch failed!')
})
},
},
}
const { useToast } = useAppToast()
const gmsUri = ref('not initialized')
const { onResult, result, loading, onError } = useQuery(authenticateGmsUserSearch)
onResult(({ data }) => {
gmsUri.value = `${data.authenticateGmsUserSearch.url}?accesstoken=${data.authenticateGmsUserSearch.token}`
})
onError(() => {
useToast.error('authenticateGmsUserSearch failed!')
})
</script>

View File

@ -6,6 +6,7 @@ import vue from '@vitejs/plugin-vue'
import Components from 'unplugin-vue-components/vite'
import Icons from 'unplugin-icons/vite'
import IconsResolve from 'unplugin-icons/resolver'
import EnvironmentPlugin from 'vite-plugin-environment'
import { BootstrapVueNextResolver } from 'bootstrap-vue-next'
@ -43,6 +44,32 @@ export default defineConfig({
compiler: 'vue3',
autoInstall: true,
}),
EnvironmentPlugin({
BUILD_COMMIT: null,
GMS_ACTIVE: null,
HUMHUB_ACTIVE: null,
NODE_ENV: null,
DEFAULT_PUBLISHER_ID: null,
PORT: null,
COMMUNITY_HOST: null,
URL_PROTOCOL: null,
COMMUNITY_URL: null,
GRAPHQL_PATH: null,
ADMIN_AUTH_PATH: null,
COMMUNITY_NAME: null,
COMMUNITY_REGISTER_PATH: null,
COMMUNITY_DESCRIPTION: null,
COMMUNITY_SUPPORT_MAIL: null,
META_URL: null,
META_TITLE_DE: null,
META_TITLE_EN: null,
META_DESCRIPTION_DE: null,
META_DESCRIPTION_EN: null,
META_KEYWORDS_DE: null,
META_KEYWORDS_EN: null,
META_AUTHOR: null,
CONFIG_VERSION: null,
}),
commonjs(),
],
css: {

View File

@ -8570,6 +8570,11 @@ vite-plugin-dynamic-import@^1.5.0:
fast-glob "^3.2.12"
magic-string "^0.30.1"
vite-plugin-environment@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/vite-plugin-environment/-/vite-plugin-environment-1.1.3.tgz#d01a04abb2f69730a4866c9c9db51d3dab74645b"
integrity sha512-9LBhB0lx+2lXVBEWxFZC+WO7PKEyE/ykJ7EPWCq95NEcCpblxamTbs5Dm3DLBGzwODpJMEnzQywJU8fw6XGGGA==
vite@3.2.10:
version "3.2.10"
resolved "https://registry.yarnpkg.com/vite/-/vite-3.2.10.tgz#7ac79fead82cfb6b5bf65613cd82fba6dcc81340"