Packages

phoenix_kit

1.7.21
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 dimensions.html.heex
Raw

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

<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title="Storage Dimensions"
current_path={@current_path}
current_locale={@current_locale}
project_title={@project_title}
>
<div class="container mx-auto px-4 py-8 max-w-6xl">
<%!-- Header Section --%>
<header class="w-full relative mb-6">
<%!-- Back Button --%>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/settings/media")}
class="btn btn-outline mb-4"
>
<.icon name="hero-arrow-left" class="w-4 h-4 mr-2" /> Back to Storage Settings
</.link>
<%!-- Title Section --%>
<div class="text-center mb-8">
<h1 class="text-4xl font-bold text-base-content mb-2">
Instance Dimensions
</h1>
<p class="text-base-content/70">
Manage dimension presets for automatic file instance generation
</p>
</div>
</header>
<%!-- Info Alert --%>
<div class="alert alert-info mb-6">
<.icon name="hero-information-circle" class="w-5 h-5" />
<div>
<div class="flex justify-between items-start">
<div>
<h3 class="font-bold">Dimension Presets</h3>
<p class="text-sm">
Dimensions define the target sizes for automatic variant generation. Images are resized and videos are transcoded to these preset sizes.
The migration seeds 8 default dimensions: 4 image sizes (thumbnail, small, medium, large) and 4 video variants (360p, 720p, 1080p, video_thumbnail).
</p>
</div>
<button
phx-click="reset_dimensions_to_defaults"
data-confirm="Are you sure? This will delete all current dimensions and restore the default 8 dimensions. This action cannot be undone."
class="btn btn-error btn-sm"
>
<.icon name="hero-arrow-path" class="w-4 h-4 mr-1" /> Reset to Defaults
</button>
</div>
</div>
</div>
<%!-- Dimensions List --%>
<div class="card bg-base-100 shadow-xl">
<div class="card-body">
<%= if length(@dimensions) == 0 do %>
<div class="text-center py-12">
<.icon name="hero-photo" class="w-16 h-16 mx-auto mb-4 text-base-content/30" />
<p class="text-lg text-base-content/70 mb-2">No dimensions configured</p>
<p class="text-sm text-base-content/50 mb-4">
Create your first dimension preset to start generating file variants.
</p>
<div class="flex justify-center gap-4">
<.link
navigate={
PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions/new/image")
}
class="btn btn-info"
>
<.icon name="hero-plus" class="w-4 h-4 mr-1" /> Add Image Dimension
</.link>
<.link
navigate={
PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions/new/video")
}
class="btn btn-warning"
>
<.icon name="hero-plus" class="w-4 h-4 mr-1" /> Add Video Dimension
</.link>
</div>
</div>
<% else %>
<%!-- Image Dimensions --%>
<div class="mb-8">
<div class="flex justify-between items-center mb-4">
<h3 class="text-2xl font-bold text-info">
<.icon name="hero-photo" class="w-6 h-6 mr-2" /> Image Dimensions
</h3>
<.link
navigate={
PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions/new/image")
}
class="btn btn-info"
>
<.icon name="hero-plus" class="w-4 h-4 mr-1" /> Add Image Dimension
</.link>
</div>
<div class="overflow-x-auto">
<table class="table table-zebra">
<thead>
<tr>
<th>Name</th>
<th>
<%= if Enum.any?(Enum.filter(@dimensions, & &1.applies_to in ["image", "both"]), & &1.maintain_aspect_ratio) do %>
Target Width / Size
<% else %>
Size
<% end %>
</th>
<th>Mode</th>
<th>Quality</th>
<th>Format</th>
<th>Status</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
<%= for dimension <- Enum.filter(@dimensions, & &1.applies_to in ["image", "both"]) do %>
<tr>
<td>
<div class="font-bold">{dimension.name}</div>
</td>
<td>
<span class="font-mono text-sm">
<%= if dimension.maintain_aspect_ratio do %>
{dimension.width}px
<% else %>
{format_dimension_size(dimension.width, dimension.height)}
<% end %>
</span>
</td>
<td>
<%= if dimension.maintain_aspect_ratio do %>
<span class="badge badge-info badge-sm">Aspect Ratio</span>
<% else %>
<span class="badge badge-secondary badge-sm">Fixed</span>
<% end %>
</td>
<td>
<span class="text-sm">{dimension.quality}%</span>
</td>
<td>
<%= if dimension.format do %>
<span class="text-sm font-mono uppercase">{dimension.format}</span>
<% else %>
<span class="text-sm text-base-content/60">Original</span>
<% end %>
</td>
<td>
<%= if dimension.enabled do %>
<span class="badge badge-success badge-sm">Enabled</span>
<% else %>
<span class="badge badge-error badge-sm">Disabled</span>
<% end %>
</td>
<td>
<div class="flex justify-end gap-1">
<.link
navigate={
PhoenixKit.Utils.Routes.path(
"/admin/settings/media/dimensions/#{dimension.id}/edit"
)
}
class="btn btn-xs btn-ghost"
title="Edit dimension"
>
<.icon name="hero-pencil" class="w-4 h-4" />
</.link>
<button
phx-click="toggle_dimension"
phx-debounce="1000"
phx-value-id={dimension.id}
class="btn btn-xs btn-ghost"
title={
if dimension.enabled,
do: "Disable dimension",
else: "Enable dimension"
}
>
<%= if dimension.enabled do %>
<.icon name="hero-eye-slash" class="w-4 h-4" />
<% else %>
<.icon name="hero-eye" class="w-4 h-4" />
<% end %>
</button>
<button
phx-click="delete_dimension"
phx-debounce="1000"
phx-value-id={dimension.id}
data-confirm="Are you sure you want to delete this dimension?"
class="btn btn-xs btn-ghost text-error"
title="Delete dimension"
>
<.icon name="hero-trash" class="w-4 h-4" />
</button>
</div>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<%!-- Video Dimensions --%>
<div>
<div class="flex justify-between items-center mb-4">
<h3 class="text-2xl font-bold text-warning">
<.icon name="hero-video-camera" class="w-6 h-6 mr-2" /> Video Dimensions
</h3>
<.link
navigate={
PhoenixKit.Utils.Routes.path("/admin/settings/media/dimensions/new/video")
}
class="btn btn-warning"
>
<.icon name="hero-plus" class="w-4 h-4 mr-1" /> Add Video Dimension
</.link>
</div>
<div class="overflow-x-auto">
<table class="table table-zebra">
<thead>
<tr>
<th>Name</th>
<th>
<%= if Enum.any?(Enum.filter(@dimensions, & &1.applies_to in ["video", "both"]), & &1.maintain_aspect_ratio) do %>
Target Width / Resolution
<% else %>
Resolution
<% end %>
</th>
<th>Mode</th>
<th>Quality (CRF)</th>
<th>Codec</th>
<th>Status</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
<%= for dimension <- Enum.filter(@dimensions, & &1.applies_to in ["video", "both"]) do %>
<tr>
<td>
<div class="font-bold">{dimension.name}</div>
</td>
<td>
<span class="font-mono text-sm">
<%= if dimension.maintain_aspect_ratio do %>
{dimension.width}px
<% else %>
{format_dimension_size(dimension.width, dimension.height)}
<% end %>
</span>
</td>
<td>
<%= if dimension.maintain_aspect_ratio do %>
<span class="badge badge-info badge-sm">Aspect Ratio</span>
<% else %>
<span class="badge badge-secondary badge-sm">Fixed</span>
<% end %>
</td>
<td>
<span class="text-sm">{dimension.quality}</span>
</td>
<td>
<%= if dimension.format do %>
<span class="text-sm font-mono uppercase">{dimension.format}</span>
<% else %>
<span class="text-sm text-base-content/60">Original</span>
<% end %>
</td>
<td>
<%= if dimension.enabled do %>
<span class="badge badge-success badge-sm">Enabled</span>
<% else %>
<span class="badge badge-error badge-sm">Disabled</span>
<% end %>
</td>
<td>
<div class="flex justify-end gap-1">
<.link
navigate={
PhoenixKit.Utils.Routes.path(
"/admin/settings/media/dimensions/#{dimension.id}/edit"
)
}
class="btn btn-xs btn-ghost"
title="Edit dimension"
>
<.icon name="hero-pencil" class="w-4 h-4" />
</.link>
<button
phx-click="toggle_dimension"
phx-debounce="1000"
phx-value-id={dimension.id}
class="btn btn-xs btn-ghost"
title={
if dimension.enabled,
do: "Disable dimension",
else: "Enable dimension"
}
>
<%= if dimension.enabled do %>
<.icon name="hero-eye-slash" class="w-4 h-4" />
<% else %>
<.icon name="hero-eye" class="w-4 h-4" />
<% end %>
</button>
<button
phx-click="delete_dimension"
phx-debounce="1000"
phx-value-id={dimension.id}
data-confirm="Are you sure you want to delete this dimension?"
class="btn btn-xs btn-ghost text-error"
title="Delete dimension"
>
<.icon name="hero-trash" class="w-4 h-4" />
</button>
</div>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<% end %>
</div>
</div>
<%!-- Help Section --%>
<div class="alert mt-6">
<.icon name="hero-light-bulb" class="w-5 h-5" />
<div>
<h3 class="font-bold">Variant Generation System</h3>
<p class="text-sm">
<strong>Quality Settings:</strong>
Images use 1-100 scale (compression quality)<br />
<strong>Video Settings:</strong>
Videos use CRF 0-51 scale (lower = higher quality)<br />
<strong>Format Override:</strong>
Leave empty to preserve original format, or specify jpg/png/webp/mp4
</p>
</div>
</div>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>