feat: replace form helper functions with components in admin template

This commit is contained in:
Yassine Doghri 2021-09-15 15:58:21 +00:00
parent 6536729546
commit e64548b982
70 changed files with 1391 additions and 2501 deletions

View File

@ -81,9 +81,8 @@ class PostController extends FediversePostController
if (! ($cachedView = cache($cacheName))) { if (! ($cachedView = cache($cacheName))) {
$data = [ $data = [
'podcast' => $this->podcast,
'actor' => $this->actor,
'post' => $this->post, 'post' => $this->post,
'podcast' => $this->podcast,
]; ];
// if user is logged in then send to the authenticated activity view // if user is logged in then send to the authenticated activity view

View File

@ -69,9 +69,6 @@ class EpisodeComment extends UuidEntity
'is_from_post' => 'boolean', 'is_from_post' => 'boolean',
]; ];
/**
* Returns the comment's attached episode
*/
public function getEpisode(): ?Episode public function getEpisode(): ?Episode
{ {
if ($this->episode_id === null) { if ($this->episode_id === null) {

View File

@ -3,23 +3,34 @@
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright 2020 Podlibre * @copyright 2021 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/ * @link https://castopod.org/
*/ */
return [ return [
'blocked_actors' => 'Blocked accounts', 'your_handle' => 'Your handle',
'blocked_domains' => 'Blocked domains', 'your_handle_hint' => 'Enter the @username@domain you want to act from.',
'block_lists_form' => [ 'follow' => [
'handle' => 'Account handle', 'label' => 'Follow',
'handle_hint' => 'Input @username@domain account.', 'title' => 'Follow {actorDisplayName}',
'domain' => 'Domain name', 'subtitle' => 'You are going to follow:',
'submit' => 'Block!', 'accountNotFound' => 'The account could not be found.',
'submit' => 'Proceed to follow',
], ],
'list' => [ 'favourite' => [
'actor' => 'Account', 'title' => "Favourite {actorDisplayName}'s post",
'domain' => 'Domain name', 'subtitle' => 'You are going to favourite:',
'unblock' => 'Unblock', 'submit' => 'Proceed to favourite',
],
'reblog' => [
'title' => "Share {actorDisplayName}'s post",
'subtitle' => 'You are going to share:',
'submit' => 'Proceed to share',
],
'reply' => [
'title' => "Reply to {actorDisplayName}'s post",
'subtitle' => 'You are going to reply to:',
'submit' => 'Proceed to reply',
], ],
]; ];

View File

@ -3,20 +3,35 @@
declare(strict_types=1); declare(strict_types=1);
/** /**
* @copyright 2020 Podlibre * @copyright 2021 Podlibre
* @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3 * @license https://www.gnu.org/licenses/agpl-3.0.en.html AGPL3
* @link https://castopod.org/ * @link https://castopod.org/
*/ */
return [ return [
'block_lists' => 'Listes de blocage', 'your_handle' => 'Votre pseudonyme',
'block_lists_form' => [ 'your_handle_hint' =>
'blocked_users' => 'Utilisateurs bloqués', 'Entrez le @utilisateur@domaine avec lequel vous voulez interagir.',
'blocked_users_hint' => 'follow' => [
'Entrez les pseudonymes @utilisateur@domaine séparés par une virgule.', 'label' => 'Suivre',
'blocked_domains' => 'Domaines bloqués', 'title' => 'Suivre {actorDisplayName}',
'blocked_domains_hint' => 'subtitle' => 'Vous allez suivre :',
'Entrez les noms de domaine séparés par une virgule.', 'accountNotFound' => 'Le compte na pas pu être trouvé.',
'submit' => 'Sauvegarder les listes', 'submit' => 'Poursuivre',
],
'favourite' => [
'title' => 'Mettez la publication de {actorDisplayName} en favori',
'subtitle' => 'Vous allez mettre en favori :',
'submit' => 'Poursuivre',
],
'reblog' => [
'title' => 'Partagez la publication de {actorDisplayName}',
'subtitle' => 'Vous allez partager :',
'submit' => 'Poursuivre',
],
'reply' => [
'title' => 'Répondre à la publication de {actorDisplayName}',
'subtitle' => 'Vous allez répondre à :',
'submit' => 'Poursuivre',
], ],
]; ];

View File

@ -24,11 +24,12 @@ class Component implements ComponentInterface
{ {
helper('viewcomponents'); helper('viewcomponents');
// overwrite default attributes if set
$this->attributes = array_merge($this->attributes, $attributes);
if ($attributes !== []) { if ($attributes !== []) {
$this->hydrate($attributes); $this->hydrate($attributes);
} }
// overwrite default attributes if set
$this->attributes = array_merge($this->attributes, $attributes);
} }
/** /**

View File

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59 40">
<path d="M52.801 38.23h-8.853s-.93-1.975-1.306-2.671c-.378-.697-1.278-.668-1.278-.668H17.33s-.871-.116-1.307.668c-.464.784-1.335 2.67-1.335 2.67H5.98c-2.003 0-3.658-1.625-3.658-3.628V5.893c0-2.003 1.626-3.658 3.629-3.658h46.821c2.003 0 3.658 1.626 3.658 3.629v28.708c.029 2.003-1.626 3.657-3.629 3.657Z" fill="#009486"/>
<path d="M17.01 10.014h24.703c4.267-.028 7.721 3.426 7.692 7.722 0 4.238-3.454 7.692-7.692 7.692H17.01c-4.238 0-7.692-3.454-7.692-7.692 0-4.238 3.454-7.722 7.692-7.722Z" fill="#E7F9E4"/>
<path d="M39.768 14.804a3.773 3.773 0 0 0-3.774 3.777c0 .861.298 1.656.795 2.319 0 0 1.29-.96 3.111-.96 1.357 0 2.946.827 2.946.827.43-.63.695-1.358.695-2.186a3.773 3.773 0 0 0-3.773-3.777Zm-20.9 0a3.773 3.773 0 0 0-3.774 3.777c0 .828.265 1.557.695 2.186 0 0 1.59-.828 2.946-.828 1.821 0 3.112.96 3.112.96a3.707 3.707 0 0 0 .794-2.318 3.773 3.773 0 0 0-3.773-3.777Z" fill="#009486"/>
</svg>

After

Width:  |  Height:  |  Size: 966 B

View File

@ -1,39 +1,6 @@
<?xml version="1.0" encoding="utf-8"?> <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 59 40">
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <path d="M53.024 38.23H43.55s-.35-.726-.728-1.423c-.38-.697-1.283-.668-1.283-.668H17.403s-.875-.116-1.312.668a16.505 16.505 0 0 0-.758 1.422H6.005c-2.011 0-3.673-1.625-3.673-3.628V5.893c0-2.003 1.632-3.658 3.644-3.658h47.02c2.01 0 3.672 1.626 3.672 3.629v28.708c.03 2.003-1.632 3.657-3.644 3.657Z" fill="#009486"/>
viewBox="0 0 202.4 137.8" style="enable-background:new 0 0 202.4 137.8;" xml:space="preserve"> <path d="M41.889 10.014H17.082c-4.256 0-7.725 3.484-7.725 7.722s3.47 7.692 7.725 7.692h24.807c4.256 0 7.725-3.454 7.725-7.692a7.655 7.655 0 0 0-7.725-7.722Zm-21.98 9.928s-1.136-.842-2.74-.842c-1.195 0-2.594.726-2.594.726a3.333 3.333 0 0 1-.612-1.916 3.315 3.315 0 0 1 3.323-3.31 3.315 3.315 0 0 1 3.323 3.31c0 .784-.262 1.48-.7 2.032Zm9.591 1.916c-3.644 0-3.498-2.787-3.498-2.787-.058-.522.612-.697.845-.377.117.174.117.174.204.493.496 1.713 2.449 1.626 2.449 1.626s1.953.116 2.449-1.626c.087-.29.087-.32.204-.493.233-.29.903-.145.845.377 0 0 .146 2.787-3.498 2.787Zm14.896-2.003s-1.4-.726-2.595-.726c-1.603 0-2.74.842-2.74.842a3.238 3.238 0 0 1-.7-2.032 3.315 3.315 0 0 1 3.324-3.31 3.315 3.315 0 0 1 3.323 3.31 3.014 3.014 0 0 1-.612 1.916Z" fill="#E7F9E4"/>
<style type="text/css"> <path d="M41.714 14.63a3.315 3.315 0 0 0-3.323 3.309c0 .755.262 1.451.7 2.032 0 0 1.136-.842 2.74-.842 1.195 0 2.594.726 2.594.726.379-.552.612-1.19.612-1.916a3.315 3.315 0 0 0-3.323-3.31ZM17.286 14.63a3.315 3.315 0 0 0-3.323 3.309c0 .726.233 1.364.612 1.916 0 0 1.4-.726 2.594-.726 1.604 0 2.74.842 2.74.842.438-.552.7-1.248.7-2.032a3.315 3.315 0 0 0-3.323-3.31Z" fill="#009486"/>
.st0{fill:#009486;} <path d="M13.73 6.763c-1.837-.493-3.41.61-4.285 2.12-.204.348-.059.638.145.754.292.087.496.03.817-.435.641-1.132 1.72-1.77 2.944-1.539 0 0 .845.262.962-.29.087-.348-.233-.522-.583-.61ZM46.611 7.925c-.03.551.845.551.845.551 1.225.116 1.983.668 2.274 1.945.175.551.35.639.67.639.234-.03.467-.29.35-.697-.408-1.684-1.486-2.845-3.41-2.874-.35-.029-.7.058-.729.436Z" fill="#E7F9E4"/>
.st1{fill:#E7F9E4;}
.st2{fill:none;}
.st3{fill:#E7FFE3;}
</style>
<g>
<path id="dark_greeen_19_" class="st0" d="M181.9,131.7h-32.5c0,0-1.2-2.5-2.5-4.9c-1.3-2.4-4.4-2.3-4.4-2.3H59.7
c0,0-3-0.4-4.5,2.3c-1.6,2.7-2.6,4.9-2.6,4.9H20.6c-6.9,0-12.6-5.6-12.6-12.5V20.3c0-6.9,5.6-12.6,12.5-12.6h161.3
c6.9,0,12.6,5.6,12.6,12.5v98.9C194.5,126,188.8,131.7,181.9,131.7z"/>
<path class="st1" d="M143.7,34.5H58.6c-14.6,0-26.5,12-26.5,26.6c0,14.6,11.9,26.5,26.5,26.5h85.1c14.6,0,26.5-11.9,26.5-26.5
C170.3,46.3,158.4,34.4,143.7,34.5z M68.3,68.7c0,0-3.9-2.9-9.4-2.9c-4.1,0-8.9,2.5-8.9,2.5c-1.3-1.9-2.1-4.1-2.1-6.6
c0-6.3,5.1-11.4,11.4-11.4s11.4,5.1,11.4,11.4C70.7,64.4,69.8,66.8,68.3,68.7z M101.2,75.3c-12.5,0-12-9.6-12-9.6
c-0.2-1.8,2.1-2.4,2.9-1.3c0.4,0.6,0.4,0.6,0.7,1.7c1.7,5.9,8.4,5.6,8.4,5.6s6.7,0.4,8.4-5.6c0.3-1,0.3-1.1,0.7-1.7
c0.8-1,3.1-0.5,2.9,1.3C113.2,65.7,113.7,75.3,101.2,75.3z M152.3,68.4c0,0-4.8-2.5-8.9-2.5c-5.5,0-9.4,2.9-9.4,2.9
c-1.5-1.9-2.4-4.3-2.4-7c0-6.3,5.1-11.4,11.4-11.4s11.4,5.1,11.4,11.4C154.5,64.2,153.7,66.5,152.3,68.4z"/>
<path class="st2" d="M110.3,64.3c-0.4,0.6-0.4,0.6-0.7,1.7c-1.7,5.9-8.4,5.6-8.4,5.6s-6.7,0.4-8.4-5.6c-0.3-1-0.3-1.1-0.7-1.7
c-0.8-1-3.1-0.5-2.9,1.3c0,0-0.5,9.6,12,9.6c12.5,0,12-9.6,12-9.6C113.4,63.9,111.1,63.3,110.3,64.3z"/>
<path class="st2" d="M143.1,50.4c-6.3,0-11.4,5.1-11.4,11.4c0,2.6,0.9,5,2.4,7c0,0,3.9-2.9,9.4-2.9c4.1,0,8.9,2.5,8.9,2.5
c1.3-1.9,2.1-4.1,2.1-6.6C154.5,55.5,149.4,50.4,143.1,50.4z"/>
<path class="st2" d="M59.3,50.4c-6.3,0-11.4,5.1-11.4,11.4c0,2.5,0.8,4.7,2.1,6.6c0,0,4.8-2.5,8.9-2.5c5.5,0,9.4,2.9,9.4,2.9
c1.5-1.9,2.4-4.3,2.4-7C70.7,55.5,65.6,50.4,59.3,50.4z"/>
<g>
<g>
<path class="st3" d="M47.1,23.3c-6.3-1.7-11.7,2.1-14.7,7.3c-0.7,1.2-0.2,2.2,0.5,2.6c1,0.3,1.7,0.1,2.8-1.5
c2.2-3.9,5.9-6.1,10.1-5.3c0,0,2.9,0.9,3.3-1C49.4,24.2,48.3,23.6,47.1,23.3z"/>
</g>
</g>
<g>
<g>
<path class="st3" d="M159.9,27.3c-0.1,1.9,2.9,1.9,2.9,1.9c4.2,0.4,6.8,2.3,7.8,6.7c0.6,1.9,1.2,2.2,2.3,2.2
c0.8-0.1,1.6-1,1.2-2.4c-1.4-5.8-5.1-9.8-11.7-9.9C161.2,25.7,160,26,159.9,27.3z"/>
</g>
</g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -1,234 +1,68 @@
<?xml version="1.0" encoding="utf-8"?> <svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" x="0" y="0" viewBox="0 0 155.9 184.3" xml:space="preserve">
<svg version="1.1" id="Calque_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <style>
viewBox="0 0 155.9 184.3" style="enable-background:new 0 0 155.9 184.3;" xml:space="preserve"> .st0{fill:#006d60}.st1{fill:#00564a}.st2{fill:#009486}.st3{fill:#2b6b5f}.st4{fill:#e7f9e4}.st5{fill:#71afa3}
<style type="text/css"> </style>
.st0{fill:#006D60;}
.st1{fill:#00564A;}
.st2{fill:#009486;}
.st3{fill:#2B6B5F;}
.st4{fill:#E7F9E4;}
.st5{fill:#71AFA3;}
.st6{fill:#DCF4D7;}
</style>
<g>
<g id="FOOTS_1_"> <g id="FOOTS_1_">
<path class="st0" d="M55.8,134.7l37.2-0.3c1.4,0,2.5-1.2,2.5-2.6l0,0c0-1.4-1.2-2.5-2.6-2.5l-37.2,0.3c-1.4,0-2.5,1.2-2.5,2.6v0 <path class="st0" d="m55.8 134.7 37.2-.3c1.4 0 2.5-1.2 2.5-2.6 0-1.4-1.2-2.5-2.6-2.5l-37.2.3c-1.4 0-2.5 1.2-2.5 2.6.1 1.3 1.2 2.5 2.6 2.5z"/>
C53.3,133.5,54.4,134.7,55.8,134.7z"/> <path class="st1" d="m89.2 129.3-29.5.2s7.5 1.3 15.2 1.2c7.9 0 14.3-1.4 14.3-1.4z"/>
<path class="st1" d="M89.2,129.3l-29.5,0.2c0,0,7.5,1.3,15.2,1.2C82.8,130.7,89.2,129.3,89.2,129.3z"/>
</g> </g>
<g id="LEGS_5_"> <g id="LEGS_5_">
<path transform="matrix(-1 .00772 -.00772 -1 149.368 218.272)" class="st1" d="M40.6 102.5h67.3v13.8H40.6z"/>
<rect x="40.6" y="102.5" transform="matrix(-1 7.722594e-03 -7.722594e-03 -1 149.3678 218.2719)" class="st1" width="67.3" height="13.8"/> <path class="st2" d="M38.4 116.2c.1 6.5 5.4 11.8 11.9 11.8l48.2-.4c6.5 0 11.7-5.5 11.7-12v-1.9c0-1.6-1.3-2.9-2.9-2.9l-66 .5c-1.6 0-2.9 1.3-2.9 2.9v2z"/>
<path class="st2" d="M38.4,116.2L38.4,116.2c0.1,6.5,5.4,11.8,11.9,11.8l48.2-0.4c6.5,0,11.7-5.5,11.7-12l0,0l0-1.9 <path transform="matrix(-1 .00772 -.00772 -1 149.335 215.458)" class="st3" d="M41.4 107.9h65.8v.2H41.4z"/>
c0-1.6-1.3-2.9-2.9-2.9l-66,0.5c-1.6,0-2.9,1.3-2.9,2.9L38.4,116.2z"/> <path transform="matrix(-1 .00772 -.00772 -1 149.354 217.11)" class="st3" d="M41.4 108.7h65.8v.2H41.4z"/>
<g> <path transform="matrix(-1 .00772 -.00772 -1 149.374 218.761)" class="st3" d="M41.4 109.6h65.8v.2H41.4z"/>
<path class="st0" d="m75.1 127.8 23.3-.2c6.5-.1 11.8-5.5 11.7-12 0 0-1 5.3-8.2 8-5.3 2-12.8 1.6-26.9 1.7-14.1.1-23 .6-28.4-1.3-7.2-2.6-8.3-7.8-8.3-7.8.1 6.5 5.4 11.8 11.9 11.8l24.9-.2z"/>
<rect x="41.4" y="107.9" transform="matrix(-1 7.722594e-03 -7.722594e-03 -1 149.3352 215.4585)" class="st3" width="65.8" height="0.2"/>
<rect x="41.4" y="108.7" transform="matrix(-1 7.722594e-03 -7.722594e-03 -1 149.3543 217.1097)" class="st3" width="65.8" height="0.2"/>
<rect x="41.4" y="109.6" transform="matrix(-1 7.722594e-03 -7.722594e-03 -1 149.3735 218.761)" class="st3" width="65.8" height="0.2"/>
</g>
<path class="st0" d="M75.1,127.8l23.3-0.2c6.5-0.1,11.8-5.5,11.7-12l0,0c0,0-1,5.3-8.2,8c-5.3,2-12.8,1.6-26.9,1.7
c-14.1,0.1-23,0.6-28.4-1.3c-7.2-2.6-8.3-7.8-8.3-7.8l0,0c0.1,6.5,5.4,11.8,11.9,11.8L75.1,127.8z"/>
</g> </g>
<g id="NECK_5_"> <g id="NECK_5_">
<path class="st1" d="M51.3,82.6l0.1-1.3l2.9-5c0,0,0.3-0.7,2-0.6c0.8,0,38.5,2.1,39.3,2.1c1.8,0.1,2,0.8,2,0.8l1.6,3.8l-0.1,1.3 <path class="st1" d="m51.3 82.6.1-1.3 2.9-5s.3-.7 2-.6c.8 0 38.5 2.1 39.3 2.1 1.8.1 2 .8 2 .8l1.6 3.8-.1 1.3-47.8-1.1z"/>
L51.3,82.6z"/> <path transform="rotate(-86.884 75.824 78.055) scale(.99998)" class="st3" d="M75.7 57.7h.2v40.7h-.2z"/>
<g> <path transform="rotate(-86.884 75.779 78.88) scale(.99998)" class="st3" d="M75.7 57.8h.2V100h-.2z"/>
<rect x="75.7" y="57.7" transform="matrix(5.436085e-02 -0.9985 0.9985 5.436085e-02 -6.2381 149.5234)" class="st3" width="0.2" height="40.7"/>
<rect x="75.7" y="57.8" transform="matrix(5.436085e-02 -0.9985 0.9985 5.436085e-02 -7.1037 150.2582)" class="st3" width="0.2" height="42.2"/>
</g>
</g> </g>
<g id="HEAD_18_"> <g id="HEAD_18_">
<path id="dark_greeen_9_" class="st2" d="M35.2,76.5l16.4,0.9c0,0,0.7-1.2,1.4-2.4c0.7-1.2,2.3-1,2.3-1l41.7,2.3 <path id="dark_greeen_9_" class="st2" d="m35.2 76.5 16.4.9L53 75c.7-1.2 2.3-1 2.3-1L97 76.3s1.5-.1 2.2 1.3c.7 1.4 1.2 2.5 1.2 2.5l16.1.9c3.5.2 6.5-2.5 6.7-6l2.7-49.8c.2-3.5-2.5-6.5-6-6.7l-81.1-4.4c-3.5-.2-6.5 2.5-6.7 6l-2.7 49.8c-.4 3.4 2.3 6.4 5.8 6.6z"/>
c0,0,1.5-0.1,2.2,1.3c0.7,1.4,1.2,2.5,1.2,2.5l16.1,0.9c3.5,0.2,6.5-2.5,6.7-6l2.7-49.8c0.2-3.5-2.5-6.5-6-6.7l-81.1-4.4 <path class="st0" d="m98.1 57.7-43.4-2.4s10.9 2.5 22.2 3.1c11.7.7 21.2-.7 21.2-.7z"/>
c-3.5-0.2-6.5,2.5-6.7,6l-2.7,49.8C29,73.3,31.7,76.3,35.2,76.5z"/>
<path class="st0" d="M98.1,57.7l-43.4-2.4c0,0,10.9,2.5,22.2,3.1C88.6,59.1,98.1,57.7,98.1,57.7z"/>
<g id="light_green_4_"> <g id="light_green_4_">
<path class="st4" d="M43.3,41.3c-0.4,7.4,5.3,13.7,12.6,14.1l42.8,2.3c7.4,0.4,13.7-5.2,14.1-12.6c0.4-7.4-5.3-13.7-12.6-14.1 <path class="st4" d="M43.3 41.3c-.4 7.4 5.3 13.7 12.6 14.1l42.8 2.3c7.4.4 13.7-5.2 14.1-12.6.4-7.4-5.3-13.7-12.6-14.1l-42.8-2.3c-7.4-.5-13.7 5.2-14.1 12.6zM109.4 28.1c3.2.8 4.7 3.7 4.8 6.7 0 .7-.4 1.1-.9 1-.5-.1-.8-.3-.9-1.3 0-2.3-1.2-4.1-3.2-4.8 0 0-1.5-.3-1.2-1.2.2-.5.8-.5 1.4-.4zM50.2 25.8c.1 1-1.4 1-1.4 1-2.1.3-3.3 1.3-3.7 3.6-.3 1-.5 1.2-1.1 1.2-.4 0-.8-.4-.7-1.1.5-3 2.3-5.1 5.6-5.3.5-.1 1.2 0 1.3.6z"/>
l-42.8-2.3C50,28.2,43.7,33.9,43.3,41.3z"/>
<g>
<g>
<path class="st4" d="M109.4,28.1c3.2,0.8,4.7,3.7,4.8,6.7c0,0.7-0.4,1.1-0.9,1c-0.5-0.1-0.8-0.3-0.9-1.3c0-2.3-1.2-4.1-3.2-4.8
c0,0-1.5-0.3-1.2-1.2C108.2,28,108.8,28,109.4,28.1z"/>
</g>
</g>
<g>
<g>
<path class="st4" d="M50.2,25.8c0.1,1-1.4,1-1.4,1c-2.1,0.3-3.3,1.3-3.7,3.6c-0.3,1-0.5,1.2-1.1,1.2c-0.4,0-0.8-0.4-0.7-1.1
c0.5-3,2.3-5.1,5.6-5.3C49.4,25.1,50.1,25.2,50.2,25.8z"/>
</g>
</g>
</g>
<path id="dark_greeen_3_" class="st0" d="M50.8,77.4l-15.6-0.8c-3.5-0.2-6.2-3.3-5.9-6.8l1.9-33.9l1.7,33.9c0,0-0.6,3.7,5,4.9
L50.8,77.4z"/>
<path class="st0" d="M82.8,46.5c0,0-2.8-0.3-5.9,0c-3.1,0.3-4.7,1-4.7,1c-0.6,0-1.1-0.4-1.1-0.9v0c0-0.6,0.3-0.9,0.9-1.1
c0,0,3-0.8,4.8-1c1.8-0.1,5.9,0,5.9,0c0.6,0,1.1,0.4,1.1,0.9l0,0C83.7,45.9,83.3,46.4,82.8,46.5z"/>
<g id="light_green_5_">
<path class="st0" d="M62.9,44.4c0,0-2.1-1.2-4.8-0.9c-2,0.2-4.3,1.8-4.3,1.8c-0.8-0.8-1.3-1.9-1.5-3.1c-0.4-3.1,1.8-6,5-6.4
s6,1.9,6.3,5C63.8,42.1,63.5,43.4,62.9,44.4z M101.8,47.9c0,0-2.1-1.7-4.1-2.2c-2.7-0.6-4.9,0.5-4.9,0.5
c-0.5-1.1-0.7-2.4-0.4-3.7c0.7-3.1,3.7-5.1,6.8-4.4c3.1,0.7,5,3.7,4.4,6.8C103.3,46.1,102.7,47.1,101.8,47.9z"/>
</g> </g>
<path id="dark_greeen_3_" class="st0" d="m50.8 77.4-15.6-.8c-3.5-.2-6.2-3.3-5.9-6.8l1.9-33.9 1.7 33.9s-.6 3.7 5 4.9l12.9 2.7z"/>
<path class="st0" d="M82.8 46.5s-2.8-.3-5.9 0c-3.1.3-4.7 1-4.7 1-.6 0-1.1-.4-1.1-.9 0-.6.3-.9.9-1.1 0 0 3-.8 4.8-1 1.8-.1 5.9 0 5.9 0 .6 0 1.1.4 1.1.9-.1.5-.5 1-1 1.1z"/>
<path class="st0" d="M62.9 44.4s-2.1-1.2-4.8-.9c-2 .2-4.3 1.8-4.3 1.8-.8-.8-1.3-1.9-1.5-3.1-.4-3.1 1.8-6 5-6.4s6 1.9 6.3 5c.2 1.3-.1 2.6-.7 3.6zm38.9 3.5s-2.1-1.7-4.1-2.2c-2.7-.6-4.9.5-4.9.5-.5-1.1-.7-2.4-.4-3.7.7-3.1 3.7-5.1 6.8-4.4 3.1.7 5 3.7 4.4 6.8-.3 1.2-.9 2.2-1.8 3z" id="light_green_5_"/>
</g> </g>
<g id="ARMS_5_"> <g id="ARMS_5_">
<g id="BRAS_10_"> <g id="BRAS_10_">
<g id="ARM_20_"> <path class="st0" d="M115.4 97.6c1-.1 1.8-1.6 1.7-3.4l-.2-6.2c-.1-2.3-1.5-3.3-7.1-3-1.6.1-6 .4-6 .4-1 .1-1.8 1.6-1.7 3.4l.6 9.6c.4 0 12.7-.8 12.7-.8z" id="ARM_20_"/>
<path class="st0" d="M115.4,97.6c1-0.1,1.8-1.6,1.7-3.4l-0.2-6.2c-0.1-2.3-1.5-3.3-7.1-3c-1.6,0.1-6,0.4-6,0.4
c-1,0.1-1.8,1.6-1.7,3.4l0.6,9.6C103.1,98.4,115.4,97.6,115.4,97.6z"/>
</g>
</g> </g>
<g id="ARM_19_"> <g id="ARM_19_">
<path class="st2" d="M144.5,67.9l0.5,0.5c2.5,2.6,2,7.3-0.6,9.8l-8.4,8.3c-3,3-11.7,7.8-16,3.5l-1-1c-2.5-2.6-0.5-4.7,2.1-7.2 <path class="st2" d="m144.5 67.9.5.5c2.5 2.6 2 7.3-.6 9.8l-8.4 8.3c-3 3-11.7 7.8-16 3.5l-1-1c-2.5-2.6-.5-4.7 2.1-7.2l14.1-13.9c2.6-2.6 6.8-2.5 9.3 0z"/>
l14.1-13.9C137.8,65.3,142,65.4,144.5,67.9z"/> <path class="st0" d="M144.5 67.9s-2.8-2.7-8.1 1.6c-2.2 1.8-14.5 14-15.8 15.6-1.8 2.3-1.6 3.9-1.6 3.9-2.5-2.6-.5-4.7 2.1-7.2l14.1-13.9c2.6-2.6 6.8-2.5 9.3 0z"/>
<path class="st0" d="M144.5,67.9c0,0-2.8-2.7-8.1,1.6c-2.2,1.8-14.5,14-15.8,15.6c-1.8,2.3-1.6,3.9-1.6,3.9 <path transform="rotate(-134.628 138.09 77.75)" class="st5" d="M134 77.6h8.2v.2H134z"/>
c-2.5-2.6-0.5-4.7,2.1-7.2l14.1-13.9C137.8,65.3,142,65.4,144.5,67.9z"/> <path transform="rotate(-134.628 139.195 76.66)" class="st5" d="M135.1 76.6h8.2v.2h-8.2z"/>
<g> <path transform="rotate(-134.628 140.298 75.571)" class="st5" d="M136.2 75.5h8.2v.2h-8.2z"/>
<rect x="134" y="77.6" transform="matrix(-0.7025 -0.7117 0.7117 -0.7025 179.7647 230.6487)" class="st5" width="8.2" height="0.2"/>
<rect x="135.1" y="76.6" transform="matrix(-0.7025 -0.7117 0.7117 -0.7025 182.4193 229.5794)" class="st5" width="8.2" height="0.2"/>
<rect x="136.2" y="75.5" transform="matrix(-0.7025 -0.7117 0.7117 -0.7025 185.074 228.5101)" class="st5" width="8.2" height="0.2"/>
</g>
</g> </g>
<g id="BRAS_8_"> <g id="BRAS_8_">
<g id="ARM_18_"> <path class="st0" d="M33.5 96c-1-.1-1.7-1.7-1.4-3.5l.6-6.1c.3-2.3 1.7-3.2 7.3-2.5 1.6.2 5.9.8 5.9.8 1 .1 1.7 1.7 1.4 3.5L46 97.7c-.2 0-12.5-1.7-12.5-1.7z" id="ARM_18_"/>
<path class="st0" d="M33.5,96c-1-0.1-1.7-1.7-1.4-3.5l0.6-6.1c0.3-2.3,1.7-3.2,7.3-2.5c1.6,0.2,5.9,0.8,5.9,0.8
c1,0.1,1.7,1.7,1.4,3.5l-1.3,9.5C45.8,97.7,33.5,96,33.5,96z"/>
</g>
</g> </g>
<g id="ARM_16_"> <g id="ARM_16_">
<path class="st2" d="M13.4,58.2l-0.6,0.3c-3.3,1.5-4.4,6.1-2.9,9.4l5,10.8c1.8,3.8,8.2,11.4,13.7,8.9l1.3-0.6 <path class="st2" d="m13.4 58.2-.6.3c-3.3 1.5-4.4 6.1-2.9 9.4l5 10.8c1.8 3.8 8.2 11.4 13.7 8.9l1.3-.6c3.3-1.5 2.1-4.2.6-7.5l-8.3-18c-1.6-3.4-5.5-4.8-8.8-3.3z"/>
c3.3-1.5,2.1-4.2,0.6-7.5l-8.3-18C20.6,58.1,16.7,56.7,13.4,58.2z"/> <path class="st0" d="M13.4 58.2s3.5-1.6 7 4.4c1.4 2.5 8.7 18.2 9.3 20.2.9 2.8.2 4.2.2 4.2 3.3-1.5 2.1-4.2.6-7.5l-8.3-18c-1.6-3.4-5.5-4.8-8.8-3.3z"/>
<path class="st0" d="M13.4,58.2c0,0,3.5-1.6,7,4.4c1.4,2.5,8.7,18.2,9.3,20.2c0.9,2.8,0.2,4.2,0.2,4.2c3.3-1.5,2.1-4.2,0.6-7.5 <path transform="rotate(-24.72 16.01 69.65)" class="st5" d="M11.9 69.5h8.2v.2h-8.2z"/>
l-8.3-18C20.6,58.1,16.7,56.7,13.4,58.2z"/> <path transform="rotate(-24.72 15.362 68.242)" class="st5" d="M11.2 68.1h8.2v.2h-8.2z"/>
<g> <path transform="rotate(-24.72 14.713 66.833)" class="st5" d="M10.6 66.7h8.2v.2h-8.2z"/>
<rect x="11.9" y="69.5" transform="matrix(0.9084 -0.4182 0.4182 0.9084 -27.6607 13.0783)" class="st5" width="8.2" height="0.2"/>
<rect x="11.2" y="68.1" transform="matrix(0.9084 -0.4182 0.4182 0.9084 -27.131 12.678)" class="st5" width="8.2" height="0.2"/>
<rect x="10.6" y="66.7" transform="matrix(0.9084 -0.4182 0.4182 0.9084 -26.6013 12.2776)" class="st5" width="8.2" height="0.2"/>
</g> </g>
</g> </g>
</g> <path id="BELLY_5_" class="st2" d="M43.3 105.4c-6.7-.1-8-2.6-8-9.1 0 0-.2-10.9-.2-12.2 0-2.2 4.5-3.9 8.9-3.8l61.8 1.3c4.4.1 8.8 1.9 8.7 4.2 0 1.3-.7 12.1-.7 12.1-.3 6.5-1.7 8.9-8.4 8.8l-62.1-1.3z"/>
<path id="BELLY_5_" class="st2" d="M43.3,105.4c-6.7-0.1-8-2.6-8-9.1c0,0-0.2-10.9-0.2-12.2c0-2.2,4.5-3.9,8.9-3.8l61.8,1.3 <ellipse id="SHADOW_5_" cx="74.3" cy="163.5" rx="53.1" ry="6.7" fill="#dcf4d7"/>
c4.4,0.1,8.8,1.9,8.7,4.2c0,1.3-0.7,12.1-0.7,12.1c-0.3,6.5-1.7,8.9-8.4,8.8L43.3,105.4z"/>
<ellipse id="SHADOW_5_" class="st6" cx="74.3" cy="163.5" rx="53.1" ry="6.7"/>
<g id="TXT_4_"> <g id="TXT_4_">
<path class="st1" d="M64.3 91.8v-.7h.7c0 .1 0 .1-.1.4v.2h1l.3.3c0 .1 0 .1-.1.3 0 .8-.1 1.4-.2 1.6-.1.3-.3.4-.7.4h-.5c0-.3 0-.4-.1-.6.2.1.4.1.5.1.2 0 .2-.1.3-.4 0-.2.1-.7.1-1h-.7c0 .2 0 .2-.1.4-.2.7-.5 1.2-1.3 1.7-.2-.3-.3-.4-.5-.6.5-.2.8-.5 1-.9.1-.2.1-.3.2-.6h-1v-.6h1.2zM69.3 94.5c-.3-.4-.6-.7-1-1.1-.4.4-.8.7-1.4 1-.1-.3-.2-.4-.4-.6.5-.2.9-.4 1.2-.7.3-.3.6-.6.8-1H67v-.6h2.1l.3.3c-.1.1-.1.1-.1.2-.2.4-.3.7-.6 1 .4.3.6.5 1.1 1l-.5.5zM70.5 94.5v-.6l.1-2.1v-.5h.7v1c.6.2 1.1.4 1.6.8l-.4.6c-.3-.3-.8-.5-1.1-.7-.1-.1-.1-.1-.2-.1v1.5l-.7.1zM73.3 92.7c.2 0 .4 0 .7.1h2.4v.7H73.3v-.8zM77.9 93v.1c-.1.6-.3 1-.6 1.4l-.6-.3c.3-.4.5-.9.6-1.4l.6.2zm2.2-.3H78.8v2.1h-.7v-2.2h-1.2V92H78.2v-.5h.7v.5h.8c-.1-.1-.1-.2-.1-.3 0-.2.2-.4.4-.4s.4.2.4.4c0 .1-.1.3-.2.4l-.1.6zm-.5.1c.1.5.3 1.1.6 1.4l-.6.3c-.3-.5-.4-.8-.5-1.4 0-.1 0-.1-.1-.2l.6-.1zm.1-1c0 .1.1.2.2.2s.2-.1.2-.2-.1-.2-.2-.2-.2.1-.2.2zM81.1 92.4l.3.9-.6.2c-.1-.4-.2-.6-.3-.9l.6-.2zm2.1.1c0 .1 0 .1-.1.2-.1.5-.3.9-.5 1.2-.2.3-.5.5-.8.7-.1.1-.2.1-.4.2-.1-.2-.2-.3-.4-.5.7-.3 1.1-.6 1.4-1.2.1-.3.2-.5.2-.8l.6.2zm-1.3-.2c.2.4.2.5.3.9l-.6.2-.3-.9.6-.2zM84 94.9v-.6l.1-2.1v-.5h.7v1c.6.2 1.1.5 1.6.8l-.4.6c-.3-.2-.7-.5-1.1-.7-.1 0-.1 0-.1-.1v1.5l-.8.1zm1.7-3c.1.2.2.3.3.5l-.3.2c-.1-.2-.2-.4-.3-.5l.3-.2zm.5-.2c.1.1.2.3.4.5l-.3.2c-.1-.2-.2-.4-.3-.5l.2-.2z"/>
<g> <g>
<path class="st1" d="M64.3,91.8c0-0.1,0-0.4,0-0.5c0-0.1,0-0.1,0-0.2l0.7,0c0,0.1,0,0.1-0.1,0.4c0,0.1,0,0.1,0,0.2l0.8,0 <path class="st1" d="M70.6 97.8c-.1 0-.1 0-.2.1h-.2c-.2 0-.4-.1-.5-.2-.1-.1-.2-.3-.2-.6s.1-.5.2-.6c.1-.1.3-.2.5-.2h.2c.1 0 .1 0 .2.1v.3c-.1-.1-.1-.1-.2-.1h-.2c-.1 0-.2 0-.3.1.1 0 .1.2.1.3 0 .2 0 .3.1.4.1.1.1.1.3.1h.2c.1 0 .1-.1.2-.1l-.2.4zM71.5 96.3h.3v1h.2v.3h-.2v.3h-.3v-.3h-.6v-.3l.6-1zm0 .3-.4.6h.4v-.6zM72.3 96.3h.9v.3h-.6v.3h.2c.2 0 .3.1.4.2s.1.2.1.4-.1.3-.2.4c-.1.1-.3.1-.4.1h-.2c-.1 0-.1 0-.2-.1v-.3c.1 0 .1.1.2.1h.2c.1 0 .2 0 .3-.1.1 0 .1-.1.1-.2s0-.2-.1-.2c-.1-.1-.1-.1-.2-.1h-.2c-.1 0-.1 0-.2.1l-.1-.9zM73.6 96.3h1v.2l-.6 1.4h-.3l.5-1.3h-.7l.1-.3zM74.8 97.2c0-.3.1-.5.1-.6.1-.1.2-.2.4-.2s.3.1.4.2c.1.1.1.3.1.6s-.1.5-.1.6c-.1.1-.2.2-.4.2s-.3-.1-.4-.2-.1-.4-.1-.6zm.6-.6c-.1 0-.1 0-.2.1 0 .1-.1.2-.1.4v.2l.4-.6s0-.1-.1-.1zm-.2 1c0 .1.1.1.2.1s.1 0 .2-.1c0-.1.1-.2.1-.4V97l-.5.6zM76.2 96.4h.4c.2 0 .4 0 .5.1.1.1.1.2.1.4s-.1.3-.2.4c-.1.1-.3.1-.5.1h-.1v.6h-.3l.1-1.6zm.3.3v.5H76.8s.1-.1.1-.2 0-.1-.1-.2c0 0-.1-.1-.2-.1h-.1zM77.5 97.2c0-.3.1-.5.1-.6.1-.1.2-.2.4-.2s.3.1.4.2c.1.1.1.3.1.6s-.1.5-.1.6c-.1.1-.2.2-.4.2s-.3-.1-.4-.2-.1-.3-.1-.6zm.5-.5c-.1 0-.1 0-.2.1 0 .1-.1.2-.1.4v.2l.4-.6c0-.1 0-.1-.1-.1zm-.2 1c0 .1.1.1.2.1s.1 0 .2-.1c0-.1.1-.2.1-.4v-.2l-.5.6c0-.1 0-.1 0 0zM78.8 96.5h.3c.3 0 .4.1.6.2.1.1.2.3.2.6s-.1.5-.2.6c-.1.1-.3.2-.6.2h-.3v-1.6zm.3.2v1h.1c.1 0 .2 0 .3-.1.1-.1.1-.2.1-.4s0-.3-.1-.4c-.1 0-.2 0-.4-.1z"/>
c0.1,0,0.2,0,0.2,0l0.3,0.3c0,0.1,0,0.1-0.1,0.3c0,0.8-0.1,1.4-0.2,1.6c-0.1,0.3-0.3,0.4-0.7,0.4c-0.1,0-0.2,0-0.5,0
c0-0.3,0-0.4-0.1-0.6c0.2,0.1,0.4,0.1,0.5,0.1c0.2,0,0.2-0.1,0.3-0.4c0-0.2,0.1-0.7,0.1-1l-0.7,0c0,0.2,0,0.2-0.1,0.4
c-0.2,0.7-0.5,1.2-1.3,1.7c-0.2-0.3-0.3-0.4-0.5-0.6c0.5-0.2,0.8-0.5,1-0.9c0.1-0.2,0.1-0.3,0.2-0.6l-0.5,0c-0.2,0-0.3,0-0.5,0
l0-0.6c0.2,0,0.2,0,0.5,0L64.3,91.8z"/>
<path class="st1" d="M69.3,94.5c-0.3-0.4-0.6-0.7-1-1.1c-0.4,0.4-0.8,0.7-1.4,1c-0.1-0.3-0.2-0.4-0.4-0.6
c0.5-0.2,0.9-0.4,1.2-0.7c0.3-0.3,0.6-0.6,0.8-1l-0.9,0c-0.3,0-0.4,0-0.6,0l0-0.6c0.1,0,0.2,0,0.4,0c0,0,0.1,0,0.2,0l1.2,0
c0.2,0,0.2,0,0.3,0l0.3,0.3c-0.1,0.1-0.1,0.1-0.1,0.2c-0.2,0.4-0.3,0.7-0.6,1c0.4,0.3,0.6,0.5,1.1,1L69.3,94.5z"/>
<path class="st1" d="M70.5,94.5c0-0.2,0-0.3,0-0.6l0.1-2.1c0-0.3,0-0.3,0-0.5l0.7,0c0,0.1,0,0.3,0,0.5l0,0.5
c0.6,0.2,1.1,0.4,1.6,0.8l-0.4,0.6c-0.3-0.3-0.8-0.5-1.1-0.7c-0.1-0.1-0.1-0.1-0.2-0.1l0,0.9c0,0.2,0,0.4,0,0.6L70.5,94.5z"/>
<path class="st1" d="M73.3,92.7c0.2,0,0.4,0,0.7,0.1l1.7,0c0.4,0,0.5,0,0.7,0l0,0.7c-0.2,0-0.3,0-0.7,0l-1.7,0
c-0.4,0-0.5,0-0.7,0L73.3,92.7z"/>
<path class="st1" d="M77.9,93c0,0.1,0,0.1,0,0.1c-0.1,0.6-0.3,1-0.6,1.4c-0.2-0.1-0.4-0.2-0.6-0.3c0.3-0.4,0.5-0.9,0.6-1.4
L77.9,93z M80.1,92.7c-0.1,0-0.2,0-0.6,0l-0.7,0l0,1.6c0,0.2,0,0.4,0,0.5l-0.7,0c0-0.1,0-0.3,0-0.6l0-1.6l-0.7,0
c-0.3,0-0.4,0-0.5,0l0-0.6c0.1,0,0.2,0,0.6,0l0.7,0l0-0.1c0-0.2,0-0.3,0-0.4l0.7,0c0,0.1,0,0.2,0,0.4l0,0.1l0.8,0
c-0.1-0.1-0.1-0.2-0.1-0.3c0-0.2,0.2-0.4,0.4-0.4c0.2,0,0.4,0.2,0.4,0.4c0,0.1-0.1,0.3-0.2,0.4L80.1,92.7z M79.6,92.8
c0.1,0.5,0.3,1.1,0.6,1.4c-0.2,0.1-0.4,0.2-0.6,0.3c-0.3-0.5-0.4-0.8-0.5-1.4c0-0.1,0-0.1-0.1-0.2L79.6,92.8z M79.7,91.8
c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2c0-0.1-0.1-0.2-0.2-0.2C79.8,91.6,79.7,91.7,79.7,91.8z"/>
<path class="st1" d="M81.1,92.4c0.1,0.3,0.2,0.6,0.3,0.9l-0.6,0.2c-0.1-0.4-0.2-0.6-0.3-0.9L81.1,92.4z M83.2,92.5
c0,0.1,0,0.1-0.1,0.2c-0.1,0.5-0.3,0.9-0.5,1.2c-0.2,0.3-0.5,0.5-0.8,0.7c-0.1,0.1-0.2,0.1-0.4,0.2c-0.1-0.2-0.2-0.3-0.4-0.5
c0.7-0.3,1.1-0.6,1.4-1.2c0.1-0.3,0.2-0.5,0.2-0.8L83.2,92.5z M81.9,92.3c0.2,0.4,0.2,0.5,0.3,0.9l-0.6,0.2
c-0.1-0.3-0.2-0.6-0.3-0.9L81.9,92.3z"/>
<path class="st1" d="M84,94.9c0-0.2,0-0.3,0-0.6l0.1-2.1c0-0.3,0-0.3,0-0.5l0.7,0c0,0.1,0,0.2,0,0.5l0,0.5
c0.6,0.2,1.1,0.5,1.6,0.8L86,94.1c-0.3-0.2-0.7-0.5-1.1-0.7c-0.1,0-0.1,0-0.1-0.1c0,0,0,0,0,0l0,0.9c0,0.3,0,0.5,0,0.6L84,94.9z
M85.7,91.9c0.1,0.2,0.2,0.3,0.3,0.5l-0.3,0.2c-0.1-0.2-0.2-0.4-0.3-0.5L85.7,91.9z M86.2,91.7c0.1,0.1,0.2,0.3,0.4,0.5l-0.3,0.2
c-0.1-0.2-0.2-0.4-0.3-0.5L86.2,91.7z"/>
</g> </g>
<g> <g>
<path class="st1" d="M70.6,97.8c-0.1,0-0.1,0-0.2,0.1c-0.1,0-0.1,0-0.2,0c-0.2,0-0.4-0.1-0.5-0.2c-0.1-0.1-0.2-0.3-0.2-0.6 <path class="st4" d="M64.3 91.6v-.7h.7c0 .1 0 .1-.1.4v.2h1l.3.3c0 .1 0 .1-.1.3 0 .8-.1 1.4-.2 1.6-.1.3-.3.4-.7.4h-.5c0-.3 0-.4-.1-.6.2.1.4.1.5.1.2 0 .2-.1.3-.4 0-.2.1-.7.1-1h-.7c0 .2 0 .2-.1.4-.2.7-.5 1.2-1.3 1.7-.2-.3-.3-.4-.5-.6.5-.2.8-.5 1-.9.1-.2.1-.3.2-.6h-1v-.6h1.2zM69.3 94.3c-.3-.4-.6-.7-1-1.1-.4.4-.8.7-1.4 1-.1-.3-.2-.4-.4-.6.5-.2.9-.4 1.2-.7.3-.3.6-.6.8-1H67v-.6h2.1l.3.3c-.1.1-.1.1-.1.2-.2.4-.3.7-.6 1 .4.3.6.5 1.1 1l-.5.5zM70.5 94.3v-.6l.1-2.1v-.5h.7v1c.6.2 1.1.4 1.6.8l-.4.6c-.3-.3-.8-.5-1.1-.7-.1-.1-.1-.1-.2-.1v1.5l-.7.1zM73.3 92.4c.2 0 .4 0 .7.1h2.4v.7H73.3v-.8zM77.9 92.7v.1c-.1.6-.3 1-.6 1.4l-.6-.3c.3-.4.5-.9.6-1.4l.6.2zm2.2-.2H78.8v2.1h-.7v-2.2h-1.2v-.6H78.2v-.5h.7v.5h.8c-.1-.1-.1-.2-.1-.3 0-.2.2-.4.4-.4s.4.2.4.4c0 .1-.1.3-.2.4l-.1.6zm-.5.1c.1.5.3 1.1.6 1.4l-.6.3c-.3-.5-.4-.8-.5-1.4 0-.1 0-.1-.1-.2l.6-.1zm.1-1c0 .1.1.2.2.2s.2-.1.2-.2-.1-.2-.2-.2-.2.1-.2.2zM81.1 92.2l.3.9-.6.2c-.1-.4-.2-.6-.3-.9l.6-.2zm2.1.1c0 .1 0 .1-.1.2-.1.5-.3.9-.5 1.2-.2.3-.5.5-.8.7-.1.1-.2.1-.4.2-.1-.2-.2-.3-.4-.5.7-.3 1.1-.6 1.4-1.2.1-.3.2-.5.2-.8l.6.2zm-1.3-.2c.2.4.2.5.3.9l-.6.2-.3-.9.6-.2zM84 94.7v-.6l.1-2.1v-.5h.7v1c.6.2 1.1.5 1.6.8l-.4.6c-.3-.2-.7-.5-1.1-.7-.1 0-.1 0-.1-.1v1.5l-.8.1zm1.7-3c.1.2.2.3.3.5l-.3.2c-.1-.2-.2-.4-.3-.5l.3-.2zm.5-.2c.1.1.2.3.4.5l-.3.2c-.1-.2-.2-.4-.3-.5l.2-.2z"/>
c0-0.3,0.1-0.5,0.2-0.6c0.1-0.1,0.3-0.2,0.5-0.2c0.1,0,0.1,0,0.2,0c0.1,0,0.1,0,0.2,0.1l0,0.3c-0.1-0.1-0.1-0.1-0.2-0.1
c0,0-0.1,0-0.2,0c-0.1,0-0.2,0-0.3,0.1C70,96.7,70,96.9,70,97c0,0.2,0,0.3,0.1,0.4c0.1,0.1,0.1,0.1,0.3,0.1c0.1,0,0.1,0,0.2,0
c0.1,0,0.1-0.1,0.2-0.1L70.6,97.8z"/>
<path class="st1" d="M71.5,96.3l0.3,0l0,1l0.2,0l0,0.3l-0.2,0l0,0.3l-0.3,0l0-0.3l-0.6,0l0-0.3L71.5,96.3z M71.5,96.6l-0.4,0.6
l0.4,0L71.5,96.6z"/>
<path class="st1" d="M72.3,96.3l0.9,0l0,0.3l-0.6,0l0,0.3c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.2,0,0.3,0.1,0.4,0.2
s0.1,0.2,0.1,0.4c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.1-0.4,0.1c-0.1,0-0.1,0-0.2,0c-0.1,0-0.1,0-0.2-0.1l0-0.3
c0.1,0,0.1,0.1,0.2,0.1c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1c0.1,0,0.1-0.1,0.1-0.2c0-0.1,0-0.2-0.1-0.2
c-0.1-0.1-0.1-0.1-0.2-0.1c-0.1,0-0.1,0-0.2,0c-0.1,0-0.1,0-0.2,0.1L72.3,96.3z"/>
<path class="st1" d="M73.6,96.3l1,0l0,0.2L74,97.9l-0.3,0l0.5-1.3l-0.7,0L73.6,96.3z"/>
<path class="st1" d="M74.8,97.2c0-0.3,0.1-0.5,0.1-0.6c0.1-0.1,0.2-0.2,0.4-0.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.1,0.3,0.1,0.6
c0,0.3-0.1,0.5-0.1,0.6c-0.1,0.1-0.2,0.2-0.4,0.2c-0.2,0-0.3-0.1-0.4-0.2S74.8,97.4,74.8,97.2z M75.4,96.6c-0.1,0-0.1,0-0.2,0.1
c0,0.1-0.1,0.2-0.1,0.4c0,0.1,0,0.1,0,0.2l0.4-0.6c0,0,0,0,0,0C75.5,96.7,75.5,96.6,75.4,96.6z M75.2,97.6c0,0.1,0.1,0.1,0.2,0.1
c0.1,0,0.1,0,0.2-0.1c0-0.1,0.1-0.2,0.1-0.4c0-0.1,0-0.1,0-0.2L75.2,97.6C75.2,97.6,75.2,97.6,75.2,97.6z"/>
<path class="st1" d="M76.2,96.4l0.4,0c0.2,0,0.4,0,0.5,0.1c0.1,0.1,0.1,0.2,0.1,0.4c0,0.2-0.1,0.3-0.2,0.4
c-0.1,0.1-0.3,0.1-0.5,0.1l-0.1,0l0,0.6l-0.3,0L76.2,96.4z M76.5,96.7l0,0.5l0.1,0c0.1,0,0.2,0,0.2,0c0,0,0.1-0.1,0.1-0.2
c0-0.1,0-0.1-0.1-0.2c0,0-0.1-0.1-0.2-0.1L76.5,96.7z"/>
<path class="st1" d="M77.5,97.2c0-0.3,0.1-0.5,0.1-0.6c0.1-0.1,0.2-0.2,0.4-0.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.1,0.3,0.1,0.6
c0,0.3-0.1,0.5-0.1,0.6c-0.1,0.1-0.2,0.2-0.4,0.2c-0.2,0-0.3-0.1-0.4-0.2S77.5,97.5,77.5,97.2z M78,96.7c-0.1,0-0.1,0-0.2,0.1
c0,0.1-0.1,0.2-0.1,0.4c0,0.1,0,0.1,0,0.2l0.4-0.6c0,0,0,0,0,0C78.1,96.7,78.1,96.7,78,96.7z M77.8,97.7c0,0.1,0.1,0.1,0.2,0.1
c0.1,0,0.1,0,0.2-0.1c0-0.1,0.1-0.2,0.1-0.4c0-0.1,0-0.1,0-0.2L77.8,97.7C77.8,97.6,77.8,97.6,77.8,97.7z"/>
<path class="st1" d="M78.8,96.5l0.3,0c0.3,0,0.4,0.1,0.6,0.2c0.1,0.1,0.2,0.3,0.2,0.6c0,0.3-0.1,0.5-0.2,0.6
c-0.1,0.1-0.3,0.2-0.6,0.2l-0.3,0L78.8,96.5z M79.1,96.7l0,1l0.1,0c0.1,0,0.2,0,0.3-0.1c0.1-0.1,0.1-0.2,0.1-0.4
c0-0.2,0-0.3-0.1-0.4C79.4,96.8,79.3,96.8,79.1,96.7L79.1,96.7z"/>
</g> </g>
<g> <g>
<path class="st4" d="M64.3,91.6c0-0.1,0-0.4,0-0.5c0-0.1,0-0.1,0-0.2l0.7,0c0,0.1,0,0.1-0.1,0.4c0,0.1,0,0.1,0,0.2l0.8,0 <path class="st4" d="M70.6 97.6c-.1 0-.1 0-.2.1h-.2c-.2 0-.4-.1-.5-.2s-.2-.3-.2-.6.1-.5.2-.6c.1-.1.3-.2.5-.2h.2c.1 0 .1 0 .2.1v.3c-.1-.1-.1-.1-.2-.1h-.2c-.1 0-.2 0-.3.1.1 0 .1.1.1.3 0 .2 0 .3.1.4.1.1.1.1.3.1h.2c.1 0 .1-.1.2-.1l-.2.4zM71.5 96.1h.3v1h.2v.3h-.2v.3h-.3v-.3h-.6v-.3l.6-1zm0 .3-.4.6h.4v-.6zM72.3 96.1h.9v.3h-.6v.3h.2c.2 0 .3.1.4.2.1.1.1.2.1.4s-.1.3-.2.4c-.1.1-.3.1-.4.1h-.2c-.1 0-.1 0-.2-.1v-.3c.1 0 .1.1.2.1h.2c.1 0 .2 0 .3-.1.1 0 .1-.1.1-.2s0-.2-.1-.2c-.1-.1-.1-.1-.2-.1h-.2c-.1 0-.1 0-.2.1l-.1-.9zM73.6 96.1h1v.2l-.6 1.4h-.3l.5-1.3h-.7l.1-.3zM74.8 96.9c0-.3.1-.5.1-.6.1-.1.2-.2.4-.2s.3.1.4.2c.1.1.1.3.1.6s-.1.5-.1.6c-.1.1-.2.2-.4.2s-.3-.1-.4-.2-.1-.3-.1-.6zm.6-.5c-.1 0-.1 0-.2.1 0 .1-.1.2-.1.4v.2l.4-.6c0-.1 0-.1-.1-.1zm-.2 1c0 .1.1.1.2.1s.1 0 .2-.1c0-.1.1-.2.1-.4v-.2l-.5.6zM76.2 96.2h.4c.2 0 .4 0 .5.1.1.1.1.2.1.4s-.1.3-.2.4c-.1.1-.3.1-.5.1h-.1v.6h-.3l.1-1.6zm.3.3v.5H76.8s.1-.1.1-.2 0-.1-.1-.2c0 0-.1-.1-.2-.1h-.1zM77.5 97c0-.3.1-.5.1-.6.1-.1.2-.2.4-.2s.3.1.4.2c.1.1.1.3.1.6s-.1.5-.1.6c-.1.1-.2.2-.4.2s-.3-.1-.4-.2-.1-.3-.1-.6zm.5-.5c-.1 0-.1 0-.2.1 0 .1-.1.2-.1.4v.2l.4-.6c0-.1 0-.1-.1-.1zm-.2.9c0 .1.1.1.2.1s.1 0 .2-.1c0-.1.1-.2.1-.4v-.2l-.5.6zM78.8 96.2h.3c.3 0 .4.1.6.2.1.1.2.3.2.6s-.1.5-.2.6c-.1.1-.3.2-.6.2h-.3v-1.6zm.3.3v1h.1c.1 0 .2 0 .3-.1.1-.1.1-.2.1-.4s0-.3-.1-.4c-.1 0-.2-.1-.4-.1z"/>
c0.1,0,0.2,0,0.2,0l0.3,0.3c0,0.1,0,0.1-0.1,0.3c0,0.8-0.1,1.4-0.2,1.6c-0.1,0.3-0.3,0.4-0.7,0.4c-0.1,0-0.2,0-0.5,0
c0-0.3,0-0.4-0.1-0.6c0.2,0.1,0.4,0.1,0.5,0.1c0.2,0,0.2-0.1,0.3-0.4c0-0.2,0.1-0.7,0.1-1l-0.7,0c0,0.2,0,0.2-0.1,0.4
c-0.2,0.7-0.5,1.2-1.3,1.7c-0.2-0.3-0.3-0.4-0.5-0.6c0.5-0.2,0.8-0.5,1-0.9c0.1-0.2,0.1-0.3,0.2-0.6l-0.5,0c-0.2,0-0.3,0-0.5,0
l0-0.6c0.2,0,0.2,0,0.5,0L64.3,91.6z"/>
<path class="st4" d="M69.3,94.3c-0.3-0.4-0.6-0.7-1-1.1c-0.4,0.4-0.8,0.7-1.4,1c-0.1-0.3-0.2-0.4-0.4-0.6
c0.5-0.2,0.9-0.4,1.2-0.7c0.3-0.3,0.6-0.6,0.8-1l-0.9,0c-0.3,0-0.4,0-0.6,0l0-0.6c0.1,0,0.2,0,0.4,0c0,0,0.1,0,0.2,0l1.2,0
c0.2,0,0.2,0,0.3,0l0.3,0.3c-0.1,0.1-0.1,0.1-0.1,0.2c-0.2,0.4-0.3,0.7-0.6,1c0.4,0.3,0.6,0.5,1.1,1L69.3,94.3z"/>
<path class="st4" d="M70.5,94.3c0-0.2,0-0.3,0-0.6l0.1-2.1c0-0.3,0-0.3,0-0.5l0.7,0c0,0.1,0,0.3,0,0.5l0,0.5
c0.6,0.2,1.1,0.4,1.6,0.8l-0.4,0.6c-0.3-0.3-0.8-0.5-1.1-0.7c-0.1-0.1-0.1-0.1-0.2-0.1l0,0.9c0,0.2,0,0.4,0,0.6L70.5,94.3z"/>
<path class="st4" d="M73.3,92.4c0.2,0,0.4,0,0.7,0.1l1.7,0c0.4,0,0.5,0,0.7,0l0,0.7c-0.2,0-0.3,0-0.7,0l-1.7,0
c-0.4,0-0.5,0-0.7,0L73.3,92.4z"/>
<path class="st4" d="M77.9,92.7c0,0.1,0,0.1,0,0.1c-0.1,0.6-0.3,1-0.6,1.4c-0.2-0.1-0.4-0.2-0.6-0.3c0.3-0.4,0.5-0.9,0.6-1.4
L77.9,92.7z M80.1,92.5c-0.1,0-0.2,0-0.6,0l-0.7,0l0,1.6c0,0.2,0,0.4,0,0.5l-0.7,0c0-0.1,0-0.3,0-0.6l0-1.6l-0.7,0
c-0.3,0-0.4,0-0.5,0l0-0.6c0.1,0,0.2,0,0.6,0l0.7,0l0-0.1c0-0.2,0-0.3,0-0.4l0.7,0c0,0.1,0,0.2,0,0.4l0,0.1l0.8,0
c-0.1-0.1-0.1-0.2-0.1-0.3c0-0.2,0.2-0.4,0.4-0.4c0.2,0,0.4,0.2,0.4,0.4c0,0.1-0.1,0.3-0.2,0.4L80.1,92.5z M79.6,92.6
c0.1,0.5,0.3,1.1,0.6,1.4c-0.2,0.1-0.4,0.2-0.6,0.3c-0.3-0.5-0.4-0.8-0.5-1.4c0-0.1,0-0.1-0.1-0.2L79.6,92.6z M79.7,91.6
c0,0.1,0.1,0.2,0.2,0.2c0.1,0,0.2-0.1,0.2-0.2c0-0.1-0.1-0.2-0.2-0.2C79.8,91.4,79.7,91.5,79.7,91.6z"/>
<path class="st4" d="M81.1,92.2c0.1,0.3,0.2,0.6,0.3,0.9l-0.6,0.2c-0.1-0.4-0.2-0.6-0.3-0.9L81.1,92.2z M83.2,92.3
c0,0.1,0,0.1-0.1,0.2c-0.1,0.5-0.3,0.9-0.5,1.2c-0.2,0.3-0.5,0.5-0.8,0.7c-0.1,0.1-0.2,0.1-0.4,0.2c-0.1-0.2-0.2-0.3-0.4-0.5
c0.7-0.3,1.1-0.6,1.4-1.2c0.1-0.3,0.2-0.5,0.2-0.8L83.2,92.3z M81.9,92.1c0.2,0.4,0.2,0.5,0.3,0.9l-0.6,0.2
c-0.1-0.3-0.2-0.6-0.3-0.9L81.9,92.1z"/>
<path class="st4" d="M84,94.7c0-0.2,0-0.3,0-0.6l0.1-2.1c0-0.3,0-0.3,0-0.5l0.7,0c0,0.1,0,0.2,0,0.5l0,0.5
c0.6,0.2,1.1,0.5,1.6,0.8L86,93.9c-0.3-0.2-0.7-0.5-1.1-0.7c-0.1,0-0.1,0-0.1-0.1c0,0,0,0,0,0l0,0.9c0,0.3,0,0.5,0,0.6L84,94.7z
M85.7,91.7c0.1,0.2,0.2,0.3,0.3,0.5l-0.3,0.2c-0.1-0.2-0.2-0.4-0.3-0.5L85.7,91.7z M86.2,91.5c0.1,0.1,0.2,0.3,0.4,0.5l-0.3,0.2
c-0.1-0.2-0.2-0.4-0.3-0.5L86.2,91.5z"/>
</g>
<g>
<path class="st4" d="M70.6,97.6c-0.1,0-0.1,0-0.2,0.1c-0.1,0-0.1,0-0.2,0c-0.2,0-0.4-0.1-0.5-0.2s-0.2-0.3-0.2-0.6
c0-0.3,0.1-0.5,0.2-0.6c0.1-0.1,0.3-0.2,0.5-0.2c0.1,0,0.1,0,0.2,0s0.1,0,0.2,0.1l0,0.3c-0.1-0.1-0.1-0.1-0.2-0.1
c0,0-0.1,0-0.2,0c-0.1,0-0.2,0-0.3,0.1C70,96.5,70,96.6,70,96.8c0,0.2,0,0.3,0.1,0.4c0.1,0.1,0.1,0.1,0.3,0.1c0.1,0,0.1,0,0.2,0
c0.1,0,0.1-0.1,0.2-0.1L70.6,97.6z"/>
<path class="st4" d="M71.5,96.1l0.3,0l0,1l0.2,0l0,0.3l-0.2,0l0,0.3l-0.3,0l0-0.3l-0.6,0l0-0.3L71.5,96.1z M71.5,96.4L71.1,97
l0.4,0L71.5,96.4z"/>
<path class="st4" d="M72.3,96.1l0.9,0l0,0.3l-0.6,0l0,0.3c0,0,0.1,0,0.1,0c0,0,0.1,0,0.1,0c0.2,0,0.3,0.1,0.4,0.2
c0.1,0.1,0.1,0.2,0.1,0.4c0,0.2-0.1,0.3-0.2,0.4c-0.1,0.1-0.3,0.1-0.4,0.1c-0.1,0-0.1,0-0.2,0c-0.1,0-0.1,0-0.2-0.1l0-0.3
c0.1,0,0.1,0.1,0.2,0.1c0.1,0,0.1,0,0.2,0c0.1,0,0.2,0,0.3-0.1c0.1,0,0.1-0.1,0.1-0.2c0-0.1,0-0.2-0.1-0.2
c-0.1-0.1-0.1-0.1-0.2-0.1c-0.1,0-0.1,0-0.2,0c-0.1,0-0.1,0-0.2,0.1L72.3,96.1z"/>
<path class="st4" d="M73.6,96.1l1,0l0,0.2L74,97.7l-0.3,0l0.5-1.3l-0.7,0L73.6,96.1z"/>
<path class="st4" d="M74.8,96.9c0-0.3,0.1-0.5,0.1-0.6c0.1-0.1,0.2-0.2,0.4-0.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.1,0.3,0.1,0.6
c0,0.3-0.1,0.5-0.1,0.6c-0.1,0.1-0.2,0.2-0.4,0.2c-0.2,0-0.3-0.1-0.4-0.2S74.8,97.2,74.8,96.9z M75.4,96.4c-0.1,0-0.1,0-0.2,0.1
c0,0.1-0.1,0.2-0.1,0.4c0,0.1,0,0.1,0,0.2l0.4-0.6c0,0,0,0,0,0C75.5,96.4,75.5,96.4,75.4,96.4z M75.2,97.4c0,0.1,0.1,0.1,0.2,0.1
c0.1,0,0.1,0,0.2-0.1c0-0.1,0.1-0.2,0.1-0.4c0-0.1,0-0.1,0-0.2L75.2,97.4C75.2,97.4,75.2,97.4,75.2,97.4z"/>
<path class="st4" d="M76.2,96.2l0.4,0c0.2,0,0.4,0,0.5,0.1c0.1,0.1,0.1,0.2,0.1,0.4c0,0.2-0.1,0.3-0.2,0.4
c-0.1,0.1-0.3,0.1-0.5,0.1l-0.1,0l0,0.6l-0.3,0L76.2,96.2z M76.5,96.5l0,0.5l0.1,0c0.1,0,0.2,0,0.2,0c0,0,0.1-0.1,0.1-0.2
c0-0.1,0-0.1-0.1-0.2c0,0-0.1-0.1-0.2-0.1L76.5,96.5z"/>
<path class="st4" d="M77.5,97c0-0.3,0.1-0.5,0.1-0.6c0.1-0.1,0.2-0.2,0.4-0.2c0.2,0,0.3,0.1,0.4,0.2c0.1,0.1,0.1,0.3,0.1,0.6
c0,0.3-0.1,0.5-0.1,0.6c-0.1,0.1-0.2,0.2-0.4,0.2c-0.2,0-0.3-0.1-0.4-0.2S77.5,97.3,77.5,97z M78,96.5c-0.1,0-0.1,0-0.2,0.1
c0,0.1-0.1,0.2-0.1,0.4c0,0.1,0,0.1,0,0.2l0.4-0.6c0,0,0,0,0,0C78.1,96.5,78.1,96.5,78,96.5z M77.8,97.4c0,0.1,0.1,0.1,0.2,0.1
c0.1,0,0.1,0,0.2-0.1c0-0.1,0.1-0.2,0.1-0.4c0-0.1,0-0.1,0-0.2L77.8,97.4C77.8,97.4,77.8,97.4,77.8,97.4z"/>
<path class="st4" d="M78.8,96.2l0.3,0c0.3,0,0.4,0.1,0.6,0.2c0.1,0.1,0.2,0.3,0.2,0.6c0,0.3-0.1,0.5-0.2,0.6
c-0.1,0.1-0.3,0.2-0.6,0.2l-0.3,0L78.8,96.2z M79.1,96.5l0,1l0.1,0c0.1,0,0.2,0,0.3-0.1c0.1-0.1,0.1-0.2,0.1-0.4
c0-0.2,0-0.3-0.1-0.4C79.4,96.6,79.3,96.5,79.1,96.5L79.1,96.5z"/>
</g> </g>
</g> </g>
</g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 17 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -5,13 +5,13 @@ const Clipboard = (): void => {
if (buttons) { if (buttons) {
for (let i = 0; i < buttons.length; i++) { for (let i = 0; i < buttons.length; i++) {
const button: HTMLButtonElement = buttons[i]; const button: HTMLButtonElement = buttons[i];
const textArea: HTMLTextAreaElement | null = document.querySelector( const element: HTMLFormElement | null = document.querySelector(
`textarea[id="${button.dataset.clipboardTarget}"]` `[id="${button.dataset.clipboardTarget}"]`
); );
if (textArea) { if (element) {
button.addEventListener("click", () => { button.addEventListener("click", () => {
textArea.select(); element.select();
textArea.setSelectionRange(0, textArea.value.length); element.setSelectionRange(0, element.value.length);
document.execCommand("copy"); document.execCommand("copy");
}); });
} }

View File

@ -4,11 +4,10 @@ const ThemePicker = (): void => {
const iframe: HTMLIFrameElement | null = document.querySelector( const iframe: HTMLIFrameElement | null = document.querySelector(
`iframe[id="embeddable_player"]` `iframe[id="embeddable_player"]`
); );
const iframeTextArea: HTMLTextAreaElement | null = document.querySelector( const iframeTextArea: HTMLFormElement | null =
`textarea[id="iframe"]` document.querySelector(`[id="iframe"]`);
); const urlTextArea: HTMLFormElement | null =
const urlTextArea: HTMLTextAreaElement | null = document.querySelector(`[id="url"]`);
document.querySelector(`textarea[id="url"]`);
if (buttons && iframe && iframeTextArea && urlTextArea) { if (buttons && iframe && iframeTextArea && urlTextArea) {
for (let i = 0; i < buttons.length; i++) { for (let i = 0; i < buttons.length; i++) {

View File

@ -1,5 +1,5 @@
.breadcrumb { .breadcrumb {
@apply inline-flex flex-wrap px-1 text-sm; @apply inline-flex flex-wrap px-1;
} }
.breadcrumb-item + .breadcrumb-item::before { .breadcrumb-item + .breadcrumb-item::before {

View File

@ -15,25 +15,49 @@
} }
&:checked + .form-switch-slider::after { &:checked + .form-switch-slider::after {
@apply transform translate-x-1; @apply transform translate-x-0 left-2;
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='%23ffffff'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m10 15.172 9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E%0A"); content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23ffffff'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m10 15.172 9.192-9.193 1.415 1.414L10 18l-6.364-6.364 1.414-1.414z'/%3E%3C/svg%3E%0A");
}
&:checked + .form-switch-slider.form-switch-slider--small::before {
@apply translate-x-6;
}
&:checked + .form-switch-slider.form-switch-slider--small::after {
@apply left-1;
} }
} }
.form-switch-slider { .form-switch-slider {
@apply relative inset-0 flex-shrink-0 w-[72px] h-10 transition duration-200 bg-gray-400 border-black rounded-full cursor-pointer border-3; @apply relative inset-0 flex-shrink-0 w-16 h-8 transition duration-200 bg-gray-400 border-black rounded-full cursor-pointer border-3;
&.form-switch-slider--small {
@apply w-12 h-6;
&::before { &::before {
@apply absolute z-10 w-[28px] h-[28px] transition duration-200 bg-white rounded-full ring-1 ring-black ring-opacity-5 shadow; @apply w-4 h-4;
content: "";
left: 3px;
bottom: 3px;
} }
&::after { &::after {
@apply absolute w-6 h-6 transition duration-150 transform translate-x-8 top-1 left-1; @apply translate-x-5;
left: 0;
top: -1px;
}
}
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m12 10.586 4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z'/%3E%3C/svg%3E%0A"); &::before {
@apply absolute z-10 w-6 h-6 transition duration-200 bg-white rounded-full shadow ring-1 ring-black ring-opacity-5;
content: "";
left: 1px;
bottom: 1px;
}
&::after {
@apply absolute w-5 h-5 transition duration-150 transform translate-x-5;
content: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' %3E%3Cpath fill='none' d='M0 0h24v24H0z'/%3E%3Cpath d='m12 10.586 4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636z'/%3E%3C/svg%3E%0A");
top: 3px;
left: 10px;
} }
} }
} }

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace App\Views\Components;
use ViewComponents\Component;
class Alert extends Component
{
protected ?string $glyph = null;
protected ?string $title = null;
/**
* @var 'default'|'success'|'danger'|'warning'
*/
protected string $variant = 'default';
public function render(): string
{
$variantClasses = [
'default' => 'text-gray-800 bg-gray-100 border-gray-300',
'success' => 'text-pine-900 bg-pine-100 border-pine-300',
'danger' => 'text-red-900 bg-red-100 border-red-300',
'warning' => 'text-yellow-900 bg-yellow-100 border-yellow-300',
];
$glyph = $this->glyph === null ? '' : '<Icon glyph="' . $this->glyph . '" class="flex-shrink-0 mr-2 text-lg" />';
$title = $this->title === null ? '' : '<div class="font-semibold">' . $this->title . '</div>';
$class = 'inline-flex w-full p-2 text-sm border rounded ' . $variantClasses[$this->variant] . ' ' . $this->class;
$attributes = stringify_attributes($this->attributes);
return <<<HTML
<div class="{$class}" role="alert" {$attributes}>{$glyph}<div>{$title}{$this->slot}</div></div>
HTML;
}
}

View File

@ -8,8 +8,6 @@ use ViewComponents\Component;
class Button extends Component class Button extends Component
{ {
protected string $label = '';
protected string $uri = ''; protected string $uri = '';
protected string $variant = 'default'; protected string $variant = 'default';
@ -22,6 +20,11 @@ class Button extends Component
protected bool $isSquared = false; protected bool $isSquared = false;
public function setIsSquared(string $value): void
{
$this->isSquared = $value === 'true';
}
public function render(): string public function render(): string
{ {
$baseClass = $baseClass =
@ -80,19 +83,31 @@ class Button extends Component
$this->slot .= '<Icon glyph="' . $this->iconRight . '" class="ml-2" />'; $this->slot .= '<Icon glyph="' . $this->iconRight . '" class="ml-2" />';
} }
if ($this->uri !== '') { unset($this->attributes['slot']);
return anchor($this->uri, $this->label, array_merge([ unset($this->attributes['variant']);
'class' => $buttonClass, unset($this->attributes['size']);
], $this->attributes)); unset($this->attributes['iconLeft']);
} unset($this->attributes['iconRight']);
unset($this->attributes['isSquared']);
unset($this->attributes['uri']);
unset($this->attributes['label']);
if ($this->uri !== '') {
$tagName = 'a';
$defaultButtonAttributes = [
'href' => $this->uri,
];
} else {
$tagName = 'button';
$defaultButtonAttributes = [ $defaultButtonAttributes = [
'type' => 'button', 'type' => 'button',
]; ];
}
$attributes = stringify_attributes(array_merge($defaultButtonAttributes, $this->attributes)); $attributes = stringify_attributes(array_merge($defaultButtonAttributes, $this->attributes));
return <<<HTML return <<<HTML
<button class="{$buttonClass}" {$attributes}>{$this->slot}</button> <{$tagName} class="{$buttonClass}" {$attributes}>{$this->slot}</{$tagName}>
HTML; HTML;
} }
} }

View File

@ -0,0 +1,39 @@
<?php
declare(strict_types=1);
namespace App\Views\Components\Forms;
class Checkbox extends FormComponent
{
protected ?string $hint = null;
protected bool $isChecked = false;
public function setIsChecked(string $value): void
{
$this->isChecked = $value === 'true';
}
public function render(): string
{
$checkboxInput = form_checkbox(
[
'id' => $this->value,
'name' => $this->name,
'class' => 'form-checkbox text-pine-500 border-black border-3 focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 w-6 h-6',
],
$this->value,
old($this->name) ? old($this->name) === $this->value : $this->isChecked,
);
$hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1');
return <<<HTML
<label class="leading-8">
{$checkboxInput}
<span class="ml-2">{$this->slot}{$hint}</label>
</label>
HTML;
}
}

View File

@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace App\Views\Components\Forms;
class DatetimePicker extends FormComponent
{
public function render(): string
{
$this->attributes['class'] = 'rounded-l-lg border-0 border-rounded-r-none flex-1 focus:ring-0';
$this->attributes['data-input'] = '';
$dateInput = form_input($this->attributes, old($this->name, $this->value));
$clearLabel = lang(
'Episode.publish_form.scheduled_publication_date_clear',
);
$closeIcon = icon('close');
return <<<HTML
<div class="flex border-3 rounded-lg border-black focus-within:ring-2 focus-within:ring-pine-500 focus-within:ring-offset-2 focus-within:ring-offset-pine-100 {$this->class}" data-picker="datetime">
{$dateInput}
<button class="p-3 bg-white hover:bg-pine-100 focus:outline-none rounded-r-md focus:ring-inset focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100" type="button" aria-label="{$clearLabel}" title="{$clearLabel}" data-clear="">
{$closeIcon}
</button>
</div>
HTML;
}
}

View File

@ -16,17 +16,35 @@ class FormComponent extends Component
protected bool $required = false; protected bool $required = false;
protected bool $readonly = false;
public function __construct($attributes) public function __construct($attributes)
{ {
parent::__construct($attributes); parent::__construct($attributes);
if ($this->id === null) { if ($this->id === null) {
$this->id = $this->name; $this->id = $this->name;
$this->attributes['id'] = $this->id;
} }
} }
public function setRequired(string $value): void public function setRequired(string $value): void
{ {
$this->required = $value === 'true'; $this->required = $value === 'true';
if ($this->required) {
$this->attributes['required'] = 'required';
} else {
unset($this->attributes['required']);
}
}
public function setReadonly(string $value): void
{
$this->readonly = $value === 'true';
if ($this->readonly) {
$this->attributes['readonly'] = 'readonly';
} else {
unset($this->attributes['readonly']);
}
} }
} }

