From bed50e9b7ee0cdc6b93ac5169fbacd67fb8fa001 Mon Sep 17 00:00:00 2001 From: Daniel Nitsikopoulos Date: Fri, 24 Nov 2023 22:37:31 +1100 Subject: [PATCH] Search posts --- app/actions/posts/index.rb | 2 +- app/assets/builds/tailwind.css | 76 +++++++++++++++++++++++++ app/relations/posts.rb | 7 +++ app/repos/post_repo.rb | 10 ++++ app/templates/bookmarks/index.html.slim | 18 +++--- app/templates/posts/index.html.slim | 12 +++- app/views/posts/index.rb | 16 +++++- 7 files changed, 130 insertions(+), 11 deletions(-) diff --git a/app/actions/posts/index.rb b/app/actions/posts/index.rb index c83d4eb..964db7d 100644 --- a/app/actions/posts/index.rb +++ b/app/actions/posts/index.rb @@ -4,7 +4,7 @@ module Adamantium class Index < Action include Deps["views.posts.index"] def handle(req, res) - res.render index + res.render index, query: req.params[:q] end end end diff --git a/app/assets/builds/tailwind.css b/app/assets/builds/tailwind.css index bb22c88..ee24982 100644 --- a/app/assets/builds/tailwind.css +++ b/app/assets/builds/tailwind.css @@ -1278,6 +1278,10 @@ video { width: 100vw; } +.w-64 { + width: 16rem; +} + .max-w-3xl { max-width: 48rem; } @@ -1306,10 +1310,26 @@ video { flex: none; } +.flex-auto { + flex: 1 1 auto; +} + .grow { flex-grow: 1; } +.basis-1\/4 { + flex-basis: 25%; +} + +.basis-full { + flex-basis: 100%; +} + +.basis-auto { + flex-basis: auto; +} + .table-auto { table-layout: auto; } @@ -1601,6 +1621,26 @@ video { background-color: rgb(254 249 195 / 0.6); } +.bg-indigo-50 { + --tw-bg-opacity: 1; + background-color: rgb(238 242 255 / var(--tw-bg-opacity)); +} + +.bg-indigo-400 { + --tw-bg-opacity: 1; + background-color: rgb(129 140 248 / var(--tw-bg-opacity)); +} + +.bg-indigo-600 { + --tw-bg-opacity: 1; + background-color: rgb(79 70 229 / var(--tw-bg-opacity)); +} + +.bg-indigo-300 { + --tw-bg-opacity: 1; + background-color: rgb(165 180 252 / var(--tw-bg-opacity)); +} + .bg-opacity-75 { --tw-bg-opacity: 0.75; } @@ -1704,6 +1744,22 @@ video { padding-top: 1rem; } +.pr-1 { + padding-right: 0.25rem; +} + +.pr-4 { + padding-right: 1rem; +} + +.pt-1 { + padding-top: 0.25rem; +} + +.pt-1\.5 { + padding-top: 0.375rem; +} + .text-left { text-align: left; } @@ -1872,6 +1928,16 @@ video { color: rgb(255 255 255 / var(--tw-text-opacity)); } +.text-indigo-50 { + --tw-text-opacity: 1; + color: rgb(238 242 255 / var(--tw-text-opacity)); +} + +.text-indigo-900 { + --tw-text-opacity: 1; + color: rgb(49 46 129 / var(--tw-text-opacity)); +} + .underline { text-decoration-line: underline; } @@ -2465,6 +2531,16 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { background-color: rgb(15 23 42 / var(--tw-bg-opacity)); } + .dark\:bg-indigo-300 { + --tw-bg-opacity: 1; + background-color: rgb(165 180 252 / var(--tw-bg-opacity)); + } + + .dark\:bg-indigo-400 { + --tw-bg-opacity: 1; + background-color: rgb(129 140 248 / var(--tw-bg-opacity)); + } + .dark\:text-amber-100 { --tw-text-opacity: 1; color: rgb(254 243 199 / var(--tw-text-opacity)); diff --git a/app/relations/posts.rb b/app/relations/posts.rb index a615244..389a3e5 100644 --- a/app/relations/posts.rb +++ b/app/relations/posts.rb @@ -35,6 +35,13 @@ module Adamantium where(self[:published_at] >= start_date) .where(self[:published_at] <= end_date) end + + def search(term:) + ref = dataset + .full_text_search([:content], [term]) + .select(:id) + where(id: ref) + end end end end diff --git a/app/repos/post_repo.rb b/app/repos/post_repo.rb index 921b41f..7c5155b 100644 --- a/app/repos/post_repo.rb +++ b/app/repos/post_repo.rb @@ -186,6 +186,16 @@ module Adamantium .order(:year) .to_a end + + def search(term:) + posts + .where(post_type: "post", location: nil) + .published + .search(term: term) + .combine(:tags) + .order(Sequel.desc(:published_at)) + .to_a + end end end end diff --git a/app/templates/bookmarks/index.html.slim b/app/templates/bookmarks/index.html.slim index 126ce12..d19f957 100644 --- a/app/templates/bookmarks/index.html.slim +++ b/app/templates/bookmarks/index.html.slim @@ -3,13 +3,17 @@ div class="flex justify-between prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" div h1 Bookmarks -div class="flex mb-4 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" - form method="GET" action="/bookmarks" - input class="border-blue-400 border-2 rounded mr-2 px-2 dark:text-gray-800" id="search" type="text" name="q" value=q - button class="border-blue-400 border-2 rounded bg-blue-400 hover:bg-blue-800 hover:border-blue-800 hover:text-blue-100 px-1 text-gray-200" type="submit" Search - - unless q.nil? - div class="ml-2" - a class="text-gray-400" href="/bookmarks" Clear search + +div class="h-feed mb-12 max-w-prose mx-auto" + form action="/bookmarks" method="GET" + div class="flex" + div class="flex-auto basis-auto mr-4" + input id="search" type="text" class="p-1 rounded w-full bg-indigo-50 dark:bg-indigo-400" name="q" value=q + div class="mr-4" + input type="submit" class="bg-indigo-300 p-1 rounded text-indigo-900" value="Search" + -if q + div class="" + a href="/bookmarks" class="text-gray-400 dark:text-gray-100 pt-1" Clear search div class="mb-12 max-w-prose mx-auto" - bookmarks.each do |bookmark| diff --git a/app/templates/posts/index.html.slim b/app/templates/posts/index.html.slim index 3ad0dfa..4f3e663 100644 --- a/app/templates/posts/index.html.slim +++ b/app/templates/posts/index.html.slim @@ -3,13 +3,23 @@ div class="mb-4 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" h1 Writing -div class="mb-12 max-w-prose mx-auto text-gray-800 dark:text-gray-200" +div class="mb-4 max-w-prose mx-auto text-gray-800 dark:text-gray-200" nav class="space-x-1 text-sm md:text-sm uppercase md:block" span Archive: - post_years.each do |year| a href="/posts/archive/#{year}" class="text-sm hover:text-gray-400"= year - if year != post_years.last span · +div class="h-feed mb-12 max-w-prose mx-auto" + form action="/posts" method="GET" + div class="flex" + div class="flex-auto basis-auto mr-4" + input id="search" type="text" class="p-1 rounded w-full bg-indigo-50 dark:bg-indigo-400" name="q" value=query + div class="mr-4" + input type="submit" class="bg-indigo-300 p-1 rounded text-indigo-900" value="Search" + -if query + div class="" + a href="/posts" class="text-gray-400 dark:text-gray-100 pt-1" Clear search div class="h-feed mb-12 max-w-prose mx-auto" - posts.each do |post| == render "shared/post", post: post diff --git a/app/views/posts/index.rb b/app/views/posts/index.rb index 0513da7..291eef1 100644 --- a/app/views/posts/index.rb +++ b/app/views/posts/index.rb @@ -4,12 +4,24 @@ module Adamantium class Index < Adamantium::View include Deps["repos.post_repo"] - expose :posts do - post_repo.post_listing.map do |post| + expose :posts do |post_query| + post_query.map do |post| Decorators::Posts::Decorator.new(post) end end + private_expose :post_query do |query| + if query + post_repo.search(term: query) + else + post_repo.post_listing + end + end + + expose :query do |query:| + query + end + expose :post_years do post_repo.post_years.map { |py| py[:year].to_i } end