mirror of
https://github.com/IT4Change/Ocelot-Social.git
synced 2025-12-13 07:45:56 +00:00
merged tags and categories in
This commit is contained in:
parent
987fa33d58
commit
c96e22492c
@ -118,3 +118,11 @@ blockquote {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
width: 100%;
|
||||
color: $color-neutral-80;
|
||||
background-color: $color-neutral-80;
|
||||
height: 1px !important;
|
||||
}
|
||||
|
||||
@ -31,13 +31,22 @@
|
||||
</no-ssr>
|
||||
</ds-space>
|
||||
<template slot="footer">
|
||||
<span :style="{ opacity: post.shoutedCount ? 1 : .5 }">
|
||||
<ds-icon name="heart-o" /> <small>{{ post.shoutedCount }}</small>
|
||||
</span>
|
||||
|
||||
<span :style="{ opacity: post.commentsCount ? 1 : .5 }">
|
||||
<ds-icon name="comments" /> <small>{{ post.commentsCount }}</small>
|
||||
</span>
|
||||
<div style="display: inline-block; opacity: .5;">
|
||||
<ds-icon
|
||||
v-tooltip="{content: category.name, placement: 'bottom-start', delay: { show: 500 }}"
|
||||
v-for="category in post.categories"
|
||||
:key="category.id"
|
||||
:name="category.icon" />
|
||||
</div>
|
||||
<div style="display: inline-block; float: right">
|
||||
<span :style="{ opacity: post.shoutedCount ? 1 : .5 }">
|
||||
<ds-icon name="bullhorn" /> <small>{{ post.shoutedCount }}</small>
|
||||
</span>
|
||||
|
||||
<span :style="{ opacity: post.commentsCount ? 1 : .5 }">
|
||||
<ds-icon name="comments" /> <small>{{ post.commentsCount }}</small>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
</ds-card>
|
||||
</a>
|
||||
|
||||
@ -7,9 +7,8 @@
|
||||
:disabled="disabled || loading"
|
||||
danger
|
||||
size="x-large"
|
||||
icon="heart"
|
||||
@click="shout"
|
||||
/>
|
||||
icon="bullhorn"
|
||||
@click="shout" />
|
||||
<ds-space margin-bottom="xx-small" />
|
||||
<ds-text color="soft">
|
||||
<ds-heading
|
||||
|
||||
@ -6,14 +6,8 @@ export default gql(`
|
||||
id
|
||||
name
|
||||
avatar
|
||||
about
|
||||
createdAt
|
||||
friendsCount
|
||||
friends {
|
||||
id
|
||||
name
|
||||
slug
|
||||
avatar
|
||||
}
|
||||
badges {
|
||||
id
|
||||
key
|
||||
@ -63,6 +57,11 @@ export default gql(`
|
||||
deleted
|
||||
image
|
||||
createdAt
|
||||
categories {
|
||||
id
|
||||
name
|
||||
icon
|
||||
}
|
||||
author {
|
||||
id
|
||||
avatar
|
||||
|
||||
@ -48,6 +48,10 @@ export default {
|
||||
name: 'Categories',
|
||||
path: `/admin/categories`
|
||||
},
|
||||
{
|
||||
name: 'Tags',
|
||||
path: `/admin/tags`
|
||||
},
|
||||
{
|
||||
name: 'Settings',
|
||||
path: `/admin/settings`
|
||||
|
||||
@ -1,7 +1,42 @@
|
||||
<template>
|
||||
<ds-card>
|
||||
<ds-space margin="small">
|
||||
Categories...
|
||||
</ds-space>
|
||||
<ds-card space="small">
|
||||
<ds-heading tag="h3">Themen / Kategorien</ds-heading>
|
||||
<ds-table
|
||||
:data="Category"
|
||||
:fields="['icon', 'name', 'postCount']"
|
||||
condensed>
|
||||
<template
|
||||
slot="icon"
|
||||
slot-scope="scope">
|
||||
<ds-icon :name="scope.row.icon" />
|
||||
</template>
|
||||
</ds-table>
|
||||
</ds-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
Category: []
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
Category: {
|
||||
query: gql(`
|
||||
query {
|
||||
Category(orderBy: postCount_desc) {
|
||||
id
|
||||
name
|
||||
slug
|
||||
icon
|
||||
postCount
|
||||
}
|
||||
}
|
||||
`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
47
pages/admin/tags.vue
Normal file
47
pages/admin/tags.vue
Normal file
@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<ds-card space="small">
|
||||
<ds-heading tag="h3">Tags</ds-heading>
|
||||
<ds-table
|
||||
:data="Tag"
|
||||
:fields="fields"
|
||||
condensed>
|
||||
<template
|
||||
slot="id"
|
||||
slot-scope="scope">
|
||||
{{ scope.index + 1 }}
|
||||
</template>
|
||||
</ds-table>
|
||||
</ds-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
Tag: [],
|
||||
fields: {
|
||||
id: { label: '#' },
|
||||
name: { label: 'Name' },
|
||||
taggedCountUnique: { label: 'Nutzer' },
|
||||
taggedCount: { label: 'Beiträge' }
|
||||
}
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
Tag: {
|
||||
query: gql(`
|
||||
query {
|
||||
Tag(first: 20, orderBy: taggedCountUnique_desc) {
|
||||
id
|
||||
name
|
||||
taggedCount
|
||||
taggedCountUnique
|
||||
}
|
||||
}
|
||||
`)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -107,6 +107,7 @@ export default {
|
||||
categories {
|
||||
id
|
||||
name
|
||||
icon
|
||||
}
|
||||
shoutedCount
|
||||
}
|
||||
|
||||
@ -23,7 +23,14 @@
|
||||
:post-id="post.id"
|
||||
/>
|
||||
<!-- Categories -->
|
||||
<div class="tags">
|
||||
<ds-icon
|
||||
v-tooltip="{content: category.name, placement: 'top-start', delay: { show: 300 }}"
|
||||
v-for="category in post.categories"
|
||||
:key="category.id"
|
||||
:name="category.icon"
|
||||
size="large" />
|
||||
<ds-space margin-bottom="small" />
|
||||
<!--<div class="tags">
|
||||
<ds-icon name="compass" /> <ds-tag
|
||||
v-for="category in post.categories"
|
||||
:key="category.id"
|
||||
@ -163,7 +170,7 @@ export default {
|
||||
name
|
||||
}
|
||||
commentsCount
|
||||
comments(orderBy: _id_desc) {
|
||||
comments(orderBy: createdAt_desc) {
|
||||
id
|
||||
contentExcerpt
|
||||
createdAt
|
||||
@ -187,6 +194,7 @@ export default {
|
||||
categories {
|
||||
id
|
||||
name
|
||||
icon
|
||||
}
|
||||
shoutedCount
|
||||
}
|
||||
|
||||
@ -7,7 +7,8 @@
|
||||
<ds-space />
|
||||
<h3><ds-icon name="compass" /> Themenkategorien</h3>
|
||||
<div class="tags">
|
||||
<ds-tag
|
||||
<ds-icon
|
||||
v-tooltip="{content: category.name, placement: 'top-start', delay: { show: 300 }}"
|
||||
v-for="category in post.categories"
|
||||
:key="category.id"
|
||||
>
|
||||
@ -81,6 +82,7 @@ export default {
|
||||
categories {
|
||||
id
|
||||
name
|
||||
icon
|
||||
}
|
||||
relatedContributions(first: 2) {
|
||||
id
|
||||
@ -89,6 +91,11 @@ export default {
|
||||
contentExcerpt
|
||||
shoutedCount
|
||||
commentsCount
|
||||
categories {
|
||||
id
|
||||
name
|
||||
icon
|
||||
}
|
||||
author {
|
||||
id
|
||||
name
|
||||
|
||||
@ -28,9 +28,8 @@
|
||||
<ds-text
|
||||
align="center"
|
||||
color="soft"
|
||||
size="small"
|
||||
>
|
||||
Mitglied seid {{ user.createdAt | date('MMMM yyyy') }}
|
||||
size="small">
|
||||
Mitglied seit {{ user.createdAt | date('MMMM yyyy') }}
|
||||
</ds-text>
|
||||
</ds-space>
|
||||
<ds-space
|
||||
|
||||
@ -1,5 +1,203 @@
|
||||
<template>
|
||||
<ds-card>
|
||||
<p>My Data...</p>
|
||||
<ds-card space="small">
|
||||
<ds-input
|
||||
id="name"
|
||||
v-model="form.name"
|
||||
icon="user"
|
||||
label="Dein Name"
|
||||
placeholder="Dein Name"/>
|
||||
<ds-select
|
||||
id="city"
|
||||
:options="cities"
|
||||
v-model="city"
|
||||
icon="map-marker"
|
||||
label="Deine Stadt"
|
||||
placeholder="Deine Stadt"
|
||||
@input="handleCitySelection"
|
||||
@input.native="handleCityInput" />
|
||||
<ds-input
|
||||
id="bio"
|
||||
v-model="form.about"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
label="Erzähl doch ein wenig (in zwei Sätzen) über dich"
|
||||
placeholder="Über mich"/>
|
||||
<template slot="footer">
|
||||
<ds-button
|
||||
style="float: right;"
|
||||
icon="check"
|
||||
primary
|
||||
@click.prevent="submit">Speichern</ds-button>
|
||||
</template>
|
||||
</ds-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
import { mapGetters } from 'vuex'
|
||||
import { CancelToken } from 'axios'
|
||||
import find from 'lodash/find'
|
||||
|
||||
let timeout
|
||||
const mapboxToken =
|
||||
'pk.eyJ1IjoiaHVtYW4tY29ubmVjdGlvbiIsImEiOiJjajl0cnBubGoweTVlM3VwZ2lzNTNud3ZtIn0.KZ8KK9l70omjXbEkkbHGsQ'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
axiosSource: null,
|
||||
cities: [],
|
||||
city: null,
|
||||
form: {
|
||||
name: null,
|
||||
locationId: null,
|
||||
about: null
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
user: 'auth/user'
|
||||
})
|
||||
},
|
||||
watch: {
|
||||
user: {
|
||||
immediate: true,
|
||||
handler: function(user) {
|
||||
this.form = {
|
||||
name: user.name,
|
||||
locationId: user.locationId,
|
||||
about: user.about
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
console.log('SUBMIT', { ...this.form })
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: gql`
|
||||
mutation(
|
||||
$id: ID!
|
||||
$name: String
|
||||
$locationId: String
|
||||
$about: String
|
||||
) {
|
||||
UpdateUser(
|
||||
id: $id
|
||||
name: $name
|
||||
locationId: $locationId
|
||||
about: $about
|
||||
) {
|
||||
id
|
||||
name
|
||||
locationId
|
||||
about
|
||||
}
|
||||
}
|
||||
`,
|
||||
// Parameters
|
||||
variables: {
|
||||
id: this.user.id,
|
||||
name: this.form.name,
|
||||
locationId: this.form.locationId,
|
||||
about: this.form.about
|
||||
},
|
||||
// Update the cache with the result
|
||||
// The query will be updated with the optimistic response
|
||||
// and then with the real result of the mutation
|
||||
update: (store, { data: { UpdateUser } }) => {
|
||||
// this.$store.dispatch('auth/refresh', UpdateUser)
|
||||
|
||||
// Read the data from our cache for this query.
|
||||
// const data = store.readQuery({ query: TAGS_QUERY })
|
||||
// Add our tag from the mutation to the end
|
||||
// data.tags.push(addTag)
|
||||
// Write our data back to the cache.
|
||||
// store.writeQuery({ query: TAGS_QUERY, data })
|
||||
}
|
||||
// Optimistic UI
|
||||
// Will be treated as a 'fake' result as soon as the request is made
|
||||
// so that the UI can react quickly and the user be happy
|
||||
/* optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
addTag: {
|
||||
__typename: 'Tag',
|
||||
id: -1,
|
||||
label: newTag
|
||||
}
|
||||
} */
|
||||
})
|
||||
.then(data => {
|
||||
console.log(data)
|
||||
this.$toast.success('Updated user')
|
||||
})
|
||||
.catch(err => {
|
||||
console.error(err)
|
||||
this.$toast.error(err.message)
|
||||
})
|
||||
},
|
||||
handleCityInput(value) {
|
||||
clearTimeout(timeout)
|
||||
timeout = setTimeout(() => this.requestGeoData(value), 500)
|
||||
},
|
||||
handleCitySelection(value) {
|
||||
console.log('SET CURRENT VALUE', value)
|
||||
const item = find(this.cities, { value: value })
|
||||
console.log('ID:', item.id)
|
||||
this.form.locationId = item.id
|
||||
},
|
||||
handleCityEnter() {
|
||||
console.log('SET CURRENT VALUE')
|
||||
},
|
||||
processCityResults(res) {
|
||||
if (
|
||||
!res ||
|
||||
!res.data ||
|
||||
!res.data.features ||
|
||||
!res.data.features.length
|
||||
) {
|
||||
return []
|
||||
}
|
||||
let output = []
|
||||
res.data.features.forEach(item => {
|
||||
output.push({
|
||||
label: item.place_name,
|
||||
value: item.place_name,
|
||||
id: item.id
|
||||
})
|
||||
})
|
||||
|
||||
return output
|
||||
},
|
||||
requestGeoData(e) {
|
||||
if (this.axiosSource) {
|
||||
// cancel last request
|
||||
this.axiosSource.cancel()
|
||||
}
|
||||
|
||||
const value = e.target ? e.target.value.trim() : ''
|
||||
if (value === '' || value.length < 3) {
|
||||
this.cities = []
|
||||
return
|
||||
}
|
||||
|
||||
this.axiosSource = CancelToken.source()
|
||||
|
||||
this.$axios
|
||||
.get(
|
||||
`https://api.mapbox.com/geocoding/v5/mapbox.places/${value}.json?access_token=${mapboxToken}&types=region,postcode,district,place,country&language=de`,
|
||||
{
|
||||
cancelToken: this.axiosSource.token
|
||||
}
|
||||
)
|
||||
.then(res => {
|
||||
this.cities = this.processCityResults(res)
|
||||
})
|
||||
console.log('TRY TO GET DATA FOR ', value)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -15,7 +15,6 @@
|
||||
|
||||
color: $text-color-base;
|
||||
background: $background-color-base;
|
||||
|
||||
border: $input-border-size solid $border-color-base;
|
||||
border-radius: $border-radius-base;
|
||||
outline: none;
|
||||
@ -24,25 +23,21 @@
|
||||
&::placeholder {
|
||||
color: $text-color-disabled;
|
||||
}
|
||||
|
||||
.ds-input-has-focus &,
|
||||
&:focus {
|
||||
border-color: $border-color-active;
|
||||
background: $background-color-base;
|
||||
}
|
||||
|
||||
.ds-input-is-disabled &,
|
||||
&:disabled {
|
||||
color: $text-color-disabled;
|
||||
opacity: $opacity-disabled;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.ds-input-has-error & {
|
||||
border-color: $border-color-danger;
|
||||
}
|
||||
}
|
||||
|
||||
.ds-input-size-small {
|
||||
font-size: $font-size-small;
|
||||
|
||||
@ -52,7 +47,6 @@
|
||||
padding: $input-padding-vertical-small $space-x-small;
|
||||
}
|
||||
}
|
||||
|
||||
.ds-input-size-large {
|
||||
font-size: $font-size-large;
|
||||
|
||||
@ -90,6 +84,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
.ds-input-size-small & {
|
||||
width: $input-height-small;
|
||||
}
|
||||
|
||||
.ds-input-size-large & {
|
||||
width: $input-height-large;
|
||||
}
|
||||
}
|
||||
|
||||
.#{$class}-icon-right {
|
||||
right: 0;
|
||||
left: auto;
|
||||
@ -102,6 +105,10 @@
|
||||
padding-left: $input-height-small;
|
||||
}
|
||||
|
||||
.ds-input-size-small & {
|
||||
padding-left: $input-height-small;
|
||||
}
|
||||
|
||||
.ds-input-size-large & {
|
||||
padding-left: $input-height-large;
|
||||
}
|
||||
@ -117,5 +124,9 @@
|
||||
.ds-input-size-large & {
|
||||
padding-right: $input-height-large;
|
||||
}
|
||||
|
||||
.ds-input-size-large & {
|
||||
padding-right: $input-height-large;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
13
yarn.lock
13
yarn.lock
@ -952,7 +952,6 @@
|
||||
"@nuxtjs/proxy@^1.3.0":
|
||||
version "1.3.1"
|
||||
resolved "https://registry.yarnpkg.com/@nuxtjs/proxy/-/proxy-1.3.1.tgz#7d76179aff321491f126d6560434579a4dc7a89a"
|
||||
integrity sha512-agcTJVRCY0XfZcGV573bdIQLsg9fr5p6zikpxtUzR3xywdUBJ+JMKAiz3ew15bOZGK8lVS8u/PBmZ33iEhr3rg==
|
||||
dependencies:
|
||||
consola "^1.4.4"
|
||||
http-proxy-middleware "^0.19.0"
|
||||
@ -1876,14 +1875,12 @@ aws4@^1.8.0:
|
||||
axios-retry@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/axios-retry/-/axios-retry-3.1.1.tgz#88d2971f671a9023b21d887c5dcac6c54f332cde"
|
||||
integrity sha512-BeNOxa/CBQQLa9gVuMta1oWIhbL6UETKBfAmFjOXwiBxgcmrDBVVwz/gKZTpzKJlVjmi5DeYC+lP5Ng7ssc1pg==
|
||||
dependencies:
|
||||
is-retry-allowed "^1.1.0"
|
||||
|
||||
axios@^0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
|
||||
integrity sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=
|
||||
resolved "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102"
|
||||
dependencies:
|
||||
follow-redirects "^1.3.0"
|
||||
is-buffer "^1.1.5"
|
||||
@ -3317,7 +3314,12 @@ copy-descriptor@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
|
||||
|
||||
core-js@^2.4.0, core-js@^2.5.0, core-js@^2.5.7:
|
||||
core-js@^2.4.0, core-js@^2.5.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.0.tgz#1e30793e9ee5782b307e37ffa22da0eacddd84d4"
|
||||
integrity sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw==
|
||||
|
||||
core-js@^2.5.7:
|
||||
version "2.5.7"
|
||||
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e"
|
||||
integrity sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==
|
||||
@ -3734,7 +3736,6 @@ debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.
|
||||
debug@=3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
|
||||
integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user