mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-13 07:46:06 +00:00
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:
commit
d9ef74dfc1
@ -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'
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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": {
|
||||
|
||||
@ -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>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user