View File

@ -7,7 +7,7 @@ namespace App\Views\Components\Forms;
class Helper extends FormComponent class Helper extends FormComponent
{ {
/** /**
* @var "default"|"error" * @var 'default'|'error'
*/ */
protected string $type = 'default'; protected string $type = 'default';

View File

@ -21,17 +21,12 @@ class Input extends FormComponent
$class .= ' border-black focus:border-black'; $class .= ' border-black focus:border-black';
} }
$data = [ $this->attributes['class'] = $class;
'id' => $this->id,
'name' => $this->name,
'class' => $class,
'type' => $this->type,
];
if ($this->required) { if ($this->required) {
$data['required'] = 'required'; $this->attributes['required'] = 'required';
} }
return form_input($data, old($this->name, $this->value)); return form_input($this->attributes, old($this->name, $this->value));
} }
} }

View File

@ -24,12 +24,17 @@ class Label extends Component
$labelClass = 'text-sm ' . $this->attributes['class']; $labelClass = 'text-sm ' . $this->attributes['class'];
unset($this->attributes['class']); unset($this->attributes['class']);
$attributes = stringify_attributes($this->attributes);
$optionalText = $this->isOptional ? '<small class="ml-1 lowercase">(' . $optionalText = $this->isOptional ? '<small class="ml-1 lowercase">(' .
lang('Common.optional') . lang('Common.optional') .
')</small>' : ''; ')</small>' : '';
$hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1'); $hint = $this->hint === null ? '' : hint_tooltip($this->hint, 'ml-1');
unset($this->attributes['isOptional']);
unset($this->attributes['hint']);
unset($this->attributes['slot']);
$attributes = stringify_attributes($this->attributes);
return <<<HTML return <<<HTML
<label class="{$labelClass}" {$attributes}>{$this->slot}{$optionalText}{$hint}</label> <label class="{$labelClass}" {$attributes}>{$this->slot}{$optionalText}{$hint}</label>
HTML; HTML;

View File

@ -4,9 +4,7 @@ declare(strict_types=1);
namespace App\Views\Components\Forms; namespace App\Views\Components\Forms;
use ViewComponents\Component; class MultiSelect extends FormComponent
class MultiSelect extends Component
{ {
/** /**
* @var array<string, string> * @var array<string, string>
@ -36,6 +34,6 @@ class MultiSelect extends Component
]; ];
$extra = array_merge($defaultAttributes, $this->attributes); $extra = array_merge($defaultAttributes, $this->attributes);
return form_dropdown($this->attributes['name'], $this->options, $this->selected, $extra); return form_dropdown($this->name, $this->options, $this->selected, $extra);
} }
} }

View File

@ -0,0 +1,32 @@
<?php
declare(strict_types=1);
namespace App\Views\Components\Forms;
class Radio extends FormComponent
{
protected bool $isChecked = false;
public function setIsChecked(string $value): void
{
$this->isChecked = $value === 'true';
}
public function render(): string
{
$radioInput = form_radio(
[
'id' => $this->value,
'name' => $this->name,
'class' => 'text-pine-500 border-black border-3 focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 w-6 h-6',
],
$this->value,
old($this->name) ? old($this->name) === $this->value : $this->isChecked,
);
return <<<HTML
<label class="leading-8">{$radioInput}<span class="ml-2">{$this->slot}</span></label>
HTML;
}
}

View File

@ -4,11 +4,6 @@ declare(strict_types=1);
namespace App\Views\Components\Forms; namespace App\Views\Components\Forms;
/**
* Form Checkbox Switch
*
* Abstracts form_label to stylize it as a switch toggle
*/
class RadioButton extends FormComponent class RadioButton extends FormComponent
{ {
protected bool $isChecked = false; protected bool $isChecked = false;

View File

@ -4,15 +4,19 @@ declare(strict_types=1);
namespace App\Views\Components\Forms; namespace App\Views\Components\Forms;
class Section extends FormComponent use ViewComponents\Component;
class Section extends Component
{ {
protected string $title = ''; protected string $title = '';
protected ?string $subtitle = null; protected ?string $subtitle = null;
protected string $subtitleClass = '';
public function render(): string public function render(): string
{ {
$subtitle = $this->subtitle === null ? '' : '<p class="text-sm text-gray-600 clear-left">' . $this->subtitle . '</p>'; $subtitle = $this->subtitle === null ? '' : '<p class="text-sm text-gray-600 clear-left ' . $this->subtitleClass . '">' . $this->subtitle . '</p>';
return <<<HTML return <<<HTML
<fieldset class="w-full max-w-xl p-8 bg-white border-2 border-black rounded-xl {$this->class}"> <fieldset class="w-full max-w-xl p-8 bg-white border-2 border-black rounded-xl {$this->class}">

View File

@ -11,7 +11,7 @@ class Select extends FormComponent
*/ */
protected array $options = []; protected array $options = [];
protected string $selected; protected string $selected = '';
public function setOptions(string $value): void public function setOptions(string $value): void
{ {

View File

@ -0,0 +1,31 @@
<?php
declare(strict_types=1);
namespace App\Views\Components\Forms;
class Textarea extends FormComponent
{
public function setValue(?string $value): void
{
if ($value) {
$this->value = html_entity_decode($value);
}
}
public function render(): string
{
unset($this->attributes['value']);
$this->attributes['class'] = 'focus:border-black focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 rounded-lg border-3 border-black ' . $this->class;
$textarea = form_textarea(
$this->attributes,
old($this->name, $this->value ?? '', false)
);
return <<<HTML
{$textarea}
HTML;
}
}

View File

@ -4,24 +4,12 @@ declare(strict_types=1);
namespace App\Views\Components\Forms; namespace App\Views\Components\Forms;
use ViewComponents\Component; class Toggler extends FormComponent
/**
* Form Checkbox Switch
*
* Abstracts form_label to stylize it as a switch toggle
*/
class Toggler extends Component
{ {
/** /**
* @var array<string, string> * @var 'base'|'small
*/ */
protected array $attributes = [ protected string $size = 'base';
'id' => '',
'name' => '',
'value' => '',
'class' => '',
];
protected string $label = ''; protected string $label = '';
@ -31,26 +19,29 @@ class Toggler extends Component
public function setChecked(string $value): void public function setChecked(string $value): void
{ {
$this->checked = $value !== ''; $this->checked = $value === 'true';
} }
public function render(): string public function render(): string
{ {
unset($this->attributes['checked']); unset($this->attributes['checked']);
$wrapperClass = $this->attributes['class']; $wrapperClass = $this->class;
unset($this->attributes['class']); unset($this->attributes['class']);
$sizeClass = [
'base' => 'form-switch-slider',
'small' => 'form-switch-slider form-switch-slider--small',
];
$this->attributes['class'] = 'form-switch'; $this->attributes['class'] = 'form-switch';
helper('form'); $checkbox = form_checkbox($this->attributes, $this->value, old($this->name, $this->checked));
$checkbox = form_checkbox($this->attributes, $this->attributes['value'], $this->checked);
$hint = $this->hint === '' ? '' : hint_tooltip($this->hint, 'ml-1'); $hint = $this->hint === '' ? '' : hint_tooltip($this->hint, 'ml-1');
return <<<HTML return <<<HTML
<label class="relative inline-flex items-center {$wrapperClass}"> <label class="relative inline-flex items-center {$wrapperClass}">
{$checkbox} {$checkbox}
<span class="form-switch-slider"></span> <span class="{$sizeClass[$this->size]}"></span>
<span class="ml-2">{$this->slot}{$hint}</span> <span class="ml-2">{$this->slot}{$hint}</span>
</label> </label>
HTML; HTML;

View File

@ -4,9 +4,7 @@ declare(strict_types=1);
namespace App\Views\Components\Forms; namespace App\Views\Components\Forms;
use ViewComponents\Component; class XMLEditor extends FormComponent
class XMLEditor extends Component
{ {
/** /**
* @var array<string, string> * @var array<string, string>

View File

@ -11,7 +11,7 @@ class Heading extends Component
protected string $tagName = 'div'; protected string $tagName = 'div';
/** /**
* @var "small"|"base"|"large" * @var 'small'|'base'|'large'
*/ */
protected string $size = 'base'; protected string $size = 'base';

View File

@ -0,0 +1,21 @@
<?php
declare(strict_types=1);
namespace App\Views\Components;
use ViewComponents\Component;
class IconButton extends Component
{
public string $glyph = '';
public function render(): string
{
$attributes = stringify_attributes($this->attributes);
return <<<HTML
<Button isSquared="true" title="{$this->slot}" data-toggle="tooltip" data-placement="bottom" {$attributes}><Icon glyph="{$this->glyph}" /></Button>
HTML;
}
}

View File

@ -118,6 +118,7 @@ return [
'post' => 'Your announcement post', 'post' => 'Your announcement post',
'post_hint' => 'post_hint' =>
"Write a message to announce the publication of your episode. The message will be broadcasted to all your followers in the fediverse and be featured in your podcast's homepage.", "Write a message to announce the publication of your episode. The message will be broadcasted to all your followers in the fediverse and be featured in your podcast's homepage.",
'message_placeholder' => 'Write your message…',
'publication_date' => 'Publication date', 'publication_date' => 'Publication date',
'publication_method' => [ 'publication_method' => [
'now' => 'Now', 'now' => 'Now',

View File

@ -17,8 +17,6 @@ return [
'edit' => 'Edit person', 'edit' => 'Edit person',
'delete' => 'Delete person', 'delete' => 'Delete person',
'form' => [ 'form' => [
'identity_section_title' => 'Identity',
'identity_section_subtitle' => 'Who is working on the podcast',
'image' => 'Picture', 'image' => 'Picture',
'image_size_hint' => 'image_size_hint' =>
'Image must be squared with at least 400px wide and tall.', 'Image must be squared with at least 400px wide and tall.',
@ -34,8 +32,6 @@ return [
], ],
'podcast_form' => [ 'podcast_form' => [
'title' => 'Manage persons', 'title' => 'Manage persons',
'manage_section_title' => 'Management',
'manage_section_subtitle' => 'Remove persons from this podcast',
'add_section_title' => 'Add persons to this podcast', 'add_section_title' => 'Add persons to this podcast',
'add_section_subtitle' => 'You may pick several persons and roles.', 'add_section_subtitle' => 'You may pick several persons and roles.',
'persons' => 'Persons', 'persons' => 'Persons',
@ -49,8 +45,6 @@ return [
], ],
'episode_form' => [ 'episode_form' => [
'title' => 'Manage persons', 'title' => 'Manage persons',
'manage_section_title' => 'Management',
'manage_section_subtitle' => 'Remove persons from this episode',
'add_section_title' => 'Add persons to this episode', 'add_section_title' => 'Add persons to this episode',
'add_section_subtitle' => 'You may pick several persons and roles.', 'add_section_subtitle' => 'You may pick several persons and roles.',
'persons' => 'Persons', 'persons' => 'Persons',

View File

@ -88,7 +88,6 @@ return [
'partner_link_url_hint' => 'The generic partner link address', 'partner_link_url_hint' => 'The generic partner link address',
'partner_image_url_hint' => 'The generic partner image address', 'partner_image_url_hint' => 'The generic partner image address',
'status_section_title' => 'Status', 'status_section_title' => 'Status',
'status_section_subtitle' => 'Dead or alive?',
'block' => 'Podcast should be hidden from all platforms', 'block' => 'Podcast should be hidden from all platforms',
'complete' => 'Podcast will not be having new episodes', 'complete' => 'Podcast will not be having new episodes',
'lock' => 'Prevent podcast from being copied', 'lock' => 'Prevent podcast from being copied',

View File

@ -20,11 +20,7 @@ return [
'advanced_params_section_title' => 'Advanced parameters', 'advanced_params_section_title' => 'Advanced parameters',
'advanced_params_section_subtitle' => 'advanced_params_section_subtitle' =>
'Keep the default values if you have no idea of what the fields are for.', 'Keep the default values if you have no idea of what the fields are for.',
'slug_field' => [ 'slug_field' => 'Field to be used to calculate episode slug',
'label' => 'Which field should be used to calculate episode slug',
'link' => '&lt;link&gt;',
'title' => '&lt;title&gt;',
],
'description_field' => 'description_field' =>
'Source field used for episode description / show notes', 'Source field used for episode description / show notes',
'force_renumber' => 'Force episodes renumbering', 'force_renumber' => 'Force episodes renumbering',

View File

@ -121,6 +121,7 @@ return [
'post' => 'Votre message de publication', 'post' => 'Votre message de publication',
'post_hint' => 'post_hint' =>
'Écrivez un message pour annoncer la publication de votre épisode. Le message sera diffusé à toutes les personnes qui vous suivent dans le fédiverse et mis en évidence sur la page daccueil de votre podcast.', 'Écrivez un message pour annoncer la publication de votre épisode. Le message sera diffusé à toutes les personnes qui vous suivent dans le fédiverse et mis en évidence sur la page daccueil de votre podcast.',
'message_placeholder' => 'Entrez votre message…',
'publication_date' => 'Date de publication', 'publication_date' => 'Date de publication',
'publication_date_clear' => 'Effacer la date de publication', 'publication_date_clear' => 'Effacer la date de publication',
'publication_date_hint' => 'publication_date_hint' =>

View File

@ -17,8 +17,6 @@ return [
'edit' => 'Modifier lintervenant', 'edit' => 'Modifier lintervenant',
'delete' => 'Supprimer lintervenant', 'delete' => 'Supprimer lintervenant',
'form' => [ 'form' => [
'identity_section_title' => 'Identité',
'identity_section_subtitle' => 'Qui intervient sur le podcast',
'image' => 'Photo', 'image' => 'Photo',
'image_size_hint' => 'image_size_hint' =>
'Limage doit être carrée et avoir au moins 400px de largeur et de hauteur.', 'Limage doit être carrée et avoir au moins 400px de largeur et de hauteur.',
@ -34,32 +32,28 @@ return [
], ],
'podcast_form' => [ 'podcast_form' => [
'title' => 'Gérer les intervenants', 'title' => 'Gérer les intervenants',
'manage_section_title' => 'Gestion',
'manage_section_subtitle' => 'Retirer des intervenants de ce podcast',
'add_section_title' => 'Ajouter des intervenants à ce podcast', 'add_section_title' => 'Ajouter des intervenants à ce podcast',
'add_section_subtitle' => 'add_section_subtitle' =>
'Vous pouvez sélectionner plusieurs intervenants et rôles.', 'Vous pouvez sélectionner plusieurs intervenants et rôles.',
'person' => 'Intervenants', 'persons' => 'Intervenants',
'person_hint' => 'persons_hint' =>
'Vous pouvez selectionner un ou plusieurs intervenants ayant les mêmes rôles. Les intervenants doivent avoir été préalablement créés.', 'Vous pouvez selectionner un ou plusieurs intervenants ayant les mêmes rôles. Les intervenants doivent avoir été préalablement créés.',
'group_role' => 'Groupes et rôles', 'roles' => 'Groupes et rôles',
'group_role_hint' => 'roles_hint' =>
'Vous pouvez sélectionner aucun, un ou plusieurs groupes et rôles par intervenant.', 'Vous pouvez sélectionner aucun, un ou plusieurs groupes et rôles par intervenant.',
'submit_add' => 'Ajouter un/des intervenant(s)', 'submit_add' => 'Ajouter un/des intervenant(s)',
'remove' => 'Retirer', 'remove' => 'Retirer',
], ],
'episode_form' => [ 'episode_form' => [
'title' => 'Gérer les intervenants', 'title' => 'Gérer les intervenants',
'manage_section_title' => 'Gestion',
'manage_section_subtitle' => 'Retirer des intervenants de cet épisode',
'add_section_title' => 'Ajouter des intervenants à cet épisode', 'add_section_title' => 'Ajouter des intervenants à cet épisode',
'add_section_subtitle' => 'add_section_subtitle' =>
'Vous pouvez sélectionner plusieurs intervenants et rôles.', 'Vous pouvez sélectionner plusieurs intervenants et rôles.',
'person' => 'Intervenants', 'persons' => 'Intervenants',
'person_hint' => 'persons_hint' =>
'Vous pouvez selectionner un ou plusieurs intervenants ayant les mêmes rôles. Les intervenants doivent avoir été préalablement créés.', 'Vous pouvez selectionner un ou plusieurs intervenants ayant les mêmes rôles. Les intervenants doivent avoir été préalablement créés.',
'group_role' => 'Groupes et rôles', 'roles' => 'Groupes et rôles',
'group_role_hint' => 'roles_hint' =>
'Vous pouvez sélectionner aucun, un ou plusieurs groupes et rôles par intervenant.', 'Vous pouvez sélectionner aucun, un ou plusieurs groupes et rôles par intervenant.',
'submit_add' => 'Ajouter un/des intervenant(s)', 'submit_add' => 'Ajouter un/des intervenant(s)',
'remove' => 'Retirer', 'remove' => 'Retirer',

View File

@ -90,7 +90,6 @@ return [
'partner_link_url_hint' => 'Ladresse générique des liens partenaire', 'partner_link_url_hint' => 'Ladresse générique des liens partenaire',
'partner_image_url_hint' => 'Ladresse générique des images partenaire', 'partner_image_url_hint' => 'Ladresse générique des images partenaire',
'status_section_title' => 'Statut', 'status_section_title' => 'Statut',
'status_section_subtitle' => 'Vivant ou mort?',
'block' => 'Le podcast doit être masqué sur toutes les plateformes', 'block' => 'Le podcast doit être masqué sur toutes les plateformes',
'complete' => 'Le podcast naura plus de nouveaux épisodes.', 'complete' => 'Le podcast naura plus de nouveaux épisodes.',
'lock' => 'Empêcher la copie du podcast', 'lock' => 'Empêcher la copie du podcast',

View File

@ -22,7 +22,7 @@ return [
'Si vous ne savez pas à quoi servent ces champs, conservez les valeurs par défaut.', 'Si vous ne savez pas à quoi servent ces champs, conservez les valeurs par défaut.',
'slug_field' => [ 'slug_field' => [
'label' => 'label' =>
'Quel champ utiliser pour calculer lidentifiant de lépisode', 'Champ à utiliser pour calculer lidentifiant de lépisode',
'link' => '&lt;link&gt; (adresse)', 'link' => '&lt;link&gt; (adresse)',
'title' => '&lt;title&gt; (titre)', 'title' => '&lt;title&gt; (titre)',
], ],

View File

@ -24,7 +24,7 @@
<a href="<?= route_to( <a href="<?= route_to(
'admin', 'admin',
) ?>" class="inline-flex items-center h-full px-2 border-r border-pine-900"> ) ?>" class="inline-flex items-center h-full px-2 border-r border-pine-900">
<?= (isset($podcast) ? icon('arrow-left', 'mr-2') : '') . svg('castopod-logo', 'h-6') ?> <?= (isset($podcast) ? icon('arrow-left', 'mr-2') : '') . svg('castopod-logo-base', 'h-6') ?>
</a> </a>
<a href="<?= route_to( <a href="<?= route_to(
'home', 'home',
@ -93,7 +93,7 @@
</div> </div>
</header> </header>
<div class="container px-2 py-8 mx-auto md:px-12"> <div class="container px-2 py-8 mx-auto md:px-12">
<!-- view('App\Views\_message_block') --> <?= view('_message_block') ?>
<?= $this->renderSection('content') ?> <?= $this->renderSection('content') ?>
</div> </div>
</main> </main>

View File

@ -0,0 +1,20 @@
<?php declare(strict_types=1);
if (session()->has('message')): ?>
<Alert variant="success"><?= session('message') ?></Alert>
<?php endif; ?>
<?php if (session()->has('error')): ?>
<Alert variant="danger"><?= session('error') ?></Alert>
<?php endif; ?>
<?php if (session()->has('errors')): ?>
<Alert variant="danger">
<ul>
<?php foreach (session('errors') as $error): ?>
<li><?= $error ?></li>
<?php endforeach; ?>
</ul>
</Alert>
<?php endif;
?>

View File

@ -11,39 +11,27 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('contributor-add', $podcast->id), [ <form method="POST" action="<?= route_to('contributor-add', $podcast->id) ?>" class="flex flex-col max-w-sm gap-y-4">
'class' => 'flex flex-col max-w-sm',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<Forms.Label for="user"><?= lang('Contributor.form.user') ?></Forms.Label> <Forms.Field
<?= form_dropdown('user', $userOptions, [old('user', '')], [ as="Select"
'id' => 'user', name="user"
'class' => 'form-select mb-4', label="<?= lang('Contributor.form.user') ?>"
'required' => 'required', options="<?= esc(json_encode($userOptions)) ?>"
'placeholder' => lang('Contributor.form.user_placeholder'), placeholder="<?= lang('Contributor.form.user_placeholder') ?>"
]) ?> required="true" />
<Forms.Label for="role"><?= lang('Contributor.form.role') ?></Forms.Label> <Forms.Field
<?= form_dropdown('role', $roleOptions, [old('role', '')], [ as="Select"
'id' => 'role', name="role"
'class' => 'form-select mb-4', label="<?= lang('Contributor.form.role') ?>"
'required' => 'required', options="<?= esc(json_encode($roleOptions)) ?>"
'placeholder' => lang('Contributor.form.role_placeholder'), placeholder="<?= lang('Contributor.form.role_placeholder') ?>"
]) ?> required="true" />
<?= button( <Button type="submit" class="self-end" variant="primary"><?= lang('Contributor.form.submit_add') ?></Button>
lang('Contributor.form.submit_add'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,30 +11,20 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('contributor-edit', $podcast->id, $user->id), [ <form method="POST" action="<?= route_to('contributor-edit', $podcast->id, $user->id) ?>" class="flex flex-col max-w-sm gap-y-4">
'class' => 'flex flex-col max-w-sm',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<Forms.Label for="role"><?= lang('Contributor.form.role') ?></Forms.Label> <Forms.Field
<?= form_dropdown('role', $roleOptions, [old('role', $contributorGroupId)], [ as="Select"
'id' => 'role', name="role"
'class' => 'form-select mb-4', label="<?= lang('Contributor.form.role') ?>"
'required' => 'required', selected="<?= $contributorGroupId ?>"
]) ?> options="<?= esc(json_encode($roleOptions)) ?>"
placeholder="<?= lang('Contributor.form.role_placeholder') ?>"
required="true" />
<?= button( <Button variant="primary" type="submit" class="self-end"><?= lang('Contributor.form.submit_edit') ?></Button>
lang('Contributor.form.submit_edit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,356 +11,203 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart(route_to('episode-create', $podcast->id), [ <Alert variant="danger" glyph="alert"><?= lang('Episode.form.warning') ?></Alert>
'method' => 'post',
'class' => 'flex flex-col', <form action="<?= route_to('episode-create', $podcast->id) ?>" method="POST" enctype="multipart/form-data" class="flex flex-col mt-6 gap-y-8">
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_hidden('client_timezone', 'UTC') ?>
<div class="inline-flex w-full p-2 mb-4 text-sm font-semibold text-yellow-800 bg-red-100 border border-red-300 rounded" role="alert">
<?= icon('alert', 'mr-2 text-lg flex-shrink-0') .
lang('Episode.form.warning') ?>
</div>
<?= form_section( <Forms.Section title="<?= lang('Episode.form.info_section_title') ?>" >
lang('Episode.form.info_section_title'),
lang('Episode.form.info_section_subtitle'),
) ?>
<Forms.Label for="audio_file" hint="<?= lang('Episode.form.audio_file_hint') ?>"><?= lang('Episode.form.audio_file') ?></Forms.Label> <Forms.Field
<?= form_input([ name="audio_file"
'id' => 'audio_file', label="<?= lang('Episode.form.audio_file') ?>"
'name' => 'audio_file', hintText="<?= lang('Episode.form.audio_file_hint') ?>"
'class' => 'form-input mb-4', type="file"
'required' => 'required', accept=".mp3,.m4a"
'type' => 'file', required="true" />
'accept' => '.mp3,.m4a',
]) ?>
<Forms.Label for="image" hint="<?= lang('Episode.form.image_hint') ?>" isOptional="true"><?= lang('Episode.form.image') ?></Forms.Label> <Forms.Field
<?= form_input([ name="image"
'id' => 'image', label="<?= lang('Episode.form.image') ?>"
'name' => 'image', hintText="<?= lang('Episode.form.image_hint') ?>"
'class' => 'form-input', helperText="<?= lang('Common.forms.image_size_hint', ) ?>"
'type' => 'file', type="file"
'accept' => '.jpg,.jpeg,.png', accept=".jpg,.jpeg,.png" />
]) ?>
<small class="mb-4 text-gray-600"><?= lang(
'Common.forms.image_size_hint',
) ?></small>
<Forms.Label for="title" hint="<?= lang('Episode.form.title_hint') ?>"><?= lang('Episode.form.title') ?></Forms.Label> <Forms.Field
<?= form_input([ name="title"
'id' => 'title', label="<?= lang('Episode.form.title') ?>"
'name' => 'title', hintText="<?= lang('Episode.form.title_hint') ?>"
'class' => 'form-input mb-4', required="true"
'value' => old('title'), data-slugify="title" />
'required' => 'required',
'data-slugify' => 'title',
]) ?>
<Forms.Label for="slug"><?= lang('Episode.form.permalink') ?></Forms.Label> <div>
<permalink-edit class="inline-flex items-center mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>"> <Forms.Label for="slug"><?= lang('Episode.form.permalink') ?></Forms.Label>
<permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain"><?= base_url('/@' . $podcast->handle . '/episodes') . '/' ?></span> <span slot="domain"><?= base_url('/@' . $podcast->handle . '/episodes') . '/' ?></span>
<?= form_input([ <Forms.Input name="slug" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" />
'id' => 'slug', </permalink-edit>
'name' => 'slug',
'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug'),
'required' => 'required',
'data-slugify' => 'slug',
'slot' => 'slug-input',
]) ?>
</permalink-edit>
<div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-1">
<Forms.Label for="season_number"><?= lang('Episode.form.season_number') ?></Forms.Label>
<?= form_input([
'id' => 'season_number',
'name' => 'season_number',
'class' => 'form-input w-full',
'value' => old('season_number'),
'type' => 'number',
]) ?>
</div>
<div class="flex flex-col flex-1">
<Forms.Label for="episode_number"><?= lang('Episode.form.episode_number') ?></Forms.Label>
<?= form_input([
'id' => 'episode_number',
'name' => 'episode_number',
'class' => 'form-input w-full',
'value' => old('episode_number'),
'type' => 'number',
]) ?>
</div>
</div> </div>
<div class="flex flex-col gap-x-2 gap-y-4 md:flex-row">
<Forms.Field
class="flex-1 w-0"
name="season_number"
label="<?= lang('Episode.form.season_number') ?>"
type="number"
/>
<Forms.Field
class="flex-1 w-0"
name="episode_number"
label="<?= lang('Episode.form.episode_number') ?>"
type="number"
/>
</div>
<?= form_fieldset('', [ <fieldset class="flex gap-1">
'class' => 'mb-4', <legend>
]) ?>
<legend>
<?= lang('Episode.form.type.label') . <?= lang('Episode.form.type.label') .
hint_tooltip(lang('Episode.form.type.hint'), 'ml-1') ?> hint_tooltip(lang('Episode.form.type.hint'), 'ml-1') ?>
</legend> </legend>
<?= form_radio( <Forms.RadioButton
[ value="full"
'id' => 'full', name="type"
'name' => 'type', isChecked="true" ><?= lang('Episode.form.type.full') ?></Forms.RadioButton>
'class' => 'form-radio-btn', <Forms.RadioButton
], value="trailer"
'full', name="type"
old('type') ? old('type') === 'full' : true, isChecked="false" ><?= lang('Episode.form.type.trailer') ?></Forms.RadioButton>
) ?> <Forms.RadioButton
<label for="full" class="inline-flex items-center"> value="bonus"
<?= lang('Episode.form.type.full') ?> name="type"
</label> isChecked="false" ><?= lang('Episode.form.type.bonus') ?></Forms.RadioButton>
<?= form_radio( </fieldset>
[
'id' => 'trailer',
'name' => 'type',
'class' => 'form-radio-btn',
],
'trailer',
old('type') && old('type') === 'trailer',
) ?>
<label for="trailer" class="inline-flex items-center">
<?= lang('Episode.form.type.trailer') ?>
</label>
<?= form_radio(
[
'id' => 'bonus',
'name' => 'type',
'class' => 'form-radio-btn',
],
'bonus',
old('type') && old('type') === 'bonus',
) ?>
<label for="bonus" class="inline-flex items-center">
<?= lang('Episode.form.type.bonus') ?>
</label>
<?= form_fieldset_close() ?>
<?= form_fieldset('', [ <fieldset class="flex gap-1">
'class' => 'flex mb-6 gap-1', <legend>
]) ?>
<legend>
<?= lang('Episode.form.parental_advisory.label') . <?= lang('Episode.form.parental_advisory.label') .
hint_tooltip(lang('Episode.form.parental_advisory.hint'), 'ml-1') ?> hint_tooltip(lang('Episode.form.parental_advisory.hint'), 'ml-1') ?>
</legend> </legend>
<?= form_radio( <Forms.RadioButton
[ value="undefined"
'id' => 'undefined', name="parental_advisory"
'name' => 'parental_advisory', isChecked="true" ><?= lang('Episode.form.parental_advisory.undefined') ?></Forms.RadioButton>
'class' => 'form-radio-btn', <Forms.RadioButton
], value="clean"
'undefined', name="parental_advisory"
old('parental_advisory') isChecked="false" ><?= lang('Episode.form.parental_advisory.clean') ?></Forms.RadioButton>
? old('parental_advisory') === 'undefined' <Forms.RadioButton
: true, value="explicit"
) ?> name="parental_advisory"
<label for="undefined"><?= lang( isChecked="false" ><?= lang('Episode.form.parental_advisory.explicit') ?></Forms.RadioButton>
'Episode.form.parental_advisory.undefined', </fieldset>
) ?></label>
<?= form_radio(
[
'id' => 'clean',
'name' => 'parental_advisory',
'class' => 'form-radio-btn',
],
'clean',
old('parental_advisory') && old('parental_advisory') === 'clean',
) ?>
<label for="clean"><?= lang(
'Episode.form.parental_advisory.clean',
) ?></label>
<?= form_radio(
[
'id' => 'explicit',
'name' => 'parental_advisory',
'class' => 'form-radio-btn',
],
'explicit',
old('parental_advisory') && old('parental_advisory') === 'explicit',
) ?>
<label for="explicit"><?= lang(
'Episode.form.parental_advisory.explicit',
) ?></label>
<?= form_fieldset_close() ?>
<?= form_section_close() ?> </Forms.Section>
<?= form_section( <Forms.Section
lang('Episode.form.show_notes_section_title'), title="<?= lang('Episode.form.show_notes_section_title') ?>"
lang('Episode.form.show_notes_section_subtitle'), subtitle="<?= lang('Episode.form.show_notes_section_subtitle') ?>">
) ?>
<div class="mb-4"> <Forms.Field
<Forms.Label for="description"><?= lang('Episode.form.description') ?></Forms.Label> as="MarkdownEditor"
<Forms.MarkdownEditor id="description" name="description" required="required"><?= old('description', '', false) ?></Forms.MarkdownEditor> name="description"
</div> label="<?= lang('Episode.form.description') ?>"
required="true" />
<div class="mb-4"> <Forms.Field
<Forms.Label for="description_footer" hint="<?= lang('Episode.form.description_footer_hint') ?>" isOptional="true"><?= lang('Episode.form.description_footer') ?></Forms.Label> as="MarkdownEditor"
<Forms.MarkdownEditor id="description_footer" name="description_footer" rows="6"><?= old('description_footer', $podcast->episode_description_footer_markdown ?? '', false) ?></Forms.MarkdownEditor> name="description_footer"
</div> label="<?= lang('Episode.form.description_footer') ?>"
hintText="<?= lang('Episode.form.description_footer_hint') ?>" />
<?= form_section_close() ?> </Forms.Section>
<?= form_section( <Forms.Section
lang('Episode.form.location_section_title'), title="<?= lang('Episode.form.location_section_title') ?>"
lang('Episode.form.location_section_subtitle'), subtitle="<?= lang('Episode.form.location_section_subtitle') ?>"
) ?> >
<Forms.Field
name="location_name"
label="<?= lang('Episode.form.location_name') ?>"
hint="<?= lang('Episode.form.location_name_hint') ?>" />
</Forms.Section>
<Forms.Label for="location_name" hint="<?= lang('Episode.form.location_name_hint') ?>" isOptional="true"><?= lang('Episode.form.location_name') ?></Forms.Label> <Forms.Section
<?= form_input([ title="<?= lang('Episode.form.additional_files_section_title') ?>">
'id' => 'location_name',
'name' => 'location_name',
'class' => 'form-input mb-4',
'value' => old('location_name'),
]) ?>
<?= form_section_close() ?>
<?= form_section( <fieldset class="flex flex-col">
lang('Episode.form.additional_files_section_title'), <legend><?= lang('Episode.form.transcript') .
lang('Episode.form.additional_files_section_subtitle'),
) ?>
<?= form_fieldset('', [
'class' => 'flex flex-col mb-4',
]) ?>
<legend><?= lang('Episode.form.transcript') .
'<small class="ml-1 lowercase">(' . '<small class="ml-1 lowercase">(' .
lang('Common.optional') . lang('Common.optional') .
')</small>' . ')</small>' .
hint_tooltip(lang('Episode.form.transcript_hint'), 'ml-1') ?></legend> hint_tooltip(lang('Episode.form.transcript_hint'), 'ml-1') ?></legend>
<div class="mb-4 form-input-tabs"> <div class="form-input-tabs">
<input type="radio" name="transcript-choice" id="transcript-file-upload-choice" aria-controls="transcript-file-upload-choice" value="upload-file" <?= old( <input type="radio" name="transcript-choice" id="transcript-file-upload-choice" aria-controls="transcript-file-upload-choice" value="upload-file" <?= old('transcript-choice') !== 'remote-file' ? 'checked' : '' ?> />
'transcript-choice', <label for="transcript-file-upload-choice"><?= lang('Common.forms.upload_file') ?></label>
) !== 'remote-url'
? 'checked'
: '' ?> />
<label for="transcript-file-upload-choice"><?= lang(
'Common.forms.upload_file',
) ?></label>
<input type="radio" name="transcript-choice" id="transcript-file-remote-url-choice" aria-controls="transcript-file-remote-url-choice" value="remote-url" <?= old( <input type="radio" name="transcript-choice" id="transcript-file-remote-url-choice" aria-controls="transcript-file-remote-url-choice" value="remote-url" <?= old('transcript-choice') === 'remote-file' ? 'checked' : '' ?> />
'transcript-choice', <label for="transcript-file-remote-url-choice"><?= lang('Common.forms.remote_url') ?></label>
) === 'remote-url'
? 'checked'
: '' ?> />
<label for="transcript-file-remote-url-choice"><?= lang(
'Common.forms.remote_url',
) ?></label>
<div class="py-2 tab-panels"> <div class="py-2 tab-panels">
<section id="transcript-file-upload" class="flex items-center tab-panel"> <section id="transcript-file-upload" class="flex items-center tab-panel">
<Forms.Label class="sr-only" for="transcript_file" isOptional="true"><?= lang('Episode.form.transcript_file') ?></Forms.Label> <Forms.Label class="sr-only" for="transcript_file" isOptional="true"><?= lang('Episode.form.transcript_file') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" name="transcript_file" type="file" accept=".txt,.html,.srt,.json" />
'id' => 'transcript_file',
'name' => 'transcript_file',
'class' => 'form-input',
'type' => 'file',
'accept' => '.txt,.html,.srt,.json',
]) ?>
</section> </section>
<section id="transcript-file-remote-url" class="tab-panel"> <section id="transcript-file-remote-url" class="tab-panel">
<Forms.Label class="sr-only" for="transcript_file_remote_url" isOptional="true"><?= lang('Episode.form.transcript_file_remote_url') ?></Forms.Label> <Forms.Label class="sr-only" for="transcript_file_remote_url" isOptional="true"><?= lang('Episode.form.transcript_file_remote_url') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" placeholder="https://…" name="transcript_file_remote_url" />
'id' => 'transcript_file_remote_url',
'name' => 'transcript_file_remote_url',
'class' => 'form-input w-full',
'type' => 'url',
'placeholder' => 'https://...',
'value' => old('transcript_file_remote_url'),
]) ?>
</section> </section>
</div> </div>
</div> </div>
<?= form_fieldset_close() ?> </fieldset>
<?= form_fieldset('', [
'class' => 'flex flex-col mb-4', <fieldset class="flex flex-col">
]) ?> <legend><?= lang('Episode.form.chapters') .
<legend><?= lang('Episode.form.chapters') .
'<small class="ml-1 lowercase">(' . '<small class="ml-1 lowercase">(' .
lang('Common.optional') . lang('Common.optional') .
')</small>' . ')</small>' .
hint_tooltip(lang('Episode.form.chapters_hint'), 'ml-1') ?></legend> hint_tooltip(lang('Episode.form.chapters_hint'), 'ml-1') ?></legend>
<div class="mb-4 form-input-tabs"> <div class="form-input-tabs">
<input type="radio" name="chapters-choice" id="chapters-file-upload-choice" aria-controls="chapters-file-upload-choice" value="upload-file" <?= old( <input type="radio" name="chapters-choice" id="chapters-file-upload-choice" aria-controls="chapters-file-upload-choice" value="upload-file" <?= old('chapters-choice') !== 'remote-file' ? 'checked' : '' ?> />
'chapters-choice', <label for="chapters-file-upload-choice"><?= lang('Common.forms.upload_file') ?></label>
) !== 'remote-url'
? 'checked'
: '' ?> />
<label for="chapters-file-upload-choice"><?= lang(
'Common.forms.upload_file',
) ?></label>
<input type="radio" name="chapters-choice" id="chapters-file-remote-url-choice" aria-controls="chapters-file-remote-url-choice" value="remote-url" <?= old( <input type="radio" name="chapters-choice" id="chapters-file-remote-url-choice" aria-controls="chapters-file-remote-url-choice" value="remote-url" <?= old('chapters-choice') === 'remote-file' ? 'checked' : '' ?> />
'chapters-choice', <label for="chapters-file-remote-url-choice"><?= lang('Common.forms.remote_url') ?></label>
) === 'remote-url'
? 'checked'
: '' ?> />
<label for="chapters-file-remote-url-choice"><?= lang(
'Common.forms.remote_url',
) ?></label>
<div class="py-2 tab-panels"> <div class="py-2 tab-panels">
<section id="chapters-file-upload" class="flex items-center tab-panel"> <section id="chapters-file-upload" class="flex items-center tab-panel">
<Forms.Label class="sr-only" for="chapters_file" isOptional="true"><?= lang('Episode.form.chapters_file') ?></Forms.Label> <Forms.Label class="sr-only" for="chapters_file" isOptional="true"><?= lang('Episode.form.chapters_file') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" name="chapters_file" type="file" accept=".json" />
'id' => 'chapters_file',
'name' => 'chapters_file',
'class' => 'form-input',
'type' => 'file',
'accept' => '.json',
]) ?>
</section> </section>
<section id="chapters-file-remote-url" class="tab-panel"> <section id="chapters-file-remote-url" class="tab-panel">
<Forms.Label class="sr-only" for="chapters_file_remote_url" isOptional="true"><?= lang('Episode.form.chapters_file_remote_url') ?></Forms.Label> <Forms.Label class="sr-only" for="chapters_file_remote_url" isOptional="true"><?= lang('Episode.form.chapters_file_remote_url') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" placeholder="https://…" name="chapters_file_remote_url" />
'id' => 'chapters_file_remote_url',
'name' => 'chapters_file_remote_url',
'class' => 'form-input w-full',
'type' => 'url',
'placeholder' => 'https://...',
'value' => old('chapters_file_remote_url'),
]) ?>
</section> </section>
</div> </div>
</div> </div>
<?= form_fieldset_close() ?> </fieldset>
</Forms.Section>
<?= form_section_close() ?> <Forms.Section
title="<?= lang('Episode.form.advanced_section_title') ?>"
subtitle="<?= lang('Episode.form.advanced_section_subtitle') ?>"
>
<Forms.Field
as="XMLEditor"
name="custom_rss"
label="<?= lang('Episode.form.custom_rss') ?>"
hint="<?= lang('Episode.form.custom_rss_hint') ?>"
/>
<?= form_section( </Forms.Section>
lang('Episode.form.advanced_section_title'),
lang('Episode.form.advanced_section_subtitle'),
) ?>
<Forms.Label for="custom_rss" hint="<?= lang('Episode.form.custom_rss_hint') ?>" isOptional="true"><?= lang('Episode.form.custom_rss') ?></Forms.Label>
<Forms.XMLEditor id="custom_rss" name="custom_rss"><?= old('custom_rss', '', false) ?></Forms.XMLEditor>
<?= form_section_close() ?> <Forms.Toggler name="block" value="yes" checked="false" hint="<?= lang('Episode.form.block_hint') ?>"><?= lang('Episode.form.block') ?></Forms.Toggler>
<Forms.Toggler id="block" name="block" value="yes" checked="<?= old('block', false) ?>" hint="<?= lang('Episode.form.block_hint') ?>"><?= lang('Episode.form.block') ?></Forms.Toggler> <Button class="self-end" variant="primary" type="submit"><?= lang('Episode.form.submit_create') ?></Button>
<?= button(
lang('Episode.form.submit_create'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
</form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -8,262 +8,156 @@
<?= lang('Episode.edit') ?> <?= lang('Episode.edit') ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?>
<Button variant="primary" type="submit" form="episode-edit-form"><?= lang('Episode.form.submit_edit') ?></Button>
<?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart(route_to('episode-edit', $podcast->id, $episode->id), [ <Alert variant="danger" glyph="alert"><?= lang('Episode.form.warning') ?></Alert>
'method' => 'post',
'class' => 'flex flex-col', <form id="episode-edit-form" action="<?= route_to('episode-edit', $podcast->id, $episode->id) ?>" method="POST" enctype="multipart/form-data" class="flex flex-col mt-6 gap-y-8">
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<div class="inline-flex w-full p-2 mb-4 text-sm font-semibold text-yellow-800 bg-red-100 border border-red-300 rounded" role="alert">
<?= icon('alert', 'mr-2 text-lg flex-shrink-0') .
lang('Episode.form.warning') ?>
</div>
<?= form_section( <Forms.Section title="<?= lang('Episode.form.info_section_title') ?>" >
lang('Episode.form.info_section_title'),
'<img
src="' .
$episode->image->medium_url .
'"
alt="' .
$episode->title .
'"
class="w-48"
/>',
) ?>
<Forms.Label for="audio_file" hint="<?= lang('Episode.form.audio_file_hint') ?>"><?= lang('Episode.form.audio_file') ?></Forms.Label> <Forms.Field
<?= form_input([ name="audio_file"
'id' => 'audio_file', label="<?= lang('Episode.form.audio_file') ?>"
'name' => 'audio_file', hintText="<?= lang('Episode.form.audio_file_hint') ?>"
'class' => 'form-input mb-4', type="file"
'type' => 'file', accept=".mp3,.m4a" />
'accept' => '.mp3,.m4a',
]) ?>
<Forms.Label for="image" hint="<?= lang('Episode.form.image_hint') ?>" isOptional="true"><?= lang('Episode.form.image') ?></Forms.Label> <Forms.Field
<?= form_input([ name="image"
'id' => 'image', label="<?= lang('Episode.form.image') ?>"
'name' => 'image', hintText="<?= lang('Episode.form.image_hint') ?>"
'class' => 'form-input', helperText="<?= lang('Common.forms.image_size_hint', ) ?>"
'type' => 'file', type="file"
'accept' => '.jpg,.jpeg,.png', accept=".jpg,.jpeg,.png" />
]) ?>
<small class="mb-4 text-gray-600"><?= lang(
'Common.forms.image_size_hint',
) ?></small>
<Forms.Label for="title" hint="<?= lang('Episode.form.title_hint') ?>"><?= lang('Episode.form.title') ?></Forms.Label> <Forms.Field
<?= form_input([ name="title"
'id' => 'title', label="<?= lang('Episode.form.title') ?>"
'name' => 'title', hintText="<?= lang('Episode.form.title_hint') ?>"
'class' => 'form-input mb-4', value="<?= $episode->title ?>"
'value' => old('title', $episode->title), required="true"
'required' => 'required', data-slugify="title" />
'data-slugify' => 'title',
]) ?>
<Forms.Label for="slug"><?= lang('Episode.form.permalink') ?></Forms.Label> <div>
<permalink-edit class="inline-flex items-center mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>"> <Forms.Label for="slug"><?= lang('Episode.form.permalink') ?></Forms.Label>
<permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain"><?= base_url('/@' . $podcast->handle . '/episodes') . '/' ?></span> <span slot="domain"><?= base_url('/@' . $podcast->handle . '/episodes') . '/' ?></span>
<?= form_input([ <Forms.Input name="slug" value="<?= $episode->slug ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" />
'id' => 'slug', </permalink-edit>
'name' => 'slug',
'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug', $episode->slug),
'required' => 'required',
'data-slugify' => 'slug',
'slot' => 'slug-input',
]) ?>
</permalink-edit>
<div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-1">
<Forms.Label for="season_number"><?= lang('Episode.form.season_number') ?></Forms.Label>
<?= form_input([
'id' => 'season_number',
'name' => 'season_number',
'class' => 'form-input w-full',
'value' => old('season_number', $episode->season_number),
'type' => 'number',
]) ?>
</div>
<div class="flex flex-col flex-1">
<Forms.Label for="episode_number"><?= lang('Episode.form.episode_number') ?></Forms.Label>
<?= form_input([
'id' => 'episode_number',
'name' => 'episode_number',
'class' => 'form-input w-full',
'value' => old('episode_number', $episode->number),
'type' => 'number',
]) ?>
</div>
</div> </div>
<?= form_fieldset('', [ <div class="flex flex-col gap-x-2 gap-y-4 md:flex-row">
'class' => 'flex mb-4 gap-1', <Forms.Field
]) ?> class="flex-1 w-0"
name="season_number"
label="<?= lang('Episode.form.season_number') ?>"
type="number"
value="<?= $episode->season_number ?>"
/>
<Forms.Field
class="flex-1 w-0"
name="episode_number"
label="<?= lang('Episode.form.episode_number') ?>"
type="number"
value="<?= $episode->number ?>"
/>
</div>
<fieldset class="flex gap-1">
<legend> <legend>
<?= lang('Episode.form.type.label') . <?= lang('Episode.form.type.label') .
hint_tooltip(lang('Episode.form.type.hint'), 'ml-1') ?> hint_tooltip(lang('Episode.form.type.hint'), 'ml-1') ?>
</legend> </legend>
<?= form_radio( <Forms.RadioButton
[ value="full"
'id' => 'full', name="type"
'name' => 'type', isChecked="<?= $episode->type === 'full' ? 'true' : 'false' ?>" ><?= lang('Episode.form.type.full') ?></Forms.RadioButton>
'class' => 'form-radio-btn', <Forms.RadioButton
], value="trailer"
'full', name="type"
old('type') ? old('type') === 'full' : $episode->type === 'full', isChecked="<?= $episode->type === 'trailer' ? 'true' : 'false' ?>" ><?= lang('Episode.form.type.trailer') ?></Forms.RadioButton>
) ?> <Forms.RadioButton
<label for="full" class="inline-flex items-center"> value="bonus"
<?= lang('Episode.form.type.full') ?> name="type"
</label> isChecked="<?= $episode->type === 'bonus' ? 'true' : 'false' ?>" ><?= lang('Episode.form.type.bonus') ?></Forms.RadioButton>
<?= form_radio( </fieldset>
[
'id' => 'trailer',
'name' => 'type',
'class' => 'form-radio-btn',
],
'trailer',
old('type') ? old('type') === 'trailer' : $episode->type === 'trailer',
) ?>
<label for="trailer" class="inline-flex items-center">
<?= lang('Episode.form.type.trailer') ?>
</label>
<?= form_radio(
[
'id' => 'bonus',
'name' => 'type',
'class' => 'form-radio-btn',
],
'bonus',
old('type') ? old('type') === 'bonus' : $episode->type === 'bonus',
) ?>
<label for="bonus" class="inline-flex items-center">
<?= lang('Episode.form.type.bonus') ?>
</label>
<?= form_fieldset_close() ?>
<?= form_fieldset('', [ <fieldset class="flex gap-1">
'class' => 'mb-6',
]) ?>
<legend> <legend>
<?= lang('Episode.form.parental_advisory.label') . <?= lang('Episode.form.parental_advisory.label') .
hint_tooltip(lang('Episode.form.parental_advisory.hint'), 'ml-1') ?> hint_tooltip(lang('Episode.form.parental_advisory.hint'), 'ml-1') ?>
</legend> </legend>
<?= form_radio( <Forms.RadioButton
[ value="undefined"
'id' => 'undefined', name="parental_advisory"
'name' => 'parental_advisory', isChecked="<?= $episode->parental_advisory === null ? 'true' : 'false' ?>" ><?= lang('Episode.form.parental_advisory.undefined') ?></Forms.RadioButton>
'class' => 'form-radio-btn', <Forms.RadioButton
], value="clean"
'undefined', name="parental_advisory"
old('parental_advisory') isChecked="<?= $episode->parental_advisory === 'clean' ? 'true' : 'false' ?>" ><?= lang('Episode.form.parental_advisory.clean') ?></Forms.RadioButton>
? old('parental_advisory') === 'undefined' <Forms.RadioButton
: $episode->parental_advisory === null, value="explicit"
) ?> name="parental_advisory"
<label for="undefined"><?= lang( isChecked="<?= $episode->parental_advisory === 'explicit' ? 'true' : 'false' ?>" ><?= lang('Episode.form.parental_advisory.explicit') ?></Forms.RadioButton>
'Episode.form.parental_advisory.undefined', </fieldset>
) ?></label>
<?= form_radio(
[
'id' => 'clean',
'name' => 'parental_advisory',
'class' => 'form-radio-btn',
],
'clean',
old('parental_advisory')
? old('parental_advisory') === 'clean'
: $episode->parental_advisory === 'clean',
) ?>
<label for="clean"><?= lang(
'Episode.form.parental_advisory.clean',
) ?></label>
<?= form_radio(
[
'id' => 'explicit',
'name' => 'parental_advisory',
'class' => 'form-radio-btn',
],
'explicit',
old('parental_advisory')
? old('parental_advisory') === 'explicit'
: $episode->parental_advisory === 'explicit',
) ?>
<label for="explicit"><?= lang(
'Episode.form.parental_advisory.explicit',
) ?></label>
<?= form_fieldset_close() ?>
<?= form_section_close() ?> </Forms.Section>
<?= form_section( <Forms.Section
lang('Episode.form.show_notes_section_title'), title="<?= lang('Episode.form.show_notes_section_title') ?>"
lang('Episode.form.show_notes_section_subtitle'), subtitle="<?= lang('Episode.form.show_notes_section_subtitle') ?>">
) ?>
<div class="mb-4"> <Forms.Field
<Forms.Label for="description"><?= lang('Episode.form.description') ?></Forms.Label> as="MarkdownEditor"
<Forms.MarkdownEditor id="description" name="description" required="required"><?= old('description', $episode->description_markdown, false) ?></Forms.MarkdownEditor> name="description"
</div> label="<?= lang('Episode.form.description') ?>"
value="<?= $episode->description_markdown ?>"
required="true" />
<div class="mb-4"> <Forms.Field
<Forms.Label for="description_footer" hint="<?= lang('Episode.form.description_footer_hint') ?>" isOptional="true"><?= lang('Episode.form.description_footer') ?></Forms.Label> as="MarkdownEditor"
<Forms.MarkdownEditor id="description_footer" name="description_footer" rows="6"><?= old('description_footer', $podcast->episode_description_footer_markdown ?? '', false) ?></Forms.MarkdownEditor> name="description_footer"
</div> label="<?= lang('Episode.form.description_footer') ?>"
hintText="<?= lang('Episode.form.description_footer_hint') ?>"
value="<?= $podcast->episode_description_footer_markdown ?? '' ?>" />
<?= form_section_close() ?> </Forms.Section>
<?= form_section( <Forms.Section
lang('Episode.form.location_section_title'), title="<?= lang('Episode.form.location_section_title') ?>"
lang('Episode.form.location_section_subtitle'), subtitle="<?= lang('Episode.form.location_section_subtitle') ?>"
) ?> >
<Forms.Field
name="location_name"
label="<?= lang('Episode.form.location_name') ?>"
hint="<?= lang('Episode.form.location_name_hint') ?>"
value="<?= $episode->location_name ?>" />
</Forms.Section>
<Forms.Label for="location_name" hint="<?= lang('Episode.form.location_name_hint') ?>" isOptional="true"><?= lang('Episode.form.location_name') ?></Forms.Label> <Forms.Section
<?= form_input([ title="<?= lang('Episode.form.additional_files_section_title') ?>">
'id' => 'location_name',
'name' => 'location_name',
'class' => 'form-input mb-4',
'value' => old('location_name', $episode->location_name),
]) ?>
<?= form_section_close() ?>
<fieldset class="flex flex-col">
<?= form_section(
lang('Episode.form.additional_files_section_title'),
lang('Episode.form.additional_files_section_subtitle', [
'podcastNamespaceLink' =>
'“<a href="https://github.com/Podcastindex-org/podcast-namespace" target="_blank" rel="noreferrer noopener" style="text-decoration: underline;">podcast namespace</a>”',
]),
) ?>
<?= form_fieldset('', [
'class' => 'flex flex-col mb-4',
]) ?>
<legend><?= lang('Episode.form.transcript') . <legend><?= lang('Episode.form.transcript') .
'<small class="ml-1 lowercase">(' . '<small class="ml-1 lowercase">(' .
lang('Common.optional') . lang('Common.optional') .
')</small>' . ')</small>' .
hint_tooltip(lang('Episode.form.transcript_hint'), 'ml-1') ?></legend> hint_tooltip(lang('Episode.form.transcript_hint'), 'ml-1') ?></legend>
<div class="mb-4 form-input-tabs"> <div class="form-input-tabs">
<input type="radio" name="transcript-choice" id="transcript-file-upload-choice" aria-controls="transcript-file-upload-choice" value="upload-file" <?= $episode->transcript_file_remote_url <input type="radio" name="transcript-choice" id="transcript-file-upload-choice" aria-controls="transcript-file-upload-choice" value="upload-file" <?= $episode->transcript_file_remote_url ? '' : 'checked' ?> />
? '' <label for="transcript-file-upload-choice"><?= lang('Common.forms.upload_file') ?></label>
: 'checked' ?> />
<label for="transcript-file-upload-choice"><?= lang(
'Common.forms.upload_file',
) ?></label>
<input type="radio" name="transcript-choice" id="transcript-file-remote-url-choice" aria-controls="transcript-file-remote-url-choice" value="remote-url" <?= $episode->transcript_file_remote_url <input type="radio" name="transcript-choice" id="transcript-file-remote-url-choice" aria-controls="transcript-file-remote-url-choice" value="remote-url" <?= $episode->transcript_file_remote_url ? 'checked' : '' ?> />
? 'checked' <label for="transcript-file-remote-url-choice"><?= lang('Common.forms.remote_url') ?></label>
: '' ?> />
<label for="transcript-file-remote-url-choice"><?= lang(
'Common.forms.remote_url',
) ?></label>
<div class="py-2 tab-panels"> <div class="py-2 tab-panels">
<section id="transcript-file-upload" class="flex items-center tab-panel"> <section id="transcript-file-upload" class="flex items-center tab-panel">
@ -299,54 +193,29 @@
</div> </div>
<?php endif; ?> <?php endif; ?>
<Forms.Label class="sr-only" for="transcript_file" isOptional="true"><?= lang('Episode.form.transcript_file') ?></Forms.Label> <Forms.Label class="sr-only" for="transcript_file" isOptional="true"><?= lang('Episode.form.transcript_file') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" name="transcript_file" type="file" accept=".txt,.html,.srt,.json" />
'id' => 'transcript_file',
'name' => 'transcript_file',
'class' => 'form-input',
'type' => 'file',
'accept' => '.txt,.html,.srt,.json',
]) ?>
</section> </section>
<section id="transcript-file-remote-url" class="tab-panel"> <section id="transcript-file-remote-url" class="tab-panel">
<Forms.Label class="sr-only" for="transcript_file_remote_url" isOptional="true"><?= lang('Episode.form.transcript_file_remote_url') ?></Forms.Label> <Forms.Label class="sr-only" for="transcript_file_remote_url" isOptional="true"><?= lang('Episode.form.transcript_file_remote_url') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" placeholder="https://…" name="transcript_file_remote_url" value="<?= $episode->transcript_file_remote_url ?>" />
'id' => 'transcript_file_remote_url',
'name' => 'transcript_file_remote_url',
'class' => 'form-input w-full',
'type' => 'url',
'placeholder' => 'https://...',
'value' => old(
'transcript_file_remote_url',
$episode->transcript_file_remote_url,
),
]) ?>
</section> </section>
</div> </div>
</div> </div>
<?= form_fieldset_close() ?> </fieldset>
<?= form_fieldset('', [
'class' => 'flex flex-col mb-4', <fieldset class="flex flex-col">
]) ?>
<legend><?= lang('Episode.form.chapters') . <legend><?= lang('Episode.form.chapters') .
'<small class="ml-1 lowercase">(' . '<small class="ml-1 lowercase">(' .
lang('Common.optional') . lang('Common.optional') .
')</small>' . ')</small>' .
hint_tooltip(lang('Episode.form.chapters_hint'), 'ml-1') ?></legend> hint_tooltip(lang('Episode.form.chapters_hint'), 'ml-1') ?></legend>
<div class="mb-4 form-input-tabs"> <div class="form-input-tabs">
<input type="radio" name="chapters-choice" id="chapters-file-upload-choice" aria-controls="chapters-file-upload-choice" value="upload-file" <?= $episode->chapters_file_remote_url <input type="radio" name="chapters-choice" id="chapters-file-upload-choice" aria-controls="chapters-file-upload-choice" value="upload-file" <?= $episode->chapters_file_remote_url ? '' : 'checked' ?> />
? '' <label for="chapters-file-upload-choice"><?= lang('Common.forms.upload_file') ?></label>
: 'checked' ?> />
<label for="chapters-file-upload-choice"><?= lang(
'Common.forms.upload_file',
) ?></label>
<input type="radio" name="chapters-choice" id="chapters-file-remote-url-choice" aria-controls="chapters-file-remote-url-choice" value="remote-url" <?= $episode->chapters_file_remote_url <input type="radio" name="chapters-choice" id="chapters-file-remote-url-choice" aria-controls="chapters-file-remote-url-choice" value="remote-url" <?= $episode->chapters_file_remote_url ? 'checked' : '' ?> />
? 'checked' <label for="chapters-file-remote-url-choice"><?= lang('Common.forms.remote_url') ?></label>
: '' ?> />
<label for="chapters-file-remote-url-choice"><?= lang(
'Common.forms.remote_url',
) ?></label>
<div class="py-2 tab-panels"> <div class="py-2 tab-panels">
<section id="chapters-file-upload" class="flex items-center tab-panel"> <section id="chapters-file-upload" class="flex items-center tab-panel">
@ -381,69 +250,36 @@
</div> </div>
<?php endif; ?> <?php endif; ?>
<Forms.Label class="sr-only" for="chapters_file" isOptional="true"><?= lang('Episode.form.chapters_file') ?></Forms.Label> <Forms.Label class="sr-only" for="chapters_file" isOptional="true"><?= lang('Episode.form.chapters_file') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" name="chapters_file" type="file" accept=".json" />
'id' => 'chapters_file',
'name' => 'chapters_file',
'class' => 'form-input',
'type' => 'file',
'accept' => '.json',
]) ?>
</section> </section>
<section id="chapters-file-remote-url" class="tab-panel"> <section id="chapters-file-remote-url" class="tab-panel">
<Forms.Label class="sr-only" for="chapters_file_remote_url" isOptional="true"><?= lang('Episode.form.chapters_file_remote_url') ?></Forms.Label> <Forms.Label class="sr-only" for="chapters_file_remote_url" isOptional="true"><?= lang('Episode.form.chapters_file_remote_url') ?></Forms.Label>
<?= form_input([ <Forms.Input class="w-full" placeholder="https://…" name="chapters_file_remote_url" value="<?= $episode->chapters_file_remote_url ?>" />
'id' => 'chapters_file_remote_url',
'name' => 'chapters_file_remote_url',
'class' => 'form-input w-full',
'type' => 'url',
'placeholder' => 'https://...',
'value' => old(
'chapters_file_remote_url',
$episode->chapters_file_remote_url,
),
]) ?>
</section> </section>
</div> </div>
</div> </div>
<?= form_fieldset_close() ?> </fieldset>
</Forms.Section>
<?= form_section_close() ?> <Forms.Section
title="<?= lang('Episode.form.advanced_section_title') ?>"
subtitle="<?= lang('Episode.form.advanced_section_subtitle') ?>"
>
<Forms.Field
as="XMLEditor"
name="custom_rss"
label="<?= lang('Episode.form.custom_rss') ?>"
hint="<?= lang('Episode.form.custom_rss_hint') ?>"
value="<?= $episode->custom_rss_string ?>"
/>
<?= form_section( </Forms.Section>
lang('Episode.form.advanced_section_title'),
lang('Episode.form.advanced_section_subtitle'),
) ?>
<Forms.Label for="custom_rss" hint="<?= lang('Episode.form.custom_rss_hint') ?>" isOptional="true"><?= lang('Episode.form.custom_rss') ?></Forms.Label>
<Forms.XMLEditor id="custom_rss" name="custom_rss"><?= old('custom_rss', $episode->custom_rss_string, false) ?></Forms.XMLEditor>
<?= form_section_close() ?> <Forms.Toggler id="block" name="block" value="yes" checked="<?= $episode->is_blocked ? 'true' : 'false' ?>" hint="<?= lang('Episode.form.block_hint') ?>"><?= lang('Episode.form.block') ?></Forms.Toggler>
<Forms.Toggler id="block" name="block" value="yes" checked="<?= old('block', $episode->is_blocked) ?>" hint="<?= lang('Episode.form.block_hint') ?>"><?= lang('Episode.form.block') ?></Forms.Toggler> </form>
<div class="flex items-center justify-between"> <Button class="mt-8" variant="danger" uri="<?= route_to('episode-delete', $podcast->id, $episode->id) ?>" iconLeft="delete-bin"><?= lang('Episode.delete') ?></Button>
<?= button(
lang('Episode.delete'),
route_to('episode-delete', $podcast->id, $episode->id),
[
'variant' => 'danger',
'iconLeft' => 'delete-bin',
],
) ?>
<?= button(
lang('Episode.form.submit_edit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
</div>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -12,7 +12,7 @@
<p><?= lang('Episode.embeddable_player.label') ?></p> <p><?= lang('Episode.embeddable_player.label') ?></p>
<div class="flex w-full mt-6 mb-6"> <div class="flex w-full mt-6">
<?php foreach ($themes as $themeKey => $theme): ?> <?php foreach ($themes as $themeKey => $theme): ?>
<button style="<?= $theme[ <button style="<?= $theme[
'style' 'style'
@ -24,52 +24,16 @@
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>
<iframe name="embeddable_player" id="embeddable_player" class="w-full max-w-xl h-36" frameborder="0" scrolling="no" style="width: 100%; overflow: hidden;" src="<?= $episode->embeddable_player_url ?>"></iframe> <iframe name="embeddable_player" id="embeddable_player" class="w-full max-w-xl mt-6 h-36" frameborder="0" scrolling="no" style="width: 100%; overflow: hidden;" src="<?= $episode->embeddable_player_url ?>"></iframe>
<div class="flex items-center w-full mt-8"> <div class="flex items-center mt-8 gap-x-2">
<?= form_textarea( <Forms.Textarea readonly="true" class="w-full max-w-xl" name="iframe" rows="2" value="<?= esc("<iframe width=\"100%\" height=\"280\" frameborder=\"0\" scrolling=\"no\" style=\"width: 100%; height: 280px; overflow: hidden;\" src=\"{$episode->embeddable_player_url}\"></iframe>") ?>" />
[ <IconButton glyph="file-copy" data-type="clipboard-copy" data-clipboard-target="iframe"><?= lang('Episode.embeddable_player.clipboard_iframe') ?></IconButton>
'id' => 'iframe',
'name' => 'iframe',
'class' => 'form-textarea w-full h-20 mr-2',
],
"<iframe width=\"100%\" height=\"280\" frameborder=\"0\" scrolling=\"no\" style=\"width: 100%; height: 280px; overflow: hidden;\" src=\"{$episode->embeddable_player_url}\"></iframe>",
) ?>
<?= icon_button(
'file-copy',
lang('Episode.embeddable_player.clipboard_iframe'),
'',
[
'variant' => 'default',
],
[
'data-type' => 'clipboard-copy',
'data-clipboard-target' => 'iframe',
],
) ?>
</div> </div>
<div class="flex items-center w-full mt-4"> <div class="flex items-center mt-4 gap-x-2">
<?= form_textarea( <Forms.Input readonly="true" class="w-full max-w-xl" name="url" value="<?= $episode->embeddable_player_url ?>" />
[ <IconButton glyph="file-copy" data-type="clipboard-copy" data-clipboard-target="url"><?= lang('Episode.embeddable_player.clipboard_url') ?></IconButton>
'id' => 'url',
'name' => 'url',
'class' => 'form-textarea w-full h-10 mr-2',
],
$episode->embeddable_player_url,
) ?>
<?= icon_button(
'file-copy',
lang('Episode.embeddable_player.clipboard_url'),
'',
[
'variant' => 'default',
],
[
'data-type' => 'clipboard-copy',
'data-clipboard-target' => 'url',
],
) ?>
</div> </div>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -9,38 +9,15 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button( <Button variant="primary" uri="<?= route_to('person-create') ?>" iconLeft="add"><?= lang('Person.create') ?></Button>
lang('Person.create'),
route_to('person-create'),
[
'variant' => 'primary',
'iconLeft' => 'add',
],
[
'class' => 'mr-2',
],
) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('episode-person-edit', $episode->id), [
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?>
<?= form_section(
lang('Person.episode_form.manage_section_title'),
lang('Person.episode_form.manage_section_subtitle'),
) ?>
<?= data_table( <?= data_table(
[ [
[ [
'header' => lang('Person.episode_form.person'), 'header' => lang('Person.episode_form.persons'),
'cell' => function ($person) { 'cell' => function ($person) {
return '<div class="flex">' . return '<div class="flex">' .
'<a href="' . '<a href="' .
@ -92,32 +69,40 @@
$episode->persons, $episode->persons,
) ?> ) ?>
<?= form_section_close() ?> <form action="<?= route_to('episode-person-edit', $episode->id) ?>" method="POST" class="mt-6">
<?= csrf_field() ?>
<Forms.Section
title="<?= lang('Person.episode_form.add_section_title') ?>"
subtitle="<?= lang('Person.episode_form.add_section_subtitle') ?>"
>
<?= form_section( <Forms.Field
lang('Person.episode_form.add_section_title'), as="MultiSelect"
lang('Person.episode_form.add_section_subtitle'), id="persons"
) ?> name="persons[]"
label="<?= lang('Person.episode_form.persons') ?>"
hintText="<?= lang('Person.episode_form.persons_hint') ?>"
options="<?= htmlspecialchars(json_encode($personOptions)) ?>"
selected="<?= htmlspecialchars(json_encode(old('persons', []))) ?>"
required="true"
/>
<Forms.Label for="persons" hint="<?= lang('Person.episode_form.persons_hint') ?>"><?= lang('Person.episode_form.persons') ?></Forms.Label> <Forms.Field
<Forms.MultiSelect id="persons" name="persons[]" class="mb-4" required="required" options="<?= htmlspecialchars(json_encode($personOptions)) ?>" selected="<?= htmlspecialchars(json_encode(old('persons', []))) ?>"/> as="MultiSelect"
id="roles"
name="roles[]"
label="<?= lang('Person.episode_form.roles') ?>"
hintText="<?= lang('Person.episode_form.roles_hint') ?>"
options="<?= htmlspecialchars(json_encode($taxonomyOptions)) ?>"
selected="<?= htmlspecialchars(json_encode(old('roles', []))) ?>"
required="true"
/>
<Forms.Label for="roles" hint="<?= lang('Person.episode_form.roles_hint') ?>" isOptional="true"><?= lang('Person.episode_form.roles') ?></Forms.Label> <Button variant="primary" type="submit" class="self-end"><?= lang('Person.episode_form.submit_add') ?></Button>
<Forms.MultiSelect id="roles" name="roles[]" class="mb-4" options="<?= htmlspecialchars(json_encode($taxonomyOptions)) ?>" selected="<?= htmlspecialchars(json_encode(old('roles', []))) ?>"/>
<?= form_section_close() ?> </Forms.Section>
<?= button(
lang('Person.episode_form.submit_add'), </form>
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -8,7 +8,6 @@
<?= lang('Episode.publish') ?> <?= lang('Episode.publish') ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= anchor( <?= anchor(
@ -19,14 +18,9 @@
], ],
) ?> ) ?>
<?= form_open(route_to('episode-publish', $podcast->id, $episode->id), [ <form action="<?= route_to('episode-publish', $podcast->id, $episode->id) ?>" method="POST" class="flex flex-col items-start max-w-xl mx-auto" data-submit="validate-message">
'method' => 'post',
'class' => 'mx-auto flex flex-col max-w-xl items-start',
'data-submit' => 'validate-message',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_hidden('client_timezone', 'UTC') ?> <input type="hidden" name="client_timezone" value="UTC" />
<label for="message" class="text-lg font-semibold"><?= lang( <label for="message" class="text-lg font-semibold"><?= lang(
'Episode.publish_form.post', 'Episode.publish_form.post',
@ -34,34 +28,22 @@
<small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.post_hint') ?></small> <small class="max-w-md mb-2 text-gray-600"><?= lang('Episode.publish_form.post_hint') ?></small>
<div class="mb-8 overflow-hidden bg-white shadow-md rounded-xl"> <div class="mb-8 overflow-hidden bg-white shadow-md rounded-xl">
<div class="flex px-4 py-3"> <div class="flex px-4 py-3">
<img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast <img src="<?= $podcast->actor->avatar_image_url ?>" alt="<?= $podcast->actor->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
->actor->display_name ?>" class="w-12 h-12 mr-4 rounded-full" /> <div class="flex flex-col min-w-0">
<p class="flex items-baseline min-w-0"> <p class="flex items-baseline min-w-0">
<span class="mr-2 font-semibold truncate"><?= $podcast->actor <span class="mr-2 font-semibold truncate"><?= $podcast->actor->display_name ?></span>
->display_name ?></span> <span class="text-sm text-gray-500 truncate">@<?= $podcast->actor->username ?></span>
<span class="text-sm text-gray-500 truncate">@<?= $podcast->actor
->username ?></span>
</p> </p>
</div> </div>
<div class="px-4 mb-2">
<?= form_textarea(
[
'id' => 'message',
'name' => 'message',
'class' => 'form-textarea min-w-0 w-full',
'placeholder' => 'Write your message...',
'autofocus' => '',
],
old('message', '', false),
[
'rows' => 2,
],
) ?>
</div> </div>
<div class="flex"> <div class="px-4 mb-2">
<img src="<?= $episode->image->thumbnail_url ?>" alt="<?= $episode->title ?>" class="w-24 h-24" /> <Forms.Textarea name="message" placeholder="<?= lang('Episode.publish_form.message_placeholder') ?>" autofocus="" rows="2" />
</div>
<div class="flex border-t border-b">
<img src="<?= $episode->image
->thumbnail_url ?>" alt="<?= $episode->title ?>" class="w-24 h-24" />
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">
<a href="<?= $episode->link ?>" class="flex-1 px-4 py-2 bg-gray-100"> <a href="<?= $episode->link ?>" class="flex-1 px-4 py-2">
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= $episode->title ?></span> <span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= $episode->title ?></span>
<?= episode_numbering( <?= episode_numbering(
@ -81,104 +63,47 @@
</div> </div>
</div> </div>
<footer class="flex justify-around px-6 py-3"> <footer class="flex justify-around px-6 py-3">
<span class="inline-flex items-center"><?= icon( <span class="inline-flex items-center"><Icon glyph="chat" class="mr-1 text-xl text-gray-400" />0</span>
'chat', <span class="inline-flex items-center"><Icon glyph="repeat" class="mr-1 text-xl text-gray-400" />0</span>
'text-xl mr-1 text-gray-400', <span class="inline-flex items-center"><Icon glyph="heart" class="mr-1 text-xl text-gray-400" />0</span>
) . '0' ?></span>
<span class="inline-flex items-center"><?= icon(
'repeat',
'text-xl mr-1 text-gray-400',
) . '0' ?></span>
<span class="inline-flex items-center"><?= icon(
'heart',
'text-xl mr-1 text-gray-400',
) . '0' ?></span>
</footer> </footer>
</div> </div>
<?= form_fieldset('', [ <fieldset class="flex flex-col">
'class' => 'flex flex-col mb-4',
]) ?>
<legend class="text-lg font-semibold"><?= lang( <legend class="text-lg font-semibold"><?= lang(
'Episode.publish_form.publication_date', 'Episode.publish_form.publication_date',
) ?></legend> ) ?></legend>
<label for="now" class="inline-flex items-center"> <Forms.Radio id="now" name="publication_method" isChecked="<?= old('publication_method') ? old('publish') === 'now' : true ?>"><?= lang('Episode.publish_form.publication_method.now') ?></Forms.Radio>
<?= form_radio( <div class="inline-flex flex-wrap items-center radio-toggler">
[
'id' => 'now',
'name' => 'publication_method',
'class' => 'text-pine-700',
],
'now',
old('publication_method') ? old('publish') === 'now' : true,
) ?>
<span class="ml-2"><?= lang(
'Episode.publish_form.publication_method.now',
) ?></span>
</label>
<div class="inline-flex flex-wrap items-center radio-toggler">
<?= form_radio( <?= form_radio(
[ [
'id' => 'schedule', 'id' => 'schedule',
'name' => 'publication_method', 'name' => 'publication_method',
'class' => 'text-pine-700', 'class' => 'text-pine-500 border-black border-3 focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 w-6 h-6',
], ],
'schedule', 'schedule',
old('publication_method') && old('publication_method') && old('publication_method') === 'schedule',
old('publication_method') === 'schedule', ) ?>
) ?> <Label for="schedule" class="pl-2 leading-8"><?= lang('Episode.publish_form.publication_method.schedule') ?></label>
<label for="schedule" class="ml-2"><?= lang(
'Episode.publish_form.publication_method.schedule',
) ?></label>
<div class="w-full mt-2 radio-toggler-element"> <div class="w-full mt-2 radio-toggler-element">
<?= form_label( <Forms.Field
lang('Episode.publish_form.scheduled_publication_date'), as="DatetimePicker"
'scheduled_publication_date', name="scheduled_publication_date"
[], label="<?= lang('Episode.publish_form.scheduled_publication_date') ?>"
lang('Episode.publish_form.scheduled_publication_date_hint'), hintText="<?= lang('Episode.publish_form.scheduled_publication_date_hint') ?>"
) ?> value="<?= $episode->published_at ?>"
<div class="flex" data-picker="datetime"> />
<?= form_input([
'id' => 'scheduled_publication_date',
'name' => 'scheduled_publication_date',
'class' => 'form-input rounded-r-none flex-1',
'value' => old('scheduled_publication_date', ''),
'data-input' => '',
]) ?>
<button class="p-3 border border-l-0 border-gray-500 bg-pine-100 focus:outline-none rounded-r-md hover:bg-pine-200 focus:ring" type="button" title="<?= lang(
'Episode.publish_form.scheduled_publication_date_clear',
) ?>" data-clear=""><?= icon('close') ?></button>
</div> </div>
</div> </div>
</div> </fieldset>
<?= form_fieldset_close() ?>
<div id="publish-warning" class="inline-flex flex-col hidden p-4 text-black bg-yellow-300 border-2 border-yellow-900 rounded-md" role="alert"> <Alert id="publish-warning" variant="warning" glyph="alert" class="hidden mt-2" title="<?= lang('Episode.publish_form.message_warning') ?>"><?= lang('Episode.publish_form.message_warning_hint') ?></Alert>
<p class="flex items-baseline font-semibold">
<?= icon('alert', 'mr-2 text-lg flex-shrink-0') . lang( <div class="flex items-center justify-between w-full mt-4">
'Episode.publish_form.message_warning', <Button uri="<?= route_to('episode-publish-cancel', $podcast->id, $episode->id) ?>" variant="danger"><?= lang('Episode.publish_form.cancel_publication') ?></Button>
) ?></p> <Button variant="primary" type="submit" data-btn-text-warning="<?= lang('Episode.publish_form.message_warning_submit') ?>" data-btn-text="<?= lang('Episode.publish_form.submit') ?>"><?= lang('Episode.publish_form.submit') ?></Button>
<p>
<?= lang(
'Episode.publish_form.message_warning_hint',
) ?>
</p>
</div> </div>
<?= button( </form>
lang('Episode.publish_form.submit'),
'',
[
'variant' => 'primary',
],
[
'class' => 'self-end mt-4',
'type' => 'submit',
'data-btn-text-warning' => lang('Episode.publish_form.message_warning_submit'),
'data-btn-text' => lang('Episode.publish_form.submit_edit'),
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -18,15 +18,10 @@
], ],
) ?> ) ?>
<?= form_open(route_to('episode-publish_edit', $podcast->id, $episode->id), [ <form action="<?= route_to('episode-publish_edit', $podcast->id, $episode->id) ?>" method="POST" class="flex flex-col items-start max-w-xl mx-auto" data-submit="validate-message">
'method' => 'post',
'class' => 'mx-auto flex flex-col max-w-xl items-start',
'data-submit' => 'validate-message',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_hidden('client_timezone', 'UTC') ?> <input type="hidden" name="client_timezone" value="UTC" />
<?= form_hidden('post_id', $post->id) ?> <input type="hidden" name="post_id" value="<?= $post->id ?>" />
<label for="message" class="text-lg font-semibold"><?= lang( <label for="message" class="text-lg font-semibold"><?= lang(
'Episode.publish_form.post', 'Episode.publish_form.post',
@ -44,25 +39,13 @@
</div> </div>
</div> </div>
<div class="px-4 mb-2"> <div class="px-4 mb-2">
<?= form_textarea( <Forms.Textarea name="message" placeholder="<?= lang('Episode.publish_form.message_placeholder') ?>" autofocus="" value="<?= $post->message ?>" rows="2" />
[
'id' => 'message',
'name' => 'message',
'class' => 'form-textarea',
'placeholder' => 'Write your message...',
'autofocus' => '',
],
old('message', $post->message, false),
[
'rows' => 2,
],
) ?>
</div> </div>
<div class="flex"> <div class="flex border-t border-b">
<img src="<?= $episode->image <img src="<?= $episode->image
->thumbnail_url ?>" alt="<?= $episode->title ?>" class="w-24 h-24" /> ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="w-24 h-24" />
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">
<a href="<?= $episode->link ?>" class="flex-1 px-4 py-2 bg-gray-100"> <a href="<?= $episode->link ?>" class="flex-1 px-4 py-2">
<div class="flex items-baseline"> <div class="flex items-baseline">
<span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= $episode->title ?></span> <span class="flex-1 w-0 mr-2 text-sm font-semibold truncate"><?= $episode->title ?></span>
<?= episode_numbering( <?= episode_numbering(
@ -84,119 +67,47 @@
</div> </div>
</div> </div>
<footer class="flex justify-around px-6 py-3"> <footer class="flex justify-around px-6 py-3">
<span class="inline-flex items-center"><?= icon( <span class="inline-flex items-center"><Icon glyph="chat" class="mr-1 text-xl text-gray-400" />0</span>
'chat', <span class="inline-flex items-center"><Icon glyph="repeat" class="mr-1 text-xl text-gray-400" />0</span>
'text-xl mr-1 text-gray-400', <span class="inline-flex items-center"><Icon glyph="heart" class="mr-1 text-xl text-gray-400" />0</span>
) . '0' ?></span>
<span class="inline-flex items-center"><?= icon(
'repeat',
'text-xl mr-1 text-gray-400',
) . '0' ?></span>
<span class="inline-flex items-center"><?= icon(
'heart',
'text-xl mr-1 text-gray-400',
) . '0' ?></span>
</footer> </footer>
</div> </div>
<?= form_fieldset('', [ <fieldset class="flex flex-col">
'class' => 'flex flex-col mb-4',
]) ?>
<legend class="text-lg font-semibold"><?= lang( <legend class="text-lg font-semibold"><?= lang(
'Episode.publish_form.publication_date', 'Episode.publish_form.publication_date',
) ?></legend> ) ?></legend>
<label for="now" class="inline-flex items-center"> <Forms.Radio id="now" name="publication_method" isChecked="<?= old('publication_method') && old('publish') === 'now' ?>"><?= lang('Episode.publish_form.publication_method.now') ?></Forms.Radio>
<?= form_radio( <div class="inline-flex flex-wrap items-center radio-toggler">
[
'id' => 'now',
'name' => 'publication_method',
'class' => 'text-pine-700',
],
'now',
old('publication_method') && old('publish') === 'now',
) ?>
<span class="ml-2"><?= lang(
'Episode.publish_form.publication_method.now',
) ?></span>
</label>
<div class="inline-flex flex-wrap items-center radio-toggler">
<?= form_radio( <?= form_radio(
[ [
'id' => 'schedule', 'id' => 'schedule',
'name' => 'publication_method', 'name' => 'publication_method',
'class' => 'text-pine-700', 'class' => 'text-pine-500 border-black border-3 focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 w-6 h-6',
], ],
'schedule', 'schedule',
old('publication_method') old('publication_method') ? old('publication_method') === 'schedule' : true,
? old('publication_method') === 'schedule'
: true,
) ?>
<label for="schedule" class="ml-2"><?= lang(
'Episode.publish_form.publication_method.schedule',
) ?></label>
<div class="w-full mt-2 radio-toggler-element">
<?= form_label(
lang('Episode.publish_form.scheduled_publication_date'),
'scheduled_publication_date',
[],
lang('Episode.publish_form.scheduled_publication_date_hint'),
) ?>
<div class="flex" data-picker="datetime">
<?= form_input([
'id' => 'scheduled_publication_date',
'name' => 'scheduled_publication_date',
'class' => 'form-input rounded-r-none flex-1',
'value' => old(
'scheduled_publication_date',
$episode->published_at,
),
'data-input' => '',
]) ?>
<button class="p-3 border border-l-0 border-gray-500 bg-pine-100 focus:outline-none rounded-r-md hover:bg-pine-200 focus:ring" type="button" aria-label="<?= lang(
'Episode.publish_form.scheduled_publication_date_clear',
) ?>" title="<?= lang(
'Episode.publish_form.scheduled_publication_date_clear',
) ?>" data-clear=""><?= icon('close') ?></button>
</div>
</div>
</div>
<?= form_fieldset_close() ?>
<div id="publish-warning" class="inline-flex flex-col hidden p-4 text-black bg-yellow-300 border-2 border-yellow-900 rounded-md" role="alert">
<p class="flex items-baseline font-semibold">
<?= icon('alert', 'mr-2 text-lg flex-shrink-0') . lang(
'Episode.publish_form.message_warning',
) ?></p>
<p>
<?= lang(
'Episode.publish_form.message_warning_hint',
) ?> ) ?>
</p> <Label for="schedule" class="pl-2 leading-8"><?= lang('Episode.publish_form.publication_method.schedule') ?></label>
</div> <div class="w-full mt-2 radio-toggler-element">
<Forms.Field
as="DatetimePicker"
name="scheduled_publication_date"
label="<?= lang('Episode.publish_form.scheduled_publication_date') ?>"
hintText="<?= lang('Episode.publish_form.scheduled_publication_date_hint') ?>"
value="<?= $episode->published_at ?>"
/>
</div>
</div>
</fieldset>
<Alert id="publish-warning" variant="warning" glyph="alert" class="hidden mt-2" title="<?= lang('Episode.publish_form.message_warning') ?>"><?= lang('Episode.publish_form.message_warning_hint') ?></Alert>
<div class="flex items-center justify-between w-full mt-4"> <div class="flex items-center justify-between w-full mt-4">
<?= anchor( <Button uri="<?= route_to('episode-publish-cancel', $podcast->id, $episode->id) ?>" variant="danger"><?= lang('Episode.publish_form.cancel_publication') ?></Button>
route_to('episode-publish-cancel', $podcast->id, $episode->id), <Button variant="primary" type="submit" data-btn-text-warning="<?= lang('Episode.publish_form.message_warning_submit') ?>" data-btn-text="<?= lang('Episode.publish_form.submit_edit') ?>"><?= lang('Episode.publish_form.submit_edit') ?></Button>
lang('Episode.publish_form.cancel_publication'),
[
'class' => 'py-2 px-3 rounded-full bg-red-100 text-red-900 font-semibold mr-4',
],
) ?>
<?= button(
lang('Episode.publish_form.submit_edit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'data-btn-text-warning' => lang('Episode.publish_form.message_warning_submit'),
'data-btn-text' => lang('Episode.publish_form.submit_edit'),
],
) ?>
</div> </div>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,7 +11,7 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart( <?= form_open(
route_to('episode-soundbites-edit', $podcast->id, $episode->id), route_to('episode-soundbites-edit', $podcast->id, $episode->id),
[ [
'method' => 'post', 'method' => 'post',

View File

@ -10,48 +10,18 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('episode-unpublish', $podcast->id, $episode->id), [ <form action="<?= route_to('episode-unpublish', $podcast->id, $episode->id) ?>" method="POST" class="flex flex-col max-w-xl mx-auto">
'class' => 'flex flex-col max-w-xl mx-auto', <?= csrf_field() ?>
]) ?>
<p class="flex max-w-xl p-2 mb-4 font-semibold text-red-900 bg-red-100 border border-red-300"><?= icon( <Alert variant="danger" glyph="alert" class="font-semibold"><?= lang('Episode.unpublish_form.disclaimer') ?></Alert>
'alert',
'mr-4 text-2xl flex-shrink-0 text-red-500',
) . lang('Episode.unpublish_form.disclaimer') ?></p>
<label for="understand" class="inline-flex items-center mb-4"> <Forms.Checkbox name="understand" required="true" isChecked="false"><?= lang('Episode.unpublish_form.understand') ?></Forms.Checkbox>
<?= form_checkbox(
[
'id' => 'understand',
'name' => 'understand',
'class' => 'text-pine-700',
'required' => 'required',
],
'yes',
old('understand', false),
) ?>
<span class="ml-2"><?= lang('Episode.unpublish_form.understand') ?></span>
</label>
<div class="self-end"> <div class="self-end mt-4">
<?= button( <Button uri="<?= route_to('episode-view', $podcast->id, $episode->id) ?>"><?= lang('Common.cancel') ?></Button>
lang('Common.cancel'), <Button type="submit" variant="danger"><?= lang('Episode.unpublish_form.submit') ?></Button>
route_to('episode-view', $podcast->id, $episode->id),
) ?>
<?= button(
lang('Episode.unpublish_form.submit'),
'',
[
'variant' => 'danger',
],
[
'type' => 'submit',
],
) ?>
</div> </div>
</form>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,41 +11,10 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('fediverse-attempt-block-actor'), [ <form action="<?= route_to('fediverse-attempt-block-actor') ?>" method="POST" class="flex flex-col max-w-md">
'method' => 'post', <Forms.Field name="handle" label="<?= lang('Fediverse.block_lists_form.handle') ?>" hintText="<?= lang('Fediverse.block_lists_form.handle_hint') ?>" />
'class' => 'flex flex-col max-w-md mb-8', <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.block_lists_form.submit') ?></Button>
]) ?> </form>
<?= form_label(
lang('Fediverse.block_lists_form.handle'),
'blocked_users',
[],
lang('Fediverse.block_lists_form.handle_hint'),
) ?>
<?= form_input(
[
'id' => 'handle',
'name' => 'handle',
'class' => 'form-input mb-4',
'type' => 'text',
],
old('handle', ''),
) ?>
<?= button(
lang('Fediverse.block_lists_form.submit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= data_table( <?= data_table(
[ [

View File

@ -11,39 +11,10 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('fediverse-attempt-block-domain'), [ <form action="<?= route_to('fediverse-attempt-block-domain') ?>" method="POST" class="flex flex-col max-w-md">
'method' => 'post', <Forms.Field name="domain" label="<?= lang('Fediverse.block_lists_form.domain') ?>" />
'class' => 'flex flex-col max-w-md mb-8', <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.block_lists_form.submit') ?></Button>
]) ?> </form>
<?= form_label(
lang('Fediverse.block_lists_form.domain'),
'blocked_users',
[],
) ?>
<?= form_input(
[
'id' => 'domain',
'name' => 'domain',
'class' => 'form-input mb-4',
'type' => 'text',
],
old('domain', ''),
) ?>
<?= button(
lang('Fediverse.block_lists_form.submit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= data_table( <?= data_table(
[ [
@ -83,6 +54,7 @@
], ],
], ],
$blockedDomains, $blockedDomains,
'mt-8'
) ?> ) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,43 +11,20 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('change-password'), [ <form action="<?= route_to('change-password') ?>" method="POST" class="flex flex-col max-w-sm">
'class' => 'flex flex-col max-w-sm', <?= csrf_field() ?>
]) ?> <Forms.Field
<?= csrf_field() ?> name="password"
label="<?= lang('User.form.password') ?>"
<?= form_label(lang('User.form.password'), 'password') ?> required="true"
<?= form_input([ type="password" />
'id' => 'password', <Forms.Field
'name' => 'password', name="new_password"
'class' => 'form-input mb-4', label="<?= lang('User.form.new_password') ?>"
'required' => 'required', required="true"
'type' => 'password', type="password"
]) ?> autocomplete="new-password" />
<Button variant="primary" class="self-end" type="submit"><?= lang('User.form.submit_password_change') ?></Button>
<?= form_label(lang('User.form.new_password'), 'new_password') ?> </form>
<?= form_input([
'id' => 'new_password',
'name' => 'new_password',
'class' => 'form-input mb-4',
'required' => 'required',
'type' => 'password',
'autocomplete' => 'new-password',
]) ?>
<?= button(
lang('User.form.submit_password_change'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -14,56 +14,32 @@
<?= form_open(route_to('page-create'), [ <?= form_open(route_to('page-create'), [
'class' => 'flex flex-col max-w-3xl', 'class' => 'flex flex-col max-w-3xl',
]) ?> ]) ?>
<form action="<?= route_to('page-create') ?>" method="POST" class="flex flex-col max-w-3xl">
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_label(lang('Page.form.title'), 'title', [ <Forms.Field
'class' => 'max-w-sm', name="title"
]) ?> label="<?= lang('Page.form.title') ?>"
<?= form_input([ required="true"
'id' => 'title', data-slugify="title" />
'name' => 'title',
'class' => 'form-input mb-4 max-w-sm',
'value' => old('title'),
'required' => 'required',
'data-slugify' => 'title',
]) ?>
<?= form_label( <div>
lang('Page.form.permalink'), <Forms.Label for="slug"><?= lang('Page.form.permalink') ?></Forms.Label>
'slug', <permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
[], <span slot="domain"><?= base_url('pages') . '/' ?></span>
) ?> <Forms.Input name="slug" value="<?= $episode->slug ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" />
<permalink-edit class="inline-flex items-center w-full max-w-sm mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>"> </permalink-edit>
<span slot="domain" class="flex-shrink-0"><?= base_url('pages') . '/' ?></span>
<?= form_input([
'id' => 'slug',
'name' => 'slug',
'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug'),
'required' => 'required',
'data-slugify' => 'slug',
'slot' => 'slug-input',
]) ?>
</permalink-edit>
<div class="mb-4">
<?= form_label(lang('Page.form.content'), 'content') ?>
<Forms.MarkdownEditor id="content" name="content" required="required" rows="20"><?= old('content', '', false) ?></Forms.MarkdownEditor>
</div> </div>
<Forms.Field
as="MarkdownEditor"
name="content"
label="<?= lang('Page.form.content') ?>"
required="true"
rows="20" />
<?= button( <Button variant="primary" type="submit" class="self-end"><?= lang('Page.form.submit_create') ?></Button>
lang('Page.form.submit_create'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,58 +11,36 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('page-edit', $page->id), [ <form action="<?= route_to('page-edit', $page->id) ?>" method="POST" class="flex flex-col max-w-3xl">
'class' => 'flex flex-col max-w-3xl',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_label(lang('Page.form.title'), 'title', [
'class' => 'max-w-sm',
]) ?>
<?= form_input([
'id' => 'title',
'name' => 'title',
'class' => 'form-input mb-4 max-w-sm',
'value' => old('title', $page->title),
'required' => 'required',
'data-slugify' => 'title',
'slot' => 'slug-input',
]) ?>
<?= form_label( <Forms.Field
lang('Page.form.permalink'), name="title"
'slug', label="<?= lang('Page.form.title') ?>"
[], required="true"
) ?> data-slugify="title"
<permalink-edit class="inline-flex items-center max-w-sm mb-4 text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>"> value="<?= $page->title ?>"
<span slot="domain" class="flex-shrink-0"><?= base_url('pages') . '/' ?></span> slot="slug-input" />
<?= form_input([
'id' => 'slug',
'name' => 'slug',
'class' => 'form-input flex-1 w-0 text-xs',
'value' => old('slug', $page->slug),
'required' => 'required',
'data-slugify' => 'slug',
]) ?>
</permalink-edit>
<div class="mb-4"> <div>
<?= form_label(lang('Page.form.content'), 'content') ?> <Forms.Label for="slug"><?= lang('Page.form.permalink') ?></Forms.Label>
<Forms.MarkdownEditor id="content" name="content" required="required"><?= old('content', $page->content_markdown, false) ?></Forms.MarkdownEditor> <permalink-edit class="inline-flex items-center text-xs" edit-label="<?= lang('Common.edit') ?>" copy-label="<?= lang('Common.copy') ?>" copied-label="<?= lang('Common.copied') ?>">
<span slot="domain"><?= base_url('pages') . '/' ?></span>
<Forms.Input name="slug" value="<?= $episode->slug ?>" required="true" data-slugify="slug" slot="slug-input" class="flex-1 text-xs" value="<?= $page->slug ?>"/>
</permalink-edit>
</div> </div>
<?= button( <Forms.Field
lang('Page.form.submit_edit'), as="MarkdownEditor"
'', name="content"
[ label="<?= lang('Page.form.content') ?>"
'variant' => 'primary', value="<?= $page->content_markdown ?>"
], required="true"
[ rows="20" />
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> <Button variant="primary" type="submit" class="self-end"><?= lang('Page.form.submit_edit') ?></Button>
</form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,89 +11,36 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart(route_to('person-create'), [ <form action="<?= route_to('person-create') ?>" method="POST" class="flex flex-col" enctype="multipart/form-data">
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_section( <Forms.Field
lang('Person.form.identity_section_title'), name="image"
lang('Person.form.identity_section_subtitle'), label="<?= lang('Person.form.image') ?>"
) ?> helperText="<?= lang('Person.form.image_size_hint') ?>"
type="file"
required="true"
accept=".jpg,.jpeg,.png" />
<?= form_label(lang('Person.form.image'), 'image') ?> <Forms.Field
<?= form_input([ name="full_name"
'id' => 'image', label="<?= lang('Person.form.full_name') ?>"
'name' => 'image', hintText="<?= lang('Person.form.full_name_hint') ?>"
'class' => 'form-input', required="true"
'type' => 'file', data-slugify="title" />
'accept' => '.jpg,.jpeg,.png',
]) ?>
<small class="mb-4 text-gray-600"><?= lang(
'Person.form.image_size_hint',
) ?></small>
<?= form_label( <Forms.Field
lang('Person.form.full_name'), name="unique_name"
'full_name', label="<?= lang('Person.form.unique_name') ?>"
[], hintText="<?= lang('Person.form.unique_name_hint') ?>"
lang('Person.form.full_name_hint'), required="true" />
) ?> <Forms.Field
<?= form_input([ name="information_url"
'id' => 'full_name', label="<?= lang('Person.form.information_url') ?>"
'name' => 'full_name', hintText="<?= lang('Person.form.information_url_hint') ?>" />
'class' => 'form-input mb-4',
'value' => old('full_name'),
'required' => 'required',
'data-slugify' => 'title',
]) ?>
<?= form_label( <Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_create') ?></Button>
lang('Person.form.unique_name'),
'unique_name',
[],
lang('Person.form.unique_name_hint'),
) ?>
<?= form_input([
'id' => 'unique_name',
'name' => 'unique_name',
'class' => 'form-input mb-4',
'value' => old('unique_name'),
'required' => 'required',
'data-slugify' => 'slug',
]) ?>
<?= form_label(
lang('Person.form.information_url'),
'information_url',
[],
lang('Person.form.information_url_hint'),
true,
) ?>
<?= form_input([
'id' => 'information_url',
'name' => 'information_url',
'class' => 'form-input mb-4',
'value' => old('information_url'),
]) ?>
<?= form_section_close() ?>
<?= button(
lang('Person.form.submit_create'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
</form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -11,90 +11,40 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart(route_to('person-edit', $person->id), [ <form action="<?= route_to('person-edit', $person->id) ?>" method="POST" class="flex flex-col" enctype="multipart/form-data">
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_section( <img src="<?= $person->image->thumbnail_url ?>" alt="<?= $person->full_name ?>" class="object-cover w-32 h-32 mt-3 rounded" />
lang('Person.form.identity_section_title'),
lang('Person.form.identity_section_subtitle') .
"<img src=\"{$person->image->thumbnail_url}\" alt=\"{$person->full_name}\" class=\"object-cover w-32 h-32 mt-3 rounded\" />",
) ?>
<?= form_label(lang('Person.form.image'), 'image') ?> <Forms.Field
<?= form_input([ name="image"
'id' => 'image', label="<?= lang('Person.form.image') ?>"
'name' => 'image', helperText="<?= lang('Person.form.image_size_hint') ?>"
'class' => 'form-input', type="file"
'type' => 'file', accept=".jpg,.jpeg,.png" />
'accept' => '.jpg,.jpeg,.png',
]) ?>
<small class="mb-4 text-gray-600"><?= lang(
'Person.form.image_size_hint',
) ?></small>
<?= form_label( <Forms.Field
lang('Person.form.full_name'), name="full_name"
'full_name', value="<?= $person->full_name ?>"
[], label="<?= lang('Person.form.full_name') ?>"
lang('Person.form.full_name_hint'), hintText="<?= lang('Person.form.full_name_hint') ?>"
) ?> required="true"
<?= form_input([ data-slugify="title" />
'id' => 'full_name',
'name' => 'full_name',
'class' => 'form-input mb-4',
'value' => old('full_name', $person->full_name),
'required' => 'required',
'data-slugify' => 'title',
]) ?>
<?= form_label( <Forms.Field
lang('Person.form.unique_name'), name="unique_name"
'unique_name', value="<?= $person->unique_name ?>"
[], label="<?= lang('Person.form.unique_name') ?>"
lang('Person.form.unique_name_hint'), hintText="<?= lang('Person.form.unique_name_hint') ?>"
) ?> required="true" />
<?= form_input([ <Forms.Field
'id' => 'unique_name', name="information_url"
'name' => 'unique_name', label="<?= lang('Person.form.information_url') ?>"
'class' => 'form-input mb-4', hintText="<?= lang('Person.form.information_url_hint') ?>"
'value' => old('unique_name', $person->unique_name), value="<?= $person->information_url ?>" />
'required' => 'required',
'data-slugify' => 'slug',
]) ?>
<?= form_label( <Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_edit') ?></Button>
lang('Person.form.information_url'),
'information_url',
[],
lang('Person.form.information_url_hint'),
true,
) ?>
<?= form_input([
'id' => 'information_url',
'name' => 'information_url',
'class' => 'form-input mb-4',
'value' => old('information_url', $person->information_url),
]) ?>
<?= form_section_close() ?>
<?= button(
lang('Person.form.submit_edit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
</form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -12,380 +12,206 @@
<?= lang('Podcast.create') ?> <?= lang('Podcast.create') ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart(route_to('podcast-create'), [ <form action="<?= route_to('podcast-create') ?>" method="POST" enctype='multipart/form-data' class="flex flex-col">
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_section( <Forms.Section
lang('Podcast.form.identity_section_title'), class="mb-8"
lang('Podcast.form.identity_section_subtitle'), title="<?= lang('Podcast.form.identity_section_title') ?>"
) ?> subtitle="<?= lang('Podcast.form.identity_section_subtitle') ?>" >
<?= form_label(lang('Podcast.form.image'), 'image') ?> <Forms.Field
<?= form_input([ name="image"
'id' => 'image', label="<?= lang('Podcast.form.image') ?>"
'name' => 'image', helperText="<?= lang('Common.forms.image_size_hint') ?>"
'class' => 'form-input', type="file"
'required' => 'required', required="true"
'type' => 'file', accept=".jpg,.jpeg,.png" />
'accept' => '.jpg,.jpeg,.png',
]) ?>
<small class="mb-4 text-gray-600"><?= lang(
'Common.forms.image_size_hint',
) ?></small>
<?= form_label(lang('Podcast.form.title'), 'title') ?> <Forms.Field
<?= form_input([ name="title"
'id' => 'title', label="<?= lang('Podcast.form.title') ?>"
'name' => 'title', required="true" />
'class' => 'form-input mb-4',
'value' => old('title'),
'required' => 'required',
]) ?>
<?= form_label( <div class="flex flex-col">
lang('Podcast.form.handle'), <Forms.Label for="handle" hint="<?= lang('Podcast.form.handle_hint') ?>"><?= lang('Podcast.form.handle') ?></Forms.Label>
'handle', <div class="relative">
[], <Icon glyph="at" class="absolute inset-0 h-full text-xl text-gray-400 left-3" />
lang('Podcast.form.handle_hint'), <Forms.Input name="handle" class="w-full pl-8" required="true" />
) ?> </div>
<div class="relative mb-4">
<?= icon('at', 'absolute text-xl h-full inset-0 text-gray-400 left-3') ?>
<?= form_input([
'id' => 'handle',
'name' => 'handle',
'class' => 'form-input w-full pl-8',
'value' => old('handle'),
'required' => 'required',
]) ?>
</div> </div>
<?= form_fieldset('', [ <Forms.Field
'class' => 'mb-4', as="MarkdownEditor"
]) ?> name="description"
<legend> label="<?= lang('Podcast.form.description') ?>"
<?= lang('Podcast.form.type.label') . required="true" />
hint_tooltip(lang('Podcast.form.type.hint'), 'ml-1') ?>
</legend>
<?= form_radio(
[
'id' => 'episodic',
'name' => 'type',
'class' => 'form-radio-btn',
],
'episodic',
old('type') ? old('type') === 'episodic' : true,
) ?>
<label for="episodic"><?= lang('Podcast.form.type.episodic') ?></label>
<?= form_radio(
[
'id' => 'serial',
'name' => 'type',
'class' => 'form-radio-btn',
],
'serial',
old('type') && old('type') === 'serial',
) ?>
<label for="serial"><?= lang('Podcast.form.type.serial') ?></label>
<?= form_fieldset_close() ?>
<div class="mb-4"> <fieldset>
<Forms.Label for="description"><?= lang('Podcast.form.description') ?></Forms.Label> <legend><?= lang('Podcast.form.type.label') .
<Forms.MarkdownEditor id="description" name="description" required="required"><?= old('description', '', false) ?></Forms.MarkdownEditor> hint_tooltip(lang('Podcast.form.type.hint'), 'ml-1') ?></legend>
</div> <div class="flex gap-2">
<Forms.RadioButton
value="episodic"
name="type"
isChecked="true'" ><?= lang('Podcast.form.type.episodic') ?></Forms.RadioButton>
<Forms.RadioButton
value="serial"
name="type"
isChecked="false" ><?= lang('Podcast.form.type.serial') ?></Forms.RadioButton>
</div>
</fieldset>
<?= form_section_close() ?> </Forms.Section>
<Forms.Section
class="mb-8"
title="<?= lang('Podcast.form.classification_section_title') ?>"
subtitle="<?= lang('Podcast.form.classification_section_subtitle') ?>" >
<?= form_section( <Forms.Field
lang('Podcast.form.classification_section_title'), as="Select"
lang('Podcast.form.classification_section_subtitle'), name="language"
) ?> label="<?= lang('Podcast.form.language') ?>"
selected="<?= $browserLang ?>"
required="true"
options="<?= esc(json_encode($languageOptions)) ?>" />
<?= form_label(lang('Podcast.form.language'), 'language') ?> <Forms.Field
<?= form_dropdown('language', $languageOptions, [old('language', $browserLang)], [ as="Select"
'id' => 'language', name="category"
'class' => 'form-select mb-4', label="<?= lang('Podcast.form.category') ?>"
'required' => 'required', required="true"
]) ?> options="<?= esc(json_encode($categoryOptions)) ?>" />
<?= form_label(lang('Podcast.form.category'), 'category') ?> <Forms.Field
<?= form_dropdown('category', $categoryOptions, [old('category', '')], [ as="MultiSelect"
'id' => 'category',
'class' => 'form-select mb-4',
'required' => 'required',
'placeholder' => lang('Podcast.form.category_placeholder'),
]) ?>
<?= form_label(
lang('Podcast.form.other_categories'),
'other_categories',
[],
'',
true,
) ?>
<Forms.MultiSelect
id="other_categories"
name="other_categories[]" name="other_categories[]"
class="mb-4" label="<?= lang('Podcast.form.other_categories') ?>"
data-max-item-count="2" data-max-item-count="2"
selected="<?= htmlspecialchars(json_encode(old('other_categories', []))) ?>" options="<?= esc(json_encode($categoryOptions)) ?>" />
options="<?= htmlspecialchars(json_encode($categoryOptions)) ?>" />
<?= form_fieldset('', [ <fieldset class="mb-4">
'class' => 'mb-4', <legend><?= lang('Podcast.form.parental_advisory.label') .
]) ?> hint_tooltip(lang('Podcast.form.parental_advisory.hint'), 'ml-1') ?></legend>
<legend> <div class="flex gap-2">
<?= lang('Podcast.form.parental_advisory.label') . <Forms.RadioButton
hint_tooltip(lang('Podcast.form.parental_advisory.hint'), 'ml-1') ?> value="undefined"
</legend> name="parental_advisory"
<?= form_radio( isChecked="true" ><?= lang('Podcast.form.parental_advisory.undefined') ?></Forms.RadioButton>
[ <Forms.RadioButton
'id' => 'undefined', value="clean"
'name' => 'parental_advisory', name="parental_advisory"
'class' => 'form-radio-btn', isChecked="false" ><?= lang('Podcast.form.parental_advisory.clean', ) ?></Forms.RadioButton>
], <Forms.RadioButton
'undefined', value="explicit"
old('parental_advisory') name="parental_advisory"
? old('parental_advisory') === 'undefined' isChecked="false" ><?= lang('Podcast.form.parental_advisory.explicit', ) ?></Forms.RadioButton>
: true,
) ?>
<label for="undefined"><?= lang(
'Podcast.form.parental_advisory.undefined',
) ?></label>
<?= form_radio(
[
'id' => 'clean',
'name' => 'parental_advisory',
'class' => 'form-radio-btn',
],
'clean',
old('parental_advisory') && old('parental_advisory') === 'clean',
) ?>
<label for="clean"><?= lang(
'Podcast.form.parental_advisory.clean',
) ?></label>
<?= form_radio(
[
'id' => 'explicit',
'name' => 'parental_advisory',
'class' => 'form-radio-btn',
],
'explicit',
old('parental_advisory') && old('parental_advisory') === 'explicit',
) ?>
<label for="explicit"><?= lang(
'Podcast.form.parental_advisory.explicit',
) ?></label>
<?= form_fieldset_close() ?>
<?= form_section_close() ?>
<?= form_section(
lang('Podcast.form.author_section_title'),
lang('Podcast.form.author_section_subtitle'),
) ?>
<?= form_label(
lang('Podcast.form.owner_name'),
'owner_name',
[],
lang('Podcast.form.owner_name_hint'),
) ?>
<?= form_input([
'id' => 'owner_name',
'name' => 'owner_name',
'class' => 'form-input mb-4',
'value' => old('owner_name'),
'required' => 'required',
]) ?>
<?= form_label(
lang('Podcast.form.owner_email'),
'owner_email',
[],
lang('Podcast.form.owner_email_hint'),
) ?>
<?= form_input([
'id' => 'owner_email',
'name' => 'owner_email',
'class' => 'form-input mb-4',
'value' => old('owner_email'),
'type' => 'email',
'required' => 'required',
]) ?>
<?= form_label(
lang('Podcast.form.publisher'),
'publisher',
[],
lang('Podcast.form.publisher_hint'),
true,
) ?>
<?= form_input([
'id' => 'publisher',
'name' => 'publisher',
'class' => 'form-input mb-4',
'value' => old('publisher'),
]) ?>
<?= form_label(lang('Podcast.form.copyright'), 'copyright', [], '', true) ?>
<?= form_input([
'id' => 'copyright',
'name' => 'copyright',
'class' => 'form-input mb-4',
'value' => old('copyright'),
]) ?>
<?= form_section_close() ?>
<?= form_section(
lang('Podcast.form.location_section_title'),
lang('Podcast.form.location_section_subtitle'),
) ?>
<?= form_label(
lang('Podcast.form.location_name'),
'location_name',
[],
lang('Podcast.form.location_name_hint'),
true,
) ?>
<?= form_input([
'id' => 'location_name',
'name' => 'location_name',
'class' => 'form-input mb-4',
'value' => old('location_name'),
]) ?>
<?= form_section_close() ?>
<?= form_section(
lang('Podcast.form.monetization_section_title'),
lang('Podcast.form.monetization_section_subtitle'),
) ?>
<?= form_label(
lang('Podcast.form.payment_pointer'),
'payment_pointer',
[],
lang('Podcast.form.payment_pointer_hint'),
true,
) ?>
<?= form_input([
'id' => 'payment_pointer',
'name' => 'payment_pointer',
'class' => 'form-input mb-4',
'value' => old('payment_pointer'),
]) ?>
<?= form_label(lang('Podcast.form.partnership')) ?>
<div class="flex flex-col mb-4 gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-shrink">
<?= form_label(
lang('Podcast.form.partner_id'),
'partner_id',
[
'class' => 'text-sm',
],
lang('Podcast.form.partner_id_hint'),
true,
) ?>
<?= form_input([
'id' => 'partner_id',
'name' => 'partner_id',
'class' => 'form-input w-full',
'value' => old('partner_id'),
]) ?>
</div> </div>
<div class="flex flex-col"> </fieldset>
<?= form_label( </Forms.Section>
lang('Podcast.form.partner_link_url'),
'partner_link_url', <Forms.Section
[ class="mb-8"
'class' => 'text-sm', title="<?= lang('Podcast.form.author_section_title') ?>"
], subtitle="<?= lang('Podcast.form.author_section_subtitle') ?>" >
lang('Podcast.form.partner_link_url_hint'),
true, <Forms.Field
) ?> name="owner_name"
<?= form_input([ label="<?= lang('Podcast.form.owner_name') ?>"
'id' => 'partner_link_url', hintText="<?= lang('Podcast.form.owner_name_hint') ?>"
'name' => 'partner_link_url', required="true" />
'class' => 'form-input w-full',
'value' => old('partner_link_url'), <Forms.Field
]) ?> name="owner_email"
type="email"
label="<?= lang('Podcast.form.owner_email') ?>"
hintText="<?= lang('Podcast.form.owner_email_hint') ?>"
required="true" />
<Forms.Field
name="publisher"
label="<?= lang('Podcast.form.publisher') ?>"
hintText="<?= lang('Podcast.form.publisher_hint') ?>" />
<Forms.Field
name="copyright"
label="<?= lang('Podcast.form.copyright') ?>" />
</Forms.Section>
<Forms.Section
class="mb-8"
title="<?= lang('Podcast.form.location_section_title') ?>"
subtitle="<?= lang('Podcast.form.location_section_subtitle') ?>" >
<Forms.Field
name="location_name"
label="<?= lang('Podcast.form.location_name') ?>"
hintText="<?= lang('Podcast.form.location_name_hint') ?>" />
</Forms.Section>
<Forms.Section
class="mb-8"
title="<?= lang('Podcast.form.monetization_section_title') ?>"
subtitle="<?= lang('Podcast.form.monetization_section_subtitle') ?>" >
<Forms.Field
name="payment_pointer"
label="<?= lang('Podcast.form.payment_pointer') ?>"
hintText="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
<fieldset class="flex flex-col items-start p-4 bg-gray-100 rounded">
<Heading tagName="legend" class="float-left" size="small"><?= lang('Podcast.form.partnership') ?></Heading>
<div class="flex flex-col w-full clear-left gap-x-2 gap-y-4 md:flex-row">
<div class="flex flex-col flex-shrink w-32">
<Forms.Label for="partner_id" hint="<?= lang('Podcast.form.partner_id_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_id') ?></Forms.Label>
<Forms.Input name="partner_id" />
</div> </div>
<div class="flex flex-col"> <div class="flex flex-col flex-1">
<?= form_label( <Forms.Label for="partner_link_url" hint="<?= lang('Podcast.form.partner_link_url_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_link_url') ?></Forms.Label>
lang('Podcast.form.partner_image_url'), <Forms.Input name="partner_link_url" />
'partner_image_url',
[
'class' => 'text-sm',
],
lang('Podcast.form.partner_image_url_hint'),
true,
) ?>
<?= form_input([
'id' => 'partner_image_url',
'name' => 'partner_image_url',
'class' => 'form-input w-full',
'value' => old('partner_image_url'),
]) ?>
</div> </div>
</div> </div>
<div class="flex flex-col w-full mt-2">
<Forms.Label for="partner_image_url" hint="<?= lang('Podcast.form.partner_image_url_hint') ?>" isOptional="true"><?= lang('Podcast.form.partner_image_url') ?></Forms.Label>
<Forms.Input name="partner_image_url" />
</div>
</fieldset>
</Forms.Section>
<?= form_section_close() ?> <Forms.Section
class="mb-8"
title="<?= lang('Podcast.form.advanced_section_title') ?>"
subtitle="<?= lang('Podcast.form.advanced_section_subtitle') ?>" >
<?= form_section( <Forms.Field
lang('Podcast.form.advanced_section_title'), as="XMLEditor"
lang('Podcast.form.advanced_section_subtitle'), name="custom_rss"
) ?> label="<?= lang('Podcast.form.custom_rss') ?>"
<?= form_label( hintText="<?= lang('Podcast.form.custom_rss_hint') ?>" />
lang('Podcast.form.custom_rss'),
'custom_rss',
[],
lang('Podcast.form.custom_rss_hint'),
true,
) ?>
<Forms.XMLEditor id="custom_rss" name="custom_rss"><?= old('custom_rss', '', false) ?></Forms.XMLEditor>
<?= form_section_close() ?> </Forms.Section>
<?= form_section( <Forms.Section
lang('Podcast.form.status_section_title'), class="mb-8"
lang('Podcast.form.status_section_subtitle'), title="<?= lang('Podcast.form.status_section_title') ?>" >
) ?> <Forms.Toggler class="mb-2" name="lock" value="yes" checked="true" hint="<?= lang('Podcast.form.lock_hint') ?>">
<Forms.Toggler class="mb-2" id="lock" name="lock" value="yes" checked="<?= old('complete', true) ?>" hint="<?= lang('Podcast.form.lock_hint') ?>">
<?= lang('Podcast.form.lock') ?> <?= lang('Podcast.form.lock') ?>
</Forms.Toggler> </Forms.Toggler>
<Forms.Toggler class="mb-2" id="block" name="block" value="yes" checked="<?= old('complete', false) ?>"> <Forms.Toggler class="mb-2" name="block" value="yes" checked="false">
<?= lang('Podcast.form.block') ?> <?= lang('Podcast.form.block') ?>
</Forms.Toggler> </Forms.Toggler>
<Forms.Toggler id="complete" name="complete" value="yes" checked="<?= old('complete', false) ?>"> <Forms.Toggler name="complete" value="yes" checked="false">
<?= lang('Podcast.form.complete') ?> <?= lang('Podcast.form.complete') ?>
</Forms.Toggler> </Forms.Toggler>
</Forms.Section>
<?= form_section_close() ?> <Button variant="primary" type="submit" class="self-end"><?= lang('Podcast.form.submit_create') ?></Button>
<?= button(
lang('Podcast.form.submit_create'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
</form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -18,12 +18,7 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart((string) route_to('podcast-edit', $podcast->id), [ <form id="podcast-edit-form" action="<?= route_to('podcast-edit', $podcast->id) ?>" method="POST" enctype='multipart/form-data' class="flex flex-col">
'id' => 'podcast-edit-form',
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<Forms.Section <Forms.Section
@ -210,19 +205,18 @@
<Forms.Section <Forms.Section
class="mb-8" class="mb-8"
title="<?= lang('Podcast.form.status_section_title') ?>" title="<?= lang('Podcast.form.status_section_title') ?>" >
subtitle="<?= lang('Podcast.form.status_section_subtitle') ?>" > <Forms.Toggler class="mb-2" name="lock" value="yes" checked="<?= $podcast->is_locked ? 'true' : 'false' ?>" hint="<?= lang('Podcast.form.lock_hint') ?>">
<Forms.Toggler class="mb-2" id="lock" name="lock" value="yes" checked="<?= old('complete', $podcast->is_locked) ?>" hint="<?= lang('Podcast.form.lock_hint') ?>">
<?= lang('Podcast.form.lock') ?> <?= lang('Podcast.form.lock') ?>
</Forms.Toggler> </Forms.Toggler>
<Forms.Toggler class="mb-2" id="block" name="block" value="yes" checked="<?= old('complete', $podcast->is_blocked) ?>"> <Forms.Toggler class="mb-2" name="block" value="yes" checked="<?= $podcast->is_blocked ? 'true' : 'false' ?>">
<?= lang('Podcast.form.block') ?> <?= lang('Podcast.form.block') ?>
</Forms.Toggler> </Forms.Toggler>
<Forms.Toggler id="complete" name="complete" value="yes" checked="<?= old('complete', $podcast->is_completed) ?>"> <Forms.Toggler name="complete" value="yes" checked="<?= $podcast->is_completed ? 'true' : 'false' ?>">
<?= lang('Podcast.form.complete') ?> <?= lang('Podcast.form.complete') ?>
</Forms.Toggler> </Forms.Toggler>
</Forms.Section> </Forms.Section>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -10,231 +10,90 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open_multipart(route_to('podcast-import'), [ <Alert glyph="alert" variant="danger"><?= lang('PodcastImport.warning') ?></Alert>
'method' => 'post',
'class' => 'flex flex-col items-start', <form action="<?= route_to('podcast-import') ?>" method="POST" enctype='multipart/form-data' class="flex flex-col mt-6 gap-y-8">
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<div class="inline-flex w-full p-2 mb-6 text-sm font-semibold text-yellow-800 bg-red-100 border border-red-300 rounded" role="alert"> <Forms.Section
<?= icon('alert', 'mr-2 text-lg flex-shrink-0') . title="<?= lang('PodcastImport.old_podcast_section_title') ?>"
lang('PodcastImport.warning') ?> subtitle="<?= lang('PodcastImport.old_podcast_section_subtitle') ?>"
subtitleClass="inline-flex text-xs p-2 mt-2 text-blue-800 font-semibold bg-blue-100 border border-blue-300 rounded">
<Forms.Field
name="imported_feed_url"
label="<?= lang('PodcastImport.imported_feed_url') ?>"
hintText="<?= lang('PodcastImport.imported_feed_url_hint') ?>"
placeholder="https://…"
type="url"
required="true" />
</Forms.Section>
<Forms.Section
title="<?= lang('PodcastImport.new_podcast_section_title') ?>" >
<div class="flex flex-col">
<Forms.Label for="handle" hint="<?= lang('Podcast.form.handle_hint') ?>"><?= lang('Podcast.form.handle') ?></Forms.Label>
<div class="relative">
<Icon glyph="at" class="absolute inset-0 h-full text-xl text-gray-400 left-3" />
<Forms.Input name="handle" class="w-full pl-8" required="true" />
</div>
</div> </div>
<?= form_section( <Forms.Field
lang('PodcastImport.old_podcast_section_title'), as="Select"
icon('scales', 'mr-2 text-lg flex-shrink-0') . name="language"
lang('PodcastImport.old_podcast_section_subtitle'), label="<?= lang('Podcast.form.language') ?>"
[], selected="<?= $browserLang ?>"
'inline-flex text-xs p-2 text-blue-800 font-semibold bg-blue-100 border border-blue-300 rounded', required="true"
) ?> options="<?= esc(json_encode($languageOptions)) ?>" />
<?= form_label( <Forms.Field
lang('PodcastImport.imported_feed_url'), as="Select"
'imported_feed_url', name="category"
[], label="<?= lang('Podcast.form.category') ?>"
lang('PodcastImport.imported_feed_url_hint'), required="true"
) ?> options="<?= esc(json_encode($categoryOptions)) ?>" />
<?= form_input([
'id' => 'imported_feed_url',
'name' => 'imported_feed_url',
'class' => 'form-input',
'value' => old('imported_feed_url'),
'placeholder' => 'https://...',
'type' => 'url',
'required' => 'required',
]) ?>
<?= form_section_close() ?> </Forms.Section>
<Forms.Section
title="<?= lang('PodcastImport.advanced_params_section_title') ?>"
subtitle="<?= lang('PodcastImport.advanced_params_section_subtitle') ?>" >
<?= form_section(lang('PodcastImport.new_podcast_section_title'), '') ?> <fieldset class="flex flex-col mb-4">
<legend><?= lang('PodcastImport.slug_field') ?></legend>
<Forms.Radio id="title" name="slug_field" isChecked="true">&lt;title&gt;</span></Forms.Radio>
<Forms.Radio id="link" name="slug_field">&lt;link&gt;</span></Forms.Radio>
</fieldset>
<?= form_label( <fieldset class="flex flex-col mb-4">
lang('Podcast.form.handle'),
'handle',
[],
lang('Podcast.form.handle_hint'),
) ?>
<div class="relative mb-4">
<?= icon('at', 'absolute text-xl h-full inset-0 text-gray-400 left-3') ?>
<?= form_input([
'id' => 'handle',
'name' => 'handle',
'class' => 'form-input w-full pl-8',
'value' => old('handle'),
'required' => 'required',
]) ?>
</div>
<?= form_label(lang('Podcast.form.language'), 'language') ?>
<?= form_dropdown('language', $languageOptions, [old('language', $browserLang)], [
'id' => 'language',
'class' => 'form-select mb-4',
'required' => 'required',
]) ?>
<?= form_label(lang('Podcast.form.category'), 'category') ?>
<?= form_dropdown('category', $categoryOptions, [old('category', '')], [
'id' => 'category',
'class' => 'form-select mb-4',
'required' => 'required',
'placeholder' => lang('Podcast.form.category_placeholder'),
]) ?>
<?= form_section_close() ?>
<?= form_section(
lang('PodcastImport.advanced_params_section_title'),
lang('PodcastImport.advanced_params_section_subtitle'),
) ?>
<?= form_fieldset('', [
'class' => 'flex flex-col mb-4',
]) ?>
<legend><?= lang('PodcastImport.slug_field.label') ?></legend>
<label for="link" class="inline-flex items-center">
<?= form_radio(
[
'id' => 'title',
'name' => 'slug_field',
'class' => 'form-radio text-pine-700',
],
'title',
old('slug_field') ? old('slug_field') === 'title' : true,
) ?>
<span class="ml-2"><?= lang('PodcastImport.slug_field.title') ?></span>
</label>
<label for="title" class="inline-flex items-center">
<?= form_radio(
[
'id' => 'link',
'name' => 'slug_field',
'class' => 'form-radio text-pine-700',
],
'link',
old('slug_field') && old('slug_field') === 'link',
) ?>
<span class="ml-2"><?= lang('PodcastImport.slug_field.link') ?></span>
</label>
<?= form_fieldset_close() ?>
<?= form_fieldset('', [
'class' => 'flex flex-col mb-4',
]) ?>
<legend><?= lang('PodcastImport.description_field') ?></legend> <legend><?= lang('PodcastImport.description_field') ?></legend>
<label for="description" class="inline-flex items-center"> <Forms.Radio id="description" name="description_field" isChecked="true">&lt;description&gt;</Forms.Radio>
<?= form_radio( <Forms.Radio id="summary" name="description_field">&lt;itunes:summary&gt;</Forms.Radio>
[ <Forms.Radio id="subtitle_summary" name="description_field">&lt;itunes:subtitle&gt; + &lt;itunes:summary&gt;</Forms.Radio>
'id' => 'description', <Forms.Radio id="content" name="description_field">&lt;content:encoded&gt;</Forms.Radio>
'name' => 'description_field', </fieldset>
'class' => 'form-radio text-pine-700',
],
'description',
old('description_field')
? old('description_field') === 'description'
: true,
) ?>
<span class="ml-2">&lt;description&gt;</span>
</label>
<label for="summary" class="inline-flex items-center">
<?= form_radio(
[
'id' => 'summary',
'name' => 'description_field',
'class' => 'form-radio text-pine-600',
],
'summary',
old('description_field') && old('description_field') === 'summary',
) ?>
<span class="ml-2">&lt;itunes:summary&gt;</span>
</label>
<label for="subtitle_summary" class="inline-flex items-center">
<?= form_radio(
[
'id' => 'subtitle_summary',
'name' => 'description_field',
'class' => 'form-radio text-pine-700',
],
'subtitle_summary',
old('description_field') &&
old('description_field') === 'subtitle_summary',
) ?>
<span class="ml-2">&lt;itunes:subtitle&gt; + &lt;itunes:summary&gt;</span>
</label>
<label for="content" class="inline-flex items-center">
<?= form_radio(
[
'id' => 'content',
'name' => 'description_field',
'class' => 'form-radio text-pine-700',
],
'content',
old('description_field') && old('description_field') === 'content',
) ?>
<span class="ml-2">&lt;content:encoded&gt;</span>
</label>
<?= form_fieldset_close() ?>
<Forms.Checkbox name="force_renumber" hint="<?= lang('PodcastImport.force_renumber_hint') ?>"><?= lang('PodcastImport.force_renumber') ?></Forms.Checkbox>
<label class="inline-flex items-center mb-4"> <Forms.Field
<?= form_checkbox( name="season_number"
[ type="number"
'id' => 'force_renumber', label="<?= lang('PodcastImport.season_number') ?>"
'name' => 'force_renumber', hintText="<?= lang('PodcastImport.season_number_hint') ?>" />
'class' => 'form-checkbox text-pine-700',
],
'yes',
old('force_renumber', false),
) ?>
<span class="ml-2"><?= lang('PodcastImport.force_renumber') ?></span>
<?= hint_tooltip(lang('PodcastImport.force_renumber_hint'), 'ml-1') ?>
</label>
<?= form_label( <Forms.Field
lang('PodcastImport.season_number'), name="max_episodes"
'season_number', type="number"
[], label="<?= lang('PodcastImport.max_episodes') ?>"
lang('PodcastImport.season_number_hint'), hintText="<?= lang('PodcastImport.max_episodes_hint') ?>" />
) ?>
<?= form_input([
'id' => 'season_number',
'name' => 'season_number',
'class' => 'form-input mb-4',
'value' => old('season_number'),
'type' => 'number',
]) ?>
<?= form_label( </Forms.Section>
lang('PodcastImport.max_episodes'),
'max_episodes',
[],
lang('PodcastImport.max_episodes_hint'),
) ?>
<?= form_input([
'id' => 'max_episodes',
'name' => 'max_episodes',
'class' => 'form-input mb-4',
'value' => old('max_episodes'),
'type' => 'number',
]) ?>
<?= form_section_close() ?> <Button variant="primary" type="submit" class="self-end"><?= lang('PodcastImport.submit') ?></Button>
<?= button( </form>
lang('PodcastImport.submit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -24,22 +24,10 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('podcast-person-edit', $podcast->id), [
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?>
<?= form_section(
lang('Person.podcast_form.manage_section_title'),
lang('Person.podcast_form.manage_section_subtitle'),
) ?>
<?= data_table( <?= data_table(
[ [
[ [
'header' => lang('Person.podcast_form.person'), 'header' => lang('Person.podcast_form.persons'),
'cell' => function ($person) { 'cell' => function ($person) {
return '<div class="flex">' . return '<div class="flex">' .
'<a href="' . '<a href="' .
@ -90,43 +78,24 @@
$podcast->persons, $podcast->persons,
) ?> ) ?>
<?= form_section_close() ?> <form action="<?= route_to('podcast-person-edit', $podcast->id) ?>" method="POST" class="mt-6">
<?= csrf_field() ?>
<Forms.Section
title="<?= lang('Person.podcast_form.add_section_title') ?>"
subtitle="<?= lang('Person.podcast_form.add_section_subtitle') ?>"
>
<?= form_section( <Forms.Label for="persons" hint="<?= lang('Person.podcast_form.persons_hint') ?>"><?= lang('Person.podcast_form.persons') ?></Forms.Label>
lang('Person.podcast_form.add_section_title'), <Forms.MultiSelect id="persons" name="persons[]" class="mb-4" required="required" options="<?= esc(json_encode($personOptions)) ?>" selected="<?= esc(json_encode(old('persons', []))) ?>"/>
lang('Person.podcast_form.add_section_subtitle'),
) ?>
<?= form_label( <Forms.Label for="roles" hint="<?= lang('Person.podcast_form.roles_hint') ?>" isOptional="true"><?= lang('Person.podcast_form.roles') ?></Forms.Label>
lang('Person.podcast_form.persons'), <Forms.MultiSelect id="roles" name="roles[]" class="mb-4" options="<?= esc(json_encode($taxonomyOptions)) ?>" selected="<?= esc(json_encode(old('roles', []))) ?>"/>
'persons',
[],
lang('Person.podcast_form.persons_hint'),
) ?>
<Forms.MultiSelect id="persons" name="persons[]" class="mb-4" required="required" options="<?= htmlspecialchars(json_encode($personOptions)) ?>" selected="<?= htmlspecialchars(json_encode(old('persons', []))) ?>"/>
<?= form_label( <Button variant="primary" class="self-end" type="submit"><?= lang('Person.podcast_form.submit_add') ?></Button>
lang('Person.podcast_form.roles'),
'roles',
[],
lang('Person.podcast_form.roles_hint'),
true,
) ?>
<Forms.MultiSelect id="roles" name="roles[]" class="mb-4" options="<?= htmlspecialchars(json_encode($taxonomyOptions)) ?>" selected="<?= htmlspecialchars(json_encode(old('roles', []))) ?>"/>
<?= form_section_close() ?> </Forms.Section>
<?= button(
lang('Person.podcast_form.submit_add'), </form>
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -81,46 +81,30 @@
], ],
) )
: '' ?> : '' ?>
<?= form_label($platform->label, $platform->slug, [ <fieldset>
'class' => 'font-semibold mb-2', <legend class="mb-2 font-semibold"><?= $platform->label ?></legend>
]) ?> <Forms.Input
<?= form_input([ class="w-full mb-1"
'id' => $platform->slug . '_link_url', id="<?= $platform->slug . '_link_url' ?>"
'name' => 'platforms[' . $platform->slug . '][url]', name="<?= 'platforms[' . $platform->slug . '][url]' ?>"
'class' => 'form-input mb-1 w-full', value="<?= $platform->link_url ?>"
'value' => old($platform->slug . '_link_url', $platform->link_url), type="url"
'type' => 'url', placeholder="https://…" />
'placeholder' => 'https://...', <Forms.Input
]) ?> class="w-full mb-1"
<?= form_input([ id="<?= $platform->slug . '_link_content' ?>"
'id' => $platform->slug . '_link_content', name="<?= 'platforms[' . $platform->slug . '][content]' ?>"
'name' => 'platforms[' . $platform->slug . '][content]', value="<?= $platform->link_content ?>"
'class' => 'form-input mb-1 w-full', placeholder="<?= lang("Platforms.description.{$platform->type}") ?>" />
'value' => old( <Forms.Toggler size="small" class="text-sm" id="<?= $platform->slug . '_visible' ?>" name="<?= 'platforms[' . $platform->slug . '][visible]'?>" value="yes" checked="<?= old($platform->slug . '_visible', $platform->is_visible ? $platform->is_visible : false) ?>"><?= lang('Platforms.visible') ?></Forms.Toggler>
$platform->slug . '_link_content', <Forms.Toggler size="small" class="text-sm" id="<?= $platform->slug . '_on_embeddable_player' ?>" name="<?= 'platforms[' . $platform->slug . '][on_embeddable_player]'?>" value="yes" checked="<?= old($platform->slug . '_on_embeddable_player', $platform->is_on_embeddable_player ? $platform->is_on_embeddable_player : false) ?>"><?= lang('Platforms.on_embeddable_player') ?></Forms.Toggler>
$platform->link_content, </fieldset>
),
'type' => 'text',
'placeholder' => lang("Platforms.description.{$platform->type}"),
]) ?>
<Forms.Toggler class="mb-1 text-sm" id="<?= $platform->slug . '_visible' ?>" name="<?= 'platforms[' . $platform->slug . '][visible]'?>" value="yes" checked="<?= old($platform->slug . '_visible', $platform->is_visible ? $platform->is_visible : false) ?>"><?= lang('Platforms.visible') ?></Forms.Toggler>
<Forms.Toggler class="text-sm" id="<?= $platform->slug . '_on_embeddable_player' ?>" name="<?= 'platforms[' . $platform->slug . '][on_embeddable_player]'?>" value="yes" checked="<?= old($platform->slug . '_on_embeddable_player', $platform->is_on_embeddable_player ? $platform->is_on_embeddable_player : false) ?>"><?= lang('Platforms.on_embeddable_player') ?></Forms.Toggler>
</div> </div>
</div> </div>
<?php endforeach; ?> <?php endforeach; ?>
<?= button( <Button variant="primary" type="submit" class="self-end"><?= lang('Platforms.submit') ?></Button>
lang('Platforms.submit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> <?= form_close() ?>

View File

@ -19,7 +19,7 @@
<a href="<?= route_to( <a href="<?= route_to(
'home', 'home',
) ?>" class="inline-flex items-baseline text-3xl font-semibold font-display"><?= 'castopod' . ) ?>" class="inline-flex items-baseline text-3xl font-semibold font-display"><?= 'castopod' .
svg('castopod-logo', 'h-6 ml-2') ?></a> svg('castopod-logo-base', 'h-6 ml-2') ?></a>
</div> </div>
</header> </header>
<main class="container flex-1 px-4 py-10 mx-auto"> <main class="container flex-1 px-4 py-10 mx-auto">

View File

@ -26,7 +26,7 @@
<div class="fixed top-0 left-0 z-50 flex items-center justify-between w-full h-12 px-4 text-white shadow bg-pine-800"> <div class="fixed top-0 left-0 z-50 flex items-center justify-between w-full h-12 px-4 text-white shadow bg-pine-800">
<?= anchor( <?= anchor(
route_to('admin'), route_to('admin'),
'castopod' . svg('castopod-logo', 'h-5 ml-1'), 'castopod' . svg('castopod-logo-base', 'h-5 ml-1'),
[ [
'class' => 'class' =>
'text-2xl inline-flex items-baseline font-bold font-display', 'text-2xl inline-flex items-baseline font-bold font-display',

View File

@ -1,5 +1,5 @@
<footer> <footer>
<form action="<?= route_to('comment-attempt-like', interact_as_actor()->username, $episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4"> <form action="<?= route_to('comment-attempt-like', interact_as_actor()->username, $comment->episode->slug, $comment->id) ?>" method="POST" class="flex items-center gap-x-4">
<button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang( <button type="submit" name="action" class="inline-flex items-center hover:underline group" title="<?= lang(
'Comment.likes', 'Comment.likes',
[ [
@ -8,7 +8,7 @@
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button> ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $comment->likes_count ?></button>
<?= button( <?= button(
lang('Comment.reply'), lang('Comment.reply'),
route_to('comment', $podcast->handle, $episode->slug, $comment->id), route_to('comment', $podcast->handle, $comment->episode->slug, $comment->id),
[ [
'size' => 'small', 'size' => 'small',
], ],
@ -16,7 +16,7 @@
</form> </form>
<?php if ($comment->replies_count): ?> <?php if ($comment->replies_count): ?>
<?= anchor( <?= anchor(
route_to('comment', $podcast->handle, $episode->slug, $comment->id), route_to('comment', $podcast->handle, $comment->episode->slug, $comment->id),
icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', [ icon('caret-down', 'text-xl mr-1') . lang('Comment.view_replies', [
'numberOfReplies' => $comment->replies_count, 'numberOfReplies' => $comment->replies_count,
]), ]),

View File

@ -21,6 +21,6 @@
</div> </div>
<?= relative_time($episode->published_at, 'text-xs whitespace-nowrap') ?> <?= relative_time($episode->published_at, 'text-xs whitespace-nowrap') ?>
</a> </a>
<?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype, 'mt-auto') ?> <?= play_episode_button($episode->id, $episode->image->thumbnail_url, $episode->title, $episode->podcast->title, $episode->audio_file_web_url, $episode->audio_file_mimetype, 'mt-auto') ?>
</div> </div>
</div> </div>

View File

@ -46,11 +46,13 @@
<?php if ($post->reblog_of_id !== null): ?> <?php if ($post->reblog_of_id !== null): ?>
<?= view('podcast/_partials/reblog', [ <?= view('podcast/_partials/reblog', [
'post' => $post->reblog_of_post, 'post' => $post->reblog_of_post,
]) ?> 'podcast' => $podcast,
]) ?>
<?php else: ?> <?php else: ?>
<?= view('podcast/_partials/post', [ <?= view('podcast/_partials/post', [
'post' => $post, 'post' => $post,
]) ?> 'podcast' => $podcast,
]) ?>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
</section> </section>

View File

@ -100,10 +100,12 @@
<?php if ($post->reblog_of_id !== null): ?> <?php if ($post->reblog_of_id !== null): ?>
<?= view('podcast/_partials/reblog_authenticated', [ <?= view('podcast/_partials/reblog_authenticated', [
'post' => $post->reblog_of_post, 'post' => $post->reblog_of_post,
'podcast' => $podcast,
]) ?> ]) ?>
<?php else: ?> <?php else: ?>
<?= view('podcast/_partials/post_authenticated', [ <?= view('podcast/_partials/post_authenticated', [
'post' => $post, 'post' => $post,
'podcast' => $podcast,
]) ?> ]) ?>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>

View File

@ -98,6 +98,7 @@
<?php foreach ($episode->posts as $post): ?> <?php foreach ($episode->posts as $post): ?>
<?= view('podcast/_partials/post', [ <?= view('podcast/_partials/post', [
'post' => $post, 'post' => $post,
'podcast' => $podcast,
]) ?> ]) ?>
<?php endforeach; ?> <?php endforeach; ?>
</section> </section>

View File

@ -132,6 +132,7 @@
<?php foreach ($episode->comments as $comment): ?> <?php foreach ($episode->comments as $comment): ?>
<?= view('podcast/_partials/comment_authenticated', [ <?= view('podcast/_partials/comment_authenticated', [
'comment' => $comment, 'comment' => $comment,
'podcast' => $podcast,
]) ?> ]) ?>
<?php endforeach; ?> <?php endforeach; ?>
</section> </section>
@ -186,6 +187,7 @@
<?php foreach ($episode->posts as $post): ?> <?php foreach ($episode->posts as $post): ?>
<?= view('podcast/_partials/post_authenticated', [ <?= view('podcast/_partials/post_authenticated', [
'post' => $post, 'post' => $post,
'podcast' => $podcast,
]) ?> ]) ?>
<?php endforeach; ?> <?php endforeach; ?>
</section> </section>