Merge branch '5059-groups/5318-group-profile-second' of github.com:Ocelot-Social-Community/Ocelot-Social into 5059-groups/5318-group-profile-members-list-etc
# Conflicts: # webapp/locales/de.json # webapp/locales/en.json
@ -4,7 +4,7 @@ export const CATEGORIES_MAX = 3
|
||||
|
||||
export const categories = [
|
||||
{
|
||||
icon: 'users',
|
||||
icon: 'networking',
|
||||
name: 'networking',
|
||||
description: 'Kooperation, Aktionsbündnisse, Solidarität, Hilfe',
|
||||
},
|
||||
@ -14,12 +14,12 @@ export const categories = [
|
||||
description: 'Bauen, Lebensgemeinschaften, Tiny Houses, Gemüsegarten',
|
||||
},
|
||||
{
|
||||
icon: 'lightbulb',
|
||||
icon: 'energy',
|
||||
name: 'energy',
|
||||
description: 'Öl, Gas, Kohle, Wind, Wasserkraft, Biogas, Atomenergie, ...',
|
||||
},
|
||||
{
|
||||
icon: 'smile',
|
||||
icon: 'psyche',
|
||||
name: 'psyche',
|
||||
description: 'Seele, Gefühle, Glück',
|
||||
},
|
||||
@ -34,7 +34,7 @@ export const categories = [
|
||||
description: 'Menschenrechte, Gesetze, Verordnungen',
|
||||
},
|
||||
{
|
||||
icon: 'money',
|
||||
icon: 'finance',
|
||||
name: 'finance',
|
||||
description: 'Geld, Finanzsystem, Alternativwährungen, ...',
|
||||
},
|
||||
@ -44,7 +44,7 @@ export const categories = [
|
||||
description: 'Familie, Pädagogik, Schule, Prägung',
|
||||
},
|
||||
{
|
||||
icon: 'suitcase',
|
||||
icon: 'mobility',
|
||||
name: 'mobility',
|
||||
description: 'Reise, Verkehr, Elektromobilität',
|
||||
},
|
||||
@ -54,48 +54,48 @@ export const categories = [
|
||||
description: 'Handel, Konsum, Marketing, Lebensmittel, Lieferketten, ...',
|
||||
},
|
||||
{
|
||||
icon: 'angellist',
|
||||
icon: 'peace',
|
||||
name: 'peace',
|
||||
description: 'Krieg, Militär, soziale Verteidigung, Waffen, Cyberattacken',
|
||||
},
|
||||
{
|
||||
icon: 'university',
|
||||
icon: 'politics',
|
||||
name: 'politics',
|
||||
description: 'Demokratie, Mitbestimmung, Wahlen, Korruption, Parteien',
|
||||
},
|
||||
{
|
||||
icon: 'tree',
|
||||
icon: 'nature',
|
||||
name: 'nature',
|
||||
description: 'Tiere, Pflanzen, Landwirtschaft, Ökologie, Artenvielfalt',
|
||||
},
|
||||
{
|
||||
icon: 'graduation-cap',
|
||||
icon: 'science',
|
||||
name: 'science',
|
||||
description: 'Bildung, Hochschule, Publikationen, ...',
|
||||
},
|
||||
{
|
||||
icon: 'medkit',
|
||||
icon: 'health',
|
||||
name: 'health',
|
||||
description: 'Medizin, Ernährung, WHO, Impfungen, Schadstoffe, ...',
|
||||
},
|
||||
{
|
||||
icon: 'desktop',
|
||||
icon: 'media',
|
||||
name: 'it-and-media',
|
||||
description:
|
||||
'Nachrichten, Manipulation, Datenschutz, Überwachung, Datenkraken, AI, Software, Apps',
|
||||
},
|
||||
{
|
||||
icon: 'heart-o',
|
||||
icon: 'spirituality',
|
||||
name: 'spirituality',
|
||||
description: 'Religion, Werte, Ethik',
|
||||
},
|
||||
{
|
||||
icon: 'music',
|
||||
icon: 'culture',
|
||||
name: 'culture',
|
||||
description: 'Kunst, Theater, Musik, Fotografie, Film',
|
||||
},
|
||||
{
|
||||
icon: 'ellipsis-h',
|
||||
icon: 'miscellaneous',
|
||||
name: 'miscellaneous',
|
||||
description: '',
|
||||
},
|
||||
|
||||
@ -4,7 +4,10 @@ import CONFIG from '../../config'
|
||||
import { CATEGORIES_MIN, CATEGORIES_MAX } from '../../constants/categories'
|
||||
import { DESCRIPTION_WITHOUT_HTML_LENGTH_MIN } from '../../constants/groups'
|
||||
import { removeHtmlTags } from '../../middleware/helpers/cleanHtml.js'
|
||||
import Resolver from './helpers/Resolver'
|
||||
import Resolver, {
|
||||
removeUndefinedNullValuesFromObject,
|
||||
convertObjectToCypherMapLiteral,
|
||||
} from './helpers/Resolver'
|
||||
import { mergeImage } from './images/images'
|
||||
|
||||
export default {
|
||||
@ -12,20 +15,10 @@ export default {
|
||||
Group: async (_object, params, context, _resolveInfo) => {
|
||||
const { isMember, id, slug } = params
|
||||
const matchParams = { id, slug }
|
||||
Object.keys(matchParams).forEach((key) => {
|
||||
if ([undefined, null].includes(matchParams[key])) {
|
||||
delete matchParams[key]
|
||||
}
|
||||
})
|
||||
removeUndefinedNullValuesFromObject(matchParams)
|
||||
const session = context.driver.session()
|
||||
const readTxResultPromise = session.readTransaction(async (txc) => {
|
||||
const matchParamsEntries = Object.entries(matchParams)
|
||||
let groupMatchParamsCypher = ''
|
||||
matchParamsEntries.forEach((ele, index) => {
|
||||
groupMatchParamsCypher += index === 0 ? ' {' : ''
|
||||
groupMatchParamsCypher += `${ele[0]}: "${ele[1]}"`
|
||||
groupMatchParamsCypher += index < matchParamsEntries.length - 1 ? ', ' : '}'
|
||||
})
|
||||
const groupMatchParamsCypher = convertObjectToCypherMapLiteral(matchParams)
|
||||
let groupCypher
|
||||
if (isMember === true) {
|
||||
groupCypher = `
|
||||
|
||||
@ -121,3 +121,24 @@ export default function Resolver(type, options = {}) {
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
export const removeUndefinedNullValuesFromObject = (obj) => {
|
||||
Object.keys(obj).forEach((key) => {
|
||||
if ([undefined, null].includes(obj[key])) {
|
||||
delete obj[key]
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export const convertObjectToCypherMapLiteral = (params) => {
|
||||
// I have found no other way yet. maybe "apoc.convert.fromJsonMap(key)" can help, but couldn't get it how, see: https://stackoverflow.com/questions/43217823/neo4j-cypher-inline-conversion-of-string-to-a-map
|
||||
// result looks like: '{id: "g0", slug: "yoga"}'
|
||||
const paramsEntries = Object.entries(params)
|
||||
let mapLiteral = ''
|
||||
paramsEntries.forEach((ele, index) => {
|
||||
mapLiteral += index === 0 ? ' {' : ''
|
||||
mapLiteral += `${ele[0]}: "${ele[1]}"`
|
||||
mapLiteral += index < paramsEntries.length - 1 ? ', ' : '}'
|
||||
})
|
||||
return mapLiteral
|
||||
}
|
||||
|
||||
@ -20,16 +20,22 @@ export default {
|
||||
const result = await transaction.run(
|
||||
`
|
||||
MATCH (user:User {id: $id})
|
||||
WITH user, [(user)<-[:OWNED_BY]-(medium:SocialMedia) | properties(medium) ] as media
|
||||
RETURN user {.*, socialMedia: media } as user
|
||||
OPTIONAL MATCH (category:Category) WHERE NOT ((user)-[:NOT_INTERESTED_IN]->(category))
|
||||
OPTIONAL MATCH (cats:Category)
|
||||
WITH user, [(user)<-[:OWNED_BY]-(medium:SocialMedia) | properties(medium) ] AS media, category, toString(COUNT(cats)) AS categoryCount
|
||||
RETURN user {.*, socialMedia: media, activeCategories: collect(category.id) } AS user, categoryCount
|
||||
`,
|
||||
{ id: user.id },
|
||||
)
|
||||
log(result)
|
||||
return result.records.map((record) => record.get('user'))
|
||||
const [categoryCount] = result.records.map((record) => record.get('categoryCount'))
|
||||
const [currentUser] = result.records.map((record) => record.get('user'))
|
||||
// frontend expects empty array when all categories are selected
|
||||
if (currentUser.activeCategories.length === parseInt(categoryCount))
|
||||
currentUser.activeCategories = []
|
||||
return currentUser
|
||||
})
|
||||
try {
|
||||
const [currentUser] = await currentUserTransactionPromise
|
||||
const currentUser = await currentUserTransactionPromise
|
||||
return currentUser
|
||||
} finally {
|
||||
session.close()
|
||||
|
||||
@ -7,6 +7,7 @@ import { createTestClient } from 'apollo-server-testing'
|
||||
import createServer, { context } from '../../server'
|
||||
import encode from '../../jwt/encode'
|
||||
import { getNeode } from '../../db/neo4j'
|
||||
import { categories } from '../../constants/categories'
|
||||
|
||||
const neode = getNeode()
|
||||
let query, mutate, variables, req, user
|
||||
@ -119,6 +120,7 @@ describe('currentUser', () => {
|
||||
}
|
||||
email
|
||||
role
|
||||
activeCategories
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -173,6 +175,52 @@ describe('currentUser', () => {
|
||||
}
|
||||
await respondsWith(expected)
|
||||
})
|
||||
|
||||
describe('with categories in DB', () => {
|
||||
beforeEach(async () => {
|
||||
await Promise.all(
|
||||
categories.map(async ({ icon, name }, index) => {
|
||||
await Factory.build('category', {
|
||||
id: `cat${index + 1}`,
|
||||
slug: name,
|
||||
name,
|
||||
icon,
|
||||
})
|
||||
}),
|
||||
)
|
||||
})
|
||||
|
||||
it('returns empty array for all categories', async () => {
|
||||
await respondsWith({
|
||||
data: {
|
||||
currentUser: expect.objectContaining({ activeCategories: [] }),
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
describe('with categories saved for current user', () => {
|
||||
const saveCategorySettings = gql`
|
||||
mutation ($activeCategories: [String]) {
|
||||
saveCategorySettings(activeCategories: $activeCategories)
|
||||
}
|
||||
`
|
||||
beforeEach(async () => {
|
||||
await mutate({
|
||||
mutation: saveCategorySettings,
|
||||
variables: { activeCategories: ['cat1', 'cat3', 'cat5', 'cat7'] },
|
||||
})
|
||||
})
|
||||
|
||||
it('returns only the saved active categories', async () => {
|
||||
const result = await query({ query: currentUserQuery, variables })
|
||||
expect(result.data.currentUser.activeCategories).toHaveLength(4)
|
||||
expect(result.data.currentUser.activeCategories).toContain('cat1')
|
||||
expect(result.data.currentUser.activeCategories).toContain('cat3')
|
||||
expect(result.data.currentUser.activeCategories).toContain('cat5')
|
||||
expect(result.data.currentUser.activeCategories).toContain('cat7')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -286,6 +286,10 @@ export default {
|
||||
{ id },
|
||||
)
|
||||
})
|
||||
|
||||
// frontend gives [] when all categories are selected (default)
|
||||
if (activeCategories.length === 0) return true
|
||||
|
||||
const writeTxResultPromise = session.writeTransaction(async (transaction) => {
|
||||
const saveCategorySettingsResponse = await transaction.run(
|
||||
`
|
||||
|
||||
@ -602,9 +602,7 @@ describe('save category settings', () => {
|
||||
const userQuery = gql`
|
||||
query ($id: ID) {
|
||||
User(id: $id) {
|
||||
activeCategories {
|
||||
id
|
||||
}
|
||||
activeCategories
|
||||
}
|
||||
}
|
||||
`
|
||||
@ -631,11 +629,7 @@ describe('save category settings', () => {
|
||||
data: {
|
||||
User: [
|
||||
{
|
||||
activeCategories: expect.arrayContaining([
|
||||
{ id: 'cat1' },
|
||||
{ id: 'cat3' },
|
||||
{ id: 'cat5' },
|
||||
]),
|
||||
activeCategories: expect.arrayContaining(['cat1', 'cat3', 'cat5']),
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -678,11 +672,11 @@ describe('save category settings', () => {
|
||||
User: [
|
||||
{
|
||||
activeCategories: expect.arrayContaining([
|
||||
{ id: 'cat10' },
|
||||
{ id: 'cat11' },
|
||||
{ id: 'cat12' },
|
||||
{ id: 'cat8' },
|
||||
{ id: 'cat9' },
|
||||
'cat10',
|
||||
'cat11',
|
||||
'cat12',
|
||||
'cat8',
|
||||
'cat9',
|
||||
]),
|
||||
},
|
||||
],
|
||||
|
||||
@ -115,11 +115,11 @@ type User {
|
||||
|
||||
emotions: [EMOTED]
|
||||
|
||||
activeCategories: [Category] @cypher(
|
||||
activeCategories: [String] @cypher(
|
||||
statement: """
|
||||
MATCH (category:Category)
|
||||
WHERE NOT ((this)-[:NOT_INTERESTED_IN]->(category))
|
||||
RETURN category
|
||||
RETURN collect(category.id)
|
||||
"""
|
||||
)
|
||||
|
||||
|
||||
20
webapp/assets/_new/icons/svgs/culture.svg
Normal file
@ -0,0 +1,20 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M5.9,25.1c-0.3,0.3-0.3,0.8,0,1.1s0.8,0.3,1.1,0c1.7-1.7,4.5-1.7,6.3,0c0.1,0.1,0.3,0.2,0.5,0.2s0.4-0.1,0.5-0.2
|
||||
c0.3-0.3,0.3-0.8,0-1.1C12,22.8,8.2,22.8,5.9,25.1z"/>
|
||||
<path d="M24.4,8.7c0.7-0.7,2-0.7,2.7,0C27.2,8.9,27.4,9,27.6,9c0.2,0,0.4-0.1,0.5-0.2c0.3-0.3,0.3-0.8,0-1.1
|
||||
c-1.3-1.3-3.5-1.3-4.8,0C23,8,23,8.5,23.3,8.7C23.6,9,24.1,9,24.4,8.7z"/>
|
||||
<path d="M16.4,7.7c-0.3,0.3-0.3,0.8,0,1.1c0.3,0.3,0.8,0.3,1.1,0c0.7-0.7,1.9-0.7,2.7,0C20.3,8.9,20.5,9,20.7,9s0.4-0.1,0.5-0.2
|
||||
c0.3-0.3,0.3-0.8,0-1.1C19.9,6.4,17.7,6.4,16.4,7.7z"/>
|
||||
<path d="M31.4,0.8c-0.2-0.1-0.5-0.2-0.7-0.1c-2,0.8-5.1,1.2-8.4,1.2s-6.4-0.4-8.4-1.2c-0.2-0.1-0.5-0.1-0.7,0.1
|
||||
c-0.2,0.1-0.3,0.4-0.3,0.6v9.9c-1,0.1-1.9,0.1-3,0.1c-3.3,0-6.4-0.4-8.4-1.2c-0.2-0.1-0.5-0.1-0.7,0.1c-0.2,0.1-0.3,0.4-0.3,0.6
|
||||
l0,11.5c0,5.2,4.2,9.4,9.4,9.4s9.4-4.2,9.4-9.4V22c0.7,0.3,1.6,0.4,3,0.4c5.2,0,9.4-4.2,9.4-9.4V1.4C31.7,1.2,31.6,0.9,31.4,0.8z
|
||||
M9.9,30.4c-4.4,0-7.9-3.6-7.9-7.9V12c2.1,0.6,4.9,1,7.9,1c2.7,0,5.2-0.3,7.3-0.8l0.5-0.1c0,1.6,0,2.9,0,4c0,1.3,0,2.4,0.1,3.2v3.2
|
||||
C17.8,26.8,14.2,30.4,9.9,30.4z M30.2,13c0,4.4-3.6,7.9-7.9,7.9c-2.1,0-2.8,0-3-1.7v-2.8c0.9,0.5,1.9,0.8,3,0.8
|
||||
c1.6,0,3.1-0.6,4.2-1.7c0.3-0.3,0.3-0.8,0-1.1s-0.8-0.3-1.1,0c-0.8,0.8-2,1.3-3.1,1.3c-1.1,0-2.1-0.4-3-1.2v-3.6
|
||||
c0-0.2-0.1-0.5-0.3-0.6c-0.2-0.1-0.5-0.2-0.7-0.1c-0.4,0.2-0.9,0.3-1.4,0.4l-2.5,0.4V2.5c2.1,0.6,4.9,1,7.9,1c3,0,5.8-0.3,7.9-1V13
|
||||
z"/>
|
||||
<path d="M10.9,17.7c-0.3,0.3-0.3,0.8,0,1.1s0.8,0.3,1.1,0c0.7-0.7,2-0.7,2.7,0c0.1,0.1,0.3,0.2,0.5,0.2s0.4-0.1,0.5-0.2
|
||||
c0.3-0.3,0.3-0.8,0-1.1C14.4,16.4,12.2,16.4,10.9,17.7z"/>
|
||||
<path d="M7.7,18.7C7.9,18.9,8.1,19,8.3,19s0.4-0.1,0.5-0.2c0.3-0.3,0.3-0.8,0-1.1c-1.3-1.3-3.5-1.3-4.8,0c-0.3,0.3-0.3,0.8,0,1.1
|
||||
s0.8,0.3,1.1,0C5.8,18,7,18,7.7,18.7z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
14
webapp/assets/_new/icons/svgs/energy.svg
Normal file
@ -0,0 +1,14 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M27.6,19.7L26.8,19c-3-2.8-4.8-4.4-5.2-4.6c-0.9-0.6-2.9-0.5-3.6-0.4c-0.2-0.5-0.5-0.9-0.9-1.2V2.2
|
||||
c0-1-0.7-1.6-1.3-1.6c-0.6-0.1-1.4,0.4-1.6,1.4c-0.1,0.5-0.3,1.4-0.5,2.4c-0.6,2.9-1,5-1,5.4c-0.1,1.1,1.1,2.8,1.5,3.3
|
||||
c-0.3,0.4-0.5,0.9-0.5,1.4c0,0,0,0,0,0.1c-0.9,0.6-7.3,5-8.7,6c-0.8,0.6-0.9,1.4-0.6,2c0.2,0.4,0.7,0.7,1.2,0.7
|
||||
c0.3,0,0.5-0.1,0.8-0.2c1.5-0.6,6.7-2.9,7.4-3.2c0.2-0.1,0.4-0.3,0.6-0.5l-1.3,11c0,1,2.3,1,2.8,1s2.8,0,2.8-1.1l-1.4-13.5
|
||||
c1.8,1.1,7.2,4.4,8.6,5.2c0.3,0.2,0.7,0.3,0.9,0.3c0.5,0,0.9-0.2,1.1-0.5C28.5,21.4,28.5,20.5,27.6,19.7z M14.8,14.6
|
||||
c0-0.8,0.6-1.2,1.2-1.2c0.6,0,1.2,0.6,1.2,1.2c0,0.8-0.6,1.2-1.2,1.2C15.2,15.8,14.8,15.2,14.8,14.6z M14.8,4.7c0.2-1,0.4-2,0.5-2.5
|
||||
c0.1-0.5,0.3-0.7,0.5-0.6c0.2,0,0.4,0.2,0.4,0.6v10.2c-0.1,0-0.1,0-0.2,0c-0.3,0-0.6,0.1-0.9,0.2c-0.6-0.8-1.4-2-1.3-2.7
|
||||
C13.8,9.5,14.4,6.5,14.8,4.7z M13.5,19.1c-0.6,0.3-5.8,2.6-7.3,3.2c-0.4,0.2-0.7,0.1-0.8-0.1c-0.1-0.2,0-0.4,0.3-0.7
|
||||
c1.3-0.9,6.9-4.8,8.4-5.8c0.2,0.3,0.5,0.6,0.8,0.8C14.6,17.4,13.9,18.8,13.5,19.1z M16,30.4c-0.6,0-1.4-0.1-1.8-0.2l1.6-13.4
|
||||
c0,0,0.1,0,0.1,0c0.1,0,0.3,0,0.4,0l1.4,13.4C17.4,30.3,16.6,30.4,16,30.4z M27.3,21.3c-0.1,0.1-0.4,0.2-0.7,0
|
||||
c-1.5-0.9-7.2-4.4-8.8-5.3c0.2-0.3,0.3-0.6,0.4-0.9c1-0.1,2.5-0.1,3,0.3c0.4,0.2,3.6,3.2,5,4.5l0.8,0.7
|
||||
C27.3,20.8,27.4,21.1,27.3,21.3z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
13
webapp/assets/_new/icons/svgs/finance.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<rect x="8.1" y="13.3" width="1.5" height="1.9"/>
|
||||
<path d="M31.9,17.9L31.9,17.9l0-0.6c-0.2-5.5-4.1-10.3-9.5-11.6c-0.2,0-0.8-0.2-0.8-0.2c-3.1-0.6-6.3-0.5-9.5,0.1
|
||||
c-0.3,0.1-0.6,0.1-0.9,0.2C10.6,5.7,10,5.4,9.7,5.4L9.5,5.3C8.7,5,7.6,4.6,6.8,5.1C6,5.7,6,6.7,6.2,7.3l0.3,1.2
|
||||
C5.1,9.7,4,11.2,3.3,12.8c-0.4,0.8-0.8,0.8-1.2,0.8c-0.1,0-0.2,0-0.3,0H0l0,5.5l0.6,0.1c0,0,1.1,0.2,1.6,1C2.5,20.7,2.7,21,3,22.3
|
||||
c1.1,3.4,3.6,5.3,4.6,5.9l0,3.9H12l2.6-3.4h6.1l1.7,3.4h4.9v-4.6l0.4-0.4c2.5-2.2,3.9-5.2,4.1-8.5l0-0.4
|
||||
C31.9,18.1,31.9,18,31.9,17.9z M26.7,25.9l-0.9,0.9v3.8h-2.5l-1.7-3.4h-7.7l-2.6,3.4H9.1l0-3.2l-0.4-0.2c0,0-3.1-1.7-4.2-5.3
|
||||
c-0.4-1.4-0.6-1.8-1-2.3c-0.5-0.9-1.4-1.3-2-1.5v-2.8l0.6,0c0.5,0,1.8,0,2.6-1.7c0.5-1.2,1.3-2.3,2.2-3.3c0.8-0.8,1.3-1,1.1-1.5
|
||||
l0,0L7.6,7c-0.1-0.2-0.1-0.5,0-0.6c0.2-0.1,1,0.1,1.4,0.3l0.3,0.1c0.3,0.1,0.9,0.4,1.7,0.6l0.2,0.1l0.3-0.1c0.3-0.1,0.7-0.2,1-0.2
|
||||
c3-0.6,5.9-0.6,8.9-0.1c0,0,0.6,0.1,0.8,0.1c4.7,1.1,8.2,5.3,8.4,10.1l0,0.8c-0.1,1.3-1.2,2.4-2.5,2.4c-1,0-1.9-0.9-1.9-2
|
||||
c0-0.8,0.6-1.4,1.4-1.4v-1.5c-1.6,0-2.9,1.3-2.9,2.9c0,1.9,1.5,3.5,3.4,3.5c0.7,0,1.3-0.2,1.8-0.5C29.1,23.2,28.1,24.7,26.7,25.9z"
|
||||
/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
7
webapp/assets/_new/icons/svgs/health.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M26.1,20.7c-2.9,5.1-9.3,8.8-10.8,9.6c-2.1-1.1-13.7-7.8-13.7-16.1c0-3.6,2.8-6.5,6.5-6.5c2.6,0,4.9,1.5,5.9,3.9l0.7,1.7
|
||||
l0.7-1.7c1-2.4,3.3-3.9,5.9-3.9c3.6,0,6.5,2.8,6.5,6.5V15h1.5v-0.8c0-4.5-3.5-8-8-8c-2.7,0-5.2,1.3-6.6,3.5
|
||||
c-1.4-2.2-3.9-3.5-6.6-3.5c-4.5,0-8,3.5-8,8c0,10,14.3,17.3,14.9,17.6l0.3,0.2l0.3-0.2c0.3-0.2,8.3-4.2,11.8-10.4l0.4-0.7L26.5,20
|
||||
L26.1,20.7z"/>
|
||||
<polygon points="22.9,17 19.5,21.2 17,14.5 11.6,19.9 12.6,20.9 16.4,17.2 19,24.2 23.6,18.5 31.9,18.5 31.9,17 "/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 625 B |
7
webapp/assets/_new/icons/svgs/media.svg
Normal file
@ -0,0 +1,7 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M31.7,29.2L29.8,23V7.1c0-1.1-1-2.1-2.1-2.1H4.8c-1.1,0-2.1,1-2.1,2.1V23l-2,6.1c-0.2,0.6-0.1,1.3,0.2,1.9
|
||||
c0.4,0.6,1,0.9,1.7,0.9h27.1c0.7,0,1.3-0.3,1.7-0.9C31.8,30.4,31.9,29.7,31.7,29.2z M4.2,7.1c0-0.3,0.3-0.6,0.6-0.6h22.8
|
||||
c0.3,0,0.6,0.3,0.6,0.6v15.3h-24V7.1z M30.2,30.2c-0.1,0.1-0.2,0.2-0.5,0.2H2.6c-0.3,0-0.4-0.2-0.5-0.2C2.1,30,2,29.8,2.1,29.6
|
||||
L4,23.9h24.4l1.8,5.8C30.4,29.8,30.3,30,30.2,30.2z"/>
|
||||
<rect x="13.5" y="27.8" width="5.6" height="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 596 B |
13
webapp/assets/_new/icons/svgs/miscellaneous.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M7.5,4.9c0.1-0.1,0.2-0.2,0.3-0.2l0.7-0.6l-1-1.4L6.8,3.1C6.7,3.3,6.6,3.4,6.5,3.5L5.8,4.1l1,1.3L7.5,4.9z"/>
|
||||
<path d="M31.5,19.2c0.2-1,0.3-2.1,0.3-3.2c0-8.6-7-15.8-15.8-15.8c-1.7,0-3.3,0.2-5,0.8l-0.8,0.2l0.6,1.6l0.8-0.2
|
||||
c1.5-0.5,3-0.7,4.5-0.7c3.6,0,6.9,1.4,9.4,3.7C22.7,6,21.3,7.3,21,9.7c-0.2,1.3,0.6,2.4,1.4,3.3c0.3,0.5,1,1.3,0.9,1.5
|
||||
c0,0.2-0.2,0.3-0.6,0.6c-0.8,0.6-2,1.3-1.7,3.6c0.2,1.6,0.9,2.8,2.2,3.1c0.2,0.1,0.6,0.1,0.8,0.1c1,0,2.1-0.6,2.9-1.5
|
||||
c0.8-1,0.8-1,2-0.5c0.2,0.1,0.4,0.2,0.6,0.3c-1.8,5.7-7.1,9.8-13.4,9.8c-1.7,0-3.4-0.3-4.9-0.9l-0.1-0.1c-0.7-1.8,1-4.3,2.9-5.9
|
||||
c2.1-1.8,2.9-4.6,2.1-7.1c-0.5-1.2-1.4-2.1-2.7-2.3C12,13.5,10.6,14,9.7,15c-1,1.3-1.8,2-3,2c-1.3-0.1-3.3-2-4.3-3.1l-0.2-0.3
|
||||
c0.4-2.1,1.2-4,2.4-5.7L5,7.2l-1.4-1L3.1,6.8c-1.8,2.8-2.9,5.9-2.9,9.2c0,8.6,7.1,15.8,15.9,15.8c7.3,0,13.5-5.1,15.2-11.9
|
||||
L31.5,19.2L31.5,19.2z M2,16.1c0,0,0-0.1,0-0.1c1.1,1.1,2.9,2.6,4.5,2.6c2.1,0.1,3.3-1.3,4.5-2.5c0.5-0.6,1.3-0.8,2.1-0.7
|
||||
c0.3,0.1,1,0.3,1.3,1.2c0.6,1.8,0,4-1.5,5.3c-0.9,0.9-3.7,3.6-3.5,6.5C5,26,2,21.3,2,16.1z M29.6,18.4c-1.7-0.9-2.7-1-4.1,0.9
|
||||
c-0.6,0.7-1.3,1-1.8,0.9s-0.8-0.7-0.9-1.6c-0.1-1.3,0.3-1.5,0.9-2c0.5-0.3,1-0.7,1.3-1.5c0.3-1.2-0.5-2.2-1.2-3.1
|
||||
c-0.5-0.7-1.2-1.5-1-2.1c0.1-1,0.3-2.6,4.3-2.7c1.9,2.4,3.1,5.5,3.1,8.8c0,0.8-0.1,1.6-0.2,2.4C29.8,18.4,29.7,18.4,29.6,18.4z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
11
webapp/assets/_new/icons/svgs/mobility.svg
Normal file
@ -0,0 +1,11 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M31.8,20c0-6.8-5.6-9.1-8.2-9.1h-3.2c-0.3-1.6-1.7-2.9-3.5-2.9h-2.2v1.1h-3.4v1.5h3.4v2.1h-3.4v1.5h3.4v0.9h2.2
|
||||
c1.7,0,3.1-1.2,3.4-2.7h3.3c1.3,0,6.7,1.3,6.7,7.6c0,6.9-7.2,7.2-7.2,7.2h-0.8h-0.1V28c0,1.3-1.1,2.4-2.5,2.4
|
||||
c-1.4,0-2.5-1.1-2.5-2.4v-0.8H8.6V28c0,1.3-1.1,2.4-2.4,2.4c-1.5,0-2.4-1.2-2.4-2.4v-0.8H1.8v-2.6c0-0.1,0-0.8,0.5-1
|
||||
c0.5-0.1,1.3-0.4,2.2-0.7c0.5-0.2,1.1-0.4,1.2-0.4c0.4,0,0.8-0.3,1.4-1l0.1-0.1c0.1-0.1,0.5-0.7,0.9-1.1c0.8-0.9,1-1.2,1.1-1.4
|
||||
c0.1-0.1,0.5-0.4,1-0.4h8.6c0.6,0,0.8,0.2,1,0.4c0.4,0.5,1.9,2.5,1.9,2.5l1.2-0.9c0,0-1.5-2-1.9-2.5c-0.5-0.7-1.2-1-2.2-1h-8.6
|
||||
c-1,0-2,0.6-2.2,1.1c-0.1,0.1-0.6,0.8-1,1.2c-0.5,0.6-0.8,1-0.9,1.2c-0.2,0.2-0.5,0.4-0.6,0.6c-0.2,0-0.5,0.2-1.5,0.5
|
||||
c-0.7,0.3-1.6,0.6-2,0.7c-1,0.3-1.7,1.2-1.7,2.4v4.1h2.2c0.3,1.8,1.9,3.2,3.8,3.2c1.9,0,3.5-1.4,3.9-3.2h5.7
|
||||
c0.3,1.8,1.9,3.2,3.9,3.2c1.9,0,3.5-1.4,3.9-3.2C26.2,28.5,31.8,26.6,31.8,20z M16.9,13.6h-0.8V9.6h0.8c1.1,0,2.1,0.9,2.1,2
|
||||
S18,13.6,16.9,13.6z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@ -1,20 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.4.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
width="24px" height="24.3px" viewBox="0 0 24 24.3" style="enable-background:new 0 0 24 24.3;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#333333;}
|
||||
</style>
|
||||
<g>
|
||||
<circle class="st0" cx="17.1" cy="2.9" r="2.9"/>
|
||||
<path class="st0" d="M23.5,5.6L23.5,5.6c-0.6-0.5-1.4-0.5-2,0.1l-2.7,3l-2.2-1.4c0.1,0.3,0.1,0.6,0.1,0.9c0,0.6-0.2,1.1-0.5,1.6
|
||||
L16,10.2l1.5,1c0.4,0.3,0.9,0.4,1.4,0.4c0.1,0,0.2,0,0.4,0c0.6-0.1,1.2-0.4,1.6-0.9l2.7-3.1C24.2,7,24.1,6.1,23.5,5.6z"/>
|
||||
<path class="st0" d="M6.5,17c-0.3-0.2-0.5-0.5-0.7-0.8c0,0,0,0,0,0L4.6,19l-4,2.7C0,22.1-0.2,23,0.2,23.6l0,0
|
||||
c0.4,0.6,1.3,0.8,1.9,0.4l4.7-3.2l1.4-3.3l-0.7-0.1C7.2,17.4,6.8,17.2,6.5,17z"/>
|
||||
<path class="st0" d="M16.3,15.1l-4.4-0.5l3.5-4.7l0.3-0.4C16,9,16.2,8.6,16.2,8.2c0-0.7-0.4-1.4-1-1.7c-0.1,0-0.1-0.1-0.2-0.1
|
||||
l-1.8-0.7L9.4,4.4C9.1,4.3,8.8,4.3,8.5,4.3c-0.3,0-0.5,0-0.8,0.1c-0.5,0.2-1,0.5-1.3,0.9L3.7,8.5C3.2,9.1,3.3,10,3.9,10.5l0,0
|
||||
c0.3,0.2,0.6,0.3,0.9,0.3c0.4,0,0.8-0.2,1.1-0.5L8.6,7L11.4,8l-4.8,6.5l0,0c-0.1,0.1-0.1,0.3-0.2,0.4c-0.2,0.8,0.4,1.7,1.3,1.8
|
||||
l0.9,0.1l6.9,0.9l-1.7,2.7c-0.4,0.7-0.2,1.5,0.5,1.9h0c0.2,0.1,0.5,0.2,0.7,0.2c0.5,0,0.9-0.2,1.2-0.7l2-3.2
|
||||
c0.4-0.7,0.5-1.6,0.1-2.3C17.8,15.7,17.1,15.2,16.3,15.1z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M16,9.9c-2.7,0-4.8-2.2-4.8-4.8s2.2-4.8,4.8-4.8c2.7,0,4.8,2.2,4.8,4.8S18.6,9.9,16,9.9z M16,1.8c-1.8,0-3.3,1.5-3.3,3.3
|
||||
s1.5,3.3,3.3,3.3c1.8,0,3.3-1.5,3.3-3.3S17.8,1.8,16,1.8z"/>
|
||||
<path d="M19.6,32c-3.3,0-5.4-0.1-6-0.3c-2.6-1.1-2.6-2.5-2.4-3.1c0.5-2,4.1-3.1,8.7-2.6l0.3,0c0.4,0,0.8,0.3,0.8,0.8
|
||||
s-0.3,0.8-0.8,0.8h-0.3c-4.7-0.4-7,0.8-7.1,1.5c-0.1,0.3,0.4,0.9,1.5,1.4c0.8,0.3,7.5,0.2,10.1,0.2c0.7,0,1.3,0,1.7,0
|
||||
c0.6,0,1.3-0.5,1.3-1.3c0-1.6-2-3.1-3.6-4.2c-0.5-0.3-0.9-0.7-1.3-1c-0.2-0.2-0.4-0.4-0.7-0.6c-0.9-0.8-1.9-1.5-2-2.5
|
||||
c-0.1-0.5,0-1.1,0.2-1.8c0.2-0.6,0.3-1.2,0.3-2c0-0.4,0.3-0.7,0.6-0.7c0.4-0.1,0.7,0.1,0.8,0.5c0.9,2.3,1.4,2.7,2.7,3.9
|
||||
c0.6,0.5,1.3,1.1,2.4,2.1c0.5,0.5,1.2,0.5,1.6,0c0.2-0.2,0.3-0.5,0.3-0.8s-0.1-0.5-0.3-0.8l-2.9-2.8c-1.3-1.2-1.9-2.8-2.5-4
|
||||
c-0.7-1.7-1.1-2.5-2.1-2.5h-9c-0.9,0-1.3,0.7-2.1,2.5c-0.5,1.2-1.2,2.8-2.5,4l-2.9,2.8c-0.2,0.2-0.3,0.5-0.3,0.8
|
||||
c0,0.3,0.1,0.5,0.3,0.8c0.5,0.5,1.2,0.5,1.6,0c0.5-0.5,1-1,1.6-1.5c1.6-1.3,3.2-2.7,3.5-4.4c0.1-0.4,0.4-0.6,0.8-0.6
|
||||
c0.4,0,0.7,0.4,0.7,0.7c0,0.8,0.2,1.4,0.3,2c0.2,0.6,0.3,1.3,0.2,1.9c-0.2,0.9-1.2,1.7-2.1,2.5c-0.2,0.2-0.4,0.3-0.5,0.5
|
||||
c-0.4,0.3-0.8,0.7-1.3,1c-1.6,1.2-3.6,2.7-3.6,4.2c0,0.6,0.5,1.3,1.3,1.3h4c0.4,0,0.8,0.3,0.8,0.8S11.3,32,10.9,32h-4
|
||||
c-1.5,0-2.8-1.3-2.8-2.8c0-2.4,2.3-4.1,4.2-5.5c0.4-0.3,0.9-0.6,1.2-0.9c0.2-0.1,0.3-0.3,0.5-0.5c0.7-0.6,1.5-1.3,1.6-1.7
|
||||
c0.1-0.2,0-0.6-0.1-1c-0.8,1.1-1.9,2-2.9,2.9c-0.6,0.5-1.1,0.9-1.5,1.4c-1.1,1.1-2.7,1.1-3.7,0c-0.5-0.5-0.8-1.2-0.8-1.8
|
||||
s0.3-1.3,0.8-1.8l2.9-2.8c1.1-1,1.6-2.3,2.1-3.5c0.7-1.7,1.4-3.4,3.5-3.4h9c2,0,2.7,1.7,3.5,3.4c0.5,1.2,1.1,2.5,2.1,3.5l2.9,2.8
|
||||
c0.5,0.5,0.8,1.2,0.8,1.8s-0.3,1.3-0.8,1.8c-1.1,1.1-2.7,1-3.7,0c-1-0.9-1.7-1.5-2.3-2c-0.9-0.8-1.5-1.3-2.1-2.3
|
||||
c-0.1,0.4-0.2,0.8-0.2,1c0.1,0.5,0.9,1.1,1.5,1.6c0.2,0.2,0.5,0.4,0.7,0.6c0.3,0.3,0.8,0.6,1.2,0.9c1.9,1.4,4.2,3.1,4.2,5.5
|
||||
c0,1.5-1.3,2.8-2.8,2.8c-0.3,0-0.9,0-1.7,0C22.5,32,20.9,32,19.6,32z"/>
|
||||
</svg>
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 2.0 KiB |
18
webapp/assets/_new/icons/svgs/nature.svg
Normal file
@ -0,0 +1,18 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M31,20.4c-0.4-0.3-1-0.5-1.6-0.5l-0.2-0.4c-0.5-1.4-2.1-1.6-3.6-1.1c-0.2,0.1-0.6,0.3-1,0.6c-0.7-0.8-2-0.9-3.2-0.5
|
||||
c-0.5,0.2-1.8,0.9-2.5,1.3c-2.6-0.5-5.8-1.1-6.5-1.2c-2-0.2-3.3-0.2-4.9,0.3c-0.6,0.2-5.2,2.3-6.1,2.7L0.9,22l0.6,1.4l0.7-0.3
|
||||
c2.5-1.2,5.5-2.5,5.9-2.6c1.4-0.4,2.4-0.4,4.3-0.2c0.9,0.1,8.1,1.5,9.4,1.8c0.9,0.2,0.9,0.7,0.9,0.8c0,0.3-0.1,0.4-0.1,0.4
|
||||
s0,0-0.1,0h-8.6v1.5h2l0.5,0.3c0.1,0,1.4,0.9,2.4,1.3c1,0.4,2,0.4,2.7-0.2c2.6-1.7,6.7-4.4,7-4.6c0.6-0.4,1.4-0.4,1.6-0.2
|
||||
c0.1,0.1,0.2,0.2,0.2,0.3s-0.1,0.2-0.2,0.3c-2.8,2-10.3,7.5-11.2,8c-1.2,0.7-2.8,0.3-3.6,0.1c-1.2-0.4-7.1-2.5-7.6-2.7
|
||||
c-0.7-0.2-2.4-0.6-3.9,0C2.7,28,1,29,0.9,29l-0.7,0.3l0.7,1.3l0.7-0.3c0,0,1.7-0.9,2.8-1.4c0.9-0.4,2.2-0.2,2.6,0
|
||||
c0.5,0.2,6.4,2.3,7.7,2.7c0.5,0.1,1.3,0.3,2.2,0.3c0.8,0,1.7-0.2,2.5-0.3c1.1-0.6,10.9-7.8,11.3-8.1c0.5-0.4,0.8-0.9,0.8-1.5
|
||||
S31.5,20.8,31,20.4z M22,20c0,0,0.7-0.2,1.2-0.1c-0.4,0.3-0.8,0.5-1.1,0.7c0,0,0,0,0,0c-0.2-0.1-0.5-0.1-0.9-0.2
|
||||
C21.6,20.2,21.9,20.1,22,20z M19.3,25.2c-0.2-0.1-0.4-0.2-0.6-0.3h2.1c-0.1,0.1-0.2,0.2-0.3,0.2C20.3,25.3,19.9,25.5,19.3,25.2z
|
||||
M24.2,22.7c0-0.5-0.2-0.9-0.5-1.2c1.2-0.7,2.4-1.5,2.7-1.6c0,0,1.4-0.4,1.7,0.3l0,0.1c-0.2,0.1-0.3,0.1-0.5,0.2
|
||||
C27.5,20.5,25.8,21.6,24.2,22.7z"/>
|
||||
<path d="M15.9,16c3,0,4.5-1.3,5.3-2.3c1.3,1.4,1.5,3,1.5,3.1l0.1,0.7l1.6-0.1l-0.1-0.7c-0.1-0.1-0.3-2.5-2.5-4.4
|
||||
c0.4-1.6,0.1-3.5-1-4.9c-2.2-2.7-5.4-2.9-8.6-2.8c-2.9,0-4.6,0-6.4-0.9L4.9,3.2L4.7,4.2C4.3,6.3,5.2,9,7.1,11.5
|
||||
C9.4,14.4,12.7,16,15.9,16z M12.3,6.1c3-0.1,5.7,0,7.4,2.2c0.7,0.8,1,2,0.8,3c-2-1.1-4-1.6-5.6-2.1c-1.2-0.3-2.3-0.6-2.7-1
|
||||
l-0.6-0.5l-1,1.1l0.6,0.5c0.7,0.6,1.9,0.9,3.4,1.3c1.6,0.4,3.6,1,5.5,2.1c-0.7,1.2-2.1,1.8-4.1,1.8c-2.8,0-5.6-1.4-7.6-4
|
||||
C7,8.9,6.2,7,6.2,5.5C8,6.1,9.7,6.1,12.3,6.1z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.8 KiB |
22
webapp/assets/_new/icons/svgs/networking.svg
Normal file
@ -0,0 +1,22 @@
|
||||
<svg version="1.1" id="Ebene_1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M31.6,16c-0.6-6.4-1.9-6.4-2.4-6.4c-0.4,0-0.8,0.1-1.1,0.4c-0.8,0.8-0.8,2.5-0.8,4.2c0,0.5,0,1.2,0,1.7h-0.1
|
||||
C26,15.5,25.1,17,24.5,18c-0.1,0.2-0.2,0.4-0.3,0.5c-0.8,0.9-1.2,1.2-2.2,2c-0.4,0.4-1,0.6-1.5,0.9c-0.6,0.3-1.2,0.6-1.8,1.1
|
||||
c-2.3,1.9-1.8,4.1-1.4,6.1c0.2,0.8,0.3,1.5,0.3,2.3v0.8h1.5v-0.8c0-0.9-0.2-1.7-0.4-2.6c-0.4-2.1-0.6-3.4,0.9-4.6
|
||||
c0.4-0.4,1-0.6,1.5-0.9c0.6-0.3,1.2-0.6,1.8-1.1c1-0.8,1.5-1.2,2.4-2.2c0.1-0.1,0.3-0.4,0.4-0.7c0.2-0.3,0.7-1.2,1-1.4
|
||||
c0.3,0.2,0.4,1.3,0.3,1.7c-0.3,1-1.1,1.9-1.9,2.8c-0.7,0.8-1.4,1.6-1.8,2.5L23,25l1.3,0.7l0.3-0.7c0.4-0.7,1-1.4,1.6-2.2
|
||||
c0.9-1,1.8-2.1,2.2-3.3c0.2-0.5,0.2-1.4-0.1-2.2c0.4-0.5,0.4-1.4,0.4-3c0-0.8,0-2.5,0.3-3c0.3,0.5,0.7,1.8,1,4.9
|
||||
c0.2,2,0.2,4.8-1.2,7.1c-0.5,0.9-1.3,1.7-2,2.4c-1.3,1.4-2.7,2.9-3,5.2l-0.1,0.7l1.5,0.2l0.1-0.7c0.2-1.7,1.4-3,2.6-4.3
|
||||
c0.8-0.8,1.5-1.7,2.2-2.7C31.9,21.4,31.9,18.2,31.6,16z"/>
|
||||
<path d="M26.3,7.2c0-2.9-2.4-5.2-5.2-5.2c-2.4,0-3.9,1.4-4.5,2c-0.6-0.6-2.1-2-4.5-2C9.3,2,6.9,4.3,6.9,7.1c0,1,0.5,1.9,1,2.4
|
||||
c0.4,0.6,0.8,1,0.8,1l7.4,7.5l0.6,0.6l7.9-7.9C24.6,10.7,26.3,9.2,26.3,7.2z M16.6,16.7l-7-7c0,0-0.4-0.3-0.7-0.8
|
||||
C8.6,8.4,8.3,7.7,8.3,7.2c0-2.1,1.7-3.8,3.8-3.8c2,0,3.9,2,3.9,2L16.6,6l0.5-0.6c0,0,1.9-2,4-2s3.8,1.7,3.8,3.8
|
||||
c0,1.1-1.3,2.5-1.3,2.5L16.6,16.7z"/>
|
||||
<path d="M13.4,22.6c-0.6-0.4-1.2-0.8-1.8-1.1c-0.6-0.3-1.1-0.6-1.5-0.9c-1-0.8-1.4-1.2-2.2-2c-0.1-0.1-0.2-0.3-0.3-0.5
|
||||
c-0.6-1-1.5-2.5-2.7-2.1c-0.1,0-0.1,0.1-0.2,0.1c0-0.5,0-1.2,0-1.7c0-1.8,0-3.5-0.8-4.2c-0.3-0.3-0.7-0.4-1-0.4
|
||||
c-0.5,0-1.8,0-2.4,6.4c-0.3,2.2-0.2,5.4,1.4,8.1c0.6,1,1.4,1.9,2.2,2.7c1.3,1.3,2.4,2.6,2.7,4.3L6.9,32l1.5-0.2L8.1,31
|
||||
c-0.3-2.2-1.7-3.7-3.1-5.1c-0.7-0.8-1.5-1.6-2-2.5c-1.4-2.3-1.4-5.2-1.2-7.1c0.3-3.1,0.8-4.5,1-4.9c0.3,0.5,0.3,2.2,0.3,3
|
||||
c0,1.7,0,2.6,0.5,3.1c-0.2,0.8-0.2,1.7-0.1,2.1C4,20.9,4.9,22,5.8,23c0.6,0.7,1.3,1.4,1.6,2.2l0.3,0.7L9,25.2l-0.3-0.7
|
||||
c-0.5-0.9-1.2-1.7-1.8-2.5c-0.8-0.9-1.6-1.8-1.9-2.8c-0.1-0.4,0-1.5,0.3-1.7c0.3,0.2,0.8,1.1,1,1.4s0.3,0.6,0.5,0.7
|
||||
c0.8,0.9,1.4,1.4,2.4,2.2c0.6,0.4,1.2,0.8,1.8,1.1c0.6,0.3,1.1,0.6,1.5,0.9c1.5,1.3,1.3,2.6,0.9,4.6C13.1,29.3,13,30.1,13,31v0.8
|
||||
h1.5V31c0-0.7,0.2-1.5,0.3-2.3C15.2,26.8,15.7,24.5,13.4,22.6z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
8
webapp/assets/_new/icons/svgs/peace.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" width="32px" height="32px">
|
||||
<path d="M27.3,5c-1.5-1.5-3.1-2.6-5-3.4c-2-0.8-4-1.2-6.2-1.2c-2.1,0-4.2,0.4-6.2,1.2C8,2.4,6.3,3.5,4.9,5c-1.5,1.5-2.6,3.1-3.4,5
|
||||
c-0.8,2-1.2,4-1.2,6.2c0,2.1,0.4,4.2,1.2,6.2c0.8,1.9,1.9,3.6,3.4,5c1.5,1.5,3.1,2.6,5,3.4c2,0.8,4,1.2,6.2,1.2
|
||||
c2.1,0,4.2-0.4,6.2-1.2c1.9-0.8,3.6-1.9,5-3.4c1.5-1.5,2.6-3.1,3.4-5c0.8-2,1.2-4,1.2-6.2c0-2.1-0.4-4.2-1.2-6.2
|
||||
C29.8,8.1,28.7,6.4,27.3,5z M15.1,2.4v13.4L5.4,25c-2-2.4-3.2-5.5-3.2-8.8C2.2,8.9,7.9,2.9,15.1,2.4z M6.8,26.4l8.3-7.9V30
|
||||
C11.9,29.7,9,28.4,6.8,26.4z M17.1,30V18.5l8.3,7.9C23.1,28.4,20.2,29.7,17.1,30z M26.7,25l-9.7-9.2V2.4c7.2,0.5,12.8,6.5,12.8,13.8
|
||||
C29.9,19.5,28.7,22.6,26.7,25z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 742 B |
12
webapp/assets/_new/icons/svgs/politics.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M19.3,15.4c0.3,0.2,0.9,0.5,1.1,0.8c0.5,0.6,0.6,1.2,0.6,1.3l0.8,3.1l1.4-0.4l-0.8-3c0-0.1-0.2-0.9-0.9-1.8
|
||||
c-0.5-0.6-1.5-1.1-1.6-1.2l-8.5-4.7l-0.7,1.3L19.3,15.4z"/>
|
||||
<path d="M7.4,19.1c0.4,2.2,2.5,4.1,3.4,4.8l0.9-1.2c-1.7-1.4-2.8-2.9-2.9-4.2l0-0.4l-2.3-1.3L11,7.8c0.1-0.2,0.1-0.4,0-0.6
|
||||
c-0.1-0.2-0.2-0.3-0.4-0.4L6.5,4.9L5.9,6.3l3.4,1.6L4.4,17.9l-3.4-1.6l-0.6,1.4l4.1,1.9c0.1,0,0.2,0.1,0.3,0.1
|
||||
c0.3,0,0.5-0.2,0.7-0.4l0.5-1L7.4,19.1z"/>
|
||||
<path d="M28.9,30.5l-2.8-10.1l-5.6,1.5l-1.1-4c-0.1-0.4-0.5-0.6-0.9-0.5c-0.4,0.1-0.6,0.5-0.5,0.9l2.1,7.6c0.2,0.7-0.2,1.4-1,1.6
|
||||
c-0.3,0.1-0.7,0-0.9-0.1c-0.3-0.2-0.5-0.4-0.6-0.8l-1.4-5c-0.1-0.3-0.4-0.5-0.7-0.6c-0.1,0-2.4,0-3.8-3.5c-0.2-0.4-0.6-0.6-1-0.4
|
||||
c-0.4,0.2-0.6,0.6-0.4,1c1.4,3.4,3.6,4.2,4.6,4.4l0.2,0.9l-6.8,1.9l1.2,4.4l1.4-0.4l-0.8-2.9l5.3-1.5l0.6,2.1
|
||||
c0.2,0.7,0.7,1.3,1.3,1.7c0.4,0.2,0.9,0.4,1.3,0.4c0.3,0,0.5,0,0.8-0.1c1.5-0.4,2.3-1.9,1.9-3.4L21,23.4l4.1-1.1l2.2,8.2h-20V32
|
||||
h24.5v-1.5H28.9z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
8
webapp/assets/_new/icons/svgs/psyche.svg
Normal file
@ -0,0 +1,8 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path class="st0" d="M30.8,12C30.5,7.4,27.9,3.5,24,1.8c-2-0.9-4.3-1.4-6.4-1.4v0.1c0,0,0,0,0,0V0.4c-2,0-3.9,0.4-5.7,1.2
|
||||
c-1.8,0.8-3.4,2-4.7,3.6c0,0,0,0,0,0c-0.1,0.1-2.6,3.3-2.5,8.5l-3.4,6.3C1,20.7,1,21.4,1.4,22c0.3,0.6,1,0.9,1.6,0.9h1.9v2.8
|
||||
c0,1.7,1.4,3.1,3.1,3.1h2.8v1.7c0,0.7,0,1.3,0,1.3l1.4,0v-4.3h-4c-1,0-1.9-0.8-1.9-1.9v-4H3.2c-0.5,0-0.8-0.5-0.6-1L6.2,14
|
||||
c-0.2-5,2.2-8,2.2-8c1.2-1.4,2.6-2.5,4.2-3.2c1.5-0.6,3.2-1,4.8-1c2,0,4,0.4,5.9,1.3c3.7,1.6,5.7,5.3,6,9.2c0.1,2.1-0.3,4.3-1.1,6.2
|
||||
c-0.4,1-0.9,1.9-1.5,2.8c-0.3,0.5-1.8,1.9-1.8,2.4c0,0,0,6,0,6.8l0,1.3c0.2,0,1.5,0,1.5,0s0-0.8,0-1.3c0,0,0-5.4,0-6.6
|
||||
c0.2-0.3,0.6-0.7,0.9-1c0.4-0.4,0.6-0.7,0.8-0.9c0.7-1,1.2-2,1.6-3.1C30.5,16.6,30.9,14.3,30.8,12z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 823 B |
5
webapp/assets/_new/icons/svgs/save.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>save</title>
|
||||
<path d="M5 5h17.406l0.313 0.281 4 4 0.281 0.313v17.406h-22v-22zM7 7v18h2v-9h14v9h2v-14.563l-3-3v5.563h-12v-6h-3zM12 7v4h8v-4h-2v2h-2v-2h-4zM11 18v7h10v-7h-10z"></path>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 327 B |
25
webapp/assets/_new/icons/svgs/science.svg
Normal file
@ -0,0 +1,25 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M28.4,16.1c1-1.7,1.9-3.3,2.5-4.9c1.5-4,1.3-7.3-0.6-9.2C27.5-0.8,22,0.1,16.1,3.7C10.3,0.1,4.7-0.8,2,1.9
|
||||
c-2.8,2.8-1.9,8.3,1.8,14.1c-3.3,5.3-4.4,10.4-2.5,13.4C1.5,29.7,1.7,30,2,30.2c1.1,1.1,2.6,1.6,4.4,1.6c1.4,0,3-0.3,4.8-1
|
||||
c1.6-0.6,3.2-1.4,4.9-2.5c2.6,1.6,5.1,2.7,7.4,3.2c0,0,0.1,0,0.1,0c0.3,0.1,0.7,0.1,1,0.2c0.1,0,0.1,0,0.2,0c0.4,0,0.7,0.1,1,0.1
|
||||
c0,0,0,0,0,0c0,0,0,0,0,0c0.3,0,0.5,0,0.8-0.1c0.2,0,0.4,0,0.5,0c0.3,0,0.6-0.1,0.9-0.2c0.1,0,0.2,0,0.3-0.1
|
||||
c0.3-0.1,0.5-0.2,0.8-0.4c0.1,0,0.2-0.1,0.3-0.1c0.3-0.2,0.6-0.4,0.9-0.7c1.9-1.9,2.1-5.2,0.6-9.2C30.3,19.4,29.5,17.7,28.4,16.1z
|
||||
M29.5,21.5c1.3,3.4,1.1,6.2-0.3,7.6c-0.2,0.2-0.4,0.3-0.6,0.5c-0.2,0.1-0.4,0.2-0.6,0.3c0,0-0.1,0-0.1,0.1
|
||||
c-0.3,0.1-0.5,0.2-0.8,0.2c0,0,0,0,0,0c-0.3,0.1-0.6,0.1-0.9,0.1c0,0,0,0,0,0c-0.3,0-0.6,0-0.8,0c-0.1,0-0.1,0-0.2,0
|
||||
c-0.2,0-0.5-0.1-0.7-0.1c-0.2,0-0.3,0-0.5-0.1c-0.1,0-0.3-0.1-0.4-0.1c-0.3-0.1-0.6-0.1-0.9-0.2c0,0-0.1,0-0.1,0
|
||||
c-1.5-0.5-3.2-1.3-4.9-2.3c1.9-1.3,3.7-2.8,5.4-4.6c1.7-1.7,3.3-3.6,4.6-5.5C28.3,18.8,29,20.2,29.5,21.5z M5.6,16.1
|
||||
c1.3-1.9,2.9-3.9,4.7-5.8c1.9-1.9,3.8-3.5,5.8-4.7c0,0,0,0,0.1,0c0.1,0.1,0.2,0.2,0.4,0.2c0.4,0.3,0.8,0.6,1.2,0.8c0,0,0,0,0.1,0.1
|
||||
c0.4,0.3,0.8,0.6,1.2,1c0.1,0.1,0.2,0.2,0.4,0.3c0.3,0.3,0.6,0.5,0.9,0.8c0.1,0.1,0.2,0.2,0.4,0.3c0.4,0.4,0.8,0.8,1.2,1.2
|
||||
c1.8,1.8,3.5,3.8,4.8,5.8c-1.3,2-2.9,3.9-4.8,5.8c-1.8,1.8-3.8,3.4-5.8,4.8c-1.9-1.3-3.9-2.9-5.8-4.8C8.5,20,6.9,18,5.6,16.1z
|
||||
M25.8,1.8c1.4,0,2.6,0.4,3.4,1.2c1.4,1.4,1.5,4.2,0.3,7.6c-0.5,1.3-1.2,2.7-2,4c-1.3-1.9-2.8-3.7-4.6-5.5
|
||||
c-1.8-1.8-3.6-3.3-5.4-4.6C20.6,2.8,23.5,1.8,25.8,1.8z M3,3c0.2-0.2,0.4-0.4,0.7-0.5C3.8,2.4,3.9,2.4,4,2.3
|
||||
c0.1-0.1,0.3-0.1,0.4-0.2C4.6,2.1,4.8,2,4.9,2c0.1,0,0.3-0.1,0.4-0.1c0.2,0,0.4,0,0.5,0c0.1,0,0.3,0,0.4,0c0.3,0,0.6,0,1,0.1
|
||||
c0.1,0,0.1,0,0.2,0C7.8,1.9,8.1,2,8.4,2c0.1,0,0.2,0,0.3,0.1c0.3,0.1,0.7,0.2,1,0.3c0,0,0.1,0,0.1,0c0.4,0.1,0.8,0.3,1.2,0.4
|
||||
c0.1,0,0.2,0.1,0.3,0.1c0.3,0.1,0.6,0.3,0.9,0.4c0.1,0,0.2,0.1,0.3,0.1c0.4,0.2,0.8,0.4,1.1,0.6c0,0,0.1,0,0.1,0
|
||||
c0.4,0.2,0.7,0.4,1.1,0.6c-1.8,1.3-3.7,2.8-5.4,4.6C7.5,11,6,12.8,4.7,14.7C1.8,9.7,0.9,5.1,3,3z M10.7,29.4
|
||||
c-3.4,1.3-6.2,1.1-7.6-0.3C0.9,27,1.8,22.4,4.7,17.5c1.3,1.8,2.8,3.7,4.6,5.4c0.4,0.4,0.9,0.8,1.3,1.2c0.1,0.1,0.2,0.2,0.3,0.3
|
||||
c0.4,0.3,0.8,0.7,1.1,1c0.1,0.1,0.1,0.1,0.2,0.2c0.8,0.7,1.7,1.3,2.5,1.9C13.4,28.3,12,28.9,10.7,29.4z"/>
|
||||
<path d="M19.4,19.3c1.8-1.8,1.8-4.8,0-6.6c-1.8-1.8-4.8-1.8-6.6,0c-1.8,1.8-1.8,4.8,0,6.6c0.9,0.9,2.1,1.4,3.3,1.4
|
||||
C17.3,20.7,18.5,20.3,19.4,19.3z M13.9,13.8c0.6-0.6,1.4-0.9,2.2-0.9s1.6,0.3,2.2,0.9c1.2,1.2,1.2,3.2,0,4.4s-3.2,1.2-4.4,0
|
||||
S12.7,15.1,13.9,13.8z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
13
webapp/assets/_new/icons/svgs/spirituality.svg
Normal file
@ -0,0 +1,13 @@
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="32px" height="32px" viewBox="0 0 32 32">
|
||||
<path d="M15.9,18.6c-1.4,0-2.7-0.5-3.7-1.5c-1.4-1.4-1.9-3.3-1.4-5.2c0.5-1.8,1.9-3.2,3.7-3.7c1.9-0.5,3.8,0,5.2,1.4
|
||||
c1.3,1.3,1.9,3.3,1.4,5.2c-0.5,1.8-1.9,3.2-3.7,3.7c0,0,0,0,0,0C16.9,18.5,16.4,18.6,15.9,18.6z M17.2,17.7L17.2,17.7
|
||||
L17.2,17.7z M15.9,9.5c-0.3,0-0.7,0-1,0.1c-1.2,0.3-2.3,1.4-2.6,2.6c-0.4,1.4,0,2.7,1,3.7s2.4,1.3,3.7,1
|
||||
c1.2-0.3,2.3-1.4,2.6-2.6c0.4-1.4,0-2.7-1-3.7C17.9,9.9,16.9,9.5,15.9,9.5z"/>
|
||||
<path d="M27.8,32H4v-2.2c0-5.5,4.4-9.9,9.9-9.9h4c5.5,0,9.9,4.4,9.9,9.9V32z M5.5,30.5h20.8v-0.7c0-4.6-3.8-8.4-8.4-8.4h-4
|
||||
c-4.6,0-8.4,3.8-8.4,8.4V30.5z"/>
|
||||
<rect x="15.6" y="0.5" width="1.5" height="4.3"/>
|
||||
<rect x="23.6" y="7.2" transform="matrix(0.8679 -0.4968 0.4968 0.8679 -0.5339 13.83)" width="4.3" height="1.5"/>
|
||||
<rect x="5.9" y="5.9" transform="matrix(0.4969 -0.8678 0.8678 0.4969 -3.6304 9.7958)" width="1.5" height="4.3"/>
|
||||
<rect x="9.4" y="1.8" transform="matrix(0.8207 -0.5714 0.5714 0.8207 -0.4488 6.4807)" width="1.5" height="4.3"/>
|
||||
<rect x="20.1" y="3.2" transform="matrix(0.5712 -0.8208 0.8208 0.5712 6.3227 19.9037)" width="4.3" height="1.5"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@ -17,6 +17,7 @@
|
||||
|
||||
<script>
|
||||
import CategoryQuery from '~/graphql/CategoryQuery'
|
||||
import { CATEGORIES_MAX } from '~/constants/categories.js'
|
||||
import xor from 'lodash/xor'
|
||||
|
||||
export default {
|
||||
@ -32,7 +33,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
categories: null,
|
||||
selectedMax: 3,
|
||||
selectedMax: CATEGORIES_MAX,
|
||||
selectedCategoryIds: this.existingCategoryIds,
|
||||
}
|
||||
},
|
||||
|
||||
@ -15,8 +15,19 @@ describe('CategoriesFilter.vue', () => {
|
||||
'posts/filteredCategoryIds': jest.fn(() => []),
|
||||
}
|
||||
|
||||
const apolloMutationMock = jest.fn().mockResolvedValue({
|
||||
data: { saveCategorySettings: true },
|
||||
})
|
||||
|
||||
const mocks = {
|
||||
$t: jest.fn((string) => string),
|
||||
$apollo: {
|
||||
mutate: apolloMutationMock,
|
||||
},
|
||||
$toast: {
|
||||
success: jest.fn(),
|
||||
error: jest.fn(),
|
||||
},
|
||||
}
|
||||
|
||||
const Wrapper = () => {
|
||||
@ -76,5 +87,14 @@ describe('CategoriesFilter.vue', () => {
|
||||
expect(mutations['posts/RESET_CATEGORIES']).toHaveBeenCalledTimes(1)
|
||||
})
|
||||
})
|
||||
|
||||
describe('save categories', () => {
|
||||
it('calls the API', async () => {
|
||||
wrapper = await Wrapper()
|
||||
const saveButton = wrapper.findAll('.categories-filter .sidebar .base-button').at(1)
|
||||
saveButton.trigger('click')
|
||||
expect(apolloMutationMock).toBeCalled()
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@ -7,6 +7,8 @@
|
||||
icon="check"
|
||||
@click="resetCategories"
|
||||
/>
|
||||
<hr />
|
||||
<labeled-button filled :label="$t('actions.save')" icon="save" @click="saveCategories" />
|
||||
</template>
|
||||
<template #filter-list>
|
||||
<li v-for="category in categories" :key="category.id" class="item">
|
||||
@ -24,6 +26,7 @@
|
||||
<script>
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
import CategoryQuery from '~/graphql/CategoryQuery.js'
|
||||
import SaveCategories from '~/graphql/SaveCategories.js'
|
||||
import FilterMenuSection from '~/components/FilterMenu/FilterMenuSection'
|
||||
import LabeledButton from '~/components/_new/generic/LabeledButton/LabeledButton'
|
||||
|
||||
@ -47,6 +50,19 @@ export default {
|
||||
resetCategories: 'posts/RESET_CATEGORIES',
|
||||
toggleCategory: 'posts/TOGGLE_CATEGORY',
|
||||
}),
|
||||
saveCategories() {
|
||||
this.$apollo
|
||||
.mutate({
|
||||
mutation: SaveCategories(),
|
||||
variables: { activeCategories: this.filteredCategoryIds },
|
||||
})
|
||||
.then(() => {
|
||||
this.$toast.success(this.$t('filter-menu.save.success'))
|
||||
})
|
||||
.catch(() => {
|
||||
this.$toast.error(this.$t('filter-menu.save.error'))
|
||||
})
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
Category: {
|
||||
|
||||
64
webapp/components/Group/GroupCard.vue
Normal file
@ -0,0 +1,64 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-container class="group-card">
|
||||
<ds-page-title heading="Groups"></ds-page-title>
|
||||
<ds-card v-for="item in items" :key="item.id" space="xx-small">
|
||||
<nuxt-link :to="`/group/${item.id}`">{{ item.name }}</nuxt-link>
|
||||
{{ item.categories ? item.categories.map((category) => category.name) : [] }}
|
||||
<div>{{ item }}</div>
|
||||
<ds-space>
|
||||
<base-button
|
||||
v-if="item.myRole === 'owner'"
|
||||
icon="trash"
|
||||
@click="deleteGroup(item)"
|
||||
></base-button>
|
||||
<base-button
|
||||
v-if="item.myRole === 'pending'"
|
||||
icon="question-circle"
|
||||
@click="removePending(item)"
|
||||
></base-button>
|
||||
<base-button
|
||||
v-if="item.myRole === 'owner'"
|
||||
icon="edit"
|
||||
@click="editGroup(item)"
|
||||
></base-button>
|
||||
<base-button
|
||||
v-if="item.myRole === 'usual'"
|
||||
icon="close"
|
||||
@click="unfollowGroup(item)"
|
||||
></base-button>
|
||||
<base-button
|
||||
v-if="item.myRole === null"
|
||||
icon="plus"
|
||||
@click="addMemeberToGroup(item)"
|
||||
></base-button>
|
||||
</ds-space>
|
||||
</ds-card>
|
||||
</ds-container>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'GroupList',
|
||||
props: {
|
||||
items: { type: Array, default: () => [] },
|
||||
},
|
||||
methods: {
|
||||
removePending() {
|
||||
alert('removePending group')
|
||||
},
|
||||
editGroup(item) {
|
||||
this.$router.push({ path: `/group/edit/${item.id}` })
|
||||
},
|
||||
deleteGroup() {
|
||||
alert('delete group')
|
||||
},
|
||||
unfollowGroup() {
|
||||
alert('unfollow group')
|
||||
},
|
||||
addMemeberToGroup() {
|
||||
alert('addMemeberToGroup group')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
150
webapp/components/Group/GroupForm.vue
Normal file
@ -0,0 +1,150 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-container>
|
||||
<ds-form
|
||||
class="group-form"
|
||||
ref="groupForm"
|
||||
v-model="formData"
|
||||
:schema="formSchema"
|
||||
@submit="submit"
|
||||
>
|
||||
<ds-input
|
||||
v-model="formData.name"
|
||||
label="Gruppenname"
|
||||
placeholder="Your name ..."
|
||||
></ds-input>
|
||||
|
||||
<ds-select
|
||||
icon="user"
|
||||
v-model="formData.groupType"
|
||||
label="Sichtbarkeit"
|
||||
:options="['public', 'closed', 'hidden']"
|
||||
placeholder="Status ..."
|
||||
></ds-select>
|
||||
|
||||
<ds-input v-model="formData.about" label="Kurzbeschreibung" rows="3"></ds-input>
|
||||
|
||||
<ds-input
|
||||
v-model="formData.description"
|
||||
label="Beschreibung"
|
||||
type="textarea"
|
||||
rows="3"
|
||||
></ds-input>
|
||||
|
||||
<ds-select
|
||||
icon="card"
|
||||
v-model="formData.actionRadius"
|
||||
label="Radius"
|
||||
:options="['regional', 'national', 'continental', 'global']"
|
||||
placeholder="Radius ..."
|
||||
></ds-select>
|
||||
<categories-select
|
||||
v-if="categoriesActive"
|
||||
model="categoryIds"
|
||||
:existingCategoryIds="formData.categoryIds"
|
||||
/>
|
||||
|
||||
<div>{{ formData }}</div>
|
||||
|
||||
<ds-space margin-top="large">
|
||||
<ds-button @click.prevent="reset()">Reset form</ds-button>
|
||||
<ds-button
|
||||
type="submit"
|
||||
@click.prevent="submit()"
|
||||
icon="save"
|
||||
:disabled="disabled"
|
||||
primary
|
||||
>
|
||||
{{ update ? $t('group.update') : $t('group.save') }}
|
||||
</ds-button>
|
||||
</ds-space>
|
||||
</ds-form>
|
||||
<ds-space centered v-show="!update">
|
||||
<nuxt-link to="/group/my-groups">zurück</nuxt-link>
|
||||
</ds-space>
|
||||
</ds-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CategoriesSelect from '~/components/CategoriesSelect/CategoriesSelect'
|
||||
import { CATEGORIES_MIN, CATEGORIES_MAX } from '~/constants/categories.js'
|
||||
import { NAME_LENGTH_MIN, NAME_LENGTH_MAX } from '~/constants/groups.js'
|
||||
|
||||
export default {
|
||||
name: 'GroupForm',
|
||||
components: {
|
||||
CategoriesSelect,
|
||||
},
|
||||
props: {
|
||||
update: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false,
|
||||
},
|
||||
group: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
data() {
|
||||
const { name, groupType, about, description, actionRadius, categories } = this.group
|
||||
return {
|
||||
categoriesActive: this.$env.CATEGORIES_ACTIVE,
|
||||
disabled: false,
|
||||
formData: {
|
||||
name: name || '',
|
||||
groupType: groupType || '',
|
||||
about: about || '',
|
||||
description: description || '',
|
||||
actionRadius: actionRadius || '',
|
||||
categoryIds: categories ? categories.map((category) => category.id) : [],
|
||||
},
|
||||
formSchema: {
|
||||
name: { required: true, min: NAME_LENGTH_MIN, max: NAME_LENGTH_MAX },
|
||||
groupType: { required: true },
|
||||
about: { required: true },
|
||||
description: { required: true },
|
||||
actionRadius: { required: true },
|
||||
categoryIds: {
|
||||
type: 'array',
|
||||
required: this.categoriesActive,
|
||||
validator: (_, value = []) => {
|
||||
if (
|
||||
this.categoriesActive &&
|
||||
(value.length < CATEGORIES_MIN || value.length > CATEGORIES_MAX)
|
||||
) {
|
||||
return [new Error(this.$t('common.validations.categories'))]
|
||||
}
|
||||
return []
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
submit() {
|
||||
const { name, about, description, groupType, actionRadius, categoryIds } = this.formData
|
||||
const variables = {
|
||||
name,
|
||||
about,
|
||||
description,
|
||||
groupType,
|
||||
actionRadius,
|
||||
categoryIds,
|
||||
}
|
||||
this.update
|
||||
? this.$emit('updateGroup', {
|
||||
...variables,
|
||||
id: this.group.id,
|
||||
})
|
||||
: this.$emit('createGroup', variables)
|
||||
},
|
||||
reset() {
|
||||
alert('reset')
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
15
webapp/components/Group/GroupLink.vue
Normal file
@ -0,0 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>
|
||||
<ds-space><h3>Link zur Gruppe</h3></ds-space>
|
||||
<ds-space>
|
||||
<ds-copy-field>Copy Link for Invite Member please!</ds-copy-field>
|
||||
</ds-space>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'GroupLink',
|
||||
}
|
||||
</script>
|
||||
56
webapp/components/Group/GroupMember.vue
Normal file
@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-space><h3>Members</h3></ds-space>
|
||||
<ds-table :data="GroupMembers" :fields="tableFields">
|
||||
<template slot="avatar">
|
||||
<ds-avatar online size="small" name="Hans Peter"></ds-avatar>
|
||||
</template>
|
||||
<template slot="loves" slot-scope="scope">
|
||||
{{ scope.row.name }} loves {{ scope.row.loves }}
|
||||
</template>
|
||||
<template slot="edit" slot-scope="scope">
|
||||
<ds-button size="small" @click="deleteRow(scope.row)">delete</ds-button>
|
||||
</template>
|
||||
</ds-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'GroupMember',
|
||||
data() {
|
||||
return {
|
||||
tableFields: ['avatar', 'name', 'type', 'loves', 'edit'],
|
||||
GroupMembers: [
|
||||
{
|
||||
name: 'Rengar',
|
||||
type: 'Jungler',
|
||||
loves: 'Hide and seek',
|
||||
},
|
||||
{
|
||||
name: 'Renekton',
|
||||
type: 'Toplaner',
|
||||
loves: 'Slice and dice',
|
||||
},
|
||||
{
|
||||
name: 'Twitch',
|
||||
type: 'ADC',
|
||||
loves: 'Spray and pray',
|
||||
},
|
||||
{
|
||||
name: 'Blitz',
|
||||
type: 'Support',
|
||||
loves: 'Hook you up',
|
||||
},
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
deleteRow(row) {
|
||||
const index = this.tableData.indexOf(row)
|
||||
if (index > -1) {
|
||||
this.tableData.splice(index, 1)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
27
webapp/components/Group/GroupTeaser.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<div class="group-teaser">
|
||||
<ds-grid-item :row-span="2" column-span="fullWidth">
|
||||
<ds-space centered>
|
||||
<nuxt-link :to="{ name: 'group-create' }">
|
||||
<base-button
|
||||
v-tooltip="{
|
||||
content: $t('group.newGroup'),
|
||||
placement: 'left',
|
||||
delay: { show: 500 },
|
||||
}"
|
||||
:path="{ name: 'group-create' }"
|
||||
class="profile-post-add-button"
|
||||
icon="plus"
|
||||
circle
|
||||
filled
|
||||
/>
|
||||
</nuxt-link>
|
||||
</ds-space>
|
||||
</ds-grid-item>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: 'GroupTeaser',
|
||||
}
|
||||
</script>
|
||||
@ -12,6 +12,8 @@ config.stubs['nuxt-link'] = '<span><slot /></span>'
|
||||
config.stubs['locale-switch'] = '<span><slot /></span>'
|
||||
config.stubs['client-only'] = '<span><slot /></span>'
|
||||
|
||||
const authUserMock = jest.fn().mockReturnValue({ activeCategories: [] })
|
||||
|
||||
describe('LoginForm', () => {
|
||||
let mocks
|
||||
let propsData
|
||||
@ -26,10 +28,15 @@ describe('LoginForm', () => {
|
||||
storeMocks = {
|
||||
getters: {
|
||||
'auth/pending': () => false,
|
||||
'auth/user': authUserMock,
|
||||
},
|
||||
actions: {
|
||||
'auth/login': jest.fn(),
|
||||
},
|
||||
mutations: {
|
||||
'posts/TOGGLE_CATEGORY': jest.fn(),
|
||||
'posts/RESET_CATEGORIES': jest.fn(),
|
||||
},
|
||||
}
|
||||
const store = new Vuex.Store(storeMocks)
|
||||
mocks = {
|
||||
@ -43,20 +50,46 @@ describe('LoginForm', () => {
|
||||
}
|
||||
|
||||
describe('fill in email and password and submit', () => {
|
||||
const fillIn = (wrapper, opts = {}) => {
|
||||
const fillIn = async (wrapper, opts = {}) => {
|
||||
const { email = 'email@example.org', password = '1234' } = opts
|
||||
wrapper.find('input[name="email"]').setValue(email)
|
||||
wrapper.find('input[name="password"]').setValue(password)
|
||||
wrapper.find('form').trigger('submit')
|
||||
await wrapper.find('form').trigger('submit')
|
||||
}
|
||||
|
||||
it('dispatches login with form data', () => {
|
||||
fillIn(Wrapper())
|
||||
it('dispatches login with form data', async () => {
|
||||
await fillIn(Wrapper())
|
||||
expect(storeMocks.actions['auth/login']).toHaveBeenCalledWith(expect.any(Object), {
|
||||
email: 'email@example.org',
|
||||
password: '1234',
|
||||
})
|
||||
})
|
||||
|
||||
describe('setting saved categories', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
describe('no categories saved', () => {
|
||||
it('resets the categories', async () => {
|
||||
await fillIn(Wrapper())
|
||||
expect(storeMocks.mutations['posts/RESET_CATEGORIES']).toBeCalled()
|
||||
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).not.toBeCalled()
|
||||
})
|
||||
})
|
||||
|
||||
describe('categories saved', () => {
|
||||
it('sets the categories', async () => {
|
||||
authUserMock.mockReturnValue({ activeCategories: ['cat1', 'cat9', 'cat12'] })
|
||||
await fillIn(Wrapper())
|
||||
expect(storeMocks.mutations['posts/RESET_CATEGORIES']).toBeCalled()
|
||||
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledTimes(3)
|
||||
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat1')
|
||||
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat9')
|
||||
expect(storeMocks.mutations['posts/TOGGLE_CATEGORY']).toBeCalledWith({}, 'cat12')
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Visibility of password', () => {
|
||||
|
||||
@ -58,6 +58,7 @@ import PageParamsLink from '~/components/_new/features/PageParamsLink/PageParams
|
||||
import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
||||
import Logo from '~/components/Logo/Logo'
|
||||
import ShowPassword from '../ShowPassword/ShowPassword.vue'
|
||||
import { mapGetters, mapMutations } from 'vuex'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@ -84,12 +85,27 @@ export default {
|
||||
iconName() {
|
||||
return this.showPassword ? 'eye-slash' : 'eye'
|
||||
},
|
||||
...mapGetters({
|
||||
currentUser: 'auth/user',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
...mapMutations({
|
||||
toggleCategory: 'posts/TOGGLE_CATEGORY',
|
||||
resetCategories: 'posts/RESET_CATEGORIES',
|
||||
}),
|
||||
async onSubmit() {
|
||||
const { email, password } = this.form
|
||||
try {
|
||||
await this.$store.dispatch('auth/login', { email, password })
|
||||
if (this.currentUser && this.currentUser.activeCategories) {
|
||||
this.resetCategories()
|
||||
if (this.currentUser.activeCategories.length > 0) {
|
||||
this.currentUser.activeCategories.forEach((categoryId) => {
|
||||
this.toggleCategory(categoryId)
|
||||
})
|
||||
}
|
||||
}
|
||||
this.$toast.success(this.$t('login.success'))
|
||||
this.$emit('success')
|
||||
} catch (err) {
|
||||
|
||||
@ -1,2 +1,4 @@
|
||||
// this file is duplicated in `backend/src/constants/group.js` and `webapp/constants/group.js`
|
||||
export const NAME_LENGTH_MIN = 3
|
||||
export const NAME_LENGTH_MAX = 50
|
||||
export const DESCRIPTION_WITHOUT_HTML_LENGTH_MIN = 100 // with removed HTML tags
|
||||
|
||||
9
webapp/graphql/SaveCategories.js
Normal file
@ -0,0 +1,9 @@
|
||||
import gql from 'graphql-tag'
|
||||
|
||||
export default () => {
|
||||
return gql`
|
||||
mutation ($activeCategories: [String]) {
|
||||
saveCategorySettings(activeCategories: $activeCategories)
|
||||
}
|
||||
`
|
||||
}
|
||||
@ -285,6 +285,7 @@ export const currentUserQuery = gql`
|
||||
id
|
||||
url
|
||||
}
|
||||
activeCategories
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
@ -364,7 +364,11 @@
|
||||
"label": "Älteste zuerst"
|
||||
}
|
||||
},
|
||||
"order-by": "Sortieren nach ..."
|
||||
"order-by": "Sortieren nach ...",
|
||||
"save": {
|
||||
"error": "Themen konnten nicht gespeichert werden!",
|
||||
"success": "Themen gespeichert!"
|
||||
}
|
||||
},
|
||||
"followButton": {
|
||||
"follow": "Folgen",
|
||||
@ -381,6 +385,8 @@
|
||||
"actionRadius": "Aktionsradius",
|
||||
"foundation": "Gründung",
|
||||
"goal": "Ziel der Gruppe",
|
||||
"group-created": "Die Gruppe wurde angelegt!",
|
||||
"group-updated": "Die Gruppendaten wurden geändert!",
|
||||
"joinLeaveButton": {
|
||||
"iAmMember": "Bin Mitglied",
|
||||
"join": "Beitreten"
|
||||
@ -392,6 +398,7 @@
|
||||
},
|
||||
"membersCount": "Mitglieder",
|
||||
"membersListTitle": "Gruppenmitglieder",
|
||||
"newGroup": "Erstelle eine neue Gruppe",
|
||||
"role": "Deine Rolle in der Gruppe",
|
||||
"roles": {
|
||||
"admin": "Administrator",
|
||||
@ -399,12 +406,14 @@
|
||||
"pending": "Ausstehendes Mitglied",
|
||||
"usual": "Einfaches Mitglied"
|
||||
},
|
||||
"save": "Neue Gruppe anlegen",
|
||||
"type": "Gruppentyp",
|
||||
"types": {
|
||||
"closed": "Geschlossene Gruppe",
|
||||
"hidden": "Versteckte Gruppe",
|
||||
"public": "Öffentliche Gruppe"
|
||||
}
|
||||
},
|
||||
"update": "Änderung speichern"
|
||||
},
|
||||
"hashtags-filter": {
|
||||
"clearSearch": "Suche löschen",
|
||||
@ -781,6 +790,7 @@
|
||||
"unmute": "Stummschaltung aufheben",
|
||||
"unmuted": "{name} ist nicht mehr stummgeschaltet"
|
||||
},
|
||||
"myGroups": "Meine Gruppen",
|
||||
"name": "Einstellungen",
|
||||
"notifications": {
|
||||
"name": "Benachrichtigungen",
|
||||
|
||||
@ -364,7 +364,11 @@
|
||||
"label": "Oldest first"
|
||||
}
|
||||
},
|
||||
"order-by": "Order by ..."
|
||||
"order-by": "Order by ...",
|
||||
"save": {
|
||||
"error": "Failed saving topic settings!",
|
||||
"success": "Topics saved!"
|
||||
}
|
||||
},
|
||||
"followButton": {
|
||||
"follow": "Follow",
|
||||
@ -381,6 +385,8 @@
|
||||
"actionRadius": "Action radius",
|
||||
"foundation": "Foundation",
|
||||
"goal": "Goal of group",
|
||||
"group-created": "The group was created!",
|
||||
"group-updated": "The group data has been changed.",
|
||||
"joinLeaveButton": {
|
||||
"iAmMember": "I'm a member",
|
||||
"join": "Join"
|
||||
@ -392,6 +398,7 @@
|
||||
},
|
||||
"membersCount": "Members",
|
||||
"membersListTitle": "Group Members",
|
||||
"newGroup": "Create a new Group",
|
||||
"role": "Your role in the group",
|
||||
"roles": {
|
||||
"admin": "Administrator",
|
||||
@ -399,12 +406,14 @@
|
||||
"pending": "Pending Member",
|
||||
"usual": "Simple Member"
|
||||
},
|
||||
"save": "Create new group",
|
||||
"type": "Group type",
|
||||
"types": {
|
||||
"closed": "Closed Group",
|
||||
"hidden": "Hidden Group",
|
||||
"public": "Public Group"
|
||||
}
|
||||
},
|
||||
"update": "Save change"
|
||||
},
|
||||
"hashtags-filter": {
|
||||
"clearSearch": "Clear search",
|
||||
@ -781,6 +790,7 @@
|
||||
"unmute": "Unmute user",
|
||||
"unmuted": "{name} is unmuted again"
|
||||
},
|
||||
"myGroups": "My Groups",
|
||||
"name": "Settings",
|
||||
"notifications": {
|
||||
"name": "Notifications",
|
||||
|
||||
46
webapp/pages/group/create.vue
Normal file
@ -0,0 +1,46 @@
|
||||
<template>
|
||||
<div>
|
||||
<h2>Create Groupe</h2>
|
||||
<ds-flex :width="{ base: '100%' }" gutter="base">
|
||||
<ds-flex-item :width="{ base: '100%', md: 5 }">
|
||||
<group-form @createGroup="createGroup" />
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', md: 1 }"> </ds-flex-item>
|
||||
</ds-flex>
|
||||
<hr />
|
||||
<group-member />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GroupForm from '~/components/Group/GroupForm'
|
||||
import GroupMember from '~/components/Group/GroupMember'
|
||||
import { createGroupMutation } from '~/graphql/groups.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GroupForm,
|
||||
GroupMember,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
createGroupData: {},
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async createGroup(value) {
|
||||
const { name, about, description, groupType, actionRadius, categoryIds } = value
|
||||
const variables = { name, about, description, groupType, actionRadius, categoryIds }
|
||||
try {
|
||||
await this.$apollo.mutate({
|
||||
mutation: createGroupMutation,
|
||||
variables,
|
||||
})
|
||||
this.$toast.success(this.$t('group.group-created'))
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
63
webapp/pages/group/edit/_id.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-page-title heading="Group Setting"></ds-page-title>
|
||||
<ds-flex gutter="small">
|
||||
<ds-flex-item :width="{ base: '100%', md: '200px' }">
|
||||
<ds-menu :routes="routes" :is-exact="() => true" />
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', md: 1 }">
|
||||
<transition name="slide-up" appear>
|
||||
<nuxt-child :group="group" />
|
||||
</transition>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
<ds-space centered>
|
||||
<nuxt-link to="/group/my-groups">zurück</nuxt-link>
|
||||
</ds-space>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { groupQuery } from '~/graphql/groups.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
...mapGetters({
|
||||
user: 'auth/user',
|
||||
}),
|
||||
routes() {
|
||||
return [
|
||||
{
|
||||
name: 'General',
|
||||
path: `/group/edit/${this.group.id}`,
|
||||
},
|
||||
{
|
||||
name: 'Members',
|
||||
path: `/group/edit/${this.group.id}/members`,
|
||||
},
|
||||
]
|
||||
},
|
||||
},
|
||||
async asyncData(context) {
|
||||
const {
|
||||
app,
|
||||
error,
|
||||
params: { id },
|
||||
} = context
|
||||
const client = app.apolloProvider.defaultClient
|
||||
const {
|
||||
data: {
|
||||
Group: [group],
|
||||
},
|
||||
} = await client.query({
|
||||
query: groupQuery,
|
||||
variables: { id },
|
||||
})
|
||||
if (group.myRole !== 'owner') {
|
||||
error({ statusCode: 403, message: 'NONONNNO' })
|
||||
}
|
||||
return { group }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
40
webapp/pages/group/edit/_id/index.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-container>
|
||||
<group-form :group="group" :update="true" @updateGroup="updateGroup" />
|
||||
</ds-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GroupForm from '~/components/Group/GroupForm'
|
||||
import { updateGroupMutation } from '~/graphql/groups.js'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
GroupForm,
|
||||
},
|
||||
props: {
|
||||
group: {
|
||||
type: Object,
|
||||
required: false,
|
||||
default: () => ({}),
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async updateGroup(value) {
|
||||
const { id, name, about, description, groupType, actionRadius, categoryIds } = value
|
||||
const variables = { id, name, about, description, groupType, actionRadius, categoryIds }
|
||||
try {
|
||||
await this.$apollo.mutate({
|
||||
mutation: updateGroupMutation,
|
||||
variables,
|
||||
})
|
||||
this.$toast.success(this.$t('group.group-updated'))
|
||||
} catch (error) {
|
||||
this.$toast.error(error.message)
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
16
webapp/pages/group/edit/_id/members.vue
Normal file
@ -0,0 +1,16 @@
|
||||
<template>
|
||||
<div>
|
||||
<ds-container>
|
||||
<group-member />
|
||||
</ds-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import GroupMember from '~/components/Group/GroupMember'
|
||||
export default {
|
||||
components: {
|
||||
GroupMember,
|
||||
},
|
||||
}
|
||||
</script>
|
||||
44
webapp/pages/my-groups.vue
Normal file
@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>my groups</div>
|
||||
<group-teaser />
|
||||
<br />
|
||||
<br />
|
||||
<group-card :items="responseGroupListQuery" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import GroupTeaser from '~/components/Group/GroupTeaser.vue'
|
||||
import GroupCard from '~/components/Group/GroupCard.vue'
|
||||
import { groupQuery } from '~/graphql/groups.js'
|
||||
|
||||
export default {
|
||||
name: 'MyGroups',
|
||||
components: {
|
||||
GroupTeaser,
|
||||
GroupCard,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
responseGroupListQuery: [],
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async groupListQuery() {
|
||||
try {
|
||||
const response = await this.$apollo.query({
|
||||
query: groupQuery,
|
||||
})
|
||||
this.responseGroupListQuery = response.data.Group
|
||||
} catch (error) {
|
||||
this.responseGroupListQuery = []
|
||||
} finally {
|
||||
this.pending = false
|
||||
}
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.groupListQuery()
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@ -39,6 +39,10 @@ export default {
|
||||
name: this.$t('settings.social-media.name'),
|
||||
path: `/settings/my-social-media`,
|
||||
},
|
||||
{
|
||||
name: this.$t('settings.myGroups'),
|
||||
path: `/my-groups`,
|
||||
},
|
||||
{
|
||||
name: this.$t('settings.muted-users.name'),
|
||||
path: `/settings/muted-users`,
|
||||
|
||||