Centralize page layout sizing

This commit is contained in:
SimpleTest 2026-07-22 05:58:20 +03:00
parent 0880b25e73
commit 81b64deced
27 changed files with 120 additions and 51 deletions

View File

@ -105,6 +105,10 @@
/* This file is for your main application CSS */
html {
scrollbar-gutter: stable;
}
.skip-link {
position: fixed;
z-index: 100;

View File

@ -266,7 +266,7 @@ defmodule WhoNeedHelpWeb.CoreComponents do
~H"""
<div class="fieldset mb-2">
<label for={@id}>
<label for={@id} class="block min-w-0 max-w-full">
<input
type="hidden"
name={@name}
@ -274,16 +274,17 @@ defmodule WhoNeedHelpWeb.CoreComponents do
disabled={@rest[:disabled]}
form={@rest[:form]}
/>
<span class="label">
<span class="label flex w-full min-w-0 max-w-full items-start justify-start gap-2 whitespace-normal">
<input
type="checkbox"
id={@id}
name={@name}
value="true"
checked={@checked}
class={@class || "checkbox checkbox-sm"}
class={[@class || "checkbox checkbox-sm", "shrink-0"]}
{@rest}
/>{@label}
/>
<span class="min-w-0 break-words">{@label}</span>
</span>
</label>
<.error :for={msg <- @errors}>{msg}</.error>

View File

@ -31,6 +31,16 @@ defmodule WhoNeedHelpWeb.Layouts do
default: nil,
doc: "the current [scope](https://phoenix.hexdocs.pm/scopes.html)"
attr :page_width, :atom,
default: :wide,
values: [:wide, :form, :reading, :medium, :compact, :narrow, :auth],
doc: "the centralized content width used inside the stable application grid"
attr :page_align, :atom,
default: :start,
values: [:start, :center],
doc: "whether constrained content follows the application grid or is centered"
slot :inner_block, required: true
def app(assigns) do
@ -136,9 +146,15 @@ defmodule WhoNeedHelpWeb.Layouts do
</header>
<main id="main-content" tabindex="-1" class="px-4 py-8 outline-none sm:px-6 lg:px-8">
<div class="mx-auto max-w-7xl space-y-4">
<div class="mx-auto w-full max-w-7xl">
<div class={[
"w-full space-y-4",
page_width_class(@page_width),
@page_align == :center && "mx-auto"
]}>
{render_slot(@inner_block)}
</div>
</div>
</main>
<footer class="border-t border-base-300 px-4 py-6 text-center text-xs text-base-content/70">
@ -159,6 +175,14 @@ defmodule WhoNeedHelpWeb.Layouts do
"""
end
defp page_width_class(:wide), do: "max-w-none"
defp page_width_class(:form), do: "max-w-5xl"
defp page_width_class(:reading), do: "max-w-4xl"
defp page_width_class(:medium), do: "max-w-3xl"
defp page_width_class(:compact), do: "max-w-2xl"
defp page_width_class(:narrow), do: "max-w-xl"
defp page_width_class(:auth), do: "max-w-sm"
attr :current_scope, :map, default: nil
attr :link_class, :string, default: "btn btn-ghost btn-sm"

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-2xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:compact}>
<div>
<div class="text-sm font-semibold text-error">{gettext("CONTENT REMOVAL")}</div>
<h1 class="mt-2 text-4xl font-black">{gettext("Report illegal or harmful content")}</h1>
<p class="mt-3 text-base-content/65">

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-xl text-center">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:narrow}
page_align={:center}
>
<div class="text-center">
<div class="text-sm font-semibold text-success">{gettext("NOTICE RECEIVED")}</div>
<h1 class="mt-2 text-4xl font-black">
{gettext("Your reference is %{reference}", reference: @reference)}

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-2xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:compact}>
<div>
<div class="flex flex-wrap items-center gap-2">
<span class="badge badge-outline">{@notice.reference}</span>
<span class={[

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-2xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:compact}>
<div>
<div class="text-sm font-semibold text-error">{gettext("TAKE IT DOWN")}</div>
<h1 class="mt-2 text-4xl font-black">
{gettext("Request removal of intimate visual material")}

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-3xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:medium}>
<div>
<div class="text-sm font-semibold text-success">OPENAI BUILD WEEK</div>
<h1 class="mt-2 text-4xl font-black">{gettext("Build feedback")}</h1>
<p class="mt-4 text-base-content/65">

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-md space-y-5">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:narrow}
page_align={:center}
>
<div class="space-y-5">
<div class="text-center">
<.header>
{gettext("Continue with Google")}

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<article class="mx-auto max-w-4xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<article>
<div class="text-sm font-semibold text-brand">WHO NEED HELP</div>
<h1 class="mt-2 text-4xl font-black">Privacy Policy</h1>
<p class="mt-3 text-sm text-base-content/60">Effective: 21 July 2026</p>

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<article class="mx-auto max-w-4xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<article>
<div class="text-sm font-semibold text-warning">
{gettext("READ BEFORE USING THE SERVICE")}
</div>

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<article class="mx-auto max-w-4xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<article>
<div class="text-sm font-semibold text-brand">WHO NEED HELP</div>
<h1 class="mt-2 text-4xl font-black">Terms of Service</h1>
<p class="mt-3 text-sm text-base-content/60">Effective: 21 July 2026</p>

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-2xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:compact}>
<div>
<div class="text-sm font-semibold text-error">{gettext("ACCOUNT AND DATA")}</div>
<h1 class="mt-2 text-4xl font-black">{gettext("Request account deletion")}</h1>
<p class="mt-3 text-base-content/65">

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-4xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<div>
<div class="flex flex-wrap items-center justify-between gap-3">
<div>
<div class="text-sm font-semibold text-primary">{gettext("SUPPORT")}</div>

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-2xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:compact}>
<div>
<div class="text-sm font-semibold text-primary">{gettext("SUPPORT")}</div>
<h1 class="mt-2 text-4xl font-black">{gettext("Contact Who Need Help")}</h1>
<p class="mt-3 text-base-content/65">

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-xl text-center">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:narrow}
page_align={:center}
>
<div class="text-center">
<div class="text-sm font-semibold text-success">{gettext("REQUEST RECEIVED")}</div>
<h1 class="mt-2 text-4xl font-black">{gettext("Check your email")}</h1>
<p class="mt-4 text-base-content/65">

