Packages

phoenix_kit

1.7.22
1.7.208 1.7.207 1.7.206 1.7.205 1.7.204 1.7.203 1.7.202 1.7.201 1.7.200 1.7.199 1.7.198 1.7.197 1.7.196 1.7.194 1.7.193 1.7.192 1.7.191 1.7.190 1.7.189 1.7.187 1.7.186 1.7.185 1.7.184 1.7.183 1.7.182 1.7.181 1.7.180 1.7.179 1.7.178 1.7.177 1.7.176 1.7.175 1.7.174 1.7.173 1.7.172 1.7.171 1.7.170 1.7.169 1.7.168 1.7.167 1.7.166 1.7.165 1.7.164 1.7.162 1.7.161 1.7.160 1.7.159 1.7.157 1.7.156 1.7.155 1.7.154 1.7.153 1.7.152 1.7.151 1.7.150 1.7.149 1.7.146 1.7.145 1.7.144 1.7.143 1.7.138 1.7.133 1.7.132 1.7.131 1.7.130 1.7.128 1.7.126 1.7.125 1.7.121 1.7.120 1.7.119 1.7.118 1.7.117 1.7.116 1.7.115 1.7.114 1.7.113 1.7.112 1.7.111 1.7.110 1.7.109 1.7.108 1.7.107 1.7.106 1.7.105 1.7.104 1.7.103 1.7.102 1.7.101 1.7.100 1.7.99 1.7.98 1.7.97 1.7.96 1.7.95 1.7.94 1.7.93 1.7.92 1.7.91 1.7.90 1.7.89 1.7.88 1.7.87 1.7.86 1.7.85 1.7.84 1.7.83 1.7.82 1.7.81 1.7.80 1.7.79 1.7.78 1.7.77 1.7.76 1.7.75 1.7.74 1.7.71 1.7.70 1.7.69 1.7.66 1.7.65 1.7.64 1.7.63 1.7.62 1.7.61 1.7.59 1.7.58 1.7.57 1.7.56 1.7.55 1.7.54 1.7.53 1.7.52 1.7.51 1.7.49 1.7.44 1.7.43 1.7.42 1.7.41 1.7.39 1.7.38 1.7.37 1.7.36 1.7.34 1.7.33 1.7.31 1.7.30 1.7.29 1.7.28 1.7.27 1.7.26 1.7.25 1.7.24 1.7.23 1.7.22 1.7.21 1.7.20 1.7.19 1.7.18 1.7.17 1.7.16 1.7.15 1.7.14 1.7.13 1.7.12 1.7.11 1.7.10 1.7.9 1.7.8 1.7.7 1.7.6 1.7.5 1.7.4 1.7.3 1.7.2 1.7.1 1.7.0 1.6.20 1.6.19 1.6.18 1.6.17 1.6.16 1.6.15 1.6.14 1.6.13 1.6.12 1.6.11 1.6.10 1.6.9 1.6.8 1.6.7 1.6.6 1.6.5 1.6.4 1.6.3 1.5.2 1.5.1 1.5.0 1.4.9 1.4.8 1.4.7 1.4.6 1.4.5 1.4.4 1.4.3 1.4.2 1.4.1 1.4.0 1.3.2 1.3.1 1.3.0 1.2.10 1.2.9 1.2.8 1.2.7 1.2.5 1.2.4 1.2.2 1.2.1 1.2.0 1.1.0 1.0.0

A foundation for building Elixir Phoenix apps — SaaS, social networks, ERP systems, marketplaces, and more

Current section

Files

Jump to
phoenix_kit lib modules storage web dimension_form.html.heex
Raw

lib/modules/storage/web/dimension_form.html.heex

