Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/phoenix_kit/storage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ defmodule PhoenixKit.Storage do
end

defp get_redundancy_copies do
Settings.get_setting("storage_redundancy_copies", "2")
Settings.get_setting("storage_redundancy_copies", "1")
|> String.to_integer()
|> max(1)
|> min(5)
Expand Down
8 changes: 4 additions & 4 deletions lib/phoenix_kit_web/components/core/file_upload.ex
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ defmodule PhoenixKitWeb.Components.Core.FileUpload do
def file_upload(assigns) do
~H"""
<div class="space-y-4">
<%!-- Upload Button and File Input --%>
<div class="flex items-center gap-3">
<%!-- Upload Form with phx-change on form not file input --%>
<form phx-change="validate" id={"upload-form-" <> @upload.ref}>
<label for={@upload.ref} class="btn btn-primary cursor-pointer">
<.icon name={@icon} class="w-4 h-4 mr-2" />
{@label}
</label>
<.live_file_input upload={@upload} class="hidden" phx-change="validate" />
</div>
<.live_file_input upload={@upload} class="hidden" />
</form>

<%!-- File Type and Size Info --%>
<%= if @accept_description != nil or @max_size_description != nil do %>
Expand Down
23 changes: 21 additions & 2 deletions lib/phoenix_kit_web/integration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ defmodule PhoenixKitWeb.Integration do
live "/admin/users/live_sessions", Live.Users.LiveSessions, :index
live "/admin/users/sessions", Live.Users.Sessions, :index
live "/admin/users/media", Live.Users.Media, :index
live "/admin/users/media/:file_id", Live.Users.MediaDetail, :show
live "/admin/settings", Live.Settings, :index
live "/admin/settings/users", Live.Settings.Users, :index
live "/admin/modules", Live.Modules, :index
Expand Down Expand Up @@ -415,6 +416,7 @@ defmodule PhoenixKitWeb.Integration do
live "/admin/users/live_sessions", Live.Users.LiveSessions, :index
live "/admin/users/sessions", Live.Users.Sessions, :index
live "/admin/users/media", Live.Users.Media, :index
live "/admin/users/media/:file_id", Live.Users.MediaDetail, :show
live "/admin/settings", Live.Settings, :index
live "/admin/settings/users", Live.Settings.Users, :index
live "/admin/modules", Live.Modules, :index
Expand Down Expand Up @@ -451,6 +453,7 @@ defmodule PhoenixKitWeb.Integration do
Live.Settings.Storage.DimensionForm,
:edit

live "/admin/users/referral-codes", Live.Users.ReferralCodes, :index
live "/admin/users/referral-codes/new", Live.Users.ReferralCodeForm, :new
live "/admin/users/referral-codes/edit/:id", Live.Users.ReferralCodeForm, :edit
live "/admin/emails/dashboard", Live.Modules.Emails.Metrics, :index
Expand Down Expand Up @@ -513,8 +516,24 @@ defmodule PhoenixKitWeb.Integration do
scope blog_scope_multi, PhoenixKitWeb do
pipe_through [:browser, :phoenix_kit_auto_setup, :phoenix_kit_locale_validation]

get "/:blog", BlogController, :show
get "/:blog/*path", BlogController, :show
# Exclude admin paths from blogging catch-all routes
get "/:blog", BlogController, :show, constraints: %{"blog" => ~r/^(?!admin$)/}
get "/:blog/*path", BlogController, :show, constraints: %{"blog" => ~r/^(?!admin$)/}
end

# Non-localized blog routes (for when url_prefix is "/")
blog_scope_non_localized =
case unquote(url_prefix) do
"/" -> "/"
prefix -> prefix
end

scope blog_scope_non_localized, PhoenixKitWeb do
pipe_through [:browser, :phoenix_kit_auto_setup, :phoenix_kit_locale_validation]

# Exclude admin paths from blogging catch-all routes
get "/:blog", BlogController, :show, constraints: %{"blog" => ~r/^(?!admin$)/}
get "/:blog/*path", BlogController, :show, constraints: %{"blog" => ~r/^(?!admin$)/}
end
end
end
Expand Down
80 changes: 0 additions & 80 deletions lib/phoenix_kit_web/live/settings/storage.ex
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,8 @@ defmodule PhoenixKitWeb.Live.Settings.Storage do
imagemagick_status = Dependencies.check_imagemagick_cached()
ffmpeg_status = Dependencies.check_ffmpeg_cached()

# Allow uploads - SUPER SIMPLE!
socket =
socket
|> allow_upload(:files,
accept: ["image/*", "video/*", "application/pdf"],
max_entries: 10,
max_file_size: 100_000_000,
# Manually upload on submit
auto_upload: false
)
|> assign(:current_path, current_path)
|> assign(:page_title, "Storage Settings")
|> assign(:project_title, project_title)
Expand All @@ -71,7 +63,6 @@ defmodule PhoenixKitWeb.Live.Settings.Storage do
|> assign(:max_redundancy, max_redundancy)
|> assign(:form_redundancy, form_redundancy)
|> assign(:form_auto_generate_variants, form_auto_generate_variants)
|> assign(:uploaded_files, [])
|> assign(:imagemagick_status, imagemagick_status)
|> assign(:ffmpeg_status, ffmpeg_status)

Expand Down Expand Up @@ -266,77 +257,6 @@ defmodule PhoenixKitWeb.Live.Settings.Storage do
end
end

def handle_event("validate", _params, socket) do
# Handle form validation - files are being validated on change
{:noreply, socket}
end

def handle_event("save", _params, socket) do
# Check if there are files selected in the browser
if socket.assigns.uploads.files.entries == [] do
{:noreply, put_flash(socket, :info, "No files selected")}
else
# consume_uploaded_entries will automatically upload the files first, then process them
uploaded_files =
consume_uploaded_entries(socket, :files, fn %{path: path}, entry ->
# Get file info
ext = Path.extname(entry.client_name) |> String.replace_leading(".", "")
mime_type = entry.client_type || MIME.from_path(entry.client_name)
file_type = determine_file_type(mime_type)

# Get current user
current_user = socket.assigns.phoenix_kit_current_user
user_id = if current_user, do: current_user.id, else: 1

# Get file size
{:ok, stat} = File.stat(path)
file_size = stat.size

# Calculate hash
file_hash = calculate_file_hash(path)

# Store file in storage
case PhoenixKit.Storage.store_file_in_buckets(path, file_type, user_id, file_hash, ext) do
{:ok, file} ->
# Queue background job for processing
job =
%{file_id: file.id, user_id: user_id, filename: entry.client_name}
|> ProcessFileJob.new()
|> Oban.insert()

# Debug logging
Logger.debug("Oban Job Inserted: #{inspect(job)}")

{:ok,
%{
file_id: file.id,
filename: entry.client_name,
file_type: file_type,
mime_type: mime_type,
size: file_size,
status: file.status,
url: nil
}}

{:error, reason} ->
Logger.error("Storage Error: #{inspect(reason)}")
{:error, reason}
end
end)

socket =
socket
|> assign(:uploaded_files, uploaded_files)
|> put_flash(:info, "Upload successful! #{length(uploaded_files)} file(s) processed")

{:noreply, socket}
end
end

def handle_event("cancel_upload", %{"ref" => ref}, socket) do
{:noreply, cancel_upload(socket, :files, ref)}
end

defp calculate_file_hash(file_path) do
file_path
|> File.read!()
Expand Down
83 changes: 0 additions & 83 deletions lib/phoenix_kit_web/live/settings/storage.html.heex
Original file line number Diff line number Diff line change
Expand Up @@ -477,89 +477,6 @@
</div>

<%!-- Upload Test Section --%>
<div class="card bg-base-100 shadow-xl mb-6">
<div class="card-body">
<h2 class="card-title text-2xl mb-4">
<.icon name="hero-cloud-arrow-up" class="w-6 h-6 mr-2" /> Upload Test
</h2>
<p class="text-sm text-base-content/70 mb-4">
Upload a file to test the storage system. Supported formats: JPG, PNG, WebP, MP4, WebM, PDF
<br />Maximum file size: 100MB
</p>

<%!-- Super simple: file input + submit button --%>
<form phx-submit="save">
<.live_file_input upload={@uploads.files} phx-change="validate" />
<button type="submit" class="btn btn-primary mt-4">
<.icon name="hero-cloud-arrow-up" class="w-4 h-4 mr-2" /> Upload File
</button>
</form>

<%!-- Show uploaded entries --%>
<%= for entry <- @uploads.files.entries do %>
<div class="mt-4 p-4 border border-base-300 rounded-lg">
<div class="flex justify-between items-start">
<div class="flex-1">
<p class="font-semibold">{entry.client_name}</p>
<p class="text-sm text-base-content/60">
{format_bytes(entry.client_size)}
</p>
</div>
<button
type="button"
phx-click="cancel_upload"
phx-value-ref={entry.ref}
class="btn btn-xs btn-ghost"
>
<.icon name="hero-x-mark" class="w-4 h-4" />
</button>
</div>
</div>
<% end %>

<%= if length(@uploaded_files) > 0 do %>
<div class="mt-6">
<h3 class="font-bold mb-3">Uploaded Files</h3>
<div class="overflow-x-auto">
<table class="table table-zebra">
<thead>
<tr>
<th>Filename</th>
<th>Type</th>
<th>Size</th>
<th>Status</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<%= for file <- @uploaded_files do %>
<tr>
<td>
<div class="font-bold">{file.filename}</div>
</td>
<td>
<span class="badge badge-ghost">{file.file_type}</span>
</td>
<td>{format_bytes(file.size)}</td>
<td>
<span class={"badge #{if file.status == "active", do: "badge-success", else: "badge-warning"}"}>
{file.status}
</span>
</td>
<td>
<button class="btn btn-xs btn-ghost" title="View file details">
<.icon name="hero-eye" class="w-4 h-4" />
</button>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
</div>
<% end %>
</div>
</div>

<%!-- Help Section --%>
<div class="alert mt-6">
Expand Down
Loading