✨ Add search page and show search results
This commit is contained in:
committed by
Kevin
parent
fe81ffcf9e
commit
23d97f00b1
@@ -10,25 +10,32 @@ export default {
|
|||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
searchInput: '',
|
searchInput: '',
|
||||||
|
searchPath: '/search',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
methods: {
|
||||||
|
// isTag :: String -> Bool
|
||||||
|
isTag: R.startsWith('#'),
|
||||||
|
|
||||||
|
// removeFirstChar :: String -> String
|
||||||
|
removeFirstChar: R.compose(
|
||||||
|
R.join(''),
|
||||||
|
R.adjust(0, () => '')
|
||||||
|
),
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
searchInput(input) {
|
searchInput(input) {
|
||||||
const isTag = R.startsWith('#')
|
|
||||||
const removeFirstChar = R.compose(
|
|
||||||
R.join(''),
|
|
||||||
R.adjust(0, () => '')
|
|
||||||
)
|
|
||||||
|
|
||||||
const words = R.filter(isNotEmpty, R.split(' ', input))
|
const words = R.filter(isNotEmpty, R.split(' ', input))
|
||||||
const tags = R.filter(isTag, words)
|
const tags = R.filter(this.isTag, words)
|
||||||
const titles = R.filter(R.compose(R.not, isTag), words)
|
const titles = R.filter(R.compose(R.not, this.isTag), words)
|
||||||
console.group()
|
|
||||||
console.log('words:', titles)
|
const searchParams = new URLSearchParams()
|
||||||
console.log('tags:', tags)
|
if (isNotEmpty(titles))
|
||||||
console.log('returned by words search:', this.$store.getters['data/findByName'](titles))
|
searchParams.append('keywords', titles)
|
||||||
console.log('returned by tags search:', this.$store.getters['data/findByTags'](R.map(removeFirstChar, tags)))
|
if (isNotEmpty(tags))
|
||||||
console.groupEnd()
|
searchParams.append('tags', R.map(this.removeFirstChar, tags))
|
||||||
|
|
||||||
|
this.$router.push(this.searchPath + '?' + searchParams.toString())
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
81
pages/search.vue
Normal file
81
pages/search.vue
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
<template lang="pug">
|
||||||
|
div
|
||||||
|
transition(name="fade-title" @after-enter="afterEnter")
|
||||||
|
h1(v-if="showTitle") Search
|
||||||
|
transition(name="fade-card")
|
||||||
|
.cards(v-if="areCardsVisible && showCards")
|
||||||
|
template(v-for='resource in resources' )
|
||||||
|
Card(:resource='resource' :key='resource.title' :createCopyUrl="createCopyUrl" :isActive='activeCard === resource.cleanTitle')
|
||||||
|
transition(name="fade-card")
|
||||||
|
table(v-if="!areCardsVisible && showCards")
|
||||||
|
template(v-for='resource in resources' )
|
||||||
|
TableRow(:resource='resource' :key='resource.title' :createCopyUrl="createCopyUrl" :isActive='activeCard === resource.cleanTitle')
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Card from '../components/Card'
|
||||||
|
import TableRow from '../components/TableRow'
|
||||||
|
import * as R from 'ramda'
|
||||||
|
// import { removeFirstChar } from '../utils/pure'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Card, TableRow },
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
activeCard: '',
|
||||||
|
resources: [],
|
||||||
|
searchInput: {},
|
||||||
|
tags: [],
|
||||||
|
showTitle: false,
|
||||||
|
showCards: false,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
areCardsVisible() {
|
||||||
|
return this.$store.getters['Sidebar/areCardsVisible']
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(updatedChanges) {
|
||||||
|
const keywords = updatedChanges.query.keywords
|
||||||
|
const tags = updatedChanges.query.tags
|
||||||
|
const newSearchInput = {
|
||||||
|
keywords: keywords && R.split(',', keywords),
|
||||||
|
tags: tags && R.split(',', tags),
|
||||||
|
}
|
||||||
|
this.searchInput = newSearchInput
|
||||||
|
},
|
||||||
|
searchInput(searchInput) {
|
||||||
|
let resources = []
|
||||||
|
if (searchInput.keywords)
|
||||||
|
resources = resources.concat(this.$store.getters['data/findByName'](searchInput.keywords))
|
||||||
|
if (searchInput.tags)
|
||||||
|
resources = resources.concat(this.$store.getters['data/findByTags'](searchInput.tags))
|
||||||
|
this.resources = resources
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.showTitle = true
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async createCopyUrl(resource) {
|
||||||
|
try {
|
||||||
|
const { path } = resource
|
||||||
|
await this.$copyText(`https://webgems.io${path}`)
|
||||||
|
} catch (e) {
|
||||||
|
console.error(e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
afterEnter() {
|
||||||
|
this.showCards = true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
table {
|
||||||
|
width: 100%;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -32,12 +32,6 @@
|
|||||||
"url": "https://javascript.info/",
|
"url": "https://javascript.info/",
|
||||||
"tags": ["tutorial", "explanations", "basics", "advanced"]
|
"tags": ["tutorial", "explanations", "basics", "advanced"]
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"title": "30 Seconds of Code",
|
|
||||||
"desc": "A curated collection of useful JavaScript snippets that you can understand in 30 seconds or less.",
|
|
||||||
"url": "https://30secondsofcode.org",
|
|
||||||
"tags": ["resources", "educational", "short", "beginner"]
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"title": "JS Tips",
|
"title": "JS Tips",
|
||||||
"desc": "JS Tips is a collection of useful daily JavaScript tips that will allow you to improve your code writing.",
|
"desc": "JS Tips is a collection of useful daily JavaScript tips that will allow you to improve your code writing.",
|
||||||
|
|||||||
Reference in New Issue
Block a user