Merge pull request #6559 from Ocelot-Social-Community/6443-refactor-create-post-page

refactor(webapp): updated/refactored ui of create post page
This commit is contained in:
Hannes Heine 2023-07-26 13:06:01 +02:00 committed by GitHub
commit d9ef74dfc1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 241 additions and 222 deletions

View File

@ -1,185 +1,190 @@
<template>
<ds-form
class="contribution-form"
ref="contributionForm"
v-model="formData"
:schema="formSchema"
@submit="submit"
>
<template #default="{ errors }">
<base-card>
<template #heroImage>
<img
v-if="formData.image"
:src="formData.image | proxyApiUrl"
:class="['image', formData.imageBlurred && '--blur-image']"
<div>
<ds-form
class="contribution-form"
ref="contributionForm"
v-model="formData"
:schema="formSchema"
@submit="submit"
>
<template #default="{ errors }">
<base-card>
<template #heroImage>
<img
v-if="formData.image"
:src="formData.image | proxyApiUrl"
:class="['image', formData.imageBlurred && '--blur-image']"
/>
<image-uploader
:hasImage="!!formData.image"
:class="[formData.imageBlurred && '--blur-image']"
@addHeroImage="addHeroImage"
@addImageAspectRatio="addImageAspectRatio"
@addImageType="addImageType"
/>
</template>
<div v-if="formData.image" class="blur-toggle">
<label for="blur-img">{{ $t('contribution.inappropriatePicture') }}</label>
<input type="checkbox" id="blur-img" v-model="formData.imageBlurred" />
<page-params-link class="link" :pageParams="links.FAQ">
{{ $t('contribution.inappropriatePicture') }}
<base-icon name="question-circle" />
</page-params-link>
</div>
<ds-space margin-top="base" />
<ds-input
model="title"
:placeholder="$t('contribution.title')"
name="title"
autofocus
size="large"
/>
<image-uploader
:hasImage="!!formData.image"
:class="[formData.imageBlurred && '--blur-image']"
@addHeroImage="addHeroImage"
@addImageAspectRatio="addImageAspectRatio"
@addImageType="addImageType"
<ds-chip size="base" :color="errors && errors.title && 'danger'">
{{ formData.title.length }}/{{ formSchema.title.max }}
<base-icon v-if="errors && errors.title" name="warning" />
</ds-chip>
<editor
:users="users"
:value="formData.content"
:hashtags="hashtags"
@input="updateEditorContent"
/>
</template>
<div v-if="formData.image" class="blur-toggle">
<label for="blur-img">{{ $t('contribution.inappropriatePicture') }}</label>
<input type="checkbox" id="blur-img" v-model="formData.imageBlurred" />
<page-params-link class="link" :pageParams="links.FAQ">
{{ $t('contribution.inappropriatePicture') }}
<base-icon name="question-circle" />
</page-params-link>
</div>
<ds-space margin-top="base" />
<ds-input
model="title"
:placeholder="$t('contribution.title')"
name="title"
autofocus
size="large"
/>
<ds-chip size="base" :color="errors && errors.title && 'danger'">
{{ formData.title.length }}/{{ formSchema.title.max }}
<base-icon v-if="errors && errors.title" name="warning" />
</ds-chip>
<editor
:users="users"
:value="formData.content"
:hashtags="hashtags"
@input="updateEditorContent"
/>
<ds-chip size="base" :color="errors && errors.content && 'danger'">
{{ contentLength }}
<base-icon v-if="errors && errors.content" name="warning" />
</ds-chip>
<ds-chip size="base" :color="errors && errors.content && 'danger'">
{{ contentLength }}
<base-icon v-if="errors && errors.content" name="warning" />
</ds-chip>
<!-- Eventdata -->
<div v-if="createEvent" class="eventDatas">
<hr />
<ds-space margin-top="x-small" />
<ds-grid>
<ds-grid-item class="event-grid-item">
<!-- <label>Beginn</label> -->
<div class="event-grid-item-z-helper">
<date-picker
name="eventStart"
v-model="formData.eventStart"
type="datetime"
value-type="format"
:minute-step="15"
Xformat="DD-MM-YYYY HH:mm"
class="event-grid-item-z-helper"
:placeholder="$t('post.viewEvent.eventStart')"
:disabled-date="notBeforeToday"
:disabled-time="notBeforeNow"
:show-second="false"
@change="changeEventStart($event)"
></date-picker>
</div>
<div
v-if="errors && errors.eventStart"
class="chipbox event-grid-item-margin-helper"
>
<ds-chip size="base" :color="errors && errors.eventStart && 'danger'">
<base-icon name="warning" />
</ds-chip>
</div>
</ds-grid-item>
<ds-grid-item class="event-grid-item">
<!-- <label>Ende (optional)</label> -->
<!-- Eventdata -->
<div v-if="createEvent" class="eventDatas">
<hr />
<ds-space margin-top="x-small" />
<ds-grid>
<ds-grid-item class="event-grid-item">
<!-- <label>Beginn</label> -->
<div class="event-grid-item-z-helper">
<date-picker
name="eventStart"
v-model="formData.eventStart"
v-model="formData.eventEnd"
name="eventEnd"
type="datetime"
value-type="format"
:minute-step="15"
:seconds-step="0"
Xformat="DD-MM-YYYY HH:mm"
class="event-grid-item-z-helper"
:placeholder="$t('post.viewEvent.eventStart')"
:disabled-date="notBeforeToday"
:disabled-time="notBeforeNow"
:placeholder="$t('post.viewEvent.eventEnd')"
class="event-grid-item-font-helper"
:disabled-date="notBeforeEventDay"
:disabled-time="notBeforeEvent"
:show-second="false"
@change="changeEventStart($event)"
@change="changeEventEnd($event)"
></date-picker>
</div>
<div v-if="errors && errors.eventStart" class="chipbox event-grid-item-margin-helper">
<ds-chip size="base" :color="errors && errors.eventStart && 'danger'">
<base-icon name="warning" />
</ds-chip>
</div>
</ds-grid-item>
<ds-grid-item class="event-grid-item">
<!-- <label>Ende (optional)</label> -->
</ds-grid-item>
</ds-grid>
<ds-grid class="event-location-grid">
<ds-grid-item class="event-grid-item">
<ds-input
model="eventVenue"
name="eventVenue"
:placeholder="$t('post.viewEvent.eventVenue')"
/>
<div class="chipbox">
<ds-chip size="base" :color="errors && errors.eventVenue && 'danger'">
{{ formData.eventVenue.length }}/{{ formSchema.eventVenue.max }}
<base-icon v-if="errors && errors.eventVenue" name="warning" />
</ds-chip>
</div>
</ds-grid-item>
<ds-grid-item v-if="showEventLocationName" class="event-grid-item">
<ds-input
model="eventLocationName"
name="eventLocationName"
:placeholder="$t('post.viewEvent.eventLocationName')"
/>
<div class="chipbox">
<ds-chip size="base" :color="errors && errors.eventLocationName && 'danger'">
{{ formData.eventLocationName.length }}/{{ formSchema.eventLocationName.max }}
<base-icon v-if="errors && errors.eventLocationName" name="warning" />
</ds-chip>
</div>
</ds-grid-item>
</ds-grid>
<date-picker
v-model="formData.eventEnd"
name="eventEnd"
type="datetime"
value-type="format"
:minute-step="15"
:seconds-step="0"
Xformat="DD-MM-YYYY HH:mm"
:placeholder="$t('post.viewEvent.eventEnd')"
<div>
<input
type="checkbox"
v-model="formData.eventIsOnline"
model="eventIsOnline"
name="eventIsOnline"
class="event-grid-item-font-helper"
:disabled-date="notBeforeEventDay"
:disabled-time="notBeforeEvent"
:show-second="false"
@change="changeEventEnd($event)"
></date-picker>
</ds-grid-item>
</ds-grid>
<ds-grid class="event-location-grid">
<ds-grid-item class="event-grid-item">
<ds-input
model="eventVenue"
name="eventVenue"
:placeholder="$t('post.viewEvent.eventVenue')"
@change="changeEventIsOnline($event)"
/>
<div class="chipbox">
<ds-chip size="base" :color="errors && errors.eventVenue && 'danger'">
{{ formData.eventVenue.length }}/{{ formSchema.eventVenue.max }}
<base-icon v-if="errors && errors.eventVenue" name="warning" />
</ds-chip>
</div>
</ds-grid-item>
<ds-grid-item v-if="showEventLocationName" class="event-grid-item">
<ds-input
model="eventLocationName"
name="eventLocationName"
:placeholder="$t('post.viewEvent.eventLocationName')"
/>
<div class="chipbox">
<ds-chip size="base" :color="errors && errors.eventLocationName && 'danger'">
{{ formData.eventLocationName.length }}/{{ formSchema.eventLocationName.max }}
<base-icon v-if="errors && errors.eventLocationName" name="warning" />
</ds-chip>
</div>
</ds-grid-item>
</ds-grid>
<div>
<input
type="checkbox"
v-model="formData.eventIsOnline"
model="eventIsOnline"
name="eventIsOnline"
class="event-grid-item-font-helper"
@change="changeEventIsOnline($event)"
/>
{{ $t('post.viewEvent.eventIsOnline') }}
{{ $t('post.viewEvent.eventIsOnline') }}
</div>
</div>
</div>
<ds-space margin-top="x-small" />
<categories-select
v-if="categoriesActive"
model="categoryIds"
:existingCategoryIds="formData.categoryIds"
/>
<ds-chip
v-if="categoriesActive"
size="base"
:color="errors && errors.categoryIds && 'danger'"
>
{{ formData.categoryIds.length }} / 3
<base-icon v-if="errors && errors.categoryIds" name="warning" />
</ds-chip>
<ds-flex class="buttons-footer" gutter="xxx-small">
<ds-flex-item width="3.5" class="buttons-footer-helper">
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
<!-- TODO => remove v-html! only text ! no html! security first! -->
<ds-text
v-if="showGroupHint"
v-html="$t('contribution.visibleOnlyForMembersOfGroup', { name: groupName })"
/>
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
</ds-flex-item>
<ds-flex-item width="0.15" />
<ds-flex-item class="action-buttons-group" width="2">
<base-button data-test="cancel-button" :disabled="loading" @click="$router.back()">
{{ $t('actions.cancel') }}
</base-button>
<base-button type="submit" icon="check" :loading="loading" :disabled="errors" filled>
{{ $t('actions.save') }}
</base-button>
</ds-flex-item>
</ds-flex>
</base-card>
</template>
</ds-form>
<ds-space margin-top="x-small" />
<categories-select
v-if="categoriesActive"
model="categoryIds"
:existingCategoryIds="formData.categoryIds"
/>
<ds-chip
v-if="categoriesActive"
size="base"
:color="errors && errors.categoryIds && 'danger'"
>
{{ formData.categoryIds.length }} / 3
<base-icon v-if="errors && errors.categoryIds" name="warning" />
</ds-chip>
<ds-flex class="buttons-footer" gutter="xxx-small">
<ds-flex-item width="3.5" class="buttons-footer-helper">
<!-- eslint-disable vue/no-v-text-v-html-on-component -->
<!-- TODO => remove v-html! only text ! no html! security first! -->
<ds-text
v-if="showGroupHint"
v-html="$t('contribution.visibleOnlyForMembersOfGroup', { name: groupName })"
/>
<!-- eslint-enable vue/no-v-text-v-html-on-component -->
</ds-flex-item>
<ds-flex-item width="0.15" />
<ds-flex-item class="action-buttons-group" width="2">
<base-button data-test="cancel-button" :disabled="loading" @click="$router.back()">
{{ $t('actions.cancel') }}
</base-button>
<base-button type="submit" icon="check" :loading="loading" :disabled="errors" filled>
{{ $t('actions.save') }}
</base-button>
</ds-flex-item>
</ds-flex>
</base-card>
</template>
</ds-form>
</div>
</template>
<script>
import gql from 'graphql-tag'

