mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2025-12-12 23:35:58 +00:00
Extract component, start story, styling (wip)
This commit is contained in:
parent
627b47837e
commit
6d83299e75
@ -0,0 +1,148 @@
|
||||
import { storiesOf } from '@storybook/vue'
|
||||
import { withA11y } from '@storybook/addon-a11y'
|
||||
import SearchResults from './SearchResults'
|
||||
import TabNavigation from '~/components/_new/generic/TabNavigation/TabNavigation'
|
||||
import PostTeaser from '~/components/PostTeaser/PostTeaser'
|
||||
import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
||||
import helpers from '~/storybook/helpers'
|
||||
import faker from 'faker'
|
||||
import { post } from '~/components/PostTeaser/PostTeaser.story.js'
|
||||
import { user } from '~/components/UserTeaser/UserTeaser.story.js'
|
||||
|
||||
helpers.init()
|
||||
|
||||
const postMock = fields => {
|
||||
return {
|
||||
...post,
|
||||
id: faker.random.uuid(),
|
||||
createdAt: faker.date.past(),
|
||||
updatedAt: faker.date.recent(),
|
||||
deleted: false,
|
||||
disabled: false,
|
||||
typename: 'Post',
|
||||
...fields,
|
||||
}
|
||||
}
|
||||
|
||||
const userMock = fields => {
|
||||
return {
|
||||
...user,
|
||||
id: faker.random.uuid(),
|
||||
createdAt: faker.date.past(),
|
||||
updatedAt: faker.date.recent(),
|
||||
deleted: false,
|
||||
disabled: false,
|
||||
typename: 'User',
|
||||
...fields,
|
||||
}
|
||||
}
|
||||
|
||||
const posts = [
|
||||
postMock(),
|
||||
postMock({ author: user }),
|
||||
postMock({ title: faker.lorem.sentence() }),
|
||||
postMock({ contentExcerpt: faker.lorem.paragraph() }),
|
||||
postMock({ author: user }),
|
||||
postMock({ title: faker.lorem.sentence() }),
|
||||
postMock({ author: user }),
|
||||
]
|
||||
|
||||
const users = [
|
||||
userMock(),
|
||||
userMock({ slug: 'louie-rider', name: 'Louie Rider' }),
|
||||
userMock({ slug: 'louicinda-johnson', name: 'Louicinda Jonhson' }),
|
||||
userMock({ slug: 'sam-louie', name: 'Sam Louie' }),
|
||||
userMock({ slug: 'loucette', name: 'Loucette Rider' }),
|
||||
userMock({ slug: 'louis', name: 'Louis' }),
|
||||
userMock({ slug: 'louanna', name: 'Louanna' }),
|
||||
]
|
||||
|
||||
storiesOf('SearchResults', module)
|
||||
.addDecorator(withA11y)
|
||||
.addDecorator(helpers.layout)
|
||||
.add('given users', () => ({
|
||||
components: { TabNavigation, PostTeaser, UserTeaser },
|
||||
store: helpers.store,
|
||||
data: () => ({
|
||||
searchResults: users,
|
||||
activeTab: 'users',
|
||||
}),
|
||||
computed: {
|
||||
posts() {
|
||||
return []
|
||||
},
|
||||
users() {
|
||||
return this.searchResults
|
||||
},
|
||||
activeResources() {
|
||||
if (this.activeTab === 'posts') return this.posts
|
||||
else if (this.activeTab === 'users') return this.users
|
||||
},
|
||||
tabOptions() {
|
||||
return [
|
||||
{ type: 'posts', title: `0 Posts` },
|
||||
{ type: 'users', title: `${users.length} Users` },
|
||||
]
|
||||
},
|
||||
},
|
||||
template: `<div class="search-results">
|
||||
<tab-navigation
|
||||
:tabs="tabOptions"
|
||||
:activeTab="activeTab"
|
||||
@switchTab="tab => activeTab = tab"
|
||||
/>
|
||||
<section>
|
||||
<ul v-if="activeResources.length">
|
||||
<li v-for="resource in activeResources" :key="resource.key" class="list">
|
||||
<post-teaser v-if="activeTab === 'posts'" :post="resource" />
|
||||
<base-card v-else-if="activeTab === 'users'" :wideContent="true">
|
||||
<user-teaser :user="resource" />
|
||||
</base-card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>`,
|
||||
}))
|
||||
.add('given posts', () => ({
|
||||
components: { TabNavigation, PostTeaser, UserTeaser, SearchResults },
|
||||
store: helpers.store,
|
||||
data: () => ({
|
||||
searchResults: posts,
|
||||
activeTab: 'posts',
|
||||
}),
|
||||
computed: {
|
||||
posts() {
|
||||
return this.searchResults
|
||||
},
|
||||
users() {
|
||||
return []
|
||||
},
|
||||
activeResources() {
|
||||
if (this.activeTab === 'posts') return this.posts
|
||||
else if (this.activeTab === 'users') return this.users
|
||||
},
|
||||
tabOptions() {
|
||||
return [
|
||||
{ type: 'posts', title: `${posts.length} Posts` },
|
||||
{ type: 'users', title: `0 Users` },
|
||||
]
|
||||
},
|
||||
},
|
||||
template: `<div class="search-results">
|
||||
<tab-navigation
|
||||
:tabs="tabOptions"
|
||||
:activeTab="activeTab"
|
||||
@switchTab="tab => activeTab = tab"
|
||||
/>
|
||||
<section>
|
||||
<ul v-if="activeResources.length">
|
||||
<li v-for="resource in activeResources" :key="resource.key" class="list">
|
||||
<post-teaser v-if="activeTab === 'posts'" :post="resource" />
|
||||
<base-card v-else-if="activeTab === 'users'" :wideContent="true">
|
||||
<user-teaser :user="resource" />
|
||||
</base-card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>`,
|
||||
}))
|
||||
@ -0,0 +1,88 @@
|
||||
<template>
|
||||
<div class="search-results">
|
||||
<tab-navigation :tabs="tabOptions" :activeTab="activeTab" @switchTab="switchTab" />
|
||||
<section>
|
||||
<ul v-if="activeResources.length">
|
||||
<li v-for="resource in activeResources" :key="resource.key" class="list">
|
||||
<post-teaser v-if="activeTab === 'posts'" :post="resource" />
|
||||
<base-card v-else-if="activeTab === 'users'" :wideContent="true">
|
||||
<user-teaser :user="resource" />
|
||||
</base-card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { searchQuery } from '~/graphql/Search.js'
|
||||
import TabNavigation from '~/components/_new/generic/TabNavigation/TabNavigation'
|
||||
import PostTeaser from '~/components/PostTeaser/PostTeaser'
|
||||
import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TabNavigation,
|
||||
PostTeaser,
|
||||
UserTeaser,
|
||||
},
|
||||
props: {
|
||||
search: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
searchResults: [],
|
||||
activeTab: 'posts',
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
posts() {
|
||||
return this.searchResults.filter(result => result.__typename === 'Post')
|
||||
},
|
||||
users() {
|
||||
return this.searchResults.filter(result => result.__typename === 'User')
|
||||
},
|
||||
activeResources() {
|
||||
if (this.activeTab === 'posts') return this.posts
|
||||
else if (this.activeTab === 'users') return this.users
|
||||
},
|
||||
tabOptions() {
|
||||
return [
|
||||
{ type: 'posts', title: `${this.posts.length} Posts` },
|
||||
{ type: 'users', title: `${this.users.length} Users` },
|
||||
]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
switchTab(tab) {
|
||||
this.activeTab = tab
|
||||
},
|
||||
},
|
||||
apollo: {
|
||||
searchResults: {
|
||||
query() {
|
||||
return searchQuery
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
query: this.search,
|
||||
limit: 37,
|
||||
}
|
||||
},
|
||||
skip() {
|
||||
return !this.search
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.search-results {
|
||||
width: 40%;
|
||||
}
|
||||
.search-results .list {
|
||||
margin: $space-xxx-small 0 $space-small 0;
|
||||
}
|
||||
</style>
|
||||
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<ul class="tabs">
|
||||
<li v-for="tab in tabs" :key="tab.type" class="tab">
|
||||
<button @click="$emit('openTab', tab.type)">
|
||||
<button :class="{ '--active': activeTab === tab.type }" @click="$emit('switchTab', tab.type)">
|
||||
{{ tab.title }}
|
||||
</button>
|
||||
</li>
|
||||
@ -14,7 +14,34 @@ export default {
|
||||
tabs: {
|
||||
type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
activeTab: {
|
||||
type: String,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
<style lang="scss">
|
||||
.tabs {
|
||||
overflow: hidden;
|
||||
|
||||
> .tab {
|
||||
display: inline-block;
|
||||
color: darkgrey;
|
||||
margin: $space-small;
|
||||
|
||||
> button {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
color: #555;
|
||||
padding: 20px;
|
||||
border-radius: 5px 5px 0 0;
|
||||
border-right: 1px solid #ccc;
|
||||
}
|
||||
|
||||
.--active {
|
||||
background: $background-color-softer-active;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { findResourcesQuery } from '~/graphql/Search.js'
|
||||
import { searchQuery } from '~/graphql/Search.js'
|
||||
import SearchableInput from '~/components/generic/SearchableInput/SearchableInput.vue'
|
||||
|
||||
export default {
|
||||
@ -28,14 +28,14 @@ export default {
|
||||
this.pending = true
|
||||
try {
|
||||
const {
|
||||
data: { findResources },
|
||||
data: { searchResults },
|
||||
} = await this.$apollo.query({
|
||||
query: findResourcesQuery,
|
||||
query: searchQuery,
|
||||
variables: {
|
||||
query: value,
|
||||
},
|
||||
})
|
||||
this.searchResults = findResources
|
||||
this.searchResults = searchResults
|
||||
} catch (error) {
|
||||
this.searchResults = []
|
||||
} finally {
|
||||
|
||||
@ -102,7 +102,7 @@ export default {
|
||||
onEnter(event) {
|
||||
this.$router.push({
|
||||
path: '/search/search-results',
|
||||
query: { item: this.unprocessedSearchInput },
|
||||
query: { search: this.unprocessedSearchInput },
|
||||
})
|
||||
},
|
||||
onDelete(event) {
|
||||
|
||||
@ -1,91 +1,24 @@
|
||||
<template>
|
||||
<div class="search-results">
|
||||
|
||||
<tab-navigation
|
||||
:tabs="tabOptions"
|
||||
@openTab="switchTab"
|
||||
/>
|
||||
<section>
|
||||
<ul v-if="activeResources.length">
|
||||
<li v-for="resource in activeResources" :key="resource.key">
|
||||
<post-teaser v-if="activeTab === 'posts'" :post="resource" />
|
||||
<base-card v-else-if="activeTab === 'users'" :wideContent="true">
|
||||
<user-teaser :user="resource" />
|
||||
</base-card>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
</div>
|
||||
<search-results :search="search" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { findResourcesQuery } from '~/graphql/Search.js'
|
||||
import FilterMenu from '~/components/FilterMenu/FilterMenu'
|
||||
import TabNavigation from '~/components/_new/generic/TabNavigation/TabNavigation'
|
||||
import PostTeaser from '~/components/PostTeaser/PostTeaser'
|
||||
import UserTeaser from '~/components/UserTeaser/UserTeaser'
|
||||
import SearchResults from '~/components/_new/features/SearchResults/SearchResults'
|
||||
|
||||
export default {
|
||||
layout: 'default',
|
||||
watchQuery: ['search'],
|
||||
head() {
|
||||
return {
|
||||
title: 'SearchResults',
|
||||
}
|
||||
},
|
||||
components: {
|
||||
FilterMenu,
|
||||
TabNavigation,
|
||||
PostTeaser,
|
||||
UserTeaser,
|
||||
SearchResults,
|
||||
},
|
||||
data() {
|
||||
const { item = null } = this.$route.query
|
||||
console.log('data', item)
|
||||
return {
|
||||
loading: true,
|
||||
value: '',
|
||||
pending: false,
|
||||
findResources: [],
|
||||
activeTab : 'posts',
|
||||
item,
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
posts() {
|
||||
return this.findResources.filter(result => result.__typename === 'Post')
|
||||
},
|
||||
users() {
|
||||
return this.findResources.filter(result => result.__typename === 'User')
|
||||
},
|
||||
activeResources() {
|
||||
if (this.activeTab === 'posts') return this.posts
|
||||
else if (this.activeTab === 'users') return this.users
|
||||
},
|
||||
tabOptions() {
|
||||
return [
|
||||
{ type: 'posts', title: `${this.posts.length} Posts` },
|
||||
{ type: 'users', title: `${this.users.length} Users` },
|
||||
]
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
switchTab(tab) {
|
||||
this.activeTab = tab
|
||||
}
|
||||
},
|
||||
apollo: {
|
||||
findResources: {
|
||||
query() {
|
||||
return findResourcesQuery
|
||||
},
|
||||
variables() {
|
||||
return {
|
||||
query: this.item,
|
||||
limit: 37
|
||||
}
|
||||
},
|
||||
fetchPolicy: 'cache-and-network',
|
||||
},
|
||||
asyncData(context) {
|
||||
const { search = null } = context.query
|
||||
return { search }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user