feat: even more site functionality
This commit is contained in:
@@ -1,14 +1,61 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||||
<title>Strain Search</title>
|
<title>Strain Search</title>
|
||||||
</head>
|
<style>
|
||||||
|
.tag:not(body).is-indica {
|
||||||
|
background-color: hsl(217, 71%, 53%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
<body>
|
.tag:not(body).is-sativa {
|
||||||
|
background-color: hsl(348, 100%, 61%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tag:not(body).is-hybrid {
|
||||||
|
background-color: hsl(271, 100%, 71%);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
#strain-list .cards {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
#strain-list .cards .card {
|
||||||
|
width: 100%;
|
||||||
|
margin: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 769px) {
|
||||||
|
#strain-list .cards .card {
|
||||||
|
width: 45%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 1280px) {
|
||||||
|
#strain-list .cards .card {
|
||||||
|
width: 30%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-form .filters .select {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
#search-form .filters .select select[multiple] {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
<noscript><h1>You're going to want to enable JavaScript</h1></noscript>
|
<noscript><h1>You're going to want to enable JavaScript</h1></noscript>
|
||||||
|
|
||||||
<section class="section">
|
<section class="section">
|
||||||
@@ -27,29 +74,25 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Multi-Selects -->
|
<!-- Multi-Selects -->
|
||||||
<div class="columns">
|
<div class="columns filters">
|
||||||
<div class="column">
|
<div class="column is-half">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
<div class="column">
|
<div class="column is-half">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Desired Effects</label>
|
<label class="label">Desired Effects</label>
|
||||||
<div class="select is-multiple">
|
<div class="select is-multiple">
|
||||||
<select ref="effects" multiple size="6">
|
<select ref="effects" multiple size="6">
|
||||||
<option value="Happy">Happy</option>
|
<option v-for="effect in effects" :value="effect">{{effect | capitalize}}</option>
|
||||||
<option value="Euphoric">Euphoric</option>
|
|
||||||
<option value="Sleepy">Sleepy</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="column">
|
<div class="column is-half">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Medical Use</label>
|
<label class="label">Medical Use</label>
|
||||||
<div class="select is-multiple">
|
<div class="select is-multiple">
|
||||||
<select ref="uses" multiple size="6">
|
<select ref="uses" multiple size="6">
|
||||||
<option value="Pain">Pain</option>
|
<option v-for="use in uses" :value="use">{{use | capitalize}}</option>
|
||||||
<option value="Depression">Depression</option>
|
|
||||||
<option value="Insomnia">Insomnia</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -57,26 +100,25 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column is-half">
|
||||||
<div class="columns is-mobile">
|
<div class="columns is-mobile">
|
||||||
<div class="column">
|
<div class="column is-half">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Condition</label>
|
<label class="label">Condition</label>
|
||||||
<div class="select is-multiple">
|
<div class="select is-multiple">
|
||||||
<select ref="conditions" multiple size="6">
|
<select ref="conditions" multiple size="6">
|
||||||
<option value="PTSD">PTSD</option>
|
<option v-for="condition in conditions" :value="condition">{{condition | capitalize}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="column">
|
<div class="column is-half">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label">Flavor</label>
|
<label class="label">Flavor</label>
|
||||||
<div class="select is-multiple">
|
<div class="select is-multiple">
|
||||||
<select ref="flavors" multiple size="6">
|
<select ref="flavors" multiple size="6">
|
||||||
<option value="Sweet">Sweet</option>
|
<option v-for="flavor in flavors" :value="flavor">{{flavor | capitalize}}</option>
|
||||||
<option value="Woody">Woody</option>
|
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -98,8 +140,26 @@
|
|||||||
</form>
|
</form>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="section">
|
<section class="section" id="strain-list">
|
||||||
<div class="container" id="strain"></div>
|
<div v-if="strains.length === 0" class="container">
|
||||||
|
<p>NO MATCHING STRAINS :(</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="strains.length > 0" class="container cards">
|
||||||
|
<div v-for="strain in strains" class="card">
|
||||||
|
<header class="card-header">
|
||||||
|
<p class="card-header-title">{{strain.name | capitalize}}</p>
|
||||||
|
<div class="tags" style="margin: 0 12px;">
|
||||||
|
<span class="tag is-rounded is-light">{{strain.rating | round}} ({{strain.rating_count}})</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="card-content">
|
||||||
|
<span v-if="strain.category === 'indica'" class="tag is-rounded is-indica">{{strain.category}}</span>
|
||||||
|
<span v-if="strain.category === 'sativa'" class="tag is-rounded is-sativa">{{strain.category}}</span>
|
||||||
|
<span v-if="strain.category === 'hybrid'" class="tag is-rounded is-hybrid">{{strain.category}}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<script src="https://unpkg.com/lunr@2.3.1/lunr.js"></script>
|
<script src="https://unpkg.com/lunr@2.3.1/lunr.js"></script>
|
||||||
@@ -112,17 +172,31 @@
|
|||||||
const data = <%- data %>;
|
const data = <%- data %>;
|
||||||
const emitter = mitt();
|
const emitter = mitt();
|
||||||
|
|
||||||
// debugging...
|
|
||||||
const target = document.querySelector('#strain').textContent = data.strains[20].name;
|
|
||||||
|
|
||||||
// helpers
|
// helpers
|
||||||
const getMultiValues = node => Array.from(node.selectedOptions).map(o => o.value);
|
const getMultiValues = node => Array.from(node.selectedOptions).map(o => o.value);
|
||||||
|
|
||||||
|
// vue helpers
|
||||||
|
Vue.filter('capitalize', value => {
|
||||||
|
if (!value) return '';
|
||||||
|
const v = value.toString();
|
||||||
|
return v.charAt(0).toUpperCase() + v.slice(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
Vue.filter('round', (value, digits = 2) => {
|
||||||
|
const v = parseFloat(value, 10);
|
||||||
|
return Math.round(v * (10 * digits)) / (10 * digits);
|
||||||
|
});
|
||||||
|
|
||||||
// form handler
|
// form handler
|
||||||
new Vue({
|
new Vue({
|
||||||
el: '#search-form',
|
el: '#search-form',
|
||||||
data() {
|
data() {
|
||||||
return {};
|
return {
|
||||||
|
effects: data.effects,
|
||||||
|
uses: data.uses,
|
||||||
|
conditions: data.conditions,
|
||||||
|
flavors: data.flavors,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleSubmit() {
|
handleSubmit() {
|
||||||
@@ -133,14 +207,58 @@
|
|||||||
conditions: getMultiValues(this.$refs.conditions),
|
conditions: getMultiValues(this.$refs.conditions),
|
||||||
flavors: getMultiValues(this.$refs.flavors),
|
flavors: getMultiValues(this.$refs.flavors),
|
||||||
}
|
}
|
||||||
console.log(requirements)
|
emitter.emit('search', requirements)
|
||||||
},
|
},
|
||||||
resetForm() {
|
resetForm() {
|
||||||
this.$el.reset();
|
this.$el.reset();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
new Vue({
|
||||||
|
el: '#strain-list',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
all_strains: data.strains,
|
||||||
|
strains: [],
|
||||||
|
requirements: {
|
||||||
|
name: '',
|
||||||
|
effects: [],
|
||||||
|
uses: [],
|
||||||
|
conditions: [],
|
||||||
|
flavors: [],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
emitter.on('search', this.setRequirements);
|
||||||
|
this.updateStrains();
|
||||||
|
},
|
||||||
|
beforeDestroy() {
|
||||||
|
emitter.off('search', this.setRequirements);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
setRequirements(reqs) {
|
||||||
|
// this.requirements = reqs;
|
||||||
|
reqs => console.log('search params', reqs);
|
||||||
|
},
|
||||||
|
updateStrains(limit = 20) {
|
||||||
|
const hasName = this.requirements.name.length > 0;
|
||||||
|
const hasFilters =
|
||||||
|
this.requirements.effects.length > 0 ||
|
||||||
|
this.requirements.uses.length > 0 ||
|
||||||
|
this.requirements.conditions.length > 0 ||
|
||||||
|
this.requirements.flavors.length > 0;
|
||||||
|
|
||||||
|
if (!hasName && !hasFilters) {
|
||||||
|
this.strains = this.all_strains.slice(0, limit);
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
})(this);
|
})(this);
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -9,7 +9,7 @@ function getData() {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
fs.readFile('../scraper/db.json', (err, str) => {
|
fs.readFile('../scraper/db.json', (err, str) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
else resolve(str);
|
else resolve(JSON.parse(str));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -17,9 +17,13 @@ function getData() {
|
|||||||
async function build() {
|
async function build() {
|
||||||
const data = await getData();
|
const data = await getData();
|
||||||
const options = {};
|
const options = {};
|
||||||
|
data.strains = data.strains.sort((n, strain) => {
|
||||||
|
if (strain.rating === n.rating) return 0;
|
||||||
|
return strain.rating < n.rating ? -1 : 1;
|
||||||
|
});
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
ejs.renderFile(srcFile, { data }, options, (err, str) => {
|
ejs.renderFile(srcFile, { data: JSON.stringify(data) }, options, (err, str) => {
|
||||||
if (err) reject(err);
|
if (err) reject(err);
|
||||||
else {
|
else {
|
||||||
fs.writeFile(destFile, str, er => {
|
fs.writeFile(destFile, str, er => {
|
||||||
|
|||||||
Reference in New Issue
Block a user