View File

@ -749,13 +749,13 @@
"forGroup": {
"title": "Für die Gruppe „{name}“"
},
"title": "Erstelle ein neues Event"
"title": "Erstelle eine Veranstaltung"
},
"createNewPost": {
"forGroup": {
"title": "Für die Gruppe „{name}“"
},
"title": "Erstelle einen neuen Beitrag"
"title": "Erstelle einen Beitrag"
},
"edited": "bearbeitet",
"editPost": {

View File

@ -749,13 +749,13 @@
"forGroup": {
"title": "For The Group “{name}”"
},
"title": "Create A New Event"
"title": "Create an Event"
},
"createNewPost": {
"forGroup": {
"title": "For The Group “{name}”"
},
"title": "Create A New Article"
"title": "Create an Article"
},
"edited": "edited",
"editPost": {

View File

@ -1,55 +1,33 @@
<template>
<div>
<ds-flex :width="{ base: '100%' }">
<ds-flex-item :width="{ base: '100%' }">
<ds-flex gutter="base" :width="{ base: '100%', sm: 1 }">
<ds-flex-item>
<ds-card class="create-form-btn" :primary="!createEvent" centered>
<div>
<ds-button
v-if="!createEvent"
ghost
fullwidth
size="x-large"
class="inactive-tab-button"
>
{{ $t('post.createNewPost.title') }}
</ds-button>
<ds-button v-else ghost fullwidth size="x-large" @click="switchPostType()">
{{ $t('post.createNewPost.title') }}
</ds-button>
</div>
</ds-card>
</ds-flex-item>
<ds-flex-item>
<ds-card class="create-form-btn" :primary="!!createEvent" centered>
<div>
<ds-button
ghost
fullwidth
size="x-large"
v-if="createEvent"
hover
class="inactive-tab-button"
>
{{ $t('post.createNewEvent.title') }}
</ds-button>
<ds-button ghost fullwidth size="x-large" v-else @click="switchPostType()">
{{ $t('post.createNewEvent.title') }}
</ds-button>
</div>
</ds-card>
</ds-flex-item>
</ds-flex>
<div v-if="group" class="group-create-title">
{{ $t('post.createNewPost.forGroup.title', { name: group.name }) }}
</div>
<ds-flex gutter="small">
<ds-flex-item :width="{ base: '100%', md: '200px' }">
<ds-menu class="post-type-menu" :routes="routes">
<ds-menu-item
@click.prevent="switchPostType($event, item)"
slot="menuitem"
slot-scope="item"
:route="item.route"
class="post-type-menu-item"
>
{{ item.route.name }}
</ds-menu-item>
</ds-menu>
</ds-flex-item>
</ds-flex>
<ds-flex :width="{ base: '100%' }" gutter="base">
<ds-flex-item :width="{ base: '100%' }">
<contribution-form :group="group" :createEvent="createEvent" />
<ds-flex-item :width="{ base: '100%', md: 1 }">
<transition name="slide-up" appear>
<div>
<div>
<h1 v-if="!createEvent" class="title">
{{ $t('post.createNewPost.title') }}
</h1>
<h1 v-else class="title">
{{ $t('post.createNewEvent.title') }}
</h1>
</div>
<contribution-form :group="group" :createEvent="createEvent" />
</div>
</transition>
</ds-flex-item>
</ds-flex>
</div>
@ -74,6 +52,20 @@ export default {
group() {
return this.Group && this.Group[0] ? this.Group[0] : null
},
routes() {
return [
{
name: this.$t('post.name'),
path: `/post/create`,
type: 'post',
},
{
name: this.$t('post.event'),
path: `/`,
type: 'event',
},
]
},
},
apollo: {
Group: {
@ -97,8 +89,18 @@ export default {
},
},
methods: {
switchPostType() {
this.createEvent = !this.createEvent
switchPostType(event, route) {
if (route.route.type.toLowerCase() === 'event') {
this.createEvent = true
} else {
this.createEvent = false
}
// hacky way to set active element
const menuItems = document.querySelectorAll('.post-type-menu-item')
menuItems.forEach((menuItem) => {
menuItem.firstChild.classList.remove('router-link-exact-active', 'router-link-active')
})
event.target.classList.add('router-link-exact-active')
},
},
}
@ -120,4 +122,16 @@ export default {
.create-form-btn .ds-button-ghost:hover {
background-color: transparent;
}
.menu-item-active {
color: $color-primary;
border-left: 2px solid $color-primary;
background-color: #faf9fa;
}
@media screen and (min-width: 768px) {
.post-type-menu {
margin-top: 39px;
}
}
</style>