diff --git a/packages/search-site/src/components/SearchForm.vue b/packages/search-site/src/components/SearchForm.vue
new file mode 100644
index 0000000..569a45d
--- /dev/null
+++ b/packages/search-site/src/components/SearchForm.vue
@@ -0,0 +1,138 @@
+
+
+
+
+
+
+
diff --git a/packages/search-site/src/components/StrainCard.vue b/packages/search-site/src/components/StrainCard.vue
new file mode 100644
index 0000000..bb166a4
--- /dev/null
+++ b/packages/search-site/src/components/StrainCard.vue
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
diff --git a/packages/search-site/src/components/StrainList.vue b/packages/search-site/src/components/StrainList.vue
new file mode 100644
index 0000000..ee3c97c
--- /dev/null
+++ b/packages/search-site/src/components/StrainList.vue
@@ -0,0 +1,62 @@
+
+
+
+
No Matching Strains :(
+ Found {{strains.length}} Strains
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/search-site/src/components/TagList.vue b/packages/search-site/src/components/TagList.vue
new file mode 100644
index 0000000..d68652a
--- /dev/null
+++ b/packages/search-site/src/components/TagList.vue
@@ -0,0 +1,22 @@
+
+
+
+
+
diff --git a/packages/search-site/src/index.ejs b/packages/search-site/src/index.ejs
deleted file mode 100644
index 5a602c2..0000000
--- a/packages/search-site/src/index.ejs
+++ /dev/null
@@ -1,417 +0,0 @@
-
-
-
-
-
-
-
-
- Strain Search
-
-
-
-
-
-
-
-
-
-
-
NO MATCHING STRAINS :(
-
-
-
-
-
Found {{strains.length}} Strains
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/packages/search-site/src/index.mjs b/packages/search-site/src/index.mjs
index bd6f405..25b5822 100644
--- a/packages/search-site/src/index.mjs
+++ b/packages/search-site/src/index.mjs
@@ -1,105 +1,33 @@
-import http from 'http';
-import fs from 'fs';
-import ejs from 'ejs';
+import Vue from 'vue';
+import Router from 'vue-router';
-const srcFile = 'src/index.ejs';
-const destFile = 'dist/index.html';
+Vue.use(Router);
-function getData() {
- return new Promise((resolve, reject) => {
- fs.readFile('../scraper/db.json', (err, str) => {
- if (err) reject(err);
- else resolve(JSON.parse(str));
- });
- });
-}
+Vue.filter('capitalize', value => {
+ if (!value) return '';
+ const v = value.toString();
+ return v.charAt(0).toUpperCase() + v.slice(1);
+});
-async function build() {
- const data = await getData();
- const options = {};
+Vue.filter('round', (value, digits = 2) => {
+ const v = parseFloat(value, 10);
+ return Math.round(v * (10 * digits)) / (10 * digits);
+});
- // calculate adjusted ratings
- const totalMean =
- data.strains.reduce((acc, strain) => acc + strain.rating + strain.rating_count, 0) /
- data.strains.length;
+const router = new Router({
+ mode: 'history',
+ routes: [
+ {
+ path: '/',
+ name: 'home',
+ component: () => import(/* webpackChunkName: "homeapp" */ './pages/Home.vue'),
+ },
+ ],
+});
- data.strains = data.strains.map(strain => {
- const minRatings = 10;
- const { rating, rating_count: count } = strain;
- return Object.assign(strain, {
- rating_adjusted:
- (((count / (count + minRatings)) * rating) / (minRatings / (count + minRatings))) *
- totalMean,
- });
- });
+const app = new Vue({
+ router,
+ render: h => h('div', { attrs: { id: 'app' } }, [h('router-view')]),
+});
- // order strains by rating
- data.strains = data.strains.sort((n, strain) => {
- if (strain.rating_adjusted === n.rating_adjusted) return 0;
- return strain.rating_adjusted < n.rating_adjusted ? -1 : 1;
- });
-
- return new Promise((resolve, reject) => {
- ejs.renderFile(srcFile, { data: JSON.stringify(data) }, options, (err, str) => {
- if (err) reject(err);
- else {
- fs.writeFile(destFile, str, er => {
- if (er) reject(er);
- else {
- console.log(`Site built: ${destFile}`);
- resolve();
- }
- });
- }
- });
- });
-}
-
-async function serve() {
- const PORT = '3000';
-
- await build();
-
- http
- .createServer((req, res) => {
- fs.readFile(destFile, (err, str) => {
- if (err) {
- res.writeHead(500, { 'Content-Type': 'text/plain' });
- res.end('Failed :(');
- console.error(err);
- return;
- }
-
- res.writeHead(200, { 'Content-Type': 'text/html' });
- res.end(str);
- });
- })
- .listen(PORT, () => {
- console.log(`Server listening on http://localhost:${PORT}`);
- });
-}
-
-export default async function() {
- const cmds = ['build', 'serve'];
- const cmd = process.argv.splice(2)[0];
-
- try {
- switch (cmd) {
- case 'build': {
- await build();
- break;
- }
- case 'serve': {
- await serve();
- break;
- }
- default: {
- const msg = `Please use one of ${cmds.map(c => `"${c}"`).join(', ')}`;
- if (cmd.length) console.error(`Unknown command "${cmd}". ${msg}`);
- else console.error(`No command provided. ${msg}`);
- }
- }
- } catch (err) {
- console.error(err);
- }
-}
+export default app;
diff --git a/packages/search-site/src/lib/emitter.mjs b/packages/search-site/src/lib/emitter.mjs
new file mode 100644
index 0000000..4b06ecd
--- /dev/null
+++ b/packages/search-site/src/lib/emitter.mjs
@@ -0,0 +1,5 @@
+import mitt from 'mitt';
+
+const emitter = mitt();
+
+export default emitter;
diff --git a/packages/search-site/src/lib/store.mjs b/packages/search-site/src/lib/store.mjs
new file mode 100644
index 0000000..c0012c8
--- /dev/null
+++ b/packages/search-site/src/lib/store.mjs
@@ -0,0 +1,17 @@
+/* eslint-env browser */
+
+const storage = (() => {
+ // return localstorage in the browser env
+ if (this && this.localStorage) return this.localStorage;
+
+ // return a mock localstorage in the server env
+ return {
+ getItem: () => null,
+ setItem: () => null,
+ };
+})();
+
+export default {
+ get: id => JSON.parse(storage.getItem(id)),
+ set: (id, val) => storage.setItem(id, JSON.stringify(val)),
+};
diff --git a/packages/search-site/src/pages/Home.vue b/packages/search-site/src/pages/Home.vue
new file mode 100644
index 0000000..f1b5004
--- /dev/null
+++ b/packages/search-site/src/pages/Home.vue
@@ -0,0 +1,149 @@
+
+
+
+
+
+
+
+