mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
basic invite button in frontend
This commit is contained in:
parent
176c4f0c37
commit
356f026226
5
webapp/assets/_new/icons/svgs/copy.svg
Normal file
5
webapp/assets/_new/icons/svgs/copy.svg
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
<!-- Generated by IcoMoon.io -->
|
||||||
|
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32">
|
||||||
|
<title>copy</title>
|
||||||
|
<path d="M4 4h16v3h-2v-1h-12v16h5v2h-7v-20zM12 8h16v20h-16v-20zM14 10v16h12v-16h-12z"></path>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 252 B |
@ -1,17 +1,83 @@
|
|||||||
<template>
|
<template>
|
||||||
<dropdown class="avatar-menu" offset="8" :placement="placement">
|
<dropdown class="invite-button" offset="8" :placement="placement">
|
||||||
<template #default="{ toggleMenu }">
|
<template #default="{ toggleMenu }">
|
||||||
XXX
|
<base-button icon="user-plus" circle ghost @click.prevent="toggleMenu" />
|
||||||
|
</template>
|
||||||
|
<template #popover>
|
||||||
|
<div class="invite-button-menu-popover">
|
||||||
|
<div v-if="inviteCode && inviteCode.code">
|
||||||
|
<ds-text align="center">{{ $t('invite-codes.your-code') }}</ds-text>
|
||||||
|
<ds-text bold>
|
||||||
|
{{ inviteCode.code }}
|
||||||
|
<base-button
|
||||||
|
v-if="canCopy"
|
||||||
|
icon="copy"
|
||||||
|
ghost
|
||||||
|
size="small"
|
||||||
|
@click="copyInviteCode"
|
||||||
|
></base-button>
|
||||||
|
</ds-text>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<ds-text>{{ $t('invite-codes.not-available') }}</ds-text>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</dropdown>
|
</dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Dropdown from '~/components/Dropdown'
|
import Dropdown from '~/components/Dropdown'
|
||||||
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Dropdown,
|
Dropdown,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
placement: { type: String, default: 'top-end' },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
inviteCode: null,
|
||||||
|
canCopy: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.canCopy = !!navigator.clipboard
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async copyInviteCode() {
|
||||||
|
await navigator.clipboard.writeText(this.inviteCode.code)
|
||||||
|
this.$toast.success(this.$t('invite-codes.copy-success'))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
apollo: {
|
||||||
|
inviteCode: {
|
||||||
|
query() {
|
||||||
|
return gql`
|
||||||
|
query {
|
||||||
|
getInviteCode {
|
||||||
|
code
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
},
|
||||||
|
variables() {},
|
||||||
|
update({ getInviteCode }) {
|
||||||
|
return getInviteCode
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.invite-button {
|
||||||
|
color: $color-secondary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.invite-button-menu-popover {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -29,8 +29,8 @@ const sentry = {
|
|||||||
const options = {
|
const options = {
|
||||||
VERSION: process.env.VERSION || pkg.version,
|
VERSION: process.env.VERSION || pkg.version,
|
||||||
DESCRIPTION: process.env.DESCRIPTION || pkg.description,
|
DESCRIPTION: process.env.DESCRIPTION || pkg.description,
|
||||||
PUBLIC_REGISTRATION: process.env.PUBLIC_REGISTRATION === 'true',
|
PUBLIC_REGISTRATION: process.env.PUBLIC_REGISTRATION,
|
||||||
INVITE_REGISTRATION: process.env.INVITE_REGISTRATION === 'true',
|
INVITE_REGISTRATION: process.env.INVITE_REGISTRATION,
|
||||||
// Cookies
|
// Cookies
|
||||||
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 730, // Two years by default
|
COOKIE_EXPIRE_TIME: process.env.COOKIE_EXPIRE_TIME || 730, // Two years by default
|
||||||
COOKIE_HTTPS_ONLY: process.env.COOKIE_HTTPS_ONLY || process.env.NODE_ENV === 'production', // ensure true in production if not set explicitly
|
COOKIE_HTTPS_ONLY: process.env.COOKIE_HTTPS_ONLY || process.env.NODE_ENV === 'production', // ensure true in production if not set explicitly
|
||||||
|
|||||||
@ -50,10 +50,11 @@
|
|||||||
<client-only>
|
<client-only>
|
||||||
<notification-menu placement="top" />
|
<notification-menu placement="top" />
|
||||||
</client-only>
|
</client-only>
|
||||||
XXX {{ showInviteButton }}
|
<div v-if="inviteRegistration">
|
||||||
<client-only v-if="showInviteButton">
|
<client-only>
|
||||||
<invite-button placement="top" />
|
<invite-button placement="top" />
|
||||||
</client-only>
|
</client-only>
|
||||||
|
</div>
|
||||||
<client-only>
|
<client-only>
|
||||||
<avatar-menu placement="top" />
|
<avatar-menu placement="top" />
|
||||||
</client-only>
|
</client-only>
|
||||||
@ -78,19 +79,19 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import Logo from '~/components/Logo/Logo'
|
import Logo from '~/components/Logo/Logo'
|
||||||
import { mapGetters } from 'vuex'
|
import { mapGetters } from 'vuex'
|
||||||
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
||||||
import SearchField from '~/components/features/SearchField/SearchField.vue'
|
import SearchField from '~/components/features/SearchField/SearchField.vue'
|
||||||
import Modal from '~/components/Modal'
|
import Modal from '~/components/Modal'
|
||||||
import NotificationMenu from '~/components/NotificationMenu/NotificationMenu'
|
import NotificationMenu from '~/components/NotificationMenu/NotificationMenu'
|
||||||
import seo from '~/mixins/seo'
|
import seo from '~/mixins/seo'
|
||||||
import FilterMenu from '~/components/FilterMenu/FilterMenu.vue'
|
import FilterMenu from '~/components/FilterMenu/FilterMenu.vue'
|
||||||
import PageFooter from '~/components/PageFooter/PageFooter'
|
import PageFooter from '~/components/PageFooter/PageFooter'
|
||||||
import AvatarMenu from '~/components/AvatarMenu/AvatarMenu'
|
import AvatarMenu from '~/components/AvatarMenu/AvatarMenu'
|
||||||
import InviteButton from '~/components/InviteButton/InviteButton'
|
import InviteButton from '~/components/InviteButton/InviteButton'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
Logo,
|
Logo,
|
||||||
LocaleSwitch,
|
LocaleSwitch,
|
||||||
@ -107,11 +108,7 @@
|
|||||||
return {
|
return {
|
||||||
mobileSearchVisible: false,
|
mobileSearchVisible: false,
|
||||||
toggleMobileMenu: false,
|
toggleMobileMenu: false,
|
||||||
}
|
inviteRegistration: this.$env.inviteRegistration,
|
||||||
},
|
|
||||||
asyncData({ app }) {
|
|
||||||
return {
|
|
||||||
inviteRegistration: app.$env.INVITE_REGISTRATION,
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -122,56 +119,53 @@
|
|||||||
const [firstRoute] = this.$route.matched
|
const [firstRoute] = this.$route.matched
|
||||||
return firstRoute && firstRoute.name === 'index'
|
return firstRoute && firstRoute.name === 'index'
|
||||||
},
|
},
|
||||||
showInviteButton() {
|
|
||||||
return this.inviteRegistration
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
toggleMobileMenuView() {
|
toggleMobileMenuView() {
|
||||||
this.toggleMobileMenu = !this.toggleMobileMenu
|
this.toggleMobileMenu = !this.toggleMobileMenu
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
.topbar-locale-switch {
|
.topbar-locale-switch {
|
||||||
display: flex;
|
display: flex;
|
||||||
margin-right: $space-xx-small;
|
margin-right: $space-xx-small;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
.main-container {
|
.main-container {
|
||||||
padding-top: 6rem;
|
padding-top: 6rem;
|
||||||
padding-bottom: 5rem;
|
padding-bottom: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-navigation-flex {
|
.main-navigation-flex {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.main-navigation {
|
.main-navigation {
|
||||||
a {
|
a {
|
||||||
color: $text-color-soft;
|
color: $text-color-soft;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.main-navigation-right {
|
.main-navigation-right {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
}
|
}
|
||||||
.main-navigation-right .desktop-view {
|
.main-navigation-right .desktop-view {
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
.ds-flex-item.mobile-hamburger-menu {
|
.ds-flex-item.mobile-hamburger-menu {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
@media only screen and (min-width: 730px) {
|
@media only screen and (min-width: 730px) {
|
||||||
.mobile-hamburger-menu {
|
.mobile-hamburger-menu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media only screen and (max-width: 730px) {
|
@media only screen and (max-width: 730px) {
|
||||||
#nav-search-box,
|
#nav-search-box,
|
||||||
.main-navigation-right {
|
.main-navigation-right {
|
||||||
margin: 10px 0px;
|
margin: 10px 0px;
|
||||||
@ -179,5 +173,5 @@
|
|||||||
.hide-mobile-menu {
|
.hide-mobile-menu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -336,6 +336,12 @@
|
|||||||
"change-filter-settings": "Verändere die Filter-Einstellungen, um mehr Ergebnisse zu erhalten.",
|
"change-filter-settings": "Verändere die Filter-Einstellungen, um mehr Ergebnisse zu erhalten.",
|
||||||
"no-results": "Keine Beiträge gefunden."
|
"no-results": "Keine Beiträge gefunden."
|
||||||
},
|
},
|
||||||
|
"invite-codes": {
|
||||||
|
"copy-code": "Einladungscode in die Zwischenablage kopieren",
|
||||||
|
"copy-success": "Einladungscode erfolgreich in die Zwischenablage kopiert",
|
||||||
|
"not-available": "Du hast keinen Einladungscode zur Verfügung!",
|
||||||
|
"your-code": "Das ist dein Einladungscode:"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"email": "Deine E-Mail",
|
"email": "Deine E-Mail",
|
||||||
"failure": "Fehlerhafte E-Mail-Adresse oder Passwort.",
|
"failure": "Fehlerhafte E-Mail-Adresse oder Passwort.",
|
||||||
|
|||||||
@ -336,6 +336,12 @@
|
|||||||
"change-filter-settings": "Change your filter settings to get more results.",
|
"change-filter-settings": "Change your filter settings to get more results.",
|
||||||
"no-results": "No contributions found."
|
"no-results": "No contributions found."
|
||||||
},
|
},
|
||||||
|
"invite-codes": {
|
||||||
|
"copy-code": "Copy invite code to clipboard",
|
||||||
|
"copy-success": "Invite code copied to clipboard",
|
||||||
|
"not-available": "You have no valid invite code available!",
|
||||||
|
"your-code": "This is your invite code:"
|
||||||
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"email": "Your E-mail",
|
"email": "Your E-mail",
|
||||||
"failure": "Incorrect email address or password.",
|
"failure": "Incorrect email address or password.",
|
||||||
|
|||||||
@ -28,6 +28,8 @@ export default {
|
|||||||
|
|
||||||
env: {
|
env: {
|
||||||
release: CONFIG.VERSION,
|
release: CONFIG.VERSION,
|
||||||
|
publicRegistration: String(CONFIG.PUBLIC_REGISTRATION) === 'true',
|
||||||
|
inviteRegistration: String(CONFIG.INVITE_REGISTRATION) === 'true',
|
||||||
// pages which do NOT require a login
|
// pages which do NOT require a login
|
||||||
publicPages: [
|
publicPages: [
|
||||||
'login',
|
'login',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user