<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title={@page_title}
current_path={@current_path}
current_locale={@current_locale}
project_title={@project_title}
>
<div class="container mx-auto px-4 py-8 max-w-4xl">
<%!-- Header Section --%>
<header class="w-full relative mb-6">
<%!-- Back Button --%>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions")}
class="btn btn-outline mb-4"
>
<.icon name="hero-arrow-left" class="w-4 h-4 mr-2" /> Back to Dimensions
</.link>
<%!-- Title Section --%>
<div class="text-center mb-8">
<h1 class="text-4xl font-bold text-base-content mb-2">
{@page_title}
</h1>
<p class="text-base-content/70">
Configure dimension presets for automatic file variant generation
</p>
</div>
</header>
<%!-- Form Section --%>
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<.form for={@changeset} phx-change="validate" phx-submit="save" class="space-y-6">
<%!-- Basic Information --%>
<div class="form-control">
<label class="label">
<span class="label-text font-semibold">Dimension Name *</span>
<span class="label-text-alt">Unique name for this dimension preset</span>
</label>
<input
type="text"
name="dimension[name]"
phx-debounce="blur"
value={get_field_value(@changeset, :name)}
class={"input input-bordered #{input_class(@changeset, :name)}"}
placeholder="e.g., thumbnail, medium, 720p"
required
/>
{render_error(@changeset, :name)}
</div>
<%!-- Aspect Ratio Toggle --%>
<div class="form-control">
<label class="label cursor-pointer">
<span class="label-text font-semibold">
<.icon name="hero-photo" class="w-4 h-4 inline mr-2" /> Maintain Aspect Ratio
</span>
<%!-- Hidden input sends "false" by default, checkbox overrides with "true" --%>
<input type="hidden" name="dimension[maintain_aspect_ratio]" value="false" />
<input
type="checkbox"
name="dimension[maintain_aspect_ratio]"
value="true"
checked={get_field_value(@changeset, :maintain_aspect_ratio) != false}
phx-change="validate"
class="checkbox checkbox-primary"
/>
</label>
<p class="text-sm text-base-content/60 mt-1">
<%= if get_field_value(@changeset, :maintain_aspect_ratio) != false do %>
When enabled: Only width is used, height is calculated automatically
<% else %>
When disabled: Both width and height are used for fixed dimensions (crops/thumbnails)
<% end %>
</p>
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="form-control">
<label class="label">
<span class="label-text font-semibold">
<%= if get_field_value(@changeset, :maintain_aspect_ratio) != false do %>
Target Width (px) *
<% else %>
Width (px) *
<% end %>
</span>
<span class="label-text-alt">
<%= if get_field_value(@changeset, :maintain_aspect_ratio) != false do %>
Target width for responsive sizing
<% else %>
Width in pixels
<% end %>
</span>
</label>
<input
type="number"
name="dimension[width]"
phx-debounce="blur"
value={get_field_value(@changeset, :width)}
class={"input input-bordered #{input_class(@changeset, :width)}"}
placeholder="800"
min="1"
required
/>
{render_error(@changeset, :width)}
</div>
<%= if get_field_value(@changeset, :maintain_aspect_ratio) == false do %>
<div class="form-control">
<label class="label">
<span class="label-text font-semibold">Height (px) *</span>
<span class="label-text-alt">Required for fixed dimensions</span>
</label>
<input
type="number"
name="dimension[height]"
phx-debounce="blur"
value={get_field_value(@changeset, :height)}
class={"input input-bordered #{input_class(@changeset, :height)}"}
placeholder="600"
min="1"
required
/>
{render_error(@changeset, :height)}
</div>
<% end %>
</div>
<%!-- Quality and Format --%>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="form-control">
<label class="label">
<span class="label-text font-semibold">
<%= if @dimension_type == "video" do %>
Quality (CRF)
<% else %>
Quality
<% end %>
</span>
<span class="label-text-alt">
<%= if @dimension_type == "video" do %>
Compression quality (0-51, lower = higher quality)
<% else %>
Compression quality (1-100)
<% end %>
</span>
</label>
<input
type="number"
name="dimension[quality]"
phx-debounce="blur"
value={get_field_value(@changeset, :quality)}
class={"input input-bordered #{input_class(@changeset, :quality)}"}
placeholder={if @dimension_type == "video", do: "23", else: "85"}
min={if @dimension_type == "video", do: "0", else: "1"}
max={if @dimension_type == "video", do: "51", else: "100"}
/>
{render_error(@changeset, :quality)}
<label class="label">
<span class="label-text-alt">
<%= if @dimension_type == "video" do %>
Videos use CRF 0-51 (lower = higher quality, 18-28 recommended)
<% else %>
Images use 1-100 (higher = better quality, 80-90 recommended)
<% end %>
</span>
</label>
</div>
<div class="form-control">
<label class="label">
<span class="label-text font-semibold">
<%= if @dimension_type == "video" do %>
Codec Override
<% else %>
Format Override
<% end %>
</span>
<span class="label-text-alt">Leave empty to preserve original</span>
</label>
<%!-- Get format value safely --%>
<% format_value = get_field_value(@changeset, :format) %>
<select
name="dimension[format]"
class={"select select-bordered #{input_class(@changeset, :format)}"}
>
<option value="">Preserve original</option>
<%= if @dimension_type != "video" do %>
<option value="jpg" selected={format_value == "jpg"}>
JPEG
</option>
<option value="png" selected={format_value == "png"}>
PNG
</option>
<option value="webp" selected={format_value == "webp"}>
WebP
</option>
<% end %>
<%= if @dimension_type == "video" do %>
<option value="mp4" selected={format_value == "mp4"}>
MP4
</option>
<% end %>
</select>
{render_error(@changeset, :format)}
</div>
</div>
<%!-- Hidden field for applies_to (auto-set based on dimension type) --%>
<input
type="hidden"
name="dimension[applies_to]"
value={@dimension_type}
/>
<%!-- Form Actions --%>
<div class="flex justify-end gap-2 pt-4">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions")}
class="btn btn-outline"
>
Cancel
</.link>
<button type="submit" class="btn btn-primary" disabled={!@changeset.valid?}>
<.icon name="hero-check" class="w-4 h-4 mr-1" />
{@form_action}
</button>
</div>
</.form>
</div>
</div>
<%!-- Help Section --%>
<div class="alert mt-6">
<.icon name="hero-light-bulb" class="w-5 h-5" />
<div>
<h3 class="font-bold">Dimension Configuration Guide</h3>
<p class="text-sm">
<strong>Maintain Aspect Ratio (Default ON):</strong>
When enabled, only the width is used and height is calculated automatically to preserve the image's aspect ratio. Perfect for responsive images.<br />
<strong>Fixed Dimensions (When Aspect Ratio OFF):</strong>
Both width and height are used for exact dimensions. Images are center-cropped to fit. Great for thumbnails and square previews.<br />
<strong>Quality Settings:</strong>
Images use 1-100 (compression quality), Videos use CRF 0-51 (constant rate factor)<br />
<strong>Format Override:</strong>
Use to convert files to a specific format, or leave empty to preserve original
</p>
</div>
</div>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>