Add trips
This commit is contained in:
12
app/actions/trips/index.rb
Normal file
12
app/actions/trips/index.rb
Normal file
@@ -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
|
16
app/actions/trips/show.rb
Normal file
16
app/actions/trips/show.rb
Normal file
@@ -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
|
@@ -207,7 +207,7 @@ module Adamantium
|
||||
def fetch!(slug)
|
||||
posts
|
||||
.published
|
||||
.combine(:tags)
|
||||
.combine(:tags, :trips)
|
||||
.where(slug: slug)
|
||||
.one!
|
||||
end
|
||||
|
18
app/repos/trip_repo.rb
Normal file
18
app/repos/trip_repo.rb
Normal file
@@ -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
|
@@ -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
|
||||
|
||||
|
@@ -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"
|
||||
|
24
app/templates/shared/_compact_post.html.slim
Normal file
24
app/templates/shared/_compact_post.html.slim
Normal file
@@ -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"
|
||||
= "🛫"
|
15
app/templates/trips/index.html.slim
Normal file
15
app/templates/trips/index.html.slim
Normal file
@@ -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"
|
9
app/templates/trips/show.html.slim
Normal file
9
app/templates/trips/show.html.slim
Normal file
@@ -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"
|
@@ -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
|
||||
|
13
app/views/trips/index.rb
Normal file
13
app/views/trips/index.rb
Normal file
@@ -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
|
21
app/views/trips/show.rb
Normal file
21
app/views/trips/show.rb
Normal file
@@ -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
|
@@ -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
|
||||
|
14
db/migrate/20230509092845_create_trips.rb
Normal file
14
db/migrate/20230509092845_create_trips.rb
Normal file
@@ -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
|
10
db/migrate/20230509094041_create_post_trips.rb
Normal file
10
db/migrate/20230509094041_create_post_trips.rb
Normal file
@@ -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
|
18
lib/adamantium/persistence/relations/post_trips.rb
Normal file
18
lib/adamantium/persistence/relations/post_trips.rb
Normal file
@@ -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
|
@@ -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
|
||||
|
18
lib/adamantium/persistence/relations/trips.rb
Normal file
18
lib/adamantium/persistence/relations/trips.rb
Normal file
@@ -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
|
@@ -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));
|
||||
|
16
slices/admin/actions/trips/add_post.rb
Normal file
16
slices/admin/actions/trips/add_post.rb
Normal file
@@ -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
|
16
slices/admin/actions/trips/create.rb
Normal file
16
slices/admin/actions/trips/create.rb
Normal file
@@ -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
|
12
slices/admin/actions/trips/index.rb
Normal file
12
slices/admin/actions/trips/index.rb
Normal file
@@ -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
|
12
slices/admin/actions/trips/new.rb
Normal file
12
slices/admin/actions/trips/new.rb
Normal file
@@ -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
|
16
slices/admin/actions/trips/show.rb
Normal file
16
slices/admin/actions/trips/show.rb
Normal file
@@ -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
|
16
slices/admin/commands/trips/add_post.rb
Normal file
16
slices/admin/commands/trips/add_post.rb
Normal file
@@ -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
|
16
slices/admin/commands/trips/create.rb
Normal file
16
slices/admin/commands/trips/create.rb
Normal file
@@ -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
|
@@ -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
|
7
slices/admin/repos/post_trip_repo.rb
Normal file
7
slices/admin/repos/post_trip_repo.rb
Normal file
@@ -0,0 +1,7 @@
|
||||
module Admin
|
||||
module Repos
|
||||
class PostTripRepo < Adamantium::Repo[:post_trips]
|
||||
commands :create
|
||||
end
|
||||
end
|
||||
end
|
15
slices/admin/repos/trip_repo.rb
Normal file
15
slices/admin/repos/trip_repo.rb
Normal file
@@ -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
|
@@ -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"
|
||||
|
||||
|
15
slices/admin/templates/shared/_post.html.slim
Normal file
15
slices/admin/templates/shared/_post.html.slim
Normal file
@@ -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
|
17
slices/admin/templates/trips/index.html.slim
Normal file
17
slices/admin/templates/trips/index.html.slim
Normal file
@@ -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"
|
||||
|
||||
|
||||
|
27
slices/admin/templates/trips/new.html.slim
Normal file
27
slices/admin/templates/trips/new.html.slim
Normal file
@@ -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"
|
8
slices/admin/templates/trips/show.html.slim
Normal file
8
slices/admin/templates/trips/show.html.slim
Normal file
@@ -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"
|
14
slices/admin/views/trips/index.rb
Normal file
14
slices/admin/views/trips/index.rb
Normal file
@@ -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
|
11
slices/admin/views/trips/new.rb
Normal file
11
slices/admin/views/trips/new.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
module Admin
|
||||
module Views
|
||||
module Trips
|
||||
class New < Admin::View
|
||||
expose :errors do
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
18
slices/admin/views/trips/show.rb
Normal file
18
slices/admin/views/trips/show.rb
Normal file
@@ -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
|
Reference in New Issue
Block a user