invitation page implementation

This commit is contained in:
Čarodej
2021-10-25 17:14:27 +02:00
parent b45662942d
commit 524791f251
21 changed files with 616 additions and 57 deletions

View File

@@ -1,5 +1,5 @@
<template>
<div class="auth-form" v-if="isVisible">
<div v-if="isVisible" class="auth-form">
<slot></slot>
</div>
</template>

View File

@@ -1,5 +1,5 @@
<template>
<svg width="53px" height="52px" viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<svg viewBox="0 0 53 39" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<linearGradient x1="50%" y1="6.48193497%" x2="50%" y2="35.9903566%" id="linearGradient-8fktz2_lvc-1">
<stop stop-color="#3DB07D" offset="0%"></stop>

View File

@@ -5,7 +5,7 @@
v-if="member.data.attributes.avatar"
:src="member.data.attributes.avatar"
:alt="member.data.attributes.name"
class="rounded-lg"
class="rounded-xl border-4 border-white"
>
<TypedAvatar
v-else

View File

@@ -6,6 +6,7 @@ import routesIndex from './routes/routesIndex'
import routesAuth from './routes/routesAuth'
import routesUser from './routes/routesUser'
import routesFile from './routes/routesFile'
import routesTeam from './routes/routesTeam'
import store from './store/index'
import Router from 'vue-router'
import Vue from 'vue'
@@ -23,6 +24,7 @@ const router = new Router({
...routesAuth,
...routesUser,
...routesFile,
...routesTeam,
],
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {

13
resources/js/routes/routesTeam.js vendored Normal file
View File

@@ -0,0 +1,13 @@
const routesTeam = [
{
name: 'Invitation',
path: '/team-folder-invitation/:id',
component: () =>
import(/* webpackChunkName: "chunks/invitation" */ '../views/Teams/Invitation'),
meta: {
requiresAuth: false
},
},
]
export default routesTeam

View File

@@ -1,7 +1,13 @@
<template>
<div>
<img v-if="config.app_logo" class="logo mx-auto" :src="$getImage(config.app_logo)" :alt="config.app_name">
<b v-if="! config.app_logo" class="auth-logo-text">{{ config.app_name }}</b>
<!--Custom content-->
<slot></slot>
<!--Default application logo-->
<div v-if="! $slots.default">
<img v-if="config.app_logo" class="logo mx-auto" :src="$getImage(config.app_logo)" :alt="config.app_name">
<b v-if="! config.app_logo" class="auth-logo-text">{{ config.app_name }}</b>
</div>
<h1>{{ title }}</h1>
<h2>{{ description }}:</h2>
@@ -47,4 +53,26 @@ export default {
margin-bottom: 50px;
color: $text;
}
@media only screen and (max-width: 690px) {
h1 {
@include font-size(30);
}
h2 {
@include font-size(21);
}
}
@media only screen and (max-width: 490px) {
h1 {
@include font-size(22);
}
h2 {
@include font-size(18);
}
}
</style>

View File

@@ -1,13 +1,11 @@
<template>
<AuthContentWrapper ref="auth">
<!--Password reset link sended-->
<AuthContent name="not-found" :visible="true">
<img v-if="config.app_logo" class="logo mx-auto" :src="$getImage(config.app_logo)" :alt="config.app_name">
<b v-if="! config.app_logo" class="auth-logo-text">{{ config.app_name }}</b>
<h1>{{ $t('page_shared_404.title') }}</h1>
<h2>{{ $t('page_shared_404.subtitle') }}</h2>
<Headline
:title="$t('page_shared_404.title')"
:description="$t('page_shared_404.subtitle')"
/>
<span class="additional-link">{{ $t('page_registration.have_an_account') }}
<router-link :to="{name: 'SignIn'}">
@@ -24,8 +22,8 @@
import AuthContent from '/resources/js/components/Auth/AuthContent'
import AuthButton from '/resources/js/components/Auth/AuthButton'
import {required} from 'vee-validate/dist/rules'
import Headline from "./Auth/Headline"
import {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'NotFound',
@@ -35,6 +33,7 @@
ValidationObserver,
AuthContent,
AuthButton,
Headline,
required,
},
computed: {

View File

@@ -23,7 +23,7 @@
import {ValidationProvider, ValidationObserver} from 'vee-validate/dist/vee-validate.full'
import AuthContent from '/resources/js/components/Auth/AuthContent'
import AuthButton from '/resources/js/components/Auth/AuthButton'
import Headline from "./Headline";
import Headline from "../Auth/Headline";
import {mapGetters} from "vuex";
import axios from "axios";

View File

@@ -0,0 +1,186 @@
<template>
<AuthContentWrapper ref="auth">
<!--Log In by Email-->
<AuthContent name="invitation" :visible="false">
<Headline
v-if="invitation"
:title="$t('Invitation To Join Team Folder')"
:description="$t('{name} invite you to join with his team into shared team folder', {name: invitation.data.relationships.inviter.data.attributes.name})"
>
<div class="text-center mb-10 w-24 mx-auto relative">
<VueFolderTeamIcon class="inline-block w-28" />
<MemberAvatar
class="absolute -bottom-2.5 -right-6"
:size="38"
:member="invitation.data.relationships.inviter"
/>
</div>
</Headline>
<div class="form inline-form">
<AuthButton @click.native="acceptInvitation" icon="chevron-right" :text="$t('Accept Invitation')" :loading="isLoading" :disabled="isLoading" />
</div>
<div class="additional-link font-bold">
Or
<b @click="declineInvitation" class="text-theme font-bold">
{{ $t('decline') }}
</b>
your invitation.
</div>
</AuthContent>
<!--Accepted invitation screen-->
<AuthContent v-if="invitation" name="accepted" :visible="false">
<Headline
:title="$t('You are successfully joined')"
:description="$t('You can now proceed to your account and participate in team folder')"
/>
<router-link replace v-if="! config.isAuthenticated" :to="{name: 'SignIn'}">
<AuthButton icon="chevron-right" :text="$t('Proceed to your account')"/>
</router-link>
<router-link replace v-if="config.isAuthenticated" :to="{name: 'SharedWithMe', params: {id: invitation.data.attributes.parent_id}}">
<AuthButton icon="chevron-right" :text="$t('Go to Team Folder')"/>
</router-link>
</AuthContent>
<!--Denied invitation screen-->
<AuthContent name="denied" :visible="false">
<Headline
:title="$t('You are successfully denied invitation')"
:description="$t('You can now proceed to your account')"
/>
<router-link :to="{name: 'SignIn'}">
<AuthButton icon="chevron-right" :text="$t('Proceed to your account')"/>
</router-link>
</AuthContent>
<!--Used or Expired invitation screen-->
<AuthContent name="expired" :visible="false">
<Headline
:title="$t('Your invitation has been used')"
:description="$t('We are sorry but this invitation was used previously')"
/>
<router-link replace v-if="! config.isAuthenticated" :to="{name: 'SignIn'}">
<AuthButton icon="chevron-right" :text="$t('Log In')"/>
</router-link>
<router-link replace v-if="config.isAuthenticated" :to="{name: 'SharedWithMe'}">
<AuthButton icon="chevron-right" :text="$t('Go to your shared folders')"/>
</router-link>
</AuthContent>
</AuthContentWrapper>
</template>
<script>
import {ValidationObserver, ValidationProvider} from 'vee-validate/dist/vee-validate.full'
import VueFolderTeamIcon from "../../components/FilesView/Icons/VueFolderTeamIcon"
import AuthContentWrapper from '/resources/js/components/Auth/AuthContentWrapper'
import AuthContent from '/resources/js/components/Auth/AuthContent'
import MemberAvatar from "../../components/FilesView/MemberAvatar"
import AuthButton from '/resources/js/components/Auth/AuthButton'
import Spinner from '/resources/js/components/FilesView/Spinner'
import Headline from "../Auth/Headline"
import {mapGetters} from 'vuex'
import axios from 'axios'
export default {
name: 'Invitation',
components: {
AuthContentWrapper,
ValidationProvider,
ValidationObserver,
VueFolderTeamIcon,
MemberAvatar,
AuthContent,
AuthButton,
Headline,
Spinner,
},
computed: {
...mapGetters([
'config'
]),
},
data() {
return {
isLoading: false,
invitation: undefined,
isUsed: false,
}
},
methods: {
acceptInvitation() {
this.isLoading = true
axios.put(`/api/teams/invitations/${this.$router.currentRoute.params.id}`)
.then(() => {
this.goToAuthPage('accepted')
})
.catch(() => {
this.$isSomethingWrong()
})
.finally(() => this.isLoading = false)
},
declineInvitation() {
this.isLoading = true
axios.delete(`/api/teams/invitations/${this.$router.currentRoute.params.id}`)
.then(() => {
this.goToAuthPage('denied')
})
.catch(() => {
this.$isSomethingWrong()
})
.finally(() => this.isLoading = false)
},
goToAuthPage(slug) {
this.$refs.auth.$children.forEach(page => {
// Hide current step
page.isVisible = false
if (page.$props.name === slug) {
// Go to next step
page.isVisible = true
}
})
},
},
created() {
axios.get(`/api/teams/invitations/${this.$router.currentRoute.params.id}`)
.then(response => {
this.invitation = response.data
this.goToAuthPage('invitation')
})
.catch(error => {
if (error.response.status === 410) {
this.goToAuthPage('expired')
} else {
this.$isSomethingWrong()
}
})
}
}
</script>
<style scoped lang="scss">
@import '/resources/sass/vuefilemanager/_auth-form';
@import '/resources/sass/vuefilemanager/_auth';
.spinner-wrapper {
width: 100%;
height: 50px;
position: relative;
top: 50px;
}
</style>

View File

@@ -56,27 +56,12 @@
.auth-form {
width: 100%;
h1 {
@include font-size(30);
}
h2 {
@include font-size(21);
}
}
}
@media only screen and (max-width: 490px) {
.auth-form {
h1 {
@include font-size(22);
}
h2 {
@include font-size(18);
}
input {
min-width: initial;