devel #38
11 changed files with 123 additions and 61 deletions
|
@ -86,3 +86,11 @@ a[rel] svg {
|
|||
svg {
|
||||
width: 1.5em;
|
||||
}
|
||||
|
||||
.alert {
|
||||
@apply p-3 mt-3 rounded;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
@apply bg-red-100 text-red-500 dark:bg-red-950 dark:text-red-500;
|
||||
}
|
|
@ -35,8 +35,3 @@
|
|||
background-size: contain;
|
||||
}
|
||||
|
||||
.lightbox span img {
|
||||
width: 75%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ const groupNameStyle = {
|
|||
padding: "8px 16px",
|
||||
fontSize: "10px",
|
||||
textTransform: "uppercase",
|
||||
opacity: 0.5,
|
||||
opacity: 0.75,
|
||||
};
|
||||
|
||||
|
||||
|
@ -44,7 +44,7 @@ function RenderResults() {
|
|||
items={results}
|
||||
onRender={({ item, active }) =>
|
||||
typeof item === "string" ? (
|
||||
<div style={groupNameStyle}>{item}</div>
|
||||
<div style={groupNameStyle} class="dark:text-white">{item}</div>
|
||||
) : (
|
||||
<ResultItem
|
||||
action={item}
|
||||
|
@ -88,7 +88,7 @@ const ResultItem = React.forwardRef(
|
|||
"border-l-2 border-emerald-300": active
|
||||
})}
|
||||
>
|
||||
<div className="flex gap-3 items-center text-sm">
|
||||
<div className="flex gap-3 items-center text-sm dark:text-white">
|
||||
{action.icon && action.icon}
|
||||
<div className="flex flex-col">
|
||||
<div>
|
||||
|
|
|
@ -149,7 +149,7 @@ defmodule Chiya.Notes do
|
|||
|> Repo.insert() do
|
||||
{:ok, note_image} ->
|
||||
note_image
|
||||
|> change_note_image(attrs)
|
||||
|> NoteImage.update_changeset(attrs)
|
||||
|> Repo.update()
|
||||
|
||||
{:error, changeset} ->
|
||||
|
@ -157,6 +157,12 @@ defmodule Chiya.Notes do
|
|||
end
|
||||
end
|
||||
|
||||
def update_note_image(%NoteImage{} = note_image, attrs) do
|
||||
note_image
|
||||
|> NoteImage.update_changeset(attrs)
|
||||
|> Repo.update()
|
||||
end
|
||||
|
||||
def delete_note_image(%NoteImage{} = note_image) do
|
||||
{:ok, _} = Repo.delete(note_image)
|
||||
:ok = ChiyaWeb.Uploaders.NoteImage.delete({note_image.path, note_image})
|
||||
|
@ -167,6 +173,6 @@ defmodule Chiya.Notes do
|
|||
Returns an `%Ecto.Changeset{}` for tracking note_image changes.
|
||||
"""
|
||||
def change_note_image(%NoteImage{} = note_image, attrs \\ %{}) do
|
||||
NoteImage.changeset(note_image, attrs)
|
||||
NoteImage.update_changeset(note_image, attrs)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,22 +7,23 @@ defmodule Chiya.Notes.NoteImage do
|
|||
field :content, :string, default: ""
|
||||
field :path, ChiyaWeb.Uploaders.NoteImage.Type
|
||||
field :note_id, :id
|
||||
field :featured, :boolean, default: false
|
||||
|
||||
timestamps()
|
||||
end
|
||||
|
||||
@doc false
|
||||
def changeset(note_image, attrs) do
|
||||
note_image
|
||||
|> cast(attrs, [:content, :note_id])
|
||||
|> cast_attachments(attrs, [:path], allow_paths: true)
|
||||
|> validate_required([:path, :note_id])
|
||||
end
|
||||
|
||||
@doc false
|
||||
def insert_changeset(note_image, attrs) do
|
||||
note_image
|
||||
|> cast(attrs, [:note_id])
|
||||
|> validate_required([:note_id])
|
||||
end
|
||||
|
||||
@doc false
|
||||
def update_changeset(note_image, attrs) do
|
||||
note_image
|
||||
|> cast(attrs, [:content, :note_id, :featured])
|
||||
|> cast_attachments(attrs, [:path], allow_paths: true)
|
||||
|> validate_required([:path, :note_id])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -34,14 +34,18 @@ defmodule ChiyaWeb.AdminComponents do
|
|||
<article class="upload-entry">
|
||||
<figure>
|
||||
<.live_img_preview entry={entry} />
|
||||
<figcaption><%= entry.client_name %></figcaption>
|
||||
<figcaption class="dark:text-gray-100"><%= entry.client_name %></figcaption>
|
||||
</figure>
|
||||
|
||||
<div class="flex">
|
||||
<%!-- entry.progress will update automatically for in-flight entries --%>
|
||||
<progress value={entry.progress} max="100"><%= entry.progress %>%</progress>
|
||||
<progress value={entry.progress} max="100" class="w-full">
|
||||
<%= entry.progress %>%
|
||||
</progress>
|
||||
|
||||
<%!-- a regular click event whose handler will invoke Phoenix.LiveView.cancel_upload/3 --%>
|
||||
<button
|
||||
class="px-2 dark:text-white"
|
||||
type="button"
|
||||
phx-click="cancel-upload"
|
||||
phx-value-ref={entry.ref}
|
||||
|
@ -49,6 +53,7 @@ defmodule ChiyaWeb.AdminComponents do
|
|||
>
|
||||
×
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
|
||||
<%= for err <- upload_errors(@upload, entry) do %>
|
||||
|
|
|
@ -69,7 +69,11 @@ defmodule ChiyaWeb.CoreComponents do
|
|||
phx-remove={hide_modal(@id)}
|
||||
class="relative z-50 hidden"
|
||||
>
|
||||
<div id={"#{@id}-bg"} class="fixed inset-0 bg-gray-50/90 transition-opacity" aria-hidden="true" />
|
||||
<div
|
||||
id={"#{@id}-bg"}
|
||||
class="fixed inset-0 bg-gray-50/90 dark:bg-gray-900/90 transition-opacity"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<div
|
||||
class="fixed inset-0 overflow-y-auto"
|
||||
aria-labelledby={"#{@id}-title"}
|
||||
|
@ -86,7 +90,7 @@ defmodule ChiyaWeb.CoreComponents do
|
|||
phx-window-keydown={hide_modal(@on_cancel, @id)}
|
||||
phx-key="escape"
|
||||
phx-click-away={hide_modal(@on_cancel, @id)}
|
||||
class="hidden relative rounded-2xl bg-white p-14 shadow-lg shadow-gray-700/10 ring-1 ring-gray-700/10 transition"
|
||||
class="hidden relative rounded-2xl bg-white p-14 shadow-lg shadow-gray-700/10 ring-1 ring-gray-700/10 transition dark:bg-gray-900"
|
||||
>
|
||||
<div class="absolute top-6 right-5">
|
||||
<button
|
||||
|
@ -95,7 +99,7 @@ defmodule ChiyaWeb.CoreComponents do
|
|||
class="-m-3 flex-none p-3 opacity-20 hover:opacity-40"
|
||||
aria-label={gettext("close")}
|
||||
>
|
||||
<.icon name="hero-x-mark-solid" class="w-5 h-5" />
|
||||
<.icon name="hero-x-mark-solid" class="w-5 h-5 dark:text-gray-50" />
|
||||
</button>
|
||||
</div>
|
||||
<div id={"#{@id}-content"}>
|
||||
|
|
|
@ -27,10 +27,14 @@
|
|||
</a>
|
||||
<a href="#images" class="lightbox" id={"image-#{image.id}"}>
|
||||
<span>
|
||||
<img src={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :full_dithered)} loading="lazy" />
|
||||
<img
|
||||
class="md:max-w-screen-sm lg:max-w-screen-md xl:max-w-screen-lg max-h-screen mx-auto"
|
||||
src={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :full_dithered)}
|
||||
loading="lazy"
|
||||
/>
|
||||
<span class="text-theme-background text-center"><%= image.content %></span>
|
||||
</span>
|
||||
</a>
|
||||
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
|
|
|
@ -2,6 +2,7 @@ defmodule ChiyaWeb.NoteShowLive do
|
|||
use ChiyaWeb, :live_view
|
||||
|
||||
alias Chiya.Notes
|
||||
alias Chiya.Notes.NoteImage
|
||||
|
||||
@impl true
|
||||
def render(assigns) do
|
||||
|
@ -41,28 +42,39 @@ defmodule ChiyaWeb.NoteShowLive do
|
|||
<div class="flex flex-wrap gap-3" id="images">
|
||||
<%= for image <- @note.images do %>
|
||||
<article>
|
||||
<a href={"#image-#{image.id}"}>
|
||||
<a href="#" phx-click={show_modal("image-edit-modal-#{image.id}")} phx-value-id={image.id}>
|
||||
<img
|
||||
class="rounded-lg border border-theme-dim w-28"
|
||||
src={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :thumb_dithered)}
|
||||
/>
|
||||
</a>
|
||||
<p class="text-center text-xs text-gray-700 dark:text-gray-300">
|
||||
<a
|
||||
href="#"
|
||||
|
||||
<.modal id={"image-edit-modal-#{image.id}"}>
|
||||
<.simple_form
|
||||
:let={f}
|
||||
for={to_form(Notes.change_note_image(image))}
|
||||
id={"image-edit-form-#{image.id}"}
|
||||
phx-submit="update_edit_image"
|
||||
phx-change="validate_edit_image"
|
||||
>
|
||||
<.input field={f[:id]} type="hidden" value={image.id} />
|
||||
<.input field={f[:content]} type="textarea" label="Content" />
|
||||
<.input field={f[:featured]} type="checkbox" label="Featured" />
|
||||
|
||||
<:actions>
|
||||
<.button type="submit" phx-click={hide_modal("image-edit-modal-#{image.id}")}>
|
||||
Save
|
||||
</.button>
|
||||
<.button
|
||||
phx-click="delete_image"
|
||||
phx-value-id={image.id}
|
||||
data-confirm="Are you sure?"
|
||||
>
|
||||
Delete image
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<a href="#images" class="lightbox" id={"image-#{image.id}"}>
|
||||
<span>
|
||||
<img src={ChiyaWeb.Uploaders.NoteImage.url({image.path, image}, :full_dithered)} />
|
||||
</span>
|
||||
</a>
|
||||
Delete Image
|
||||
</.button>
|
||||
</:actions>
|
||||
</.simple_form>
|
||||
</.modal>
|
||||
</article>
|
||||
<% end %>
|
||||
</div>
|
||||
|
@ -95,12 +107,13 @@ defmodule ChiyaWeb.NoteShowLive do
|
|||
|
||||
@impl true
|
||||
def mount(%{"id" => note_id}, _session, socket) do
|
||||
image_changeset = Notes.change_note_image(%Chiya.Notes.NoteImage{})
|
||||
image_changeset = Notes.change_note_image(%NoteImage{})
|
||||
|
||||
{:ok,
|
||||
socket
|
||||
|> assign(:note, Notes.get_note_preloaded!(note_id))
|
||||
|> assign(:uploaded_files, [])
|
||||
|> assign(:image_edit_form, to_form(image_changeset))
|
||||
|> assign(:image_form, to_form(image_changeset))
|
||||
|> allow_upload(:note_images, accept: ~w(.jpg .jpeg .gif .png), max_entries: 100)}
|
||||
end
|
||||
|
@ -133,6 +146,23 @@ defmodule ChiyaWeb.NoteShowLive do
|
|||
|> assign(:note, Notes.get_note_preloaded!(socket.assigns.note.id))}
|
||||
end
|
||||
|
||||
def handle_event("validate_edit_image", assigns, socket) do
|
||||
{:noreply,
|
||||
socket
|
||||
|> assign(
|
||||
:image_edit_form,
|
||||
to_form(Notes.change_note_image(%NoteImage{}, assigns))
|
||||
)}
|
||||
end
|
||||
|
||||
def handle_event("update_edit_image", %{"id" => id} = assigns, socket) do
|
||||
id
|
||||
|> Notes.get_note_image!()
|
||||
|> Notes.update_note_image(assigns)
|
||||
|
||||
{:noreply, socket}
|
||||
end
|
||||
|
||||
@impl Phoenix.LiveView
|
||||
def handle_event("delete_image", %{"id" => id}, socket) do
|
||||
:ok =
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
defmodule Chiya.Repo.Migrations.AddFeaturedFlagToNoteImage do
|
||||
use Ecto.Migration
|
||||
|
||||
def change do
|
||||
alter table(:note_images) do
|
||||
add :featured, :boolean
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in a new issue