Add books page

This commit is contained in:
2023-06-26 21:07:29 +10:00
parent c92b74b238
commit 2e019c00f4
13 changed files with 179 additions and 2 deletions

View File

@@ -0,0 +1,13 @@
module Adamantium
module Actions
module Books
class Index < Action
include Deps["views.books.index"]
def handle(req, res)
res.render index
end
end
end
end
end

View File

@@ -0,0 +1,19 @@
require "dry/monads"
module Adamantium
module Commands
module Posts
class CreateBookPost < Command
include Deps["repos.post_repo"]
include Dry::Monads[:result]
def call(post)
created_post = post_repo.create(post)
Success(created_post)
end
end
end
end
end

View File

@@ -6,9 +6,11 @@ module Adamantium
"validation.posts.post_contract",
"validation.posts.bookmark_contract",
"validation.posts.checkin_contract",
"validation.posts.book_contract",
"commands.posts.create_entry",
"commands.posts.create_bookmark",
"commands.posts.create_checkin"
"commands.posts.create_checkin",
"commands.posts.create_book_post"
]
def call(entry_type:)
@@ -17,6 +19,8 @@ module Adamantium
{command: create_bookmark, validation: bookmark_contract}
in Entities::CheckinRequest
{command: create_checkin, validation: checkin_contract}
in Entities::BookRequest
{command: create_book_post, validation: book_contract}
else
{command: create_entry, validation: post_contract}
end

View File

@@ -0,0 +1,27 @@
# frozen_string_literal: false
# auto_register: false
module Adamantium
module Decorators
module Books
class Decorator < SimpleDelegator
def display_published_at
published_at.strftime("%e %B, %Y")
end
def machine_published_at
published_at.rfc2822
end
def syndicated?
!syndication_sources.empty?
end
def template_type
:book
end
end
end
end
end

View File

@@ -0,0 +1,15 @@
module Adamantium
module Entities
class BookRequest < Dry::Struct
attribute :h, Types::Coercible::String
attribute :content, Types::Coercible::String
attribute :book_status, Types::Coercible::String
attribute :name, Types::Coercible::String
attribute :book_author, Types::Coercible::String
attribute :slug, Types::Coercible::String
attribute :category, Types::Array.of(Types::Coercible::String)
attribute :published_at, Types::Nominal::DateTime
attribute :post_type, Types::Coercible::String
end
end
end

View File

@@ -127,6 +127,15 @@ module Adamantium
.to_a
end
def books_listing(limit: nil)
posts
.where(post_type: "book")
.published
.order(Sequel.desc(:published_at))
.limit(limit)
.to_a
end
def bookmark_listing(query: nil)
base = posts
.where(post_type: "bookmark")

View File

@@ -0,0 +1,23 @@
- context.content_for(:title, "Books | ")
div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200"
h1 Books
div class="mb-12 max-w-prose mx-auto"
table class="prose dark:prose-invert table-auto"
thead
tr
td Title
td Author
td Status
- books.each do |book|
tr
td
/ a href="/books/#{book.slug}"
= book.name
td
= book.book_author
td
= book.book_status
div class="max-w-screen-md mx-auto border-t-4 border-solid border-gray-400 dark:border-gray-600"

View File

@@ -0,0 +1,18 @@
module Adamantium
module Validation
module Posts
class BookContract < Dry::Validation::Contract
params do
required(:name).maybe(:string)
required(:content).filled(:string)
required(:category).array(:string)
required(:published_at).maybe(:time)
required(:slug).filled(:string)
required(:post_type).value(included_in?: %w[book])
required(:book_author).maybe(:string)
required(:book_status).value(included_in?: %w[to-read reading read])
end
end
end
end
end

15
app/views/books/index.rb Normal file
View File

@@ -0,0 +1,15 @@
module Adamantium
module Views
module Books
class Index < Adamantium::View
include Deps["repos.post_repo"]
expose :books do
post_repo.books_listing.map do |book|
Decorators::Books::Decorator.new book
end
end
end
end
end
end

View File

@@ -59,6 +59,8 @@ module Adamantium
get "/podcasts", to: "podcasts.index"
get "/books", to: "books.index"
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"

View File

@@ -0,0 +1,10 @@
# frozen_string_literal: true
ROM::SQL.migration do
change do
alter_table :posts do
add_column :book_status, :text, default: nil
add_column :book_author, :text, default: nil
end
end
end

View File

@@ -13,6 +13,9 @@ module Adamantium
when :checkin
checkin_params = parse_checkin_params(params)
Entities::CheckinRequest.new(checkin_params)
when :book
book_params = parse_book_params(params)
Entities::BookRequest.new(book_params)
else
req_params = parse_post_params(req_type, cont_type, params)
Entities::PostRequest.new(req_params)
@@ -23,6 +26,7 @@ module Adamantium
def content_type(params)
return :bookmark if params[:"bookmark-of"]
return :book if params.dig(:properties, :"read-of")
return :checkin if params.dig(:properties, :checkin)
:post
end
@@ -110,5 +114,23 @@ module Adamantium
new_params[:location] = "geo:#{location.dig(:latitude).first},#{location.dig(:longitude).first};u=0"
new_params
end
def parse_book_params(params)
new_params = {}
new_params[:post_type] = "book"
entry = params[:properties]
new_params[:h] = "entry"
new_params[:content] = entry[:summary].first
new_params[:book_status] = entry[:"read-status"].first
book = params.dig(:properties, :"read-of").first[:properties]
new_params[:name] = book[:name].first
new_params[:book_author] = book[:author].first
new_params[:slug] = book[:uid].first
new_params[:category] = []
new_params[:published_at] = Time.now
new_params
end
end
end

View File

@@ -9,5 +9,5 @@ div class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:
button hx-post="/admin/posts/#{post.id}/syndicate/day_one" Send to Day One
article class="mb-12 prose dark:prose-invert max-w-prose mx-auto text-gray-800 dark:text-gray-200 prose-a:text-blue-600 prose-a:no-underline hover:prose-a:underline prose-img:rounded"
h1= post.name
textarea class="w-full border-pink-200 border-2 rounded p-2" x-data="{ resize: () => { $el.style.height = '5px'; $el.style.height = $el.scrollHeight + 'px' } }" x-init="resize()" @input="resize()"
textarea class="text-gray-800 w-full border-blue-200 border-2 rounded p-2" x-data="{ resize: () => { $el.style.height = '5px'; $el.style.height = $el.scrollHeight + 'px' } }" x-init="resize()" @input="resize()"
== markdown_body