Packages

phoenix_kit

1.7.78
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 entities web entities.html.heex
Raw

lib/modules/entities/web/entities.html.heex

<PhoenixKitWeb.Components.LayoutWrapper.app_layout
flash={@flash}
phoenix_kit_current_scope={assigns[:phoenix_kit_current_scope]}
page_title={
gettext("%{project_title} %{section}",
project_title: @project_title,
section: gettext("Entities")
)
}
current_path={@url_path}
project_title={@project_title}
current_locale={@current_locale}
>
<div class="container flex flex-col mx-auto px-4 py-6">
<%!-- Header Section --%>
<.admin_page_header
back={PhoenixKit.Utils.Routes.path("/admin/modules")}
title={gettext("Entity Manager")}
subtitle={gettext("Create and manage custom content types with dynamic fields")}
/>
<%!-- Action Bar --%>
<div class="flex flex-col sm:flex-row justify-between items-start sm:items-center mb-6 gap-4">
<div>
<h2 class="text-2xl font-semibold text-base-content">{gettext("All Entities")}</h2>
<p class="text-base-content/70">
{gettext("Manage custom content types and field definitions")}
</p>
</div>
<div class="flex gap-2 items-center">
<%!-- View Mode Toggle (hidden on small screens — cards are forced) --%>
<div class="join hidden md:flex">
<button
type="button"
phx-click="toggle_view_mode"
phx-value-mode="card"
class={["btn join-item", @view_mode == "card" && "btn-active"]}
title={gettext("Card view")}
>
<.icon name="hero-squares-2x2" class="w-4 h-4" />
</button>
<button
type="button"
phx-click="toggle_view_mode"
phx-value-mode="table"
class={["btn join-item", @view_mode == "table" && "btn-active"]}
title={gettext("Table view")}
>
<.icon name="hero-bars-3-bottom-left" class="w-4 h-4" />
</button>
</div>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/entities/new")}
class="btn btn-primary"
>
<.icon name="hero-plus" class="w-4 h-4 mr-2" /> {gettext("New Entity")}
</.link>
</div>
</div>
<%!-- Entities Grid --%>
<%= if Enum.empty?(@entities) do %>
<%!-- Empty State --%>
<div class="card bg-base-100 shadow-xl border-2 border-dashed border-base-300">
<div class="card-body text-center py-12">
<div class="text-6xl mb-4 opacity-50"><.icon name="hero-cube" class="w-6 h-6" /></div>
<h3 class="text-2xl font-semibold text-base-content/60 mb-4">
{gettext("No Entities Yet")}
</h3>
<p class="text-base-content/50 mb-6 max-w-md mx-auto">
{gettext(
"Get started by creating your first custom content type. Think brands, products, team members, or any structured content you need."
)}
</p>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/entities/new")}
class="btn btn-primary btn-lg"
>
<.icon name="hero-plus" class="w-5 h-5 mr-2" /> {gettext("Create Your First Entity")}
</.link>
</div>
</div>
<% else %>
<%!-- Table View: hidden on small screens, shown on md+ when table mode selected --%>
<%= if @view_mode == "table" do %>
<div class="hidden md:block">
<.table_default variant="zebra" size="sm">
<.table_default_header>
<.table_default_row>
<.table_default_header_cell>{gettext("Entity")}</.table_default_header_cell>
<.table_default_header_cell>{gettext("Status")}</.table_default_header_cell>
<.table_default_header_cell>{gettext("Fields")}</.table_default_header_cell>
<.table_default_header_cell>{gettext("Created")}</.table_default_header_cell>
<.table_default_header_cell>{gettext("Actions")}</.table_default_header_cell>
</.table_default_row>
</.table_default_header>
<.table_default_body>
<%= for entity <- @entities do %>
<.table_default_row>
<.table_default_cell>
<.link
navigate={
PhoenixKit.Utils.Routes.locale_aware_path(
assigns,
"/admin/entities/#{entity.name}/data"
)
}
class="flex items-center gap-3 hover:text-primary transition-colors cursor-pointer group"
>
<div class="text-2xl">
<%= if entity.icon do %>
<.icon name={entity.icon} class="w-6 h-6" />
<% else %>
<.icon name="hero-cube" class="w-6 h-6" />
<% end %>
</div>
<div>
<div class="font-bold">
{entity.display_name_plural || entity.display_name}
</div>
<div class="text-sm opacity-50">
<.icon name="hero-link" class="w-3 h-3 inline" />
{entity.name}
</div>
<%= if entity.description do %>
<div class="text-xs opacity-50 line-clamp-1 mt-1">
{entity.description}
</div>
<% end %>
</div>
</.link>
</.table_default_cell>
<.table_default_cell>
<.content_status_badge status={entity.status} />
</.table_default_cell>
<.table_default_cell>
<div class="flex items-center gap-1">
<.icon name="hero-list-bullet" class="w-4 h-4" />
<span>
{length(entity.fields_definition || [])}
</span>
</div>
</.table_default_cell>
<.table_default_cell>
<span class="text-sm">
{PhoenixKit.Utils.Date.format_date_with_user_format(entity.date_created)}
</span>
</.table_default_cell>
<.table_default_cell>
<div class="flex gap-2">
<.link
navigate={
PhoenixKit.Utils.Routes.locale_aware_path(
assigns,
"/admin/entities/#{entity.name}/data"
)
}
class="btn btn-xs btn-outline btn-info tooltip tooltip-bottom"
data-tip={gettext("Go to Data")}
>
<.icon name="hero-arrow-right" class="w-4 h-4 hidden sm:inline" />
<span class="sm:hidden whitespace-nowrap">{gettext("Go to Data")}</span>
</.link>
<.link
navigate={
PhoenixKit.Utils.Routes.path("/admin/entities/#{entity.uuid}/edit")
}
class="btn btn-xs btn-outline btn-info tooltip tooltip-bottom"
data-tip={gettext("Edit")}
>
<.icon name="hero-pencil" class="w-4 h-4 hidden sm:inline" />
<span class="sm:hidden whitespace-nowrap">{gettext("Edit")}</span>
</.link>
<%= if entity.status == "archived" do %>
<button
class="btn btn-xs btn-outline btn-info tooltip tooltip-bottom text-success"
phx-click="restore_entity"
phx-value-uuid={entity.uuid}
data-tip={gettext("Restore")}
>
<.icon name="hero-arrow-path" class="w-4 h-4 hidden sm:inline" />
<span class="sm:hidden whitespace-nowrap">{gettext("Restore")}</span>
</button>
<% else %>
<button
class="btn btn-xs btn-outline btn-info tooltip tooltip-bottom text-error"
phx-click="archive_entity"
phx-value-uuid={entity.uuid}
data-tip={gettext("Archive")}
>
<.icon name="hero-trash" class="w-4 h-4 hidden sm:inline" />
<span class="sm:hidden whitespace-nowrap">{gettext("Archive")}</span>
</button>
<% end %>
</div>
</.table_default_cell>
</.table_default_row>
<% end %>
</.table_default_body>
</.table_default>
</div>
<% end %>
<%!-- Card View: always shown on small screens, shown on md+ when card mode selected --%>
<div class={if @view_mode == "table", do: "md:hidden", else: ""}>
<div class="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
<%= for entity <- @entities do %>
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow">
<div class="card-body">
<div class="flex items-start justify-between mb-4">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/entities/#{entity.name}/data")}
class="flex items-center hover:text-primary transition-colors cursor-pointer group"
>
<div class="text-2xl mr-3">
<%= if entity.icon do %>
<.icon name={entity.icon} class="w-6 h-6" />
<% else %>
<.icon name="hero-cube" class="w-6 h-6" />
<% end %>
</div>
<div>
<h3 class="card-title text-lg">
{entity.display_name_plural || entity.display_name}
</h3>
<p class="text-sm opacity-50">
<.icon name="hero-link" class="w-3 h-3 inline" />
{entity.name}
</p>
</div>
</.link>
<%!-- Status Badge --%>
<.content_status_badge status={entity.status} />
</div>
<%= if entity.description do %>
<p class="text-sm text-base-content/70 mb-4 line-clamp-2">
{entity.description}
</p>
<% end %>
<%!-- Field Count --%>
<div class="flex items-center justify-between text-sm text-base-content/60 mb-4">
<div class="flex items-center">
<.icon name="hero-list-bullet" class="w-4 h-4 mr-1" />
<span>
{length(entity.fields_definition || [])}
{if length(entity.fields_definition || []) == 1,
do: gettext("field"),
else: gettext("fields")}
</span>
</div>
<%= if entity.creator do %>
<span class="badge badge-outline badge-xs h-auto">
{gettext("by")} {entity.creator.email}
</span>
<% end %>
</div>
<%!-- Actions --%>
<div class="card-actions justify-end">
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/entities/#{entity.name}/data")}
class="btn btn-outline btn-sm"
>
<.icon name="hero-arrow-right" class="w-4 h-4 mr-1" /> {gettext("Go to Data")}
</.link>
<.link
navigate={PhoenixKit.Utils.Routes.path("/admin/entities/#{entity.uuid}/edit")}
class="btn btn-primary btn-sm"
>
<.icon name="hero-pencil" class="w-4 h-4 mr-1" /> {gettext("Edit")}
</.link>
<%!-- Archive/Restore Button --%>
<%= if entity.status == "archived" do %>
<button
class="btn btn-success btn-sm"
phx-click="restore_entity"
phx-value-uuid={entity.uuid}
title={gettext("Restore entity")}
>
<.icon name="hero-arrow-path" class="w-4 h-4" />
</button>
<% else %>
<button
class="btn btn-error btn-sm"
phx-click="archive_entity"
phx-value-uuid={entity.uuid}
title={gettext("Archive entity")}
>
<.icon name="hero-trash" class="w-4 h-4" />
</button>
<% end %>
</div>
<%!-- Created Date --%>
<div class="text-xs text-base-content/50 mt-2 pt-2 border-t border-base-300">
{gettext("Created")} {PhoenixKit.Utils.Date.format_date_with_user_format(
entity.date_created
)}
</div>
</div>
</div>
<% end %>
</div>
</div>
<% end %>
</div>
</PhoenixKitWeb.Components.LayoutWrapper.app_layout>