View File

@ -1,5 +1,5 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-2xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:compact}>
<div>
<div class="flex flex-wrap items-center gap-2">
<span class="badge badge-outline">{@request.reference}</span>
<span class="badge badge-primary">{status_label(@request.status)}</span>

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-sm space-y-5">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:auth}
page_align={:center}
>
<div class="space-y-5">
<div class="text-center">
<.header>
{gettext("Register for an account")}

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-xl space-y-6">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:narrow}
page_align={:center}
>
<div class="space-y-6">
<div class="text-center">
<.header>
{if @email_flow == "register",

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-sm space-y-4">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:auth}
page_align={:center}
>
<div class="space-y-4">
<div class="text-center">
<.header>
<p>{gettext("Log in")}</p>

View File

@ -1,5 +1,10 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-md text-center">
<Layouts.app
flash={@flash}
current_scope={@current_scope}
page_width={:narrow}
page_align={:center}
>
<div class="text-center">
<.header>
{gettext("Confirm email change")}
<:subtitle>{gettext("Confirm the new email address for your account.")}</:subtitle>

View File

@ -1,4 +1,4 @@
<Layouts.app flash={@flash} current_scope={@current_scope}>
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<div class="text-center">
<.header>
{gettext("Account Settings")}

View File

@ -112,8 +112,8 @@ defmodule WhoNeedHelpWeb.ActivityLive.New do
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-3xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:form}>
<div>
<.link navigate={~p"/activities"} class="btn btn-ghost btn-sm mb-4">
{gettext("← Back to activities")}
</.link>

View File

@ -32,11 +32,11 @@ defmodule WhoNeedHelpWeb.LeaderboardLive do
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<.link navigate={~p"/requests"} class="btn btn-ghost btn-sm">
{gettext("← Requests")}
</.link>
<div class="mt-5 max-w-4xl">
<div class="mt-5">
<div class="text-sm font-semibold text-success">{gettext("COMMUNITY TRUST")}</div>
<h1 class="mt-1 text-4xl font-black tracking-tight">
{gettext("Helpers leaderboard")}

View File

@ -137,8 +137,8 @@ defmodule WhoNeedHelpWeb.ProfileLive do
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-4xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:reading}>
<div>
<h1 class="text-4xl font-black">{gettext("Your profile")}</h1>
<div class="mt-6 grid gap-6 md:grid-cols-[1fr_.75fr]">
<.form

View File

@ -182,8 +182,8 @@ defmodule WhoNeedHelpWeb.RequestLive.New do
@impl true
def render(assigns) do
~H"""
<Layouts.app flash={@flash} current_scope={@current_scope}>
<div class="mx-auto max-w-3xl">
<Layouts.app flash={@flash} current_scope={@current_scope} page_width={:form}>
<div>
<.link navigate={~p"/requests"} class="btn btn-ghost btn-sm mb-4">
{gettext("← Back to requests")}
</.link>

View File

@ -270,6 +270,11 @@ defmodule WhoNeedHelpWeb.MutualAidLiveTest do
test "new request form uses separate local date and time controls", %{conn: conn} do
{:ok, view, _html} = live(conn, ~p"/requests/new")
assert has_element?(
view,
"#main-content > div.max-w-7xl > div.max-w-5xl:not(.mx-auto)"
)
assert has_element?(view, "#help_request_expires_at[type='hidden']")
assert has_element?(view, "#help_request_expires_at-date[type='date']")
assert has_element?(view, "#help_request_expires_at-time[type='time']")