diff --git a/assets/components/header/header.vue b/assets/components/header/header.vue
index 2e14133c..b965aae4 100644
--- a/assets/components/header/header.vue
+++ b/assets/components/header/header.vue
@@ -1,70 +1,108 @@
+
+
diff --git a/assets/components/tile/release.vue b/assets/components/tile/release.vue
index abce7551..2257b850 100644
--- a/assets/components/tile/release.vue
+++ b/assets/components/tile/release.vue
@@ -7,7 +7,7 @@
{{ release.network.name }}
{{ release.site.name }}
+
+
+
diff --git a/assets/img/cancel-circle2.svg b/assets/img/cancel-circle2.svg
new file mode 100644
index 00000000..18ceaa72
--- /dev/null
+++ b/assets/img/cancel-circle2.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/cancel-square.svg b/assets/img/cancel-square.svg
new file mode 100644
index 00000000..f643b031
--- /dev/null
+++ b/assets/img/cancel-square.svg
@@ -0,0 +1,6 @@
+
+
diff --git a/assets/img/cancel-square2.svg b/assets/img/cancel-square2.svg
new file mode 100644
index 00000000..3ba120d4
--- /dev/null
+++ b/assets/img/cancel-square2.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/checkmark.svg b/assets/img/checkmark.svg
new file mode 100644
index 00000000..48b07f39
--- /dev/null
+++ b/assets/img/checkmark.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/checkmark3.svg b/assets/img/checkmark3.svg
new file mode 100644
index 00000000..08f8c3c1
--- /dev/null
+++ b/assets/img/checkmark3.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/cross.svg b/assets/img/cross.svg
new file mode 100644
index 00000000..9ffcb7fd
--- /dev/null
+++ b/assets/img/cross.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/cross2.svg b/assets/img/cross2.svg
new file mode 100644
index 00000000..0b03beef
--- /dev/null
+++ b/assets/img/cross2.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/cross3.svg b/assets/img/cross3.svg
new file mode 100644
index 00000000..c45560d8
--- /dev/null
+++ b/assets/img/cross3.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/minus-circle2.svg b/assets/img/minus-circle2.svg
new file mode 100644
index 00000000..e06595e1
--- /dev/null
+++ b/assets/img/minus-circle2.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/img/plus-circle2.svg b/assets/img/plus-circle2.svg
new file mode 100644
index 00000000..814d41db
--- /dev/null
+++ b/assets/img/plus-circle2.svg
@@ -0,0 +1,5 @@
+
+
diff --git a/assets/js/curate.js b/assets/js/curate.js
index ee65975d..ba8fb7eb 100644
--- a/assets/js/curate.js
+++ b/assets/js/curate.js
@@ -23,9 +23,9 @@ function curateRelease(release) {
actors: [],
poster: release.poster && release.poster.media,
tags: release.tags ? release.tags.map(({ tag }) => tag) : [],
- network: release.site.network,
};
+ if (release.site) curatedRelease.network = release.site.network;
if (release.photos) curatedRelease.photos = release.photos.map(({ media }) => media);
if (release.covers) curatedRelease.covers = release.covers.map(({ media }) => media);
if (release.trailer) curatedRelease.trailer = release.trailer.media;
diff --git a/assets/js/releases/actions.js b/assets/js/releases/actions.js
index 7c97decc..8ef89651 100644
--- a/assets/js/releases/actions.js
+++ b/assets/js/releases/actions.js
@@ -25,6 +25,63 @@ function initReleasesActions(store, _router) {
return releases.map(release => curateRelease(release));
}
+ async function searchReleases({ _commit }, { query, limit = 20 }) {
+ const res = await graphql(`
+ query SearchReleases(
+ $query: String!
+ $limit: Int = 20
+ ) {
+ releases: searchReleases(
+ search: $query
+ first: $limit
+ ) {
+ id
+ title
+ date
+ url
+ site {
+ id
+ slug
+ name
+ url
+ network {
+ id
+ slug
+ name
+ url
+ }
+ }
+ actors: releasesActors {
+ actor {
+ id
+ slug
+ name
+ }
+ }
+ tags: releasesTags {
+ tag {
+ id
+ name
+ slug
+ }
+ }
+ poster: releasesPosterByReleaseId {
+ media {
+ thumbnail
+ }
+ }
+ }
+ }
+ `, {
+ query,
+ limit,
+ });
+
+ if (!res) return [];
+
+ return res.releases.map(release => curateRelease(release));
+ }
+
async function fetchReleaseById({ _commit }, releaseId) {
// const release = await get(`/releases/${releaseId}`);
@@ -42,6 +99,7 @@ function initReleasesActions(store, _router) {
return {
fetchReleases,
fetchReleaseById,
+ searchReleases,
};
}
diff --git a/assets/js/router.js b/assets/js/router.js
index e97da921..503458a3 100644
--- a/assets/js/router.js
+++ b/assets/js/router.js
@@ -10,6 +10,7 @@ import Actor from '../components/actors/actor.vue';
import Actors from '../components/actors/actors.vue';
import Tag from '../components/tags/tag.vue';
import Tags from '../components/tags/tags.vue';
+import Search from '../components/search/search.vue';
import NotFound from '../components/errors/404.vue';
Vue.use(VueRouter);
@@ -69,6 +70,11 @@ const routes = [
component: Tags,
name: 'tags',
},
+ {
+ path: '/search',
+ component: Search,
+ name: 'search',
+ },
{
path: '*',
component: NotFound,
diff --git a/migrations/20200225223307_search.js b/migrations/20200225223307_search.js
new file mode 100644
index 00000000..bf713d14
--- /dev/null
+++ b/migrations/20200225223307_search.js
@@ -0,0 +1,14 @@
+exports.up = knex => Promise.resolve()
+ .then(() => knex.raw(`
+ CREATE FUNCTION search_releases(search text) RETURNS SETOF releases AS $$
+ SELECT * FROM releases
+ WHERE
+ title ILIKE ('%' || search || '%') OR
+ url ILIKE ('%' || search || '%')
+ $$ LANGUAGE SQL STABLE;
+ `));
+
+exports.down = knex => Promise.resolve()
+ .then(() => knex.raw(`
+ DROP FUNCTION IF EXISTS search_releases;
+ `));
diff --git a/public/img/cancel-circle2.svg b/public/img/cancel-circle2.svg
new file mode 100644
index 00000000..18ceaa72
--- /dev/null
+++ b/public/img/cancel-circle2.svg
@@ -0,0 +1,5 @@
+
+