Packages
phoenix_kit
1.7.20
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
Current section
Files
lib/modules/posts/web/group_edit.ex
defmodule PhoenixKitWeb.Live.Modules.Posts.GroupEdit do
@moduledoc """
LiveView for creating and editing post groups (collections).
Groups are user-specific collections for organizing posts. Each user can
create groups with unique slugs within their own collection (Pinterest-style).
## Features
- **Group Creation**: Create new groups with name, description, slug
- **Group Editing**: Update existing group details
- **Slug Management**: Auto-generate or manually set URL-friendly slugs
- **Visibility Control**: Public or private group settings
- **Validation**: Ensure slug uniqueness within user's groups
## Route
- New group: `{prefix}/admin/posts/groups/new`
- Edit group: `{prefix}/admin/posts/groups/:id/edit`
Note: `{prefix}` is your configured PhoenixKit URL prefix (default: `/phoenix_kit`).
"""
use PhoenixKitWeb, :live_view
alias Phoenix.Component
alias PhoenixKit.Modules.Posts
alias PhoenixKit.Settings
alias PhoenixKit.Utils.Routes
@impl true
def mount(params, _session, socket) do
current_user = socket.assigns[:phoenix_kit_current_user]
project_title = Settings.get_setting("project_title", "PhoenixKit")
allow_groups = Settings.get_setting("posts_allow_groups", "true") == "true"
if allow_groups do
group_id = Map.get(params, "id")
socket = load_group_form(socket, group_id, current_user, project_title)
{:ok, socket}
else
{:ok,
socket
|> put_flash(:error, "Groups feature is not enabled")
|> push_navigate(to: Routes.path("/admin/posts"))}
end
end
defp load_group_form(socket, nil, current_user, project_title) do
form_data = %{
"name" => "",
"description" => "",
"slug" => "",
"visibility" => "public"
}
form = Component.to_form(form_data, as: :post_group)
socket
|> assign(:page_title, "New Group")
|> assign(:project_title, project_title)
|> assign(:group, %{id: nil, user_id: current_user.id})
|> assign(:form, form)
|> assign(:current_user, current_user)
end
defp load_group_form(socket, group_id, current_user, project_title) do
case Posts.get_group(group_id) do
nil ->
socket
|> put_flash(:error, "Group not found")
|> push_navigate(to: Routes.path("/admin/posts/groups"))
group ->
load_existing_group(socket, group, current_user, project_title)
end
end
defp load_existing_group(socket, group, current_user, project_title) do
if group.user_id == current_user.id do
form_data = %{
"name" => group.name || "",
"description" => group.description || "",
"slug" => group.slug || "",
"visibility" => group.visibility || "public"
}
form = Component.to_form(form_data, as: :post_group)
socket
|> assign(:page_title, "Edit Group")
|> assign(:project_title, project_title)
|> assign(:group, group)
|> assign(:form, form)
|> assign(:current_user, current_user)
else
socket
|> put_flash(:error, "You don't have permission to edit this group")
|> push_navigate(to: Routes.path("/admin/posts/groups"))
end
end
@impl true
def handle_event("validate", %{"post_group" => group_params}, socket) do
# Auto-generate slug from name if slug is empty
group_params = maybe_generate_slug(group_params)
form = Component.to_form(group_params, as: :post_group)
{:noreply, assign(socket, :form, form)}
end
@impl true
def handle_event("save", %{"post_group" => group_params}, socket) do
# Auto-generate slug from name if slug is empty
group_params = maybe_generate_slug(group_params)
save_group(
socket,
Map.get(socket.assigns.group, :id) || socket.assigns.group[:id],
group_params
)
end
@impl true
def handle_event("cancel", _params, socket) do
{:noreply, push_navigate(socket, to: Routes.path("/admin/posts/groups"))}
end
## --- Private Helper Functions ---
defp save_group(socket, nil, group_params) do
# Creating new group
case Posts.create_group(socket.assigns.current_user.id, group_params) do
{:ok, group} ->
{:noreply,
socket
|> put_flash(:info, "Group created successfully")
|> push_navigate(to: Routes.path("/admin/posts/groups/#{group.id}"))}
{:error, _changeset} ->
{:noreply,
socket
|> put_flash(:error, "Failed to create group")
|> assign(:form, Component.to_form(group_params, as: :post_group))}
end
end
defp save_group(socket, _group_id, group_params) do
# Updating existing group
case Posts.update_group(socket.assigns.group, group_params) do
{:ok, group} ->
{:noreply,
socket
|> put_flash(:info, "Group updated successfully")
|> push_navigate(to: Routes.path("/admin/posts/groups/#{group.id}"))}
{:error, _changeset} ->
{:noreply,
socket
|> put_flash(:error, "Failed to update group")
|> assign(:form, Component.to_form(group_params, as: :post_group))}
end
end
defp maybe_generate_slug(group_params) do
slug = Map.get(group_params, "slug", "")
name = Map.get(group_params, "name", "")
if (slug == "" or is_nil(slug)) and name != "" do
# Generate slug from name
generated_slug =
name
|> String.downcase()
|> String.replace(~r/[^a-z0-9\s-]/, "")
|> String.replace(~r/\s+/, "-")
|> String.replace(~r/-+/, "-")
|> String.trim("-")
Map.put(group_params, "slug", generated_slug)
else
group_params
end
end
end