Skip to content

Commit f73ce25

Browse files
authored
Merge pull request #11 from pantanal-labs/pagination
Add pagination
2 parents 28da2fc + f85031d commit f73ce25

File tree

16 files changed

+108
-115
lines changed

16 files changed

+108
-115
lines changed

assets/css/app.css

+3-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@
22
@import "tailwindcss/components";
33
@import "tailwindcss/utilities";
44

5-
5+
.post-body h2 {
6+
@apply text-2xl mt-8 mb-6 font-bold;
7+
}

assets/js/app.js

-3
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,12 @@ import "phoenix_html";
1515
import { Socket } from "phoenix";
1616
// import NProgress from "nprogress";
1717
import { LiveSocket } from "phoenix_live_view";
18-
import Hooks from "./hooks";
1918

2019
let csrfToken = document
2120
.querySelector("meta[name='csrf-token']")
2221
.getAttribute("content");
2322
let liveSocket = new LiveSocket("/live", Socket, {
2423
params: { _csrf_token: csrfToken },
25-
hooks: Hooks,
2624
});
2725

2826
// Show progress bar on live navigation and form submits
@@ -36,4 +34,3 @@ liveSocket.connect();
3634
//liveSocket.enableDebug()
3735
// >> liveSocket.enableLatencySim(1000)
3836
window.liveSocket = liveSocket;
39-

assets/js/hooks.js

-9
This file was deleted.

assets/js/hooks/editor.js

-5
This file was deleted.

assets/js/hooks/infinitescroll.js

-22
This file was deleted.

config/config.exs

+3-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ config :tailwind,
4343
--input=css/app.css
4444
--output=../priv/static/assets/app.css
4545
),
46-
cd: Path.expand("../assets", __DIR__)
47-
]
46+
cd: Path.expand("../assets", __DIR__)
47+
]
48+
4849
# Import environment specific config. This must remain at the bottom
4950
# of this file so it overrides the configuration defined above.
5051
import_config "#{Mix.env()}.exs"

lib/brasil_em_dados/blog.ex

+7-11
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,21 @@ defmodule BrasilEmDados.Blog do
2525
|> Repo.all()
2626
end
2727

28-
def list_public_posts(offset, limit) do
28+
def list_public_posts(page) do
2929
Post
3030
|> where(status: "published")
31-
|> offset(^offset)
32-
|> limit(^limit)
33-
|> order_by(:inserted_at)
31+
|> order_by([p], asc: p.inserted_at, asc: p.id)
3432
|> preload([:user, :tags])
35-
|> Repo.all()
33+
|> Repo.paginate(page: page)
3634
end
3735

38-
def list_posts_by_tag(tag_name, offset, limit) do
39-
Repo.all(
40-
from p in Post,
36+
def list_posts_by_tag(tag_name, page) do
37+
query = from p in Post,
4138
join: t in assoc(p, :tags),
4239
where: t.name == ^tag_name,
43-
offset: ^offset,
44-
limit: ^limit,
4540
preload: [:tags]
46-
)
41+
42+
Repo.paginate(query, page: page)
4743
end
4844

4945
@doc """

lib/brasil_em_dados/repo.ex

+2
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,6 @@ defmodule BrasilEmDados.Repo do
22
use Ecto.Repo,
33
otp_app: :brasil_em_dados,
44
adapter: Ecto.Adapters.Postgres
5+
6+
use Scrivener
57
end

lib/brasil_em_dados_web/live/blog_live/index.ex

+9-48
Original file line numberDiff line numberDiff line change
@@ -2,58 +2,19 @@ defmodule BrasilEmDadosWeb.BlogLive.Index do
22
use BrasilEmDadosWeb, :live_view
33
alias BrasilEmDados.Blog
44

5-
@posts_per_page 10
6-
75
@impl true
86
def mount(params, _session, %{assigns: assigns} = socket) do
9-
if assigns.live_action == :index do
10-
{:ok,
11-
socket
12-
|> assign(current_page: 1, update: "")
13-
|> get_posts(:index, nil)}
14-
else
15-
{:ok,
16-
socket
17-
|> assign(current_page: 1, update: "")
18-
|> get_tag(params["tag_name"])
19-
|> get_posts(:tag, params["tag_name"])}
20-
end
21-
end
22-
23-
@impl true
24-
def handle_event("load-more", _params, %{assigns: assigns} = socket) do
25-
if Map.has_key?(assigns, :tag) do
26-
{:noreply,
27-
socket
28-
|> update(:current_page, &(&1 + 1))
29-
|> update_with_append()
30-
|> get_posts(assigns.live_action, assigns.tag.name)}
31-
else
32-
{:noreply,
33-
socket
34-
|> update(:current_page, &(&1 + 1))
35-
|> update_with_append()
36-
|> get_posts(assigns.live_action, nil)}
37-
end
38-
end
7+
page = String.to_integer(params["page"] || "1")
398

40-
defp get_posts(socket, :index, nil) do
41-
offset = (socket.assigns.current_page - 1) * @posts_per_page
42-
posts = Blog.list_public_posts(offset, @posts_per_page)
43-
44-
assign(socket, posts: posts)
9+
{:ok,
10+
socket
11+
|> assign(:page, page)
12+
|> get_posts()}
4513
end
4614

47-
defp get_posts(socket, :tag, tag_name) do
48-
offset = (socket.assigns.current_page - 1) * @posts_per_page
49-
posts = Blog.list_posts_by_tag(tag_name, offset, @posts_per_page)
50-
51-
assign(socket, posts: posts)
52-
end
53-
54-
defp update_with_append(socket), do: assign(socket, update: "append")
55-
56-
defp get_tag(socket, tag_name) do
57-
assign(socket, tag: Blog.get_tag_by_name!(tag_name))
15+
defp get_posts(socket) do
16+
page = socket.assigns.page
17+
%{entries: posts, total_pages: total_pages} = Blog.list_public_posts(page)
18+
assign(socket, posts: posts, total_pages: total_pages)
5819
end
5920
end
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
11
<section class="text-gray-600 body-font">
22
<div class="container px-5 mx-auto">
3-
<div class="w-full bg-red p-6">
4-
<%= if @live_action == :tag do %>
5-
<h1 class="text-2xl font-bold uppercase"><%= @tag.name %></h1>
6-
<% end %>
7-
</div>
8-
<div id="posts" phx-update="{@update}" class="flex flex-wrap -m-3">
3+
<div id="posts" class="flex flex-wrap -m-3">
94
<%= for post <- @posts do %>
105
<div id="post-{post.id}" class="p-4 md:w-1/2">
116
<%= live_redirect to: Routes.blog_show_path(@socket, :show, post.slug) do %>
127
<div class="border-2 border-gray-200 border-opacity-60 rounded-md overflow-hidden">
138
<div class="p-4">
149
<h1 class="text-xl font-bold text-gray-900 mb-4"><%= post.title %> </h1>
1510
<div class="flex items-center flex-wrap">
16-
<p class="text-black leading-relaxed mb-3">Photo booth fam kinfolk cold-pressed sriracha leggings jianbing microdosing tousled waistcoat.</p>
11+
<p class="text-black leading-relaxed mb-3">Photo booth fam kinfolk cold-pressed sriracha leggings jianbing microdosing tousled waistcoat.</p>
1712
<span class="text-gray-500 mr-3 inline-flex items-center leading-none text-sm pr-3 py-1">
1813
<%= "#{post.inserted_at.day}/#{post.inserted_at.month}/#{post.inserted_at.year}" %>
1914
</span>
@@ -24,7 +19,16 @@
2419
</div>
2520
<% end %>
2621
</div>
27-
<div id="loading" phx-hook="InfiniteScroll">
22+
<div class="mx-auto flex justify-center items-center p-2 w-full">
23+
<%= if @page > 1 do %>
24+
<%= live_redirect("Anterior", to: Routes.blog_index_path(@socket, :index, page: @page - 1), class: "p-1 hover:text-gray-900") %>
25+
<% end %>
26+
<div class="py-2 px-4 text-black">
27+
<%= @page %> de <%= @total_pages %>
28+
</div>
29+
<%= if @total_pages > @page do %>
30+
<%= live_redirect("Proximo", to: Routes.blog_index_path(@socket, :index, page: @page + 1), class: "p-1 hover:text-gray-900") %>
31+
<% end %>
2832
</div>
2933
</div>
3034
</section>

lib/brasil_em_dados_web/live/blog_live/show.html.heex

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<%= "#{@post.inserted_at.day}/#{@post.inserted_at.month}/#{@post.inserted_at.year}" %> · Roger Pinho
99
<%= if @post.tags != [] do %>
1010
<%= for tag <- @post.tags do %>
11-
<%= live_redirect class: "inline-block py-1 px-2 rounded bg-#{tag.color}-50 uppercase text-#{tag.color}-500 text-xs font-medium tracking-widest", to: Routes.blog_index_path(@socket, :tag, tag.name) do %><%= tag.name %><% end %>
11+
<%= live_redirect class: "inline-block py-1 px-2 rounded bg-#{tag.color}-50 uppercase text-#{tag.color}-500 text-xs font-medium tracking-widest", to: Routes.blog_tag_path(@socket, :index, tag.name) do %><%= tag.name %><% end %>
1212
<% end %>
1313
<% end %>
1414
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
defmodule BrasilEmDadosWeb.BlogLive.Tag do
2+
use BrasilEmDadosWeb, :live_view
3+
alias BrasilEmDados.Blog
4+
5+
@impl true
6+
def mount(params, _session, %{assigns: assigns} = socket) do
7+
page = String.to_integer(params["page"] || "1")
8+
{:ok, socket
9+
|> assign(page: page)
10+
|> get_tag(params["tag_name"])
11+
|> get_posts(params["tag_name"])}
12+
end
13+
14+
defp get_posts(socket, tag_name) do
15+
page = socket.assigns.page
16+
%{entries: posts, total_pages: total_pages} = Blog.list_posts_by_tag(tag_name, page)
17+
18+
assign(socket, posts: posts, total_pages: total_pages)
19+
end
20+
21+
defp get_tag(socket, tag_name) do
22+
assign(socket, tag: Blog.get_tag_by_name!(tag_name))
23+
end
24+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<section class="text-gray-600 body-font">
2+
<div class="container px-5 mx-auto">
3+
<div class="w-full bg-red p-6">
4+
<%= if(@tag) do %>
5+
<h1 class="text-2xl font-bold uppercase"><%= @tag.name %></h1>
6+
<% end %>
7+
</div>
8+
<div id="posts" class="flex flex-wrap -m-3">
9+
<%= for post <- @posts do %>
10+
<div id="post-{post.id}" class="p-4 md:w-1/2">
11+
<%= live_redirect to: Routes.blog_show_path(@socket, :show, post.slug) do %>
12+
<div class="border-2 border-gray-200 border-opacity-60 rounded-md overflow-hidden">
13+
<div class="p-4">
14+
<h1 class="text-xl font-bold text-gray-900 mb-4"><%= post.title %> </h1>
15+
<div class="flex items-center flex-wrap">
16+
<p class="text-black leading-relaxed mb-3">Photo booth fam kinfolk cold-pressed sriracha leggings jianbing microdosing tousled waistcoat.</p>
17+
<span class="text-gray-500 mr-3 inline-flex items-center leading-none text-sm pr-3 py-1">
18+
<%= "#{post.inserted_at.day}/#{post.inserted_at.month}/#{post.inserted_at.year}" %>
19+
</span>
20+
</div>
21+
</div>
22+
</div>
23+
<% end %>
24+
</div>
25+
<% end %>
26+
</div>
27+
<div class="mx-auto flex justify-center items-center p-2 w-full">
28+
<%= if @page > 1 do %>
29+
<%= live_redirect("Anterior", to: Routes.blog_tag_path(@socket, :index, @tag.name, page: @page - 1), class: "p-1 hover:text-gray-900") %>
30+
<% end %>
31+
<div class="py-2 px-4 text-black">
32+
<%= @page %> de <%= @total_pages %>
33+
</div>
34+
<%= if @total_pages > @page do %>
35+
<%= live_redirect("Proximo", to: Routes.blog_tag_path(@socket, :index, @tag.name, page: @page + 1), class: "p-1 hover:text-gray-900") %>
36+
<% end %>
37+
</div>
38+
</div>
39+
</section>

lib/brasil_em_dados_web/router.ex

+1-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,7 @@ defmodule BrasilEmDadosWeb.Router do
8383
pipe_through [:browser]
8484

8585
live "/", BlogLive.Index, :index
86-
# live "/blog", BlogLive.Index, :index
87-
live "/blog/tag/:tag_name", BlogLive.Index, :tag
86+
live "/blog/tag/:tag_name", BlogLive.Tag, :index
8887
live "/blog/:slug", BlogLive.Show, :show
8988

9089
scope "/admin" do

mix.exs

+4-3
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,10 @@ defmodule BrasilEmDados.MixProject do
4949
{:gettext, "~> 0.11"},
5050
{:jason, "~> 1.0"},
5151
{:plug_cowboy, "~> 2.0"},
52-
{:earmark, "~> 1.4.14" },
53-
{:esbuild,"~> 0.4.0", runtime: Mix.env() == :dev},
54-
{:tailwind, "~> 0.1.5", runtime: Mix.env() == :dev}
52+
{:earmark, "~> 1.4.14"},
53+
{:esbuild, "~> 0.4.0", runtime: Mix.env() == :dev},
54+
{:tailwind, "~> 0.1.5", runtime: Mix.env() == :dev},
55+
{:scrivener_ecto, "~> 2.7.0"}
5556
]
5657
end
5758

mix.lock

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"html_entities": {:hex, :html_entities, "0.5.1", "1c9715058b42c35a2ab65edc5b36d0ea66dd083767bef6e3edb57870ef556549", [:mix], [], "hexpm", "30efab070904eb897ff05cd52fa61c1025d7f8ef3a9ca250bc4e6513d16c32de"},
2222
"jason": {:hex, :jason, "1.3.0", "fa6b82a934feb176263ad2df0dbd91bf633d4a46ebfdffea0c8ae82953714946", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "53fc1f51255390e0ec7e50f9cb41e751c260d065dcba2bf0d08dc51a4002c2ac"},
2323
"mime": {:hex, :mime, "2.0.2", "0b9e1a4c840eafb68d820b0e2158ef5c49385d17fb36855ac6e7e087d4b1dcc5", [:mix], [], "hexpm", "e6a3f76b4c277739e36c2e21a2c640778ba4c3846189d5ab19f97f126df5f9b7"},
24+
"paginator": {:hex, :paginator, "1.1.0", "e502a91b08d14a6c8319f86eae027e67b0c699ffca4d76afbcb43eea5f32cd53", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.2.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "b484f533b4a157ff60df7c988c9ef04e9c64e1f96e74a48a700717517a1ba5d9"},
2425
"phoenix": {:hex, :phoenix, "1.6.6", "281c8ce8dccc9f60607346b72cdfc597c3dde134dd9df28dff08282f0b751754", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "807bd646e64cd9dc83db016199715faba72758e6db1de0707eef0a2da4924364"},
2526
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
2627
"phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"},
@@ -35,6 +36,8 @@
3536
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
3637
"postgrex": {:hex, :postgrex, "0.16.1", "f94628a32c571266f53cd1e5fca705e626e2417bf1eee6f868985d14e874160a", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "6b225df32c857b9430619dbe30200a7ae664e23415a771ae9209396ee8eeee64"},
3738
"ranch": {:hex, :ranch, "1.8.0", "8c7a100a139fd57f17327b6413e4167ac559fbc04ca7448e9be9057311597a1d", [:make, :rebar3], [], "hexpm", "49fbcfd3682fab1f5d109351b61257676da1a2fdbe295904176d5e521a2ddfe5"},
39+
"scrivener": {:hex, :scrivener, "2.7.2", "1d913c965ec352650a7f864ad7fd8d80462f76a32f33d57d1e48bc5e9d40aba2", [:mix], [], "hexpm", "7866a0ec4d40274efbee1db8bead13a995ea4926ecd8203345af8f90d2b620d9"},
40+
"scrivener_ecto": {:hex, :scrivener_ecto, "2.7.0", "cf64b8cb8a96cd131cdbcecf64e7fd395e21aaa1cb0236c42a7c2e34b0dca580", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:scrivener, "~> 2.4", [hex: :scrivener, repo: "hexpm", optional: false]}], "hexpm", "e809f171687806b0031129034352f5ae44849720c48dd839200adeaf0ac3e260"},
3841
"tailwind": {:hex, :tailwind, "0.1.5", "5561bed6c114434415077972f6d291e7d43b258ef0ee756bda1ead7293811f61", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "3be21a0ddec7fc29b323ee72bed7516078a2787f7b142e455698a2209296e2a5"},
3942
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
4043
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},

0 commit comments

Comments
 (0)