Skip to content

Instantly share code, notes, and snippets.

@mazz
Created Nov 12, 2021
Embed
What would you like to do?
@tailwind base;
@tailwind components;
@tailwind utilities;
@import "./phoenix.css";
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap");
.hidden {
visibility: hidden;
}
iframe[hidden] {
height: 0px;
width: 0px;
}
.sp-underline {
text-underline-position: from-font;
text-decoration-thickness: 2px !important;
text-decoration: underline;
}
.sp-underline.primary {
text-decoration-color: #7c3aed !important;
}
.sp-underline.red {
text-decoration-color: #db2777 !important;
}
.sp-underline.bold {
text-decoration-thickness: 3px !important;
}
.dropdown:hover .dropdown-menu {
display: block;
}
.phoenix-live-view-dropzone {
opacity: 0.75;
color: #ffffff;
background-color: #1D1D1D;
border: 2px solid #808080;;
padding: 15px;
border-radius: 10px;
border-style: dashed;
}
.upload-progress {
height: 3.5em;
width: 100%;
background-color: #1D1D1D;
position: relative;
border-radius: 10px;
}
.upload-progress:before {
content: attr(data-label);
font-size: 0.8em;
position: absolute;
text-align: center;
top: 18px;
left: 0;
right: 0;
}
.upload-progress .value {
background-color: #7C3AED;
display: inline-block;
height: 100%;
border-radius: 10px;
}
.unpublished-media {
background: repeating-linear-gradient(
45deg,
#1D1D1D,
#1D1D1D 10px,
#202020 10px,
#202020 20px
);
}
* {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
@layer components {
.input {
@apply rounded-md bg-gray-700 border-none focus:outline-none focus:ring-2 focus:ring-primary-300;
}
}
defmodule FaithfulWordWeb.Components.ChannelMediaItemEditModal do
use Surface.LiveComponent
require Logger
alias FaithfulWordWeb.Components.{
Button,
Modal,
ModalActions
}
alias Surface.Components.Form
alias Surface.Components.Form.{
Field,
TextInput,
TextArea,
Checkbox,
ErrorTag,
MultipleSelect,
Select,
}
@doc "Post data"
prop changeset, :changeset, required: true
@doc "The media_item data"
prop media_item, :map, required: true
@doc "Current channel's playlists"
prop playlists, :list, default: []
@doc "Current channel's language_identifiers"
prop language_identifiers, :list, default: []
prop current_user, :any
@doc "On form submit event"
prop submit, :event, required: true
@doc "On form publish event"
# prop publish, :event, required: true
@doc "Event to close the modal"
prop close, :event, required: true
# tabs
data show_primary_details, :boolean, default: true
data show_language_details, :boolean, default: false
data show_playlist_details, :boolean, default: false
data publish_verification, :string, default: ""
def render(assigns) do
~F"""
<Modal title="Edit media item">
<Form for={@changeset} submit={@submit} opts={class: "h-full"}>
<div class="h-full flex flex-col">
<div>
<nav class="flex flex-col sm:flex-row">
<Button
click="show_primary_details"
class={
"py-4",
"px-6",
"block",
"hover:text-purple-500",
"focus:outline-none",
"rounded-none",
"text-purple-500": @show_primary_details,
"border-b-2": @show_primary_details,
"border-purple-500": @show_primary_details,
"text-white": !@show_primary_details
}
>Primary details</Button>
<Button
click="show_language_details"
class={
"py-4",
"px-6",
"block",
"hover:text-purple-500",
"focus:outline-none",
"rounded-none",
"text-purple-500": @show_language_details,
"border-b-2": @show_language_details,
"border-purple-500": @show_language_details,
"text-white": !@show_language_details
}
>Language</Button>
<Button
click="show_playlist_details"
class={
"py-4",
"px-6",
"block",
"hover:text-purple-500",
"focus:outline-none",
"rounded-none",
"text-purple-500": @show_playlist_details,
"border-b-2": @show_playlist_details,
"border-purple-500": @show_playlist_details,
"text-white": !@show_playlist_details
}
>Playlist</Button>
</nav>
</div>
<div class={"hidden": !@show_primary_details}>
<div class="flex flex-row justify-between space-x-2">
<Field name={:title} class="w-full">
<div class="flex flex-row space-x-1 py-1">
</div>
<TextInput opts={placeholder: "Title"}
class="input w-full my-1"
value={@media_item.title}
/>
<ErrorTag class="text-sm text-red-500"/>
</Field>
</div>
<div class="flex flex-row justify-between space-x-2 py-2">
<Field name={:description} class="w-full">
<TextArea
rows="4"
opts={placeholder: "Description", style: "resize: none"}
class="input w-full my-1"
value={@media_item.description}
/>
</Field>
</div>
<Field name={:source_material} class="w-full">
<div class="flex flex-row space-x-1 py-1">
<div class="text-sm text-gray-300">
Name of album or name of location where content was recorded.
</div>
<div title="Must be between 1-512 characters long">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
</svg>
</div>
</div>
<TextInput opts={placeholder: "Source material"}
class="input w-full my-1"
value={@media_item.source_material}
/>
<ErrorTag class="text-sm text-red-500"/>
</Field>
<Field name={:presenter_name} class="w-full">
<div class="flex flex-row space-x-1 py-1">
</div>
<TextInput opts={placeholder: "Presenter name"}
class="input w-full my-1"
value={@media_item.presenter_name}
/>
<ErrorTag class="text-sm text-red-500"/>
</Field>
</div>
<div class={"hidden": !@show_language_details}>
<div class="flex flex-row justify-between space-x-2 py-3">
<Field :if={@language_identifiers != []} name={:language_id} class="rounded-md w-full flex flex-row items-start py-2 bg-gray-600">
<span class="pl-4 text-xs text-gray-300">Select language</span>
<Select options={make_languages(@language_identifiers)} selected={@media_item.language_id} class="py-0 text-xs bg-gray-600 flex-1 px-4 border-none text-sm font-medium placeholder-gray-300 text-white rounded-none group outline-none focus:outline-none focus:ring-0"/>
</Field>
</div>
<Field name={:localizedname} class="w-full">
<div class="flex flex-row space-x-1 py-1">
<div class="text-sm text-gray-300">
Title in localized language(same as Title if media is in english).
</div>
<div title="Must be between 1-512 characters long">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
</svg>
</div>
</div>
<TextInput opts={placeholder: "Localized name"}
class="input w-full my-1"
value={@media_item.localizedname}
/>
<ErrorTag class="text-sm text-red-500"/>
</Field>
</div>
<div class={"hidden": !@show_playlist_details}>
<div class="flex flex-row justify-between space-x-2 py-3">
<Field :if={@playlists != []} name={:playlist_ids} class="rounded-md w-full flex flex-row items-start py-2 bg-gray-600">
<span class="pl-4 text-xs text-gray-300">Select playlist(s)</span>
<MultipleSelect options={make_playlists(@playlists)} opts={placeholder: "Playlist", autocomplete: "off"} class="py-0 text-xs bg-gray-600 flex-1 px-4 border-none text-sm font-medium placeholder-gray-300 text-white rounded-none group outline-none focus:outline-none focus:ring-0"/>
</Field>
</div>
<div class="flex flex-row space-x-1 py-1">
<div class="text-sm text-gray-300">
Not selecting a playlist will add this media item to channel only.
</div>
</div>
</div>
<div class="flex-1"></div>
<ModalActions>
<div class="flex flex-row w-full space-x-2">
<Button click={@close} expand={true} color="secondary">Close</Button>
<Button type="submit" expand={true} color="primary">Update</Button>
</div>
</ModalActions>
</div>
</Form>
</Modal>
"""
end
def handle_event("show_primary_details", _params, socket) do
socket = socket
|> assign_show_primary_details(true)
|> assign_show_language_details(false)
|> assign_show_playlist_details(false)
{:noreply, socket}
# {:noreply, assign_show_primary_details(socket, !socket.assigns.show_primary_details)}
end
def handle_event("show_language_details", _params, socket) do
socket = socket
|> assign_show_primary_details(false)
|> assign_show_language_details(true)
|> assign_show_playlist_details(false)
{:noreply, socket}
# {:noreply, assign_show_language_details(socket, !socket.assigns.show_language_details)}
end
def handle_event("show_playlist_details", _params, socket) do
socket = socket
|> assign_show_primary_details(false)
|> assign_show_language_details(false)
|> assign_show_playlist_details(true)
{:noreply, socket}
# {:noreply, assign_show_playlist_details(socket, !socket.assigns.show_playlist_details)}
end
def handle_event("keyup", %{"value" => value}, socket) do
IO.inspect(value, label: "handle_event publish_verification value")
{:noreply, assign(socket, publish_verification: value)}
end
defp make_playlists(playlists) do
IO.inspect(playlists, label: "make_options playlists")
playlists
|> Enum.map(fn playlist -> {playlist.name, playlist.id} end)
|> Enum.to_list()
end
defp make_languages(language_identifiers) do
# IO.inspect(language_identifiers, label: "make_options language_identifiers")
language_identifiers
|> Enum.map(fn language_identifier -> {language_identifier.identifier, language_identifier.identifier} end)
|> Enum.to_list()
end
defp assign_show_primary_details(socket, show_primary_details) do
Logger.debug("assign_show_primary_details")
assign(socket, show_primary_details: show_primary_details)
end
defp assign_show_language_details(socket, show_language_details) do
Logger.debug("assign_show_language_details")
assign(socket, show_language_details: show_language_details)
end
defp assign_show_playlist_details(socket, show_playlist_details) do
Logger.debug("assign_show_playlist_details")
assign(socket, show_playlist_details: show_playlist_details)
end
end
@mazz
Copy link
Author

mazz commented Nov 12, 2021

reset.mp4

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment