diff --git a/app/actions/trips/index.rb b/app/actions/trips/index.rb new file mode 100644 index 0000000..362d876 --- /dev/null +++ b/app/actions/trips/index.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Adamantium + module Actions + module Trips + class Index < Adamantium::Action + def handle(req, res) + end + end + end + end +end diff --git a/app/actions/trips/show.rb b/app/actions/trips/show.rb new file mode 100644 index 0000000..fc51a53 --- /dev/null +++ b/app/actions/trips/show.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Adamantium + module Actions + module Trips + class Show < Adamantium::Action + + include Deps["views.trips.show"] + + def handle(req, res) + res.render show, id: req.params[:id] + end + end + end + end +end diff --git a/app/repos/post_repo.rb b/app/repos/post_repo.rb index 2534caa..488b5d6 100644 --- a/app/repos/post_repo.rb +++ b/app/repos/post_repo.rb @@ -207,7 +207,7 @@ module Adamantium def fetch!(slug) posts .published - .combine(:tags) + .combine(:tags, :trips) .where(slug: slug) .one! end diff --git a/app/repos/trip_repo.rb b/app/repos/trip_repo.rb new file mode 100644 index 0000000..a175450 --- /dev/null +++ b/app/repos/trip_repo.rb @@ -0,0 +1,18 @@ +module Adamantium + module Repos + class TripRepo < Adamantium::Repo[:trips] + def fetch!(id) + trips + .where(id: id) + .combine(posts: :tags) + .one! + end + + def list + trips + .order(:start_date) + .to_a + end + end + end +end diff --git a/app/templates/more/index.html.slim b/app/templates/more/index.html.slim index 3077f72..2fae5be 100644 --- a/app/templates/more/index.html.slim +++ b/app/templates/more/index.html.slim @@ -14,5 +14,6 @@ div class="mb-12 max-w-prose mx-auto text-gray-800 dark:text-gray-200" a class="block p-1 border border-lime-200 bg-lime-300 text-lime-900 hover:bg-lime-200 text-center rounded-lg" href="/colophon" 🧱 Colophon a class="block p-1 border border-lime-200 bg-lime-300 text-lime-900 hover:bg-lime-200 text-center rounded-lg" href="/hikes" 🥾 Hikes a class="block p-1 border border-lime-200 bg-lime-300 text-lime-900 hover:bg-lime-200 text-center rounded-lg" href="/movies" 🍿 Movies + a class="block p-1 border border-lime-200 bg-lime-300 text-lime-900 hover:bg-lime-200 text-center rounded-lg" href="/trips" 🛫 Trips / a class="block p-1 border border-lime-200 bg-lime-300 text-lime-900 hover:bg-lime-200 text-center rounded-lg" href="/art" 🎨 Art things diff --git a/app/templates/posts/show.html.slim b/app/templates/posts/show.html.slim index 72dfb2d..f07bd31 100644 --- a/app/templates/posts/show.html.slim +++ b/app/templates/posts/show.html.slim @@ -29,7 +29,12 @@ article class="h-entry" - if post.location img class="shadow-solid shadow-pink-100 dark:shadow-pink-200 rounded mb-4" src=post.large_map - + div class="max-w-prose mx-auto text-gray-600 dark:text-gray-200 flex gap-4" + div class="block grow bg-orange-100 dark:bg-orange-600 rounded px-4 py-2 mb-12" + a href="/trips/#{trip.id}" + = "✈️ Part of the trip: " + strong #{trip.name} + | → - if post.tags.map(&:label).include? "weekly" div class="max-w-prose mx-auto text-gray-600 dark:text-gray-200 flex gap-4" div class="grow" hx-get="/post/top_tracks/#{post.slug}" hx-trigger="load" diff --git a/app/templates/shared/_compact_post.html.slim b/app/templates/shared/_compact_post.html.slim new file mode 100644 index 0000000..8778b08 --- /dev/null +++ b/app/templates/shared/_compact_post.html.slim @@ -0,0 +1,24 @@ +div class="mb-2 h-entry" + - if !first + div class="rounded-full bg-orange-100 p-2 w-1 h-4 inline-block mb-2 dark:bg-orange-400" + - if first + div class="w-2 h-2 inline-block mb-6" + = "🛬" + + div class="ml-[7] pl-6 border-solid border-l-2 border-orange-100 dark:border-orange-400" + h3 class="text-xl font-semibold text-blue-600" + a class="border-b-2 border-transparent hover:border-blue-600 hover:border-b-2" href="/post/#{post.slug}" + = post.name + div class="e-content prose-p:mb-0 prose-img:my-2 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline p-name text-base prose prose-ul:list-none prose-ul:pl-0 prose-li:pl-0 text-gray-800 dark:text-gray-200 prose-a:dark:text-gray-100" + == post.excerpt + div class="grid gap-4 grid-flow-row grid-cols-4 grid-rows-1" + -post.photos.each do |photo| + img class="w-44 h-44 object-cover rounded" src=photo["value"] + + p class="text-sm text-blue-400" + a class="u-url" href="#{post.permalink}" + time class="dt-published" datetime=post.machine_published_at + = post.display_published_at + - if last + div class="w-2 h-2 inline-block mb-6" + = "🛫" \ No newline at end of file diff --git a/app/templates/trips/index.html.slim b/app/templates/trips/index.html.slim new file mode 100644 index 0000000..1471d63 --- /dev/null +++ b/app/templates/trips/index.html.slim @@ -0,0 +1,15 @@ +div class="mb-4 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Trips + +div class="h-feed mb-12 max-w-prose mx-auto" + - trips.each do |trip| + div class="mb-8 h-entry" + h3 class="text-xl font-semibold text-blue-600 mb-2" + a class="border-b-2 border-transparent hover:border-blue-600 hover:border-b-2" href="/trips/#{trip.id}" + = trip.name + p class="text-sm text-blue-400" + a class="u-url" href="/trips/#{trip.id}" + = "#{trip.start_date} - #{trip.end_date}" + + +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/app/templates/trips/show.html.slim b/app/templates/trips/show.html.slim new file mode 100644 index 0000000..c15aa39 --- /dev/null +++ b/app/templates/trips/show.html.slim @@ -0,0 +1,9 @@ +div class="mb-4 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 class="mb-0" #{trip.name} + p class="mt-2" class="text-gray-600 dark:text-gray-200 text-sm" (#{trip.start_date} - #{trip.end_date}) + +div class="h-feed mb-12 max-w-prose mx-auto" + - posts.each do |post| + == render "shared/compact_post", post: post, first: post.id == posts.first.id, last: post.id == posts.last.id + +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/app/views/posts/show.rb b/app/views/posts/show.rb index 5ddd8dc..7be6aa3 100644 --- a/app/views/posts/show.rb +++ b/app/views/posts/show.rb @@ -24,6 +24,10 @@ module Adamantium expose :photo_posts do |past_posts| past_posts.select(&:photos?) end + + expose :trip do |post| + post.trips.first + end end end end diff --git a/app/views/trips/index.rb b/app/views/trips/index.rb new file mode 100644 index 0000000..e773b3b --- /dev/null +++ b/app/views/trips/index.rb @@ -0,0 +1,13 @@ +module Adamantium + module Views + module Trips + class Index < View + include Deps["repos.trip_repo"] + + expose :trips do + trip_repo.list + end + end + end + end +end diff --git a/app/views/trips/show.rb b/app/views/trips/show.rb new file mode 100644 index 0000000..fd957ae --- /dev/null +++ b/app/views/trips/show.rb @@ -0,0 +1,21 @@ +module Adamantium + module Views + module Trips + class Show < Adamantium::View + include Deps[ + "repos.trip_repo" + ] + + expose :posts do |trip| + trip.posts.sort { |p, x| p.published_at.to_i <=> x.published_at.to_i }.map do |post| + Decorators::Posts::Decorator.new(post) + end + end + + expose :trip do |id:| + trip_repo.fetch!(id) + end + end + end + end +end diff --git a/config/routes.rb b/config/routes.rb index 0510179..8089ee2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -52,6 +52,9 @@ module Adamantium get "/:slug", to: "pages.show" + get "/trips", to: "trips.index" + get "/trips/:id", to: "trips.show" + redirect "deploying-a-hanami-app-to-fly-io", to: "/post/deploying-a-hanami-20-app-to-flyio" redirect "deploying-a-hanami-app-to-fly-io/", to: "/post/deploying-a-hanami-20-app-to-flyio" @@ -81,6 +84,12 @@ module Adamantium post "/posts/:id/archive", to: "posts.archive" get "/media", to: "photos.index" + + get "/trips", to: "trips.index" + get "/trips/:id", to: "trips.show" + post "/trips", to: "trips.create" + post "/trips/add_post", to: "trips.add_post" + get "/trips/new", to: "trips.new" end end end diff --git a/db/migrate/20230509092845_create_trips.rb b/db/migrate/20230509092845_create_trips.rb new file mode 100644 index 0000000..7947415 --- /dev/null +++ b/db/migrate/20230509092845_create_trips.rb @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + create_table :trips do + primary_key :id + column :name, :text, null: false + column :start_date, :date, null: false + column :end_date, :date, null: false + # column :latitude, :float, null: false + # column :longitude, :float, null: false + end + end +end diff --git a/db/migrate/20230509094041_create_post_trips.rb b/db/migrate/20230509094041_create_post_trips.rb new file mode 100644 index 0000000..32532da --- /dev/null +++ b/db/migrate/20230509094041_create_post_trips.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +ROM::SQL.migration do + change do + create_table :post_trips do + foreign_key :post_id, :posts, null: false + foreign_key :trip_id, :trips, null: false + end + end +end diff --git a/lib/adamantium/persistence/relations/post_trips.rb b/lib/adamantium/persistence/relations/post_trips.rb new file mode 100644 index 0000000..6372cda --- /dev/null +++ b/lib/adamantium/persistence/relations/post_trips.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Adamantium + module Persistence + module Relations + class PostTrips < ROM::Relation[:sql] + schema :post_trips, infer: true do + associations do + belongs_to :post + belongs_to :trip + end + end + + auto_struct(true) + end + end + end +end diff --git a/lib/adamantium/persistence/relations/posts.rb b/lib/adamantium/persistence/relations/posts.rb index 8e08ef4..bcb4ee5 100644 --- a/lib/adamantium/persistence/relations/posts.rb +++ b/lib/adamantium/persistence/relations/posts.rb @@ -8,6 +8,9 @@ module Adamantium associations do has_many :post_tags has_many :tags, through: :post_tags + + has_many :post_trips + has_many :trips, through: :post_trips end end @@ -16,6 +19,11 @@ module Adamantium def published where(self[:published_at] <= Time.now) end + + def published_between(start_date, end_date) + where(self[:published_at] >= start_date) + .where(self[:published_at] <= end_date) + end end end end diff --git a/lib/adamantium/persistence/relations/trips.rb b/lib/adamantium/persistence/relations/trips.rb new file mode 100644 index 0000000..8d79a76 --- /dev/null +++ b/lib/adamantium/persistence/relations/trips.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +module Adamantium + module Persistence + module Relations + class Trips < ROM::Relation[:sql] + schema :trips, infer: true do + associations do + has_many :post_trips + has_many :posts, through: :post_trips + end + end + + auto_struct(true) + end + end + end +end diff --git a/public/assets/index.css b/public/assets/index.css index 90956a0..85838e5 100644 --- a/public/assets/index.css +++ b/public/assets/index.css @@ -1068,6 +1068,82 @@ video { margin-top: 1.5rem; } +.mt-2 { + margin-top: 0.5rem; +} + +.ml-4 { + margin-left: 1rem; +} + +.ml-8 { + margin-left: 2rem; +} + +.ml-2 { + margin-left: 0.5rem; +} + +.ml-1 { + margin-left: 0.25rem; +} + +.mb-1 { + margin-bottom: 0.25rem; +} + +.ml-3 { + margin-left: 0.75rem; +} + +.ml-1\.5 { + margin-left: 0.375rem; +} + +.ml-2\.5 { + margin-left: 0.625rem; +} + +.ml-\[2\.15\] { + margin-left: 2.15; +} + +.ml-\[2\.25\] { + margin-left: 2.25; +} + +.ml-\[2\.5\] { + margin-left: 2.5; +} + +.ml-\[3\.5\] { + margin-left: 3.5; +} + +.ml-\[4\.5\] { + margin-left: 4.5; +} + +.ml-\[6\.5\] { + margin-left: 6.5; +} + +.ml-\[6\] { + margin-left: 6; +} + +.ml-\[6\.25\] { + margin-left: 6.25; +} + +.ml-\[6\.75\] { + margin-left: 6.75; +} + +.ml-\[7\] { + margin-left: 7; +} + .block { display: block; } @@ -1108,6 +1184,18 @@ video { height: 12rem; } +.h-2 { + height: 0.5rem; +} + +.h-4 { + height: 1rem; +} + +.h-1 { + height: 0.25rem; +} + .max-h-12 { max-height: 3rem; } @@ -1140,6 +1228,14 @@ video { width: 1.5rem; } +.w-3 { + width: 0.75rem; +} + +.w-1 { + width: 0.25rem; +} + .max-w-prose { max-width: 65ch; } @@ -1263,6 +1359,14 @@ video { border-top-width: 4px; } +.border-l-2 { + border-left-width: 2px; +} + +.border-l-4 { + border-left-width: 4px; +} + .border-solid { border-style: solid; } @@ -1286,6 +1390,16 @@ video { border-color: transparent; } +.border-blue-100 { + --tw-border-opacity: 1; + border-color: rgb(219 234 254 / var(--tw-border-opacity)); +} + +.border-orange-100 { + --tw-border-opacity: 1; + border-color: rgb(255 237 213 / var(--tw-border-opacity)); +} + .bg-blue-100 { --tw-bg-opacity: 1; background-color: rgb(219 234 254 / var(--tw-bg-opacity)); @@ -1330,6 +1444,16 @@ video { background-color: rgb(254 249 195 / 0.6); } +.bg-green-100 { + --tw-bg-opacity: 1; + background-color: rgb(220 252 231 / var(--tw-bg-opacity)); +} + +.bg-orange-100 { + --tw-bg-opacity: 1; + background-color: rgb(255 237 213 / var(--tw-bg-opacity)); +} + .fill-blue-100 { fill: #dbeafe; } @@ -1355,6 +1479,26 @@ video { padding: 0.5rem; } +.p-4 { + padding: 1rem; +} + +.p-\[1\.5\] { + padding: 1.5; +} + +.p-\[2\.5\] { + padding: 2.5; +} + +.p-\[3\.5\] { + padding: 3.5; +} + +.p-\[6\.5\] { + padding: 6.5; +} + .px-1 { padding-left: 0.25rem; padding-right: 0.25rem; @@ -1387,6 +1531,18 @@ video { padding-top: 1rem; } +.pl-8 { + padding-left: 2rem; +} + +.pl-6 { + padding-left: 1.5rem; +} + +.pl-4 { + padding-left: 1rem; +} + .text-left { text-align: left; } @@ -1423,6 +1579,10 @@ video { font-size: 0.75rem; } +.text-2xl { + font-size: 1.563rem; +} + .font-bold { font-weight: 700; } @@ -1646,6 +1806,11 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { border-color: rgb(30 64 175 / var(--tw-border-opacity)); } +.hover\:border-orange-600:hover { + --tw-border-opacity: 1; + border-color: rgb(234 88 12 / var(--tw-border-opacity)); +} + .hover\:bg-blue-100:hover { --tw-bg-opacity: 1; background-color: rgb(219 234 254 / var(--tw-bg-opacity)); @@ -1827,6 +1992,16 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { border-color: rgb(75 85 99 / var(--tw-border-opacity)); } + .dark\:border-orange-600 { + --tw-border-opacity: 1; + border-color: rgb(234 88 12 / var(--tw-border-opacity)); + } + + .dark\:border-orange-400 { + --tw-border-opacity: 1; + border-color: rgb(251 146 60 / var(--tw-border-opacity)); + } + .dark\:bg-black { --tw-bg-opacity: 1; background-color: rgb(0 0 0 / var(--tw-bg-opacity)); @@ -1866,6 +2041,21 @@ h1, h2, h3, h4, h5, h6, h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { background-color: rgb(250 204 21 / var(--tw-bg-opacity)); } + .dark\:bg-green-600 { + --tw-bg-opacity: 1; + background-color: rgb(22 163 74 / var(--tw-bg-opacity)); + } + + .dark\:bg-orange-600 { + --tw-bg-opacity: 1; + background-color: rgb(234 88 12 / var(--tw-bg-opacity)); + } + + .dark\:bg-orange-400 { + --tw-bg-opacity: 1; + background-color: rgb(251 146 60 / var(--tw-bg-opacity)); + } + .dark\:text-blue-200 { --tw-text-opacity: 1; color: rgb(191 219 254 / var(--tw-text-opacity)); diff --git a/slices/admin/actions/trips/add_post.rb b/slices/admin/actions/trips/add_post.rb new file mode 100644 index 0000000..820e93e --- /dev/null +++ b/slices/admin/actions/trips/add_post.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Admin + module Actions + module Trips + class AddPost < Admin::Action + + include Deps["commands.trips.add_post"] + + def handle(req, res) + add_post.call(post_id: req.params[:post_id], trip_id: req.params[:trip_id]) + end + end + end + end +end diff --git a/slices/admin/actions/trips/create.rb b/slices/admin/actions/trips/create.rb new file mode 100644 index 0000000..7115594 --- /dev/null +++ b/slices/admin/actions/trips/create.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Admin + module Actions + module Trips + class Create < Admin::Action + + include Deps["commands.trips.create"] + + def handle(req, res) + create.call(trip: req.params[:trip]) + end + end + end + end +end diff --git a/slices/admin/actions/trips/index.rb b/slices/admin/actions/trips/index.rb new file mode 100644 index 0000000..ce9cd71 --- /dev/null +++ b/slices/admin/actions/trips/index.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Admin + module Actions + module Trips + class Index < Admin::Action + def handle(req, res) + end + end + end + end +end diff --git a/slices/admin/actions/trips/new.rb b/slices/admin/actions/trips/new.rb new file mode 100644 index 0000000..fedf222 --- /dev/null +++ b/slices/admin/actions/trips/new.rb @@ -0,0 +1,12 @@ +# frozen_string_literal: true + +module Admin + module Actions + module Trips + class New < Admin::Action + def handle(req, res) + end + end + end + end +end diff --git a/slices/admin/actions/trips/show.rb b/slices/admin/actions/trips/show.rb new file mode 100644 index 0000000..4c1e6ee --- /dev/null +++ b/slices/admin/actions/trips/show.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Admin + module Actions + module Trips + class Show < Admin::Action + + include Deps["views.trips.show"] + + def handle(req, res) + res.render show, id: req.params[:id] + end + end + end + end +end diff --git a/slices/admin/commands/trips/add_post.rb b/slices/admin/commands/trips/add_post.rb new file mode 100644 index 0000000..06c6b0b --- /dev/null +++ b/slices/admin/commands/trips/add_post.rb @@ -0,0 +1,16 @@ +module Admin + module Commands + module Trips + class AddPost + include Dry::Monads[:result] + include Deps["repos.post_trip_repo"] + + def call(trip_id:, post_id:) + post_trip_repo.create(trip_id: trip_id, post_id: post_id) + + Success() + end + end + end + end +end diff --git a/slices/admin/commands/trips/create.rb b/slices/admin/commands/trips/create.rb new file mode 100644 index 0000000..c476166 --- /dev/null +++ b/slices/admin/commands/trips/create.rb @@ -0,0 +1,16 @@ +module Admin + module Commands + module Trips + class Create + include Dry::Monads[:result] + include Deps["repos.trip_repo"] + + def call(trip:) + trip_repo.create(trip) + + Success() + end + end + end + end +end diff --git a/slices/admin/repos/post_repo.rb b/slices/admin/repos/post_repo.rb index 4f677cd..b3809c3 100644 --- a/slices/admin/repos/post_repo.rb +++ b/slices/admin/repos/post_repo.rb @@ -46,6 +46,12 @@ module Admin def archive(id:) posts.where(id: id).update(published_at: nil) end + + def created_between(start_date, end_date) + posts + .combine(:trips) + .published_between(start_date, end_date) + end end end end \ No newline at end of file diff --git a/slices/admin/repos/post_trip_repo.rb b/slices/admin/repos/post_trip_repo.rb new file mode 100644 index 0000000..7ef0fcf --- /dev/null +++ b/slices/admin/repos/post_trip_repo.rb @@ -0,0 +1,7 @@ +module Admin + module Repos + class PostTripRepo < Adamantium::Repo[:post_trips] + commands :create + end + end +end diff --git a/slices/admin/repos/trip_repo.rb b/slices/admin/repos/trip_repo.rb new file mode 100644 index 0000000..c1e1d34 --- /dev/null +++ b/slices/admin/repos/trip_repo.rb @@ -0,0 +1,15 @@ +module Admin + module Repos + class TripRepo < Adamantium::Repo[:trips] + commands :create + + def list + trips.order(:start_date).to_a + end + + def fetch(id) + trips.where(id: id).one + end + end + end +end diff --git a/slices/admin/templates/index.html.slim b/slices/admin/templates/index.html.slim index 0b70e55..689a6a9 100644 --- a/slices/admin/templates/index.html.slim +++ b/slices/admin/templates/index.html.slim @@ -15,6 +15,8 @@ div class="max-w-prose mx-auto prose dark:prose-invert" a href="/admin/tags/merge" Merge tags li a href="/admin/bookmarks" Bookmarks + li + a href="/admin/trips" Trips div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/slices/admin/templates/shared/_post.html.slim b/slices/admin/templates/shared/_post.html.slim new file mode 100644 index 0000000..223feb0 --- /dev/null +++ b/slices/admin/templates/shared/_post.html.slim @@ -0,0 +1,15 @@ +div class="mb-8 h-entry" + - if !added + button class="text-blue-600" hx-post="/admin/trips/add_post" hx-vals='{"trip_id": "#{trip_id}", "post_id": "#{post.id}"}' + = "Add to trip" + h3 class="text-xl font-semibold text-blue-600 mb-2" + a class="border-b-2 border-transparent hover:border-blue-600 hover:border-b-2" href="/post/#{post.slug}" + == post.content + div class="e-content prose-p:mb-0 prose-img:my-2 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline p-name text-base prose prose-ul:list-none prose-ul:pl-0 prose-li:pl-0 text-gray-800 dark:text-gray-200 prose-a:dark:text-gray-100" + div class="grid gap-4 grid-flow-row grid-cols-4 grid-rows-1" + -post.photos.each do |photo| + img class="w-44 h-44 object-cover rounded" src=photo["value"] + + p class="text-sm text-blue-400" + a href="/post/#{post.slug}" + = post.published_at diff --git a/slices/admin/templates/trips/index.html.slim b/slices/admin/templates/trips/index.html.slim new file mode 100644 index 0000000..54bbab7 --- /dev/null +++ b/slices/admin/templates/trips/index.html.slim @@ -0,0 +1,17 @@ +div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Admin // Trips + +div class="max-w-prose mx-auto" + + a class="rounded bg-blue-100 hover:bg-blue-200 text-blue-600 px-2 hover:cursor-pointer" href="/admin/trips/new" Add trip + + ul class="mt-4 mb-12" + - trips.each do |trip| + li class="dark:text-gray-200 text-gray-600" + a href="/admin/trips/#{trip.id}" + = "#{trip.name} (#{trip.start_date} - #{trip.end_date})" + +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" + + + diff --git a/slices/admin/templates/trips/new.html.slim b/slices/admin/templates/trips/new.html.slim new file mode 100644 index 0000000..cf3858c --- /dev/null +++ b/slices/admin/templates/trips/new.html.slim @@ -0,0 +1,27 @@ +div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Admin // Trips + +div class="max-w-prose mx-auto" + - if errors + div class="text-gray-100 dark:text-gray-100 bg-pink-100 dark:bg-pink-600 rounded px-4 py-2 mb-12" + p Errors: + - errors.each do |error| + li = "#{error[1].join(",")}" + + form method="POST" action="/admin/trips" + div class="mb-4" + label class="text-gray-800 dark:text-gray-200 mr-2" for="name" Name: + input class="text-gray-800 p-1 border border-gray-400" type="text" id="name" name="trip[name]" + + div class="mb-4" + label class="text-gray-800 dark:text-gray-200 mr-2" for="start_date" Start date: + input class="text-gray-800 p-1 border border-gray-400" type="date" id="start_date" name="trip[start_date]" + + div class="mb-4" + label class="text-gray-800 dark:text-gray-200 mr-2" for="end_date" End date: + input class="text-gray-800 p-1 border border-gray-400" type="date" id="end_date" name="trip[end_date]" + + div class="mb-4" + button class="rounded bg-blue-100 hover:bg-blue-200 text-blue-600 px-2 hover:cursor-pointer" type="submit" + = "Create" +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/slices/admin/templates/trips/show.html.slim b/slices/admin/templates/trips/show.html.slim new file mode 100644 index 0000000..a5779e7 --- /dev/null +++ b/slices/admin/templates/trips/show.html.slim @@ -0,0 +1,8 @@ +div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200" + h1 Admin // Trips // #{trip.name} + +div class="max-w-prose mx-auto" + - posts.each do |post| + == render "shared/post", post: post, trip_id: trip.id, added: post.trips.map(&:id).include?(trip.id) + +div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600" diff --git a/slices/admin/views/trips/index.rb b/slices/admin/views/trips/index.rb new file mode 100644 index 0000000..ccc0e8e --- /dev/null +++ b/slices/admin/views/trips/index.rb @@ -0,0 +1,14 @@ +module Admin + module Views + module Trips + class Index < Admin::View + + include Deps["repos.trip_repo"] + + expose :trips do + trip_repo.list + end + end + end + end +end \ No newline at end of file diff --git a/slices/admin/views/trips/new.rb b/slices/admin/views/trips/new.rb new file mode 100644 index 0000000..94aa8bc --- /dev/null +++ b/slices/admin/views/trips/new.rb @@ -0,0 +1,11 @@ +module Admin + module Views + module Trips + class New < Admin::View + expose :errors do + nil + end + end + end + end +end \ No newline at end of file diff --git a/slices/admin/views/trips/show.rb b/slices/admin/views/trips/show.rb new file mode 100644 index 0000000..55ccf65 --- /dev/null +++ b/slices/admin/views/trips/show.rb @@ -0,0 +1,18 @@ +module Admin + module Views + module Trips + class Show < Admin::View + + include Deps["repos.trip_repo", "repos.post_repo"] + + expose :trip do |id:| + trip_repo.fetch(id) + end + + expose :posts do |trip| + post_repo.created_between(trip.start_date, trip.end_date) + end + end + end + end +end \ No newline at end of file