{date_to_string(@main_new.inserted_at)}
+ ++ {@main_new.titulo} +
+ ++ {handle_notice_desc_length(@main_new.conteudo)} +
+diff --git a/.env.dev b/.env.dev index 6f05352e..51b1e4ee 100644 --- a/.env.dev +++ b/.env.dev @@ -4,7 +4,7 @@ export DATABASE_USER=postgres export DATABASE_PASS=postgres export DATABASE_HOST=127.0.0.1 -export DATABASE_NAME=postgres +export DATABASE_NAME=pescarte export DATABASE_PORT=54322 export DATABASE_URL=ecto://$DATABASE_USER:$DATABASE_PASS@$DATABASE_HOST:$DATABASE_PORT/$DATABASE_NAME diff --git a/assets/css/noticias.scss b/assets/css/noticias.scss index b8779238..175d30f6 100644 --- a/assets/css/noticias.scss +++ b/assets/css/noticias.scss @@ -1,11 +1,25 @@ .noticias-grid, - .noticia-wrapper { +.noticia-wrapper { max-width: 100vw !important; div { max-width: 100vw; } } +.landing-grid { + .news-container { + margin-top: -15%; + } +} + +@media (max-width: 768px) { + .landing-grid { + .news-container { + margin-top: -35%; + } + } +} + /* trocando gallery-carousel por land-carousel */ .land-carousel { margin-bottom: 70px; @@ -56,28 +70,28 @@ /* pegando o get-to-know do sobre e ajustando as notícias */ .get-to-know { display: flex; + flex-direction: column; align-items: center; justify-content: center; gap: 56px; - padding: 80px 40px; + padding: 10px 10px 60px 10px; img { object-fit: cover; height: 465px; - width: 50%; - max-width: 668px; + width: 75%; + max-width: 75%; border-radius: 16px; flex-shrink: 1; } .know-content { display: flex; flex-direction: column; - width: 50%; + width: 75%; gap: 25px; } @media (max-width: 768px) { .get-to-know { - flex-direction: column; align-items: center; justify-content: center; gap: 18px; @@ -103,17 +117,18 @@ justify-content: center; gap: 56px; padding: 80px 40px; + width: 75%; + margin: 0 auto; } .noticia-text { - display: flex; - flex-direction: column; - align-items: center; - width: 100%; - gap: 25px; + display: flex; + flex-direction: column; + align-items: center; + width: 100%; + gap: 25px; } - /* Estilo para telas pequenas (móveis) */ @media (max-width: 768px) { .phases { @@ -122,6 +137,7 @@ justify-content: center; gap: 18px; padding: 40px 20px; + margin: 0; } .noticia-text { width: 100vw; @@ -158,7 +174,7 @@ } .noticia .noticia-descricao h2 { - color: #0064C8; + color: #0064c8; font-size: 32px; line-height: 38px; font-weight: 700; @@ -176,7 +192,7 @@ .noticia .noticia-descricao strong em { text-decoration: underline; - color: #0064C8; + color: #0064c8; font-weight: 400; font-style: normal; } @@ -187,11 +203,10 @@ margin-bottom: 40px; } - .noticia .noticia-descricao p a { font-weight: 700; line-height: 24px; - color: #0064C8; + color: #0064c8; } .noticia .noticia-descricao p a::after { @@ -218,3 +233,202 @@ padding: 40px; } } + +/* Estilização página de listagem de notícias */ +.news-container { + grid-area: news; + + h2 { + display: flex; + justify-content: center; + margin-top: 40px; + margin-bottom: 5rem; + } + + .news-cards { + @apply flex flex-wrap justify-center md:mt-10; + + .news-item { + @apply flex flex-col max-w-sm; + margin: 0 2.5rem 2.5rem 2.5rem; + width: 20.125rem; + gap: 6px; + + .text-container { + display: flex; + flex-direction: column; + gap: 6px; + + .news-date { + font-size: 12px; + font-weight: 400; + color: #66a2de; + line-height: 24px; + } + } + + img { + border-radius: 8px; + width: 100%; + height: auto; + object-fit: cover; + max-height: 238px; + } + + h2 { + display: flex; + justify-content: center; + } + + a.link { + display: flex; + align-items: center; + margin: auto 0 1.5rem 1.5rem; + + button { + gap: 1rem; + + p { + font-family: "Work Sans"; + font-size: 1rem; + font-style: normal; + font-weight: 500; + line-height: 1.125rem; + } + + svg { + width: 1.5rem; + height: 1.5rem; + } + } + } + } + } +} + +/* Estilização da notícia destaque na página */ +.main-new { + width: 90%; + display: flex; + justify-content: space-around; + align-items: flex-start; + margin: 0 auto; + + a { + width: 60%; + + img { + border-radius: 16px; + width: 90%; + max-height: 432px; + } + } + + .main-new-text-container { + width: 40%; + padding: 3rem 0; + display: flex; + flex-direction: column; + align-items: flex-start; + text-align: start; + + .news-date { + font-size: 14px; + font-weight: 400; + color: #66a2de; + line-height: 24px; + } + + a{ + width: 100%; + } + + .news-title { + font-size: 32px; + font-weight: 700; + line-height: 46px; + color: #0064c8; + } + + .news-description { + font-size: 14px; + font-weight: 400; + color: #101010; + line-height: 24px; + } + } +} + +@media (max-width: 768px) { + .main-new { + width: 100%; + flex-direction: column; + justify-content: center; + align-items: center; + + a { + width: 90%; + + img { + width: 100%; + min-height: 400px; + max-height: none; + } + } + + .main-new-text-container { + width: 80%; + } + } +} +/*Fim notícia destaque*/ + +/*Estilização searchbar*/ +.search-container { + width: 600px; + display: flex; + flex-direction: column; + margin: -1rem auto 2rem auto; + border-radius: 4px; + gap: 12px; + + input{ + width: inherit; + border: 1.5px solid #E7E7E7; + border-radius: 4px; + padding: 12px; + + ::placeholder{ + color: #E7E7E7; + } + } + .tags-container{ + display: flex; + gap: 12px; + justify-content: space-around; + align-items: center; + + li{ + color: #0064c8; + background-color: #F2F7FC; + padding: 6px 30px; + font-size: 16px; + border-radius: 4px; + cursor: pointer; + } + + .active{ + background-color: #0064c8; + color: #FFF; + } + + } + +} + +@media (max-width: 768px){ + .search-container{ + margin-top: 0px; + width: 328px; + } +} diff --git a/assets/package-lock.json b/assets/package-lock.json index 45fbb69f..c0b1c88d 100644 --- a/assets/package-lock.json +++ b/assets/package-lock.json @@ -25,21 +25,6 @@ "topbar": "^3.0.0" } }, - "../deps/phoenix": { - "version": "1.7.18", - "license": "MIT" - }, - "../deps/phoenix_html": { - "version": "4.1.0" - }, - "../deps/phoenix_live_view": { - "version": "0.20.17", - "license": "MIT", - "devDependencies": { - "@playwright/test": "^1.43.1", - "monocart-reporter": "^2.3.1" - } - }, "node_modules/@alloc/quick-lru": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/@alloc/quick-lru/-/quick-lru-5.2.0.tgz", @@ -1367,16 +1352,18 @@ } }, "node_modules/phoenix": { - "resolved": "../deps/phoenix", - "link": true + "version": "1.7.18", + "resolved": "file:../deps/phoenix", + "license": "MIT" }, "node_modules/phoenix_html": { - "resolved": "../deps/phoenix_html", - "link": true + "version": "4.2.0", + "resolved": "file:../deps/phoenix_html" }, "node_modules/phoenix_live_view": { - "resolved": "../deps/phoenix_live_view", - "link": true + "version": "0.20.17", + "resolved": "file:../deps/phoenix_live_view", + "license": "MIT" }, "node_modules/picocolors": { "version": "1.0.0", diff --git a/docker-compose.yml b/docker-compose.yml index 50e8ee05..0c8530ed 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,4 @@ -version: "3.8" + services: pescarte: diff --git a/lib/pescarte/blog/blog.ex b/lib/pescarte/blog/blog.ex index b004bfab..f636c231 100644 --- a/lib/pescarte/blog/blog.ex +++ b/lib/pescarte/blog/blog.ex @@ -3,6 +3,7 @@ defmodule Pescarte.Blog do O contexto Blog é responsável por gerenciar as operações relacionadas a postagens e tags. """ import Ecto.Query + alias Pescarte.Blog.Entity.Tag alias Pescarte.Blog.Post alias Pescarte.Database.Repo @@ -15,7 +16,7 @@ defmodule Pescarte.Blog do optional(:page_size) => pos_integer() } - @spec list_posts_with_filter(filters()) :: {:ok, list(Post.t())} | {:error, term()} + @spec list_posts_with_filter(filters()) :: list(Post.t()) | {:error, term()} def list_posts_with_filter(filters \\ %{}) do Post |> apply_post_search_filter(filters) @@ -57,5 +58,5 @@ defmodule Pescarte.Blog do from p in query, limit: ^page_size, offset: ^offset end - defp apply_pagination(query, _), do: from(p in query, limit: 10, offset: 0) + defp apply_pagination(query, _), do: from(p in query, limit: 7, offset: 0) end diff --git a/lib/pescarte/blog/post.ex b/lib/pescarte/blog/post.ex index 677d4e9d..9a813d19 100644 --- a/lib/pescarte/blog/post.ex +++ b/lib/pescarte/blog/post.ex @@ -47,11 +47,6 @@ defmodule Pescarte.Blog.Post do |> foreign_key_constraint(:usuario_id) end - @spec get_posts :: list(Post.t()) | Ecto.QueryError - def get_posts do - Repo.Replica.all(Post) - end - @spec get_post(String.t()) :: {:ok, Post.t()} | {:error, :not_found} def get_post(id) do Database.fetch(Post, id) diff --git a/lib/pescarte_web/controllers/noticias_controller.ex b/lib/pescarte_web/controllers/noticias_controller.ex index e43323ba..73004be0 100644 --- a/lib/pescarte_web/controllers/noticias_controller.ex +++ b/lib/pescarte_web/controllers/noticias_controller.ex @@ -1,8 +1,17 @@ defmodule PescarteWeb.NoticiasController do use PescarteWeb, :controller + alias Pescarte.Blog def show(conn, _params) do current_path = conn.request_path - render(conn, :show, current_path: current_path, error_message: nil) + + [main_new | news] = Blog.list_posts_with_filter() + + render(conn, :show, + current_path: current_path, + error_message: nil, + news: news, + main_new: main_new + ) end end diff --git a/lib/pescarte_web/live/blog/noticias_live/show.ex b/lib/pescarte_web/live/blog/noticias_live/show.ex new file mode 100644 index 00000000..75c23b88 --- /dev/null +++ b/lib/pescarte_web/live/blog/noticias_live/show.ex @@ -0,0 +1,420 @@ +defmodule PescarteWeb.Blog.NoticiasLive.Show do + use PescarteWeb, :live_view + + alias Pescarte.Blog + + @notice_title_max_length Application.compile_env!(:pescarte, [ + PescarteWeb, + :notice_title_max_length + ]) + + @notice_desc_max_length Application.compile_env!(:pescarte, [ + PescarteWeb, + :notice_desc_max_length + ]) + @impl true + def mount(_params, _session, socket) do + [main_new | news] = Blog.list_posts_with_filter() + + socket = + socket + |> assign(%{error_message: nil, news: news, main_new: main_new}) + + {:ok, socket} + end + + def handle_notice_title_length(text) do + if String.length(text) > @notice_title_max_length do + text + |> truncate_text_until(@notice_title_max_length - 4) + |> put_ellipsis() + else + text + end + end + + def handle_notice_desc_length(text) do + if String.length(text) > @notice_desc_max_length do + text + |> truncate_text_until(@notice_desc_max_length - 4) + |> put_ellipsis() + else + text + end + end + + defp truncate_text_until(text, length) do + text + |> String.slice(0..length) + |> String.trim_trailing() + end + + defp put_ellipsis(text) do + text <> "..." + end + + def date_to_string(date_time) do + DateTime.to_date(date_time) + |> Date.to_string() + |> String.split("-") + |> Enum.reverse() + |> Enum.join("/") + end + + @impl true + def handle_event("more_news", _params, socket) do + current_news_length = socket.assigns.news.length + loaded_news = Blog.list_posts_with_filter(%{page: current_news_length + 1, page_size: 6}) + + IO.inspect("funcionou") + + socket = socket |> assign(news: socket.assigns.news ++ loaded_news) + + {:noreply, socket} + end + + @impl true + def handle_event("dialog", _value, socket) do + {:noreply, socket} + end + + @impl true + def render(assigns) do + ~H""" +
{date_to_string(@main_new.inserted_at)}
+ ++ {handle_notice_desc_length(@main_new.conteudo)} +
+{date_to_string(new.inserted_at)}
+ + <.text size="h4" color="text-blue-100"> + {handle_notice_title_length(new.titulo)} + + + <.text size="base" color="text-black-60"> + {handle_notice_desc_length(new.conteudo)} + +{date_to_string(@main_new.inserted_at)}
+ ++ {handle_notice_desc_length(@main_new.conteudo)} +
{date_to_string(new.inserted_at)}
+ + <.text size="h4" color="text-blue-100"> + {handle_notice_title_length(new.titulo)} + + + <.text size="base" color="text-black-60"> + {handle_notice_desc_length(new.conteudo)} + +