lyrics

lyrics
git clone git://brookjeynes.dev/bjeynes/lyrics.git
Log | Files | Refs

new-release.templ (4725B)


      1 package newrelease
      2 
      3 import (
      4 	"fmt"
      5 	"lyrics/internal/domain"
      6 	"lyrics/internal/server/ui/layouts/base"
      7 	"time"
      8 )
      9 
     10 templ NewRelease(params NewReleaseParams) {
     11 	@base.Base(base.BaseParams{Title: "new release", PageStylesheets: []string{"new-release.css"}}) {
     12 		<h1>Add a release</h1>
     13 		<form
     14 			class="release-form"
     15 			hx-post="/release/new"
     16 			hx-swap="none"
     17 			hx-disable-elt="#add-release-btn"
     18 		>
     19 			<fieldset>
     20 				<legend>Type</legend>
     21 				<label for="type">type:</label>
     22 				<select name="type" required>
     23 					<option value="album">album</option>
     24 					<option value="single">single</option>
     25 					<option value="ep">ep</option>
     26 					<option value="other">other</option>
     27 				</select>
     28 			</fieldset>
     29 			<fieldset x-data="{ showLatinTitle: false }">
     30 				<legend>Title</legend>
     31 				<label>
     32 					title:
     33 					<input
     34 						hx-get="/release/search?format=similar"
     35 						hx-trigger="input changed delay:500ms"
     36 						hx-target="#similar-releases"
     37 						hx-swap="innerHTML"
     38 						name="release-title"
     39 						type="text"
     40 						pattern={ domain.NoTrailingOrLeadingSpaceRegex.String() }
     41 						required
     42 						@input="showLatinTitle = isNonAscii($event.target.value)"
     43 					/>
     44 				</label>
     45 				<label x-show="showLatinTitle">
     46 					latin title:
     47 					<input
     48 						name="latin-title"
     49 						type="text"
     50 						:required="showLatinTitle"
     51 						pattern={ domain.IsValidSortNamePattern }
     52 					/>
     53 				</label>
     54 			</fieldset>
     55 			<section id="similar-releases" class="similar-releases" aria-label="Similar releases"></section>
     56 			<fieldset x-data="{ items: [{ id: 0 }], uid: 1 }">
     57 				<legend>Artists</legend>
     58 				<ol class="picker-list">
     59 					<template x-for="(item, i) in items" :key="item.id">
     60 						<li
     61 							x-data="{ selected: false, artistId: '', artistName: '' }"
     62 							x-init="htmx.process($el); initLucideIcons()"
     63 						>
     64 							<div class="picker-row">
     65 								<div class="picker-main">
     66 									<label x-show="!selected">
     67 										<span>artist:</span>
     68 										<input
     69 											type="search"
     70 											hx-get="/artist/search?format=suggest"
     71 											hx-trigger="input changed delay:500ms"
     72 											hx-target="next .picker-options"
     73 											hx-swap="outerHTML"
     74 											name="artist"
     75 											autocomplete="off"
     76 											:required="!selected"
     77 										/>
     78 									</label>
     79 									<div class="picker-selected-item" x-show="selected">
     80 										<strong x-text="artistName"></strong>
     81 										<button
     82 											type="button"
     83 											class="-secondary"
     84 											@click="selected = false; artistId = ''; artistName = ''"
     85 										>
     86 											change
     87 										</button>
     88 									</div>
     89 								</div>
     90 								<div class="picker-actions">
     91 									<button
     92 										type="button"
     93 										aria-label="Remove"
     94 										x-show="items.length > 1"
     95 										@click="items.splice(i, 1)"
     96 									>
     97 										<i data-lucide="x"></i>
     98 									</button>
     99 									<button
    100 										type="button"
    101 										aria-label="Move up"
    102 										x-show="selected && items.length > 1 && i >= 1"
    103 										@click="[items[i - 1], items[i]] = [items[i], items[i - 1]]"
    104 									>
    105 										<i data-lucide="chevron-up"></i>
    106 									</button>
    107 									<button
    108 										type="button"
    109 										aria-label="Move down"
    110 										x-show="selected && items.length > 1 && i + 1 < items.length"
    111 										@click="[items[i + 1], items[i]] = [items[i], items[i + 1]]"
    112 									>
    113 										<i data-lucide="chevron-down"></i>
    114 									</button>
    115 								</div>
    116 							</div>
    117 							<div x-show="!selected">
    118 								<fieldset class="picker-options" role="radiogroup" x-show="false"></fieldset>
    119 							</div>
    120 							<input type="hidden" name="artist-id" :value="artistId"/>
    121 						</li>
    122 					</template>
    123 				</ol>
    124 				<button class="-secondary" type="button" @click="items.push({ id: uid++ })">
    125 					add additional artist
    126 				</button>
    127 			</fieldset>
    128 			<fieldset>
    129 				<legend>Release</legend>
    130 				<label>
    131 					release date:
    132 					<input
    133 						name="release-date"
    134 						type="date"
    135 						min="1000-01-01"
    136 						max={ fmt.Sprintf("%s", time.Now().AddDate(3, 0, 0).Format("2006-01-02")) }
    137 						required
    138 					/>
    139 				</label>
    140 			</fieldset>
    141 			<fieldset>
    142 				<legend>MusicBrainz</legend>
    143 				<label title="External identifier used for metadata lookups such as cover art.">
    144 					Release ID (optional):
    145 					<input
    146 						name="musicbrainz-release-id"
    147 						type="text"
    148 						pattern={ domain.IsValidMusicBrainzIDPattern }
    149 						placeholder="e32a4ae3-67d1-4541-84d8-de6ab2d7dec1"
    150 					/>
    151 					<i data-lucide="info"></i>
    152 				</label>
    153 			</fieldset>
    154 			<footer aria-label="Form actions">
    155 				<button class="-primary" id="add-release-btn" type="submit">add release</button>
    156 			</footer>
    157 		</form>
    158 		<script src="/static/js/new-release.js" defer></script>
    159 	}
    160 }