refactor: replace ui function components with class components + fix

soundbites js
This commit is contained in:
Yassine Doghri 2021-09-20 15:45:38 +00:00
parent 5413d09737
commit 746b518789
60 changed files with 507 additions and 1535 deletions

View File

@ -52,7 +52,7 @@ Other:
- [Kumbh Sans](https://fonts.google.com/specimen/Kumbh+Sans) - [Kumbh Sans](https://fonts.google.com/specimen/Kumbh+Sans)
([Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)) ([Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL))
- [Montserrat](https://fonts.google.com/specimen/Montserrat) - [Inter](https://fonts.google.com/specimen/Inter)
([Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL)) ([Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL))
- [RemixIcon](https://remixicon.com/) - [RemixIcon](https://remixicon.com/)
([Apache License 2.0](https://github.com/Remix-Design/RemixIcon/blob/master/License)) ([Apache License 2.0](https://github.com/Remix-Design/RemixIcon/blob/master/License))

View File

@ -12,140 +12,6 @@ use App\Entities\Person;
use CodeIgniter\I18n\Time; use CodeIgniter\I18n\Time;
use CodeIgniter\View\Table; use CodeIgniter\View\Table;
if (! function_exists('button')) {
/**
* Button component
*
* Creates a stylized button or button like anchor tag if the URL is defined.
*
* @param array<string, string|null|bool> $customOptions button options: variant, size, iconLeft, iconRight
* @param array<string, string> $customAttributes Additional attributes
*/
function button(
string $label = '',
string $uri = '',
array $customOptions = [],
array $customAttributes = []
): string {
$defaultOptions = [
'variant' => 'default',
'size' => 'base',
'iconLeft' => null,
'iconRight' => null,
'isSquared' => false,
];
$options = array_merge($defaultOptions, $customOptions);
$baseClass =
'inline-flex items-center font-semibold shadow-xs rounded-full focus:outline-none focus:ring';
$variantClass = [
'default' => 'text-black bg-gray-300 hover:bg-gray-400',
'primary' => 'text-white bg-pine-500 hover:bg-pine-800',
'secondary' => 'text-white bg-gray-700 hover:bg-gray-800',
'accent' => 'text-white bg-rose-600 hover:bg-rose-800',
'success' => 'text-white bg-green-600 hover:bg-green-700',
'danger' => 'text-white bg-red-600 hover:bg-red-700',
'warning' => 'text-black bg-yellow-500 hover:bg-yellow-600',
'info' => 'text-white bg-blue-500 hover:bg-blue-600',
];
$sizeClass = [
'small' => 'text-xs md:text-sm',
'base' => 'text-sm md:text-base',
'large' => 'text-lg md:text-xl',
];
$basePaddings = [
'small' => 'px-2 md:px-3 md:py-1',
'base' => 'px-3 py-1 md:px-4 md:py-2',
'large' => 'px-3 py-2 md:px-5',
];
$squaredPaddings = [
'small' => 'p-1',
'base' => 'p-2',
'large' => 'p-3',
];
$buttonClass =
$baseClass .
' ' .
($options['isSquared']
? $squaredPaddings[$options['size']]
: $basePaddings[$options['size']]) .
' ' .
$sizeClass[$options['size']] .
' ' .
$variantClass[$options['variant']];
if (array_key_exists('class', $customAttributes)) {
$buttonClass .= ' ' . $customAttributes['class'];
unset($customAttributes['class']);
}
if ($options['iconLeft']) {
$label = icon((string) $options['iconLeft'], 'mr-2') . $label;
}
if ($options['iconRight']) {
$label .= icon((string) $options['iconRight'], 'ml-2');
}
if ($uri !== '') {
return anchor($uri, $label, array_merge([
'class' => $buttonClass,
], $customAttributes));
}
$defaultButtonAttributes = [
'type' => 'button',
];
$attributes = stringify_attributes(array_merge($defaultButtonAttributes, $customAttributes));
return <<<CODE_SAMPLE
<button class="{$buttonClass}" {$attributes}>
{$label}
</button>
CODE_SAMPLE;
}
}
// ------------------------------------------------------------------------
if (! function_exists('icon_button')) {
/**
* Icon Button component
*
* Abstracts the `button()` helper to create a stylized icon button
*
* @param string $icon The button icon
* @param string $title The button label
* @param array<string, string|null|bool> $customOptions button options: variant, size, iconLeft, iconRight
* @param array<string, string> $customAttributes Additional attributes
*/
function icon_button(
string $icon,
string $title,
string $uri = '',
array $customOptions = [],
array $customAttributes = []
): string {
$defaultOptions = [
'isSquared' => true,
];
$options = array_merge($defaultOptions, $customOptions);
$defaultAttributes = [
'title' => $title,
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
];
$attributes = array_merge($defaultAttributes, $customAttributes);
return button(icon($icon), $uri, $options, $attributes);
}
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (! function_exists('hint_tooltip')) { if (! function_exists('hint_tooltip')) {
@ -296,13 +162,14 @@ if (! function_exists('publication_button')) {
break; break;
} }
return button($label, $route, [ return <<<CODE_SAMPLE
'variant' => $variant, <Button variant="{$variant}" uri="{$route}" iconLeft="{$iconLeft}" >{$label}</Button>
'iconLeft' => $iconLeft, CODE_SAMPLE;
]);
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (! function_exists('episode_numbering')) { if (! function_exists('episode_numbering')) {
/** /**
* Returns relevant translated episode numbering. * Returns relevant translated episode numbering.
@ -354,6 +221,9 @@ if (! function_exists('episode_numbering')) {
'</span>'; '</span>';
} }
} }
// ------------------------------------------------------------------------
if (! function_exists('location_link')) { if (! function_exists('location_link')) {
/** /**
* Returns link to display from location info * Returns link to display from location info
@ -377,7 +247,9 @@ if (! function_exists('location_link')) {
); );
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (! function_exists('person_list')) { if (! function_exists('person_list')) {
/** /**
* Returns list of persons images * Returns list of persons images
@ -430,7 +302,9 @@ if (! function_exists('person_list')) {
return $personList . '</div>'; return $personList . '</div>';
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (! function_exists('play_episode_button')) { if (! function_exists('play_episode_button')) {
/** /**
* Returns play episode button * Returns play episode button
@ -462,7 +336,9 @@ if (! function_exists('play_episode_button')) {
CODE_SAMPLE; CODE_SAMPLE;
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (! function_exists('audio_player')) { if (! function_exists('audio_player')) {
/** /**
* Returns audio player * Returns audio player
@ -500,7 +376,9 @@ if (! function_exists('audio_player')) {
CODE_SAMPLE; CODE_SAMPLE;
} }
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
if (! function_exists('relative_time')) { if (! function_exists('relative_time')) {
function relative_time(Time $time, string $class = ''): string function relative_time(Time $time, string $class = ''): string
{ {

View File

@ -8,137 +8,6 @@ declare(strict_types=1);
* @link https://castopod.org/ * @link https://castopod.org/
*/ */
if (! function_exists('form_section')) {
/**
* Form section
*
* Used to produce a responsive form section with a title and subtitle. To close section, use form_section_close()
*
* @param string $title The section title
* @param string $subtitle The section subtitle
* @param array<string, string> $attributes Additional attributes
*/
function form_section(
string $title = '',
string $subtitle = '',
array $attributes = [],
string $customSubtitleClass = ''
): string {
$subtitleClass = 'text-sm text-gray-600';
if ($customSubtitleClass !== '') {
$subtitleClass = $customSubtitleClass;
}
$section =
'<div class="flex flex-wrap w-full gap-6 mb-8"' .
stringify_attributes($attributes) .
">\n";
$info =
'<div class="w-full max-w-xs"><h2 class="text-lg font-semibold">' .
$title .
'</h2><p class="' .
$subtitleClass .
'">' .
$subtitle .
'</p></div>';
return $section . $info . '<div class="flex flex-col w-full max-w-lg">';
}
}
//--------------------------------------------------------------------
if (! function_exists('form_section_close')) {
/**
* Form Section close Tag
*/
function form_section_close(string $extra = ''): string
{
return '</div></div>' . $extra;
}
}
//--------------------------------------------------------------------
if (! function_exists('form_switch')) {
/**
* Form Checkbox Switch
*
* Abstracts form_label to stylize it as a switch toggle
*
* @param mixed[] $data
* @param mixed[] $extra
*/
function form_switch(
string $label = '',
array $data = [],
string $value = '',
bool $checked = false,
string $class = '',
array $extra = []
): string {
$data['class'] = 'form-switch';
return '<label class="relative inline-flex items-center' .
' ' .
$class .
'">' .
form_checkbox($data, $value, $checked, $extra) .
'<span class="form-switch-slider"></span>' .
'<span class="ml-2">' .
$label .
'</span></label>';
}
}
//--------------------------------------------------------------------
if (! function_exists('form_label')) {
/**
* Form Label Tag
*
* @param string $text The text to appear onscreen
* @param string $id The id the label applies to
* @param array<string, string> $attributes Additional attributes
* @param string $hintText Hint text to add next to the label
* @param boolean $isOptional adds an optional text if true
*/
function form_label(
string $text = '',
string $id = '',
array $attributes = [],
string $hintText = '',
bool $isOptional = false
): string {
$label = '<label';
if ($id !== '') {
$label .= ' for="' . $id . '"';
}
if (is_array($attributes) && $attributes) {
foreach ($attributes as $key => $val) {
$label .= ' ' . $key . '="' . $val . '"';
}
}
$labelContent = $text;
if ($isOptional) {
$labelContent .=
'<small class="ml-1 lowercase">(' .
lang('Common.optional') .
')</small>';
}
if ($hintText !== '') {
$labelContent .= hint_tooltip($hintText, 'ml-1');
}
return $label . '>' . $labelContent . '</label>';
}
}
//-------------------------------------------------------------------- //--------------------------------------------------------------------
if (! function_exists('form_dropdown')) { if (! function_exists('form_dropdown')) {

View File

@ -59,36 +59,28 @@ const Soundbites = (): void => {
if (soundbitePlayButtons) { if (soundbitePlayButtons) {
for (let i = 0; i < soundbitePlayButtons.length; i++) { for (let i = 0; i < soundbitePlayButtons.length; i++) {
const soundbitePlayButton: HTMLButtonElement = soundbitePlayButtons[i]; const soundbitePlayButton: HTMLButtonElement = soundbitePlayButtons[i];
soundbitePlayButton.addEventListener("click", () => {
playSoundbite(
audioPlayer,
Number(soundbitePlayButton.dataset.soundbiteStartTime),
Number(soundbitePlayButton.dataset.soundbiteDuration)
);
});
}
}
const inputFields: NodeListOf<HTMLInputElement> | null = soundbitePlayButton.addEventListener("click", () => {
document.querySelectorAll("input[data-type='soundbite-field']"); // get values from inputs to play soundbite
if (inputFields) { const startTime: HTMLInputElement | null | undefined =
for (let i = 0; i < inputFields.length; i++) { soundbitePlayButton.parentElement?.parentElement?.querySelector(
const inputField: HTMLInputElement = inputFields[i]; 'input[data-field-type="start_time"]'
const soundbitePlayButton: HTMLButtonElement | null = );
document.querySelector( const duration: HTMLInputElement | null | undefined =
`button[data-type="play-soundbite"][data-soundbite-id="${inputField.dataset.soundbiteId}"]` soundbitePlayButton.parentElement?.parentElement?.querySelector(
); 'input[data-field-type="duration"]'
if (soundbitePlayButton) { );
if (inputField.dataset.fieldType == "start-time") {
inputField.addEventListener("input", () => { console.log(soundbitePlayButton.parentElement);
soundbitePlayButton.dataset.soundbiteStartTime = inputField.value;
}); if (startTime && duration) {
} else if (inputField.dataset.fieldType == "duration") { playSoundbite(
inputField.addEventListener("input", () => { audioPlayer,
soundbitePlayButton.dataset.soundbiteDuration = inputField.value; parseFloat(startTime.value),
}); parseFloat(duration.value)
);
} }
} });
} }
} }
} }

View File

@ -15,7 +15,7 @@
} }
& .holy-grail__main { & .holy-grail__main {
@apply col-start-1 col-end-3 row-start-2 row-end-3; @apply col-start-1 col-end-3 row-start-2 row-end-4;
} }
& .holy-grail__footer { & .holy-grail__footer {

View File

@ -33,7 +33,7 @@ class Alert extends Component
$attributes = stringify_attributes($this->attributes); $attributes = stringify_attributes($this->attributes);
return <<<HTML return <<<HTML
<div class="{$class}" role="alert" {$attributes}>{$glyph}<div>{$title}{$this->slot}</div></div> <div class="{$class}" role="alert" {$attributes}>{$glyph}<div>{$title}<p>{$this->slot}</p></div></div>
HTML; HTML;
} }
} }

View File

@ -10,20 +10,25 @@ class Field extends FormComponent
protected string $label = ''; protected string $label = '';
protected ?string $helperText = null; protected ?string $helper = null;
protected ?string $hintText = null; protected ?string $hint = null;
public function render(): string public function render(): string
{ {
$helperText = $this->helperText === null ? '' : '<Forms.Helper>' . $this->helperText . '</Forms.Helper>'; $helperText = '';
if ($this->helper !== null) {
$helperId = $this->id . 'Help';
$helperText = '<Forms.Helper id="' . $helperId . '">' . $this->helper . '</Forms.Helper>';
$this->attributes['aria-describedby'] = $helperId;
}
$labelAttributes = [ $labelAttributes = [
'for' => $this->id, 'for' => $this->id,
'isOptional' => $this->required ? 'false' : 'true', 'isOptional' => $this->required ? 'false' : 'true',
]; ];
if ($this->hintText) { if ($this->hint) {
$labelAttributes['hint'] = $this->hintText; $labelAttributes['hint'] = $this->hint;
} }
$labelAttributes = stringify_attributes($labelAttributes); $labelAttributes = stringify_attributes($labelAttributes);

View File

@ -16,7 +16,7 @@ class Helper extends FormComponent
$class = 'text-gray-600'; $class = 'text-gray-600';
return <<<HTML return <<<HTML
<small class="{$class} {$this->class}">{$this->slot}</small> <small id="{$this->id}" class="{$class} {$this->class}">{$this->slot}</small>
HTML; HTML;
} }
} }

View File

@ -15,17 +15,17 @@ class Select extends FormComponent
public function setOptions(string $value): void public function setOptions(string $value): void
{ {
// dd(json_decode(html_entity_decode(html_entity_decode($value)), true));
$this->options = json_decode(html_entity_decode($value), true); $this->options = json_decode(html_entity_decode($value), true);
} }
public function render(): string public function render(): string
{ {
$defaultAttributes = [ $defaultAttributes = [
'data-class' => 'border-3 rounded-lg ' . $this->class, 'class' => 'focus:border-black focus:ring-2 focus:ring-pine-500 focus:ring-offset-2 focus:ring-offset-pine-100 border-3 rounded-lg border-black ' . $this->class,
'data-class' => $this->class,
]; ];
$extra = array_merge($defaultAttributes, $this->attributes); $extra = array_merge($this->attributes, $defaultAttributes);
return form_dropdown($this->name, $this->options, $this->selected !== '' ? [$this->selected] : [], $extra); return form_dropdown($this->name, $this->options, old($this->name, $this->selected !== '' ? [$this->selected] : []), $extra);
} }
} }

View File

@ -12,10 +12,20 @@ class IconButton extends Component
public function render(): string public function render(): string
{ {
$attributes = stringify_attributes($this->attributes); $attributes = [
'isSquared' => 'true',
'title' => $this->slot,
'data-toggle' => 'tooltip',
'data-placement' => 'bottom',
];
return <<<HTML $attributes = array_merge($attributes, $this->attributes);
<Button isSquared="true" title="{$this->slot}" data-toggle="tooltip" data-placement="bottom" {$attributes}><Icon glyph="{$this->glyph}" /></Button>
HTML; $attributes['slot'] = icon($this->glyph);
unset($attributes['glyph']);
$iconButton = new Button($attributes);
return $iconButton->render();
} }
} }

View File

@ -722,6 +722,7 @@ class EpisodeController extends BaseController
"soundbites.{$soundbite_id}.duration" => 'required|decimal|greater_than_equal_to[0]', "soundbites.{$soundbite_id}.duration" => 'required|decimal|greater_than_equal_to[0]',
]; ];
} }
if (! $this->validate($rules)) { if (! $this->validate($rules)) {
return redirect() return redirect()
->back() ->back()
@ -730,34 +731,33 @@ class EpisodeController extends BaseController
} }
foreach ($soundbites as $soundbite_id => $soundbite) { foreach ($soundbites as $soundbite_id => $soundbite) {
if ((int) $soundbite['start_time'] < (int) $soundbite['duration']) { $data = [
$data = [ 'podcast_id' => $this->podcast->id,
'podcast_id' => $this->podcast->id, 'episode_id' => $this->episode->id,
'episode_id' => $this->episode->id, 'start_time' => (float) $soundbite['start_time'],
'start_time' => (float) $soundbite['start_time'], 'duration' => (float) $soundbite['duration'],
'duration' => (float) $soundbite['duration'], 'label' => $soundbite['label'],
'label' => $soundbite['label'], 'updated_by' => user_id(),
'updated_by' => user_id(), ];
if ($soundbite_id === 0) {
$data += [
'created_by' => user_id(),
]; ];
if ($soundbite_id === 0) { } else {
$data += [ $data += [
'created_by' => user_id(), 'id' => $soundbite_id,
]; ];
} else { }
$data += [
'id' => $soundbite_id,
];
}
$soundbiteModel = new SoundbiteModel(); $soundbiteModel = new SoundbiteModel();
if (! $soundbiteModel->save($data)) { if (! $soundbiteModel->save($data)) {
return redirect() return redirect()
->back() ->back()
->withInput() ->withInput()
->with('errors', $soundbiteModel->errors()); ->with('errors', $soundbiteModel->errors());
}
} }
} }
return redirect()->route('soundbites-edit', [$this->podcast->id, $this->episode->id]); return redirect()->route('soundbites-edit', [$this->podcast->id, $this->episode->id]);
} }

View File

@ -130,7 +130,7 @@ class InstallController extends Controller
session() session()
->setFlashdata('error', lang('Install.messages.databaseConnectError')); ->setFlashdata('error', lang('Install.messages.databaseConnectError'));
return view('database_config'); return $this->databaseConfig();
} }
// migrate if no user has been created // migrate if no user has been created

View File

@ -9,6 +9,7 @@ declare(strict_types=1);
*/ */
return [ return [
'title' => 'Castopod installer',
'manual_config' => 'Manual configuration', 'manual_config' => 'Manual configuration',
'manual_config_subtitle' => 'manual_config_subtitle' =>
'Create a `.env` file with your settings and refresh the page to continue installation.', 'Create a `.env` file with your settings and refresh the page to continue installation.',

View File

@ -9,6 +9,7 @@ declare(strict_types=1);
*/ */
return [ return [
'title' => 'Installeur Castopod',
'manual_config' => 'Configuration manuelle', 'manual_config' => 'Configuration manuelle',
'manual_config_subtitle' => 'manual_config_subtitle' =>
'Créez un fichier `.env` qui contient tous vos paramètres puis rafraichissez la page pour continuer linstallation.', 'Créez un fichier `.env` qui contient tous vos paramètres puis rafraichissez la page pour continuer linstallation.',

View File

@ -9,10 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button(lang('Contributor.add'), route_to('contributor-add', $podcast->id), [ <Button uri="<?= route_to('contributor-add', $podcast->id) ?>" variant="accent" iconLeft="add"><?= lang('Contributor.add') ?></Button>
'variant' => 'accent',
'iconLeft' => 'add',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
@ -35,36 +32,8 @@
[ [
'header' => lang('Common.actions'), 'header' => lang('Common.actions'),
'cell' => function ($contributor, $podcast) { 'cell' => function ($contributor, $podcast) {
return button( return '<Button uri="' . route_to('contributor-edit', $podcast->id, $contributor->id) . '" variant="info" size="small">' . lang('Contributor.edit') . '</Button>' .
lang('Contributor.edit'), '<Button uri="' . route_to('contributor-remove', $podcast->id, $contributor->id) . '" variant="danger" size="small">' . lang('Contributor.remove') . '</Button>';
route_to(
'contributor-edit',
$podcast->id,
$contributor->id,
),
[
'variant' => 'info',
'size' => 'small',
],
[
'class' => 'mr-2',
],
) .
button(
lang('Contributor.remove'),
route_to(
'contributor-remove',
$podcast->id,
$contributor->id,
),
[
'variant' => 'danger',
'size' => 'small',
],
[
'class' => 'mr-2',
],
);
}, },
], ],
], ],

View File

@ -22,7 +22,7 @@
<Forms.Field <Forms.Field
name="audio_file" name="audio_file"
label="<?= lang('Episode.form.audio_file') ?>" label="<?= lang('Episode.form.audio_file') ?>"
hintText="<?= lang('Episode.form.audio_file_hint') ?>" hint="<?= lang('Episode.form.audio_file_hint') ?>"
type="file" type="file"
accept=".mp3,.m4a" accept=".mp3,.m4a"
required="true" /> required="true" />
@ -30,15 +30,15 @@
<Forms.Field <Forms.Field
name="image" name="image"
label="<?= lang('Episode.form.image') ?>" label="<?= lang('Episode.form.image') ?>"
hintText="<?= lang('Episode.form.image_hint') ?>" hint="<?= lang('Episode.form.image_hint') ?>"
helperText="<?= lang('Common.forms.image_size_hint', ) ?>" helper="<?= lang('Common.forms.image_size_hint', ) ?>"
type="file" type="file"
accept=".jpg,.jpeg,.png" /> accept=".jpg,.jpeg,.png" />
<Forms.Field <Forms.Field
name="title" name="title"
label="<?= lang('Episode.form.title') ?>" label="<?= lang('Episode.form.title') ?>"
hintText="<?= lang('Episode.form.title_hint') ?>" hint="<?= lang('Episode.form.title_hint') ?>"
required="true" required="true"
data-slugify="title" /> data-slugify="title" />
@ -120,7 +120,7 @@
as="MarkdownEditor" as="MarkdownEditor"
name="description_footer" name="description_footer"
label="<?= lang('Episode.form.description_footer') ?>" label="<?= lang('Episode.form.description_footer') ?>"
hintText="<?= lang('Episode.form.description_footer_hint') ?>" /> hint="<?= lang('Episode.form.description_footer_hint') ?>" />
</Forms.Section> </Forms.Section>

View File

@ -26,22 +26,22 @@
<Forms.Field <Forms.Field
name="audio_file" name="audio_file"
label="<?= lang('Episode.form.audio_file') ?>" label="<?= lang('Episode.form.audio_file') ?>"
hintText="<?= lang('Episode.form.audio_file_hint') ?>" hint="<?= lang('Episode.form.audio_file_hint') ?>"
type="file" type="file"
accept=".mp3,.m4a" /> accept=".mp3,.m4a" />
<Forms.Field <Forms.Field
name="image" name="image"
label="<?= lang('Episode.form.image') ?>" label="<?= lang('Episode.form.image') ?>"
hintText="<?= lang('Episode.form.image_hint') ?>" hint="<?= lang('Episode.form.image_hint') ?>"
helperText="<?= lang('Common.forms.image_size_hint', ) ?>" helper="<?= lang('Common.forms.image_size_hint', ) ?>"
type="file" type="file"
accept=".jpg,.jpeg,.png" /> accept=".jpg,.jpeg,.png" />
<Forms.Field <Forms.Field
name="title" name="title"
label="<?= lang('Episode.form.title') ?>" label="<?= lang('Episode.form.title') ?>"
hintText="<?= lang('Episode.form.title_hint') ?>" hint="<?= lang('Episode.form.title_hint') ?>"
value="<?= $episode->title ?>" value="<?= $episode->title ?>"
required="true" required="true"
data-slugify="title" /> data-slugify="title" />
@ -127,7 +127,7 @@
as="MarkdownEditor" as="MarkdownEditor"
name="description_footer" name="description_footer"
label="<?= lang('Episode.form.description_footer') ?>" label="<?= lang('Episode.form.description_footer') ?>"
hintText="<?= lang('Episode.form.description_footer_hint') ?>" hint="<?= lang('Episode.form.description_footer_hint') ?>"
value="<?= $podcast->episode_description_footer_markdown ?? '' ?>" /> value="<?= $podcast->episode_description_footer_markdown ?? '' ?>" />
</Forms.Section> </Forms.Section>

View File

@ -9,10 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button(lang('Episode.create'), route_to('episode-create', $podcast->id), [ <Button uri="<?= route_to('episode-create', $podcast->id) ?>" variant="accent" iconLeft="add"><?= lang('Episode.create') ?></Button>
'variant' => 'accent',
'iconLeft' => 'add',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -50,19 +50,7 @@
[ [
'header' => lang('Common.actions'), 'header' => lang('Common.actions'),
'cell' => function ($person): string { 'cell' => function ($person): string {
return button( return '<Button uri="' . route_to('episode-person-remove', $person->podcast_id, $person->episode_id, $person->id) . '" variant="danger" size="small">' . lang('Person.episode_form.remove') . '</Button>';
lang('Person.episode_form.remove'),
route_to(
'episode-person-remove',
$person->podcast_id,
$person->episode_id,
$person->id,
),
[
'variant' => 'danger',
'size' => 'small',
],
);
}, },
], ],
], ],
@ -82,7 +70,7 @@
id="persons" id="persons"
name="persons[]" name="persons[]"
label="<?= lang('Person.episode_form.persons') ?>" label="<?= lang('Person.episode_form.persons') ?>"
hintText="<?= lang('Person.episode_form.persons_hint') ?>" hint="<?= lang('Person.episode_form.persons_hint') ?>"
options="<?= htmlspecialchars(json_encode($personOptions)) ?>" options="<?= htmlspecialchars(json_encode($personOptions)) ?>"
selected="<?= htmlspecialchars(json_encode(old('persons', []))) ?>" selected="<?= htmlspecialchars(json_encode(old('persons', []))) ?>"
required="true" required="true"
@ -93,7 +81,7 @@
id="roles" id="roles"
name="roles[]" name="roles[]"
label="<?= lang('Person.episode_form.roles') ?>" label="<?= lang('Person.episode_form.roles') ?>"
hintText="<?= lang('Person.episode_form.roles_hint') ?>" hint="<?= lang('Person.episode_form.roles_hint') ?>"
options="<?= htmlspecialchars(json_encode($taxonomyOptions)) ?>" options="<?= htmlspecialchars(json_encode($taxonomyOptions)) ?>"
selected="<?= htmlspecialchars(json_encode(old('roles', []))) ?>" selected="<?= htmlspecialchars(json_encode(old('roles', []))) ?>"
required="true" required="true"

View File

@ -90,7 +90,7 @@
as="DatetimePicker" as="DatetimePicker"
name="scheduled_publication_date" name="scheduled_publication_date"
label="<?= lang('Episode.publish_form.scheduled_publication_date') ?>" label="<?= lang('Episode.publish_form.scheduled_publication_date') ?>"
hintText="<?= lang('Episode.publish_form.scheduled_publication_date_hint') ?>" hint="<?= lang('Episode.publish_form.scheduled_publication_date_hint') ?>"
value="<?= $episode->published_at ?>" value="<?= $episode->published_at ?>"
/> />
</div> </div>

View File

@ -94,7 +94,7 @@
as="DatetimePicker" as="DatetimePicker"
name="scheduled_publication_date" name="scheduled_publication_date"
label="<?= lang('Episode.publish_form.scheduled_publication_date') ?>" label="<?= lang('Episode.publish_form.scheduled_publication_date') ?>"
hintText="<?= lang('Episode.publish_form.scheduled_publication_date_hint') ?>" hint="<?= lang('Episode.publish_form.scheduled_publication_date_hint') ?>"
value="<?= $episode->published_at ?>" value="<?= $episode->published_at ?>"
/> />
</div> </div>

View File

@ -11,215 +11,63 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open( <form action="<?= route_to('episode-soundbites-edit', $podcast->id, $episode->id) ?>" method="POST" class="flex flex-col">
route_to('episode-soundbites-edit', $podcast->id, $episode->id),
[
'method' => 'post',
'class' => 'flex flex-col',
],
) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_section( <Forms.Section
lang('Episode.soundbites_form.info_section_title'), title="<?= lang('Episode.soundbites_form.info_section_title') ?>"
lang('Episode.soundbites_form.info_section_subtitle'), subtitle="<?= lang('Episode.soundbites_form.info_section_subtitle') ?>" >
) ?>
<table class="w-full table-fixed"> <?php
<thead> $table = new \CodeIgniter\View\Table();
<tr>
<th class="w-3/12 px-1 py-2">
<?= form_label(
lang('Episode.soundbites_form.start_time'),
'start_time',
[],
lang('Episode.soundbites_form.start_time_hint'),
) ?></th>
<th class="w-3/12 px-1 py-2"><?= form_label(
lang('Episode.soundbites_form.duration'),
'duration',
[],
lang('Episode.soundbites_form.duration_hint'),
) ?></th>
<th class="w-7/12 px-1 py-2"><?= form_label(
lang('Episode.soundbites_form.label'),
'label',
[],
lang('Episode.soundbites_form.label_hint'),
true,
) ?></th>
<th class="w-1/12 px-1 py-2"></th>
</tr>
</thead>
<tbody>
<?php foreach ($episode->soundbites as $soundbite): ?>
<tr>
<td class="px-1 py-2 font-medium bg-white border border-light-blue-500"><?= form_input(
[
'type' => 'number',
'min' => 0,
'max' => $episode->audio_file_duration,
'step' => 'any',
'id' => "soundbites[{$soundbite->id}][start_time]",
'name' => "soundbites[{$soundbite->id}][start_time]",
'class' => 'form-input w-full border-none text-center',
'value' => $soundbite->start_time,
'data-type' => 'soundbite-field',
'data-field-type' => 'start-time',
'data-soundbite-id' => $soundbite->id,
'required' => 'required',
],
) ?></td>
<td class="px-1 py-2 font-medium bg-white border border-light-blue-500"><?= form_input(
[
'type' => 'number',
'min' => 0,
'max' => $episode->audio_file_duration,
'step' => 'any',
'id' => "soundbites[{$soundbite->id}][duration]",
'name' => "soundbites[{$soundbite->id}][duration]",
'class' => 'form-input w-full border-none text-center',
'value' => $soundbite->duration,
'data-type' => 'soundbite-field',
'data-field-type' => 'duration',
'data-soundbite-id' => $soundbite->id,
'required' => 'required',
],
) ?></td>
<td class="px-1 py-2 font-medium bg-white border border-light-blue-500"><?= form_input(
[
'id' => "soundbites[{$soundbite->id}][label]",
'name' => "soundbites[{$soundbite->id}][label]",
'class' => 'form-input w-full border-none',
'value' => $soundbite->label,
],
) ?></td>
<td class="px-4 py-2"><?= icon_button(
'play',
lang('Episode.soundbites_form.play'),
'',
[
'variant' => 'primary',
],
[
'class' => 'mb-1 mr-1',
'data-type' => 'play-soundbite',
'data-soundbite-id' => $soundbite->id,
'data-soundbite-start-time' => $soundbite->start_time,
'data-soundbite-duration' => $soundbite->duration,
],
) ?>
<?= icon_button(
'delete-bin',
lang('Episode.soundbites_form.delete'),
route_to(
'soundbite-delete',
$podcast->id,
$episode->id,
$soundbite->id,
),
[
'variant' => 'danger',
],
[],
) ?>
</td>
</tr>
<?php endforeach; ?>
<tr>
<td class="px-1 py-4 font-medium bg-white border border-light-blue-500"><?= form_input(
[
'type' => 'number',
'min' => 0,
'max' => $episode->audio_file_duration,
'step' => 'any',
'id' => 'soundbites[0][start_time]',
'name' => 'soundbites[0][start_time]',
'class' => 'form-input w-full border-none text-center',
'value' => old('start_time'),
'data-soundbite-id' => '0',
'data-type' => 'soundbite-field',
'data-field-type' => 'start-time',
],
) ?></td>
<td class="px-1 py-4 font-medium bg-white border border-light-blue-500"><?= form_input(
[
'type' => 'number',
'min' => 0,
'max' => $episode->audio_file_duration,
'step' => 'any',
'id' => 'soundbites[0][duration]',
'name' => 'soundbites[0][duration]',
'class' => 'form-input w-full border-none text-center',
'value' => old('duration'),
'data-soundbite-id' => '0',
'data-type' => 'soundbite-field',
'data-field-type' => 'duration',
],
) ?></td>
<td class="px-1 py-4 font-medium bg-white border border-light-blue-500"><?= form_input(
[
'id' => 'soundbites[0][label]',
'name' => 'soundbites[0][label]',
'class' => 'form-input w-full border-none',
'value' => old('label'),
],
) ?></td>
<td class="px-4 py-2"><?= icon_button(
'play',
lang('Episode.soundbites_form.play'),
'',
[
'variant' => 'primary',
],
[
'data-type' => 'play-soundbite',
'data-soundbite-id' => 0,
'data-soundbite-start-time' => 0,
'data-soundbite-duration' => 0,
],
) ?>
</td>
</tr>
<tr><td colspan="3">
<audio controls preload="auto" class="w-full">
<source src="<?= $episode->audio_file_url ?>" type="<?= $episode->audio_file_mimetype ?>">
Your browser does not support the audio tag.
</audio>
</td><td class="px-4 py-2"><?= icon_button(
'timer',
lang('Episode.soundbites_form.bookmark'),
'',
[
'variant' => 'info',
],
[
'data-type' => 'get-soundbite',
'data-start-time-field-name' => 'soundbites[0][start_time]',
'data-duration-field-name' => 'soundbites[0][duration]',
],
) ?></td></tr>
</tbody>
</table>
$table->setHeading(
<?= form_section_close() ?> lang('Episode.soundbites_form.start_time') . hint_tooltip(lang('Episode.soundbites_form.start_time_hint')),
lang('Episode.soundbites_form.duration') . hint_tooltip(lang('Episode.soundbites_form.duration_hint')),
lang('Episode.soundbites_form.label') . hint_tooltip(lang('Episode.soundbites_form.label_hint')),
'',
''
);
<?= button( foreach ($episode->soundbites as $soundbite) {
lang('Episode.soundbites_form.submit_edit'), $table->addRow(
'', "<Forms.Input class='w-24' type='number' step='any' min='0' max='{$episode->audio_file_duration}' name='soundbites[{$soundbite->id}][start_time]' value='{$soundbite->start_time}' data-type='soundbite-field' data-field-type='start_time' required='true' />",
[ "<Forms.Input class='w-24' type='number' step='any' min='0' max='{$episode->audio_file_duration}' name='soundbites[{$soundbite->id}][duration]' value='{$soundbite->duration}' data-type='soundbite-field' data-field-type='duration' required='true' />",
'variant' => 'primary', "<Forms.Input class='flex-1' name='soundbites[{$soundbite->id}][label]' value='{$soundbite->label}' />",
], "<IconButton variant='primary' glyph='play' data-type='play-soundbite' data-soundbite-id='{$soundbite->id}'>" . lang('Episode.soundbites_form.play') . '</IconButton>',
[ '<IconButton uri=' . route_to(
'type' => 'submit', 'soundbite-delete',
'class' => 'self-end', $podcast->id,
], $episode->id,
) ?> $soundbite->id,
) . " variant='danger' glyph='delete-bin'>" . lang('Episode.soundbites_form.delete') . '</IconButton>'
);
}
<?= form_close() ?> $table->addRow(
"<Forms.Input class='w-24' type='number' step='any' min='0' max='{$episode->audio_file_duration}' name='soundbites[0][start_time]' data-type='soundbite-field' data-field-type='start_time' />",
"<Forms.Input class='w-24' type='number' step='any' min='0' max='{$episode->audio_file_duration}' name='soundbites[0][duration]' data-type='soundbite-field' data-field-type='duration' />",
"<Forms.Input class='flex-1' name='soundbites[0][label]' />",
"<IconButton variant='primary' glyph='play' data-type='play-soundbite' data-soundbite-id='0'>" . lang('Episode.soundbites_form.play') . '</IconButton>',
);
echo $table->generate();
?>
<div class="flex items-center gap-x-2">
<audio controls preload="auto" class="flex-1 w-full">
<source src="<?= $episode->audio_file_url ?>" type="<?= $episode->audio_file_mimetype ?>">
Your browser does not support the audio tag.
</audio>
<IconButton glyph="timer" variant="info" data-type="get-soundbite" data-start-time-field-name="soundbites[0][start_time]" data-duration-field-name="soundbites[0][duration]" ><?= lang('Episode.soundbites_form.bookmark') ?></IconButton>
</div>
</Forms.Section>
<Button variant="primary" type="submit" class="self-end"><?= lang('Episode.soundbites_form.submit_edit') ?></Button>
</form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -12,7 +12,7 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<form action="<?= route_to('fediverse-attempt-block-actor') ?>" method="POST" class="flex flex-col max-w-md"> <form action="<?= route_to('fediverse-attempt-block-actor') ?>" method="POST" class="flex flex-col max-w-md">
<Forms.Field name="handle" label="<?= lang('Fediverse.block_lists_form.handle') ?>" hintText="<?= lang('Fediverse.block_lists_form.handle_hint') ?>" /> <Forms.Field name="handle" label="<?= lang('Fediverse.block_lists_form.handle') ?>" hint="<?= lang('Fediverse.block_lists_form.handle_hint') ?>" />
<Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.block_lists_form.submit') ?></Button> <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.block_lists_form.submit') ?></Button>
</form> </form>
@ -34,21 +34,7 @@
$blockedActor->id . $blockedActor->id .
'" />' . '" />' .
csrf_field() . csrf_field() .
button( '<Button uri="' . route_to('fediverse-unblock-actor', $blockedActor->username) . '" variant="info" size="small" type="submit">' . lang('Fediverse.list.unblock') . '</Button>' .
lang('Fediverse.list.unblock'),
route_to(
'fediverse-unblock-actor',
$blockedActor->username,
),
[
'variant' => 'info',
'size' => 'small',
],
[
'class' => 'mr-2',
'type' => 'submit',
],
) .
'</form>'; '</form>';
}, },
], ],

View File

@ -34,21 +34,7 @@
$blockedDomain->name . $blockedDomain->name .
'" />' . '" />' .
csrf_field() . csrf_field() .
button( '<Button uri="' . route_to('fediverse-unblock-domain', $blockedDomain->name) . '" variant="info" size="small" type="submit">' . lang('Fediverse.list.unblock') . '</Button>' .
lang('Fediverse.list.unblock'),
route_to(
'fediverse-unblock-domain',
$blockedDomain->name,
),
[
'variant' => 'info',
'size' => 'small',
],
[
'class' => 'mr-2',
'type' => 'submit',
],
) .
'</form>'; '</form>';
}, },
], ],

View File

@ -11,9 +11,6 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('page-create'), [
'class' => 'flex flex-col max-w-3xl',
]) ?>
<form action="<?= route_to('page-create') ?>" method="POST" class="flex flex-col max-w-3xl gap-y-4"> <form action="<?= route_to('page-create') ?>" method="POST" class="flex flex-col max-w-3xl gap-y-4">
<?= csrf_field() ?> <?= csrf_field() ?>

View File

@ -9,10 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button(lang('Page.create'), route_to('page-create'), [ <Button uri="<?= route_to('page-create') ?>" variant="accent" iconLeft="add"><?= lang('Page.create') ?></Button>
'variant' => 'accent',
'iconLeft' => 'add',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
@ -33,36 +30,9 @@
[ [
'header' => lang('Common.actions'), 'header' => lang('Common.actions'),
'cell' => function ($page) { 'cell' => function ($page) {
return button( return '<Button uri="' . route_to('page', $page->slug) . '" variant="secondary" size="small">' . lang('Page.go_to_page') . '</Button>' .
lang('Page.go_to_page'), '<Button uri="' . route_to('page-edit', $page->id) . '" variant="info" size="small">' . lang('Page.edit') . '</Button>' .
route_to('page', $page->slug), '<Button uri="' . route_to('page-delete', $page->id) . '" variant="danger" size="small">' . lang('Page.delete') . '</Button>';
[
'variant' => 'secondary',
'size' => 'small',
],
[
'class' => 'mr-2',
],
) .
button(
lang('Page.edit'),
route_to('page-edit', $page->id),
[
'variant' => 'info',
'size' => 'small',
],
[
'class' => 'mr-2',
],
) .
button(
lang('Page.delete'),
route_to('page-delete', $page->id),
[
'variant' => 'danger',
'size' => 'small',
],
);
}, },
], ],
], ],

View File

@ -9,10 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button(lang('Page.edit'), route_to('page-edit', $page->id), [ <Button variant="accent" uri="<?= route_to('page-edit', $page->id) ?>" iconLeft="add"><?= lang('Page.edit') ?></Button>
'variant' => 'accent',
'iconLeft' => 'add',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>

View File

@ -17,7 +17,7 @@
<Forms.Field <Forms.Field
name="image" name="image"
label="<?= lang('Person.form.image') ?>" label="<?= lang('Person.form.image') ?>"
helperText="<?= lang('Person.form.image_size_hint') ?>" helper="<?= lang('Person.form.image_size_hint') ?>"
type="file" type="file"
required="true" required="true"
accept=".jpg,.jpeg,.png" /> accept=".jpg,.jpeg,.png" />
@ -25,19 +25,19 @@
<Forms.Field <Forms.Field
name="full_name" name="full_name"
label="<?= lang('Person.form.full_name') ?>" label="<?= lang('Person.form.full_name') ?>"
hintText="<?= lang('Person.form.full_name_hint') ?>" hint="<?= lang('Person.form.full_name_hint') ?>"
required="true" required="true"
data-slugify="title" /> data-slugify="title" />
<Forms.Field <Forms.Field
name="unique_name" name="unique_name"
label="<?= lang('Person.form.unique_name') ?>" label="<?= lang('Person.form.unique_name') ?>"
hintText="<?= lang('Person.form.unique_name_hint') ?>" hint="<?= lang('Person.form.unique_name_hint') ?>"
required="true" /> required="true" />
<Forms.Field <Forms.Field
name="information_url" name="information_url"
label="<?= lang('Person.form.information_url') ?>" label="<?= lang('Person.form.information_url') ?>"
hintText="<?= lang('Person.form.information_url_hint') ?>" /> hint="<?= lang('Person.form.information_url_hint') ?>" />
<Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_create') ?></Button> <Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_create') ?></Button>

View File

@ -19,7 +19,7 @@
<Forms.Field <Forms.Field
name="image" name="image"
label="<?= lang('Person.form.image') ?>" label="<?= lang('Person.form.image') ?>"
helperText="<?= lang('Person.form.image_size_hint') ?>" helper="<?= lang('Person.form.image_size_hint') ?>"
type="file" type="file"
accept=".jpg,.jpeg,.png" /> accept=".jpg,.jpeg,.png" />
@ -27,7 +27,7 @@
name="full_name" name="full_name"
value="<?= $person->full_name ?>" value="<?= $person->full_name ?>"
label="<?= lang('Person.form.full_name') ?>" label="<?= lang('Person.form.full_name') ?>"
hintText="<?= lang('Person.form.full_name_hint') ?>" hint="<?= lang('Person.form.full_name_hint') ?>"
required="true" required="true"
data-slugify="title" /> data-slugify="title" />
@ -35,12 +35,12 @@
name="unique_name" name="unique_name"
value="<?= $person->unique_name ?>" value="<?= $person->unique_name ?>"
label="<?= lang('Person.form.unique_name') ?>" label="<?= lang('Person.form.unique_name') ?>"
hintText="<?= lang('Person.form.unique_name_hint') ?>" hint="<?= lang('Person.form.unique_name_hint') ?>"
required="true" /> required="true" />
<Forms.Field <Forms.Field
name="information_url" name="information_url"
label="<?= lang('Person.form.information_url') ?>" label="<?= lang('Person.form.information_url') ?>"
hintText="<?= lang('Person.form.information_url_hint') ?>" hint="<?= lang('Person.form.information_url_hint') ?>"
value="<?= $person->information_url ?>" /> value="<?= $person->information_url ?>" />
<Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_edit') ?></Button> <Button variant="primary" class="self-end" type="submit"><?= lang('Person.form.submit_edit') ?></Button>

View File

@ -9,17 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button( <Button uri="<?= route_to('person-create') ?>" variant="primary" 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') ?>

View File

@ -10,17 +10,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button( <Button uri="<?= route_to('person-edit', $person->id) ?>" variant="secondary" iconLeft="edit"><?= lang('Person.edit') ?></Button>
lang('Person.edit'),
route_to('person-edit', $person->id),
[
'variant' => 'secondary',
'iconLeft' => 'edit',
],
[
'class' => 'mr-2',
],
) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>

View File

@ -25,7 +25,7 @@
<Forms.Field <Forms.Field
name="image" name="image"
label="<?= lang('Podcast.form.image') ?>" label="<?= lang('Podcast.form.image') ?>"
helperText="<?= lang('Common.forms.image_size_hint') ?>" helper="<?= lang('Common.forms.image_size_hint') ?>"
type="file" type="file"
required="true" required="true"
accept=".jpg,.jpeg,.png" /> accept=".jpg,.jpeg,.png" />
@ -121,20 +121,20 @@
<Forms.Field <Forms.Field
name="owner_name" name="owner_name"
label="<?= lang('Podcast.form.owner_name') ?>" label="<?= lang('Podcast.form.owner_name') ?>"
hintText="<?= lang('Podcast.form.owner_name_hint') ?>" hint="<?= lang('Podcast.form.owner_name_hint') ?>"
required="true" /> required="true" />
<Forms.Field <Forms.Field
name="owner_email" name="owner_email"
type="email" type="email"
label="<?= lang('Podcast.form.owner_email') ?>" label="<?= lang('Podcast.form.owner_email') ?>"
hintText="<?= lang('Podcast.form.owner_email_hint') ?>" hint="<?= lang('Podcast.form.owner_email_hint') ?>"
required="true" /> required="true" />
<Forms.Field <Forms.Field
name="publisher" name="publisher"
label="<?= lang('Podcast.form.publisher') ?>" label="<?= lang('Podcast.form.publisher') ?>"
hintText="<?= lang('Podcast.form.publisher_hint') ?>" /> hint="<?= lang('Podcast.form.publisher_hint') ?>" />
<Forms.Field <Forms.Field
name="copyright" name="copyright"
@ -150,7 +150,7 @@
<Forms.Field <Forms.Field
name="location_name" name="location_name"
label="<?= lang('Podcast.form.location_name') ?>" label="<?= lang('Podcast.form.location_name') ?>"
hintText="<?= lang('Podcast.form.location_name_hint') ?>" /> hint="<?= lang('Podcast.form.location_name_hint') ?>" />
</Forms.Section> </Forms.Section>
@ -162,7 +162,7 @@
<Forms.Field <Forms.Field
name="payment_pointer" name="payment_pointer"
label="<?= lang('Podcast.form.payment_pointer') ?>" label="<?= lang('Podcast.form.payment_pointer') ?>"
hintText="<?= lang('Podcast.form.payment_pointer_hint') ?>" /> hint="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
<fieldset class="flex flex-col items-start p-4 bg-gray-100 rounded"> <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> <Heading tagName="legend" class="float-left" size="small"><?= lang('Podcast.form.partnership') ?></Heading>
@ -192,7 +192,7 @@
as="XMLEditor" as="XMLEditor"
name="custom_rss" name="custom_rss"
label="<?= lang('Podcast.form.custom_rss') ?>" label="<?= lang('Podcast.form.custom_rss') ?>"
hintText="<?= lang('Podcast.form.custom_rss_hint') ?>" /> hint="<?= lang('Podcast.form.custom_rss_hint') ?>" />
</Forms.Section> </Forms.Section>

View File

@ -29,14 +29,14 @@
<Forms.Field <Forms.Field
name="image" name="image"
label="<?= lang('Podcast.form.image') ?>" label="<?= lang('Podcast.form.image') ?>"
helperText="<?= lang('Common.forms.image_size_hint') ?>" helper="<?= lang('Common.forms.image_size_hint') ?>"
type="file" type="file"
accept=".jpg,.jpeg,.png" /> accept=".jpg,.jpeg,.png" />
<Forms.Field <Forms.Field
name="title" name="title"
label="<?= lang('Podcast.form.title') ?>" label="<?= lang('Podcast.form.title') ?>"
helperText="<?= $podcast->link ?>" helper="<?= $podcast->link ?>"
value="<?= $podcast->title ?>" value="<?= $podcast->title ?>"
required="true" /> required="true" />
@ -74,22 +74,22 @@
name="language" name="language"
label="<?= lang('Podcast.form.language') ?>" label="<?= lang('Podcast.form.language') ?>"
selected="<?= $podcast->language_code ?>" selected="<?= $podcast->language_code ?>"
required="true" options="<?= esc(json_encode($languageOptions)) ?>"
options="<?= esc(json_encode($languageOptions)) ?>" /> required="true" />
<Forms.Field <Forms.Field
as="Select" as="Select"
name="category" name="category"
label="<?= lang('Podcast.form.category') ?>" label="<?= lang('Podcast.form.category') ?>"
selected="<?= $podcast->category_id ?>" selected="<?= $podcast->category_id ?>"
required="true" options="<?= esc(json_encode($categoryOptions)) ?>"
options="<?= esc(json_encode($categoryOptions)) ?>" /> required="true" />
<Forms.Field <Forms.Field
as="MultiSelect" as="MultiSelect"
name="other_categories[]" name="other_categories[]"
label="<?= lang('Podcast.form.other_categories') ?>" label="<?= lang('Podcast.form.other_categories') ?>"
selected="<?= json_encode(old('other_categories', $podcast->other_categories_ids)) ?>" selected="<?= json_encode($podcast->other_categories_ids) ?>"
data-max-item-count="2" data-max-item-count="2"
options="<?= esc(json_encode($categoryOptions)) ?>" /> options="<?= esc(json_encode($categoryOptions)) ?>" />
@ -122,7 +122,7 @@
name="owner_name" name="owner_name"
label="<?= lang('Podcast.form.owner_name') ?>" label="<?= lang('Podcast.form.owner_name') ?>"
value="<?= $podcast->owner_name ?>" value="<?= $podcast->owner_name ?>"
hintText="<?= lang('Podcast.form.owner_name_hint') ?>" hint="<?= lang('Podcast.form.owner_name_hint') ?>"
required="true" /> required="true" />
<Forms.Field <Forms.Field
@ -130,14 +130,14 @@
type="email" type="email"
label="<?= lang('Podcast.form.owner_email') ?>" label="<?= lang('Podcast.form.owner_email') ?>"
value="<?= $podcast->owner_email ?>" value="<?= $podcast->owner_email ?>"
hintText="<?= lang('Podcast.form.owner_email_hint') ?>" hint="<?= lang('Podcast.form.owner_email_hint') ?>"
required="true" /> required="true" />
<Forms.Field <Forms.Field
name="publisher" name="publisher"
label="<?= lang('Podcast.form.publisher') ?>" label="<?= lang('Podcast.form.publisher') ?>"
value="<?= $podcast->publisher ?>" value="<?= $podcast->publisher ?>"
hintText="<?= lang('Podcast.form.publisher_hint') ?>" /> hint="<?= lang('Podcast.form.publisher_hint') ?>" />
<Forms.Field <Forms.Field
name="copyright" name="copyright"
@ -155,7 +155,7 @@
name="location_name" name="location_name"
label="<?= lang('Podcast.form.location_name') ?>" label="<?= lang('Podcast.form.location_name') ?>"
value="<?= $podcast->location_name ?>" value="<?= $podcast->location_name ?>"
hintText="<?= lang('Podcast.form.location_name_hint') ?>" /> hint="<?= lang('Podcast.form.location_name_hint') ?>" />
</Forms.Section> </Forms.Section>
@ -168,7 +168,7 @@
name="payment_pointer" name="payment_pointer"
label="<?= lang('Podcast.form.payment_pointer') ?>" label="<?= lang('Podcast.form.payment_pointer') ?>"
value="<?= $podcast->payment_pointer ?>" value="<?= $podcast->payment_pointer ?>"
hintText="<?= lang('Podcast.form.payment_pointer_hint') ?>" /> hint="<?= lang('Podcast.form.payment_pointer_hint') ?>" />
<fieldset class="flex flex-col items-start p-4 bg-gray-100 rounded"> <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> <Heading tagName="legend" class="float-left" size="small"><?= lang('Podcast.form.partnership') ?></Heading>
@ -199,7 +199,7 @@
name="custom_rss" name="custom_rss"
label="<?= lang('Podcast.form.custom_rss') ?>" label="<?= lang('Podcast.form.custom_rss') ?>"
value="<?= $podcast->custom_rss_string ?>" value="<?= $podcast->custom_rss_string ?>"
hintText="<?= lang('Podcast.form.custom_rss_hint') ?>" /> hint="<?= lang('Podcast.form.custom_rss_hint') ?>" />
</Forms.Section> </Forms.Section>

View File

@ -22,7 +22,7 @@
<Forms.Field <Forms.Field
name="imported_feed_url" name="imported_feed_url"
label="<?= lang('PodcastImport.imported_feed_url') ?>" label="<?= lang('PodcastImport.imported_feed_url') ?>"
hintText="<?= lang('PodcastImport.imported_feed_url_hint') ?>" hint="<?= lang('PodcastImport.imported_feed_url_hint') ?>"
placeholder="https://…" placeholder="https://…"
type="url" type="url"
required="true" /> required="true" />
@ -81,13 +81,13 @@
name="season_number" name="season_number"
type="number" type="number"
label="<?= lang('PodcastImport.season_number') ?>" label="<?= lang('PodcastImport.season_number') ?>"
hintText="<?= lang('PodcastImport.season_number_hint') ?>" /> hint="<?= lang('PodcastImport.season_number_hint') ?>" />
<Forms.Field <Forms.Field
name="max_episodes" name="max_episodes"
type="number" type="number"
label="<?= lang('PodcastImport.max_episodes') ?>" label="<?= lang('PodcastImport.max_episodes') ?>"
hintText="<?= lang('PodcastImport.max_episodes_hint') ?>" /> hint="<?= lang('PodcastImport.max_episodes_hint') ?>" />
</Forms.Section> </Forms.Section>

View File

@ -9,21 +9,8 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button( <Button uri="<?= route_to('podcast-create') ?>" variant="accent" iconLeft="add"><?= lang('Podcast.create') ?></Button>
lang('Podcast.create'), <Button uri="<?= route_to('podcast-import') ?>" variant="primary" iconLeft="download"><?= lang('Podcast.import') ?></Button>
route_to('podcast-create'),
[
'variant' => 'accent',
'iconLeft' => 'add',
],
[
'class' => 'mr-2',
],
) ?>
<?= button(lang('Podcast.import'), route_to('podcast-import'), [
'variant' => 'primary',
'iconLeft' => 'download',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -9,17 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button( <Button uri="<?= route_to('person-create') ?>" variant="primary" 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') ?>
@ -60,18 +50,7 @@
[ [
'header' => lang('Common.actions'), 'header' => lang('Common.actions'),
'cell' => function ($person): string { 'cell' => function ($person): string {
return button( return '<Button uri="' . route_to('podcast-person-remove', $person->podcast_id, $person->id) . '" variant="danger" size="small">' . lang('Person.podcast_form.remove') . '</Button>';
lang('Person.podcast_form.remove'),
route_to(
'podcast-person-remove',
$person->podcast_id,
$person->id,
),
[
'variant' => 'danger',
'size' => 'small',
],
);
}, },
], ],
], ],

View File

@ -10,9 +10,7 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('platforms-save', $podcast->id, $platformType), [ <form action="<?= route_to('platforms-save', $podcast->id, $platformType) ?>" method="POST" class="flex flex-col max-w-md">
'class' => 'flex flex-col max-w-md',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?php foreach ($platforms as $platform): ?> <?php foreach ($platforms as $platform): ?>
@ -106,6 +104,6 @@
<Button variant="primary" type="submit" class="self-end"><?= lang('Platforms.submit') ?></Button> <Button variant="primary" type="submit" class="self-end"><?= lang('Platforms.submit') ?></Button>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -9,21 +9,8 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button( <Button uri="<?= route_to('podcast-edit', $podcast->id) ?>" variant="primary" iconLeft="edit"><?= lang('Podcast.edit') ?></Button>
lang('Podcast.edit'), <Button uri="<?= route_to('episode-create', $podcast->id) ?>" variant="accent" iconLeft="add"><?= lang('Episode.create') ?></Button>
route_to('podcast-edit', $podcast->id),
[
'variant' => 'primary',
'iconLeft' => 'edit',
],
[
'class' => 'mr-2',
],
) ?>
<?= button(lang('Episode.create'), route_to('episode-create', $podcast->id), [
'variant' => 'accent',
'iconLeft' => 'add',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>

View File

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

View File

@ -15,26 +15,19 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('user-edit', $user->id), [ <form action="<?= route_to('user-edit', $user->id) ?>" method="POST" class="flex flex-col max-w-sm">
'class' => 'flex flex-col max-w-sm',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_label(lang('User.form.roles'), 'roles') ?> <Forms.Field
<Forms.MultiSelect id="roles" name="roles[]" class="mb-4" required="required" options="<?= htmlspecialchars(json_encode($roleOptions)) ?>" selected="<?= htmlspecialchars(json_encode($user->roles)) ?>"/> id="roles"
name="roles[]"
label="<?= lang('User.form.roles') ?>"
required="true"
options="<?= esc(json_encode($roleOptions)) ?>"
selected="<?= esc(json_encode($user->roles)) ?>" />
<?= button( <Button variant="primary" type="submit" class="self-end"><?= lang('User.form.submit_edit') ?></Button>
lang('User.form.submit_edit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -9,10 +9,7 @@
<?= $this->endSection() ?> <?= $this->endSection() ?>
<?= $this->section('headerRight') ?> <?= $this->section('headerRight') ?>
<?= button(lang('User.create'), route_to('user-create'), [ <Button uri="<?= route_to('user-create') ?>" variant="accent" iconLeft="user-add"><?= lang('User.create') ?></Button>
'variant' => 'accent',
'iconLeft' => 'user-add',
]) ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>
@ -34,19 +31,9 @@
'header' => lang('User.list.roles'), 'header' => lang('User.list.roles'),
'cell' => function ($user) { 'cell' => function ($user) {
return implode(',', $user->roles) . return implode(',', $user->roles) .
icon_button( '<IconButton uri="' . route_to('user-edit', $user->id) . '" glyph="edit" variant="info">' . lang('User.edit_roles', [
'edit', 'username' => $user->username,
lang('User.edit_roles', [ ]) . '</IconButton>';
'username' => $user->username,
]),
route_to('user-edit', $user->id),
[
'variant' => 'info',
],
[
'class' => 'ml-2',
],
);
}, },
], ],
[ [
@ -60,39 +47,9 @@
[ [
'header' => lang('Common.actions'), 'header' => lang('Common.actions'),
'cell' => function ($user) { 'cell' => function ($user) {
return button( return '<Button uri="' . route_to('user-force_pass_reset', $user->id) . '" variant="secondary" size="small">' . lang('User.forcePassReset') . '</Button>' .
lang('User.forcePassReset'), '<Button uri="' . route_to($user->isBanned() ? 'user-unban' : 'user-ban', $user->id) . '" variant="warning" size="small">' . lang('User.' . ($user->isBanned() ? 'unban' : 'ban')) . '</Button>' .
route_to('user-force_pass_reset', $user->id), '<Button uri="' . route_to('user-delete', $user->id) . '" variant="danger" size="small">' . lang('User.delete') . '</Button>';
[
'variant' => 'secondary',
'size' => 'small',
],
[
'class' => 'mr-2',
],
) .
button(
lang('User.' . ($user->isBanned() ? 'unban' : 'ban')),
route_to(
$user->isBanned() ? 'user-unban' : 'user-ban',
$user->id,
),
[
'variant' => 'warning',
'size' => 'small',
],
[
'class' => 'mr-2',
],
) .
button(
lang('User.delete'),
route_to('user-delete', $user->id),
[
'variant' => 'danger',
'size' => 'small',
],
);
}, },
], ],
], ],

View File

@ -21,8 +21,8 @@
] ?>; color: <?= $themeData['text'] ?>;"> ] ?>; color: <?= $themeData['text'] ?>;">
<img src="<?= $episode->image <img src="<?= $episode->image
->thumbnail_url ?>" alt="<?= $episode->title ?>" class="flex-shrink w-36 h-36" /> ->thumbnail_url ?>" alt="<?= $episode->title ?>" class="flex-shrink w-36 h-36" />
<div class="flex flex-col flex-1 min-w-0 px-4 py-2 h-36"> <div class="flex flex-col items-start flex-1 min-w-0 px-4 py-2 h-36">
<div class="flex items-center"> <div class="flex items-center w-full">
<a href="<?= route_to( <a href="<?= route_to(
'podcast-activity', 'podcast-activity',
$podcast->handle, $podcast->handle,
@ -31,7 +31,7 @@
] ?>;" class="mr-2 text-xs tracking-wider uppercase truncate opacity-75 hover:opacity-100" target="_blank"> ] ?>;" class="mr-2 text-xs tracking-wider uppercase truncate opacity-75 hover:opacity-100" target="_blank">
<?= $podcast->title ?> <?= $podcast->title ?>
</a> </a>
<a href="https://castopod.org/" class="ml-auto text-3xl text-pine-700 hover:opacity-75" title="<?= lang( <a href="https://castopod.org/" class="ml-auto text-3xl text-pine-500 hover:opacity-75" title="<?= lang(
'Common.powered_by', 'Common.powered_by',
[ [
'castopod' => 'Castopod', 'castopod' => 'Castopod',

View File

@ -6,13 +6,7 @@
'numberOfLikes' => $comment->likes_count, 'numberOfLikes' => $comment->likes_count,
], ],
) ?>"><?= 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 uri="<?= route_to('comment', $podcast->handle, $comment->episode->slug, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
lang('Comment.reply'),
route_to('comment', $podcast->handle, $comment->episode->slug, $comment->id),
[
'size' => 'small',
],
) ?>
</form> </form>
<?php if ($comment->replies_count): ?> <?php if ($comment->replies_count): ?>
<?= anchor( <?= anchor(

View File

@ -6,13 +6,7 @@
'numberOfLikes' => $comment->likes_count, 'numberOfLikes' => $comment->likes_count,
], ],
) ?>"><?= 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 uri="<?= route_to('post', $podcast->handle, $comment->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
lang('Comment.reply'),
route_to('post', $podcast->handle, $comment->id),
[
'size' => 'small',
],
) ?>
</form> </form>
<?php if ($comment->replies_count): ?> <?php if ($comment->replies_count): ?>
<?= anchor( <?= anchor(

View File

@ -6,12 +6,6 @@
'numberOfLikes' => $reply->likes_count, 'numberOfLikes' => $reply->likes_count,
], ],
) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button> ) ?>"><?= icon('heart', 'text-xl mr-1 text-gray-400 group-hover:text-red-600') . $reply->likes_count ?></button>
<?= button( <Button uri="<?= route_to('comment', $podcast->handle, $episode->slug, $reply->id) ?>" size="small"><?= lang('Comment.reply') ?></Button>
lang('Comment.reply'),
route_to('comment', $podcast->handle, $episode->slug, $reply->id),
[
'size' => 'small',
],
) ?>
</form> </form>
</footer> </footer>

View File

@ -1,46 +1,21 @@
<?= $this->include('podcast/_partials/comment_card_authenticated') ?> <?= $this->include('podcast/_partials/comment_card_authenticated') ?>
<div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl"> <div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl">
<?= form_open( <form action="<?= route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 bg-gray-50">
route_to('comment-attempt-reply', $podcast->id, $episode->id, $comment->id),
[
'class' => 'bg-gray-50 flex px-6 pt-8 pb-4',
],
) ?>
<img src="<?= interact_as_actor() <img src="<?= interact_as_actor()
->avatar_image_url ?>" alt="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor()
->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" /> ->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" />
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">
<?= form_textarea( <Forms.Textarea
[ name="message"
'id' => 'message', required="true"
'name' => 'message', class="w-full mb-4"
'class' => 'form-textarea mb-4 w-full', placeholder="<?= lang('Comment.form.reply_to_placeholder', [
'required' => 'required', 'actorUsername' => $comment->actor->username,
'placeholder' => lang('Comment.form.reply_to_placeholder', [ ]) ?>"
'actorUsername' => $comment->actor->username, rows="1" />
]), <Button variant="primary" size="small" type="submit" name="action" value="reply"><?= lang('Comment.form.submit_reply') ?></Button>
],
old('message', '', false),
[
'rows' => 1,
],
) ?>
<?= button(
lang('Comment.form.submit_reply'),
'',
[
'variant' => 'primary',
'size' => 'small',
],
[
'type' => 'submit',
'class' => 'self-end',
'name' => 'action',
'value' => 'reply',
],
) ?>
</div> </div>
<?= form_close() ?> </form>
<?php foreach ($comment->replies as $reply): ?> <?php foreach ($comment->replies as $reply): ?>
<?= view('podcast/_partials/comment_reply_authenticated', [ <?= view('podcast/_partials/comment_reply_authenticated', [

View File

@ -1,46 +1,21 @@
<?= $this->include('podcast/_partials/post_authenticated') ?> <?= $this->include('podcast/_partials/post_authenticated') ?>
<div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl"> <div class="-mt-2 overflow-hidden border-b border-l border-r post-replies rounded-b-xl">
<?= form_open( <form action="<?= route_to('post-attempt-action', interact_as_actor()->username, $post->id) ?>" method="POST" class="flex px-6 pt-8 pb-4 bg-gray-50" >
route_to('post-attempt-action', interact_as_actor()->username, $post->id),
[
'class' => 'bg-gray-50 flex px-6 pt-8 pb-4',
],
) ?>
<img src="<?= interact_as_actor() <img src="<?= interact_as_actor()
->avatar_image_url ?>" alt="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor()
->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" /> ->display_name ?>" class="w-12 h-12 mr-4 rounded-full ring-gray-50 ring-2" />
<div class="flex flex-col flex-1"> <div class="flex flex-col flex-1">
<?= form_textarea( <Forms.Textarea
[ name="message"
'id' => 'message', class="w-full mb-4"
'name' => 'message', required="true"
'class' => 'form-textarea mb-4 w-full', placeholder="<?= lang('Post.form.reply_to_placeholder', [
'required' => 'required', 'actorUsername' => $post->actor->username,
'placeholder' => lang('Post.form.reply_to_placeholder', [ ]) ?>"
'actorUsername' => $post->actor->username, rows="1" />
]), <Button variant="primary" size="small" type="submit" name="action" value="reply" class="self-end"><?= lang('Post.form.submit_reply') ?></Button>
],
old('message', '', false),
[
'rows' => 1,
],
) ?>
<?= button(
lang('Post.form.submit_reply'),
'',
[
'variant' => 'primary',
'size' => 'small',
],
[
'type' => 'submit',
'class' => 'self-end',
'name' => 'action',
'value' => 'reply',
],
) ?>
</div> </div>
<?= form_close() ?> </form>
<?php if ($post->has_replies): ?> <?php if ($post->has_replies): ?>
<?php foreach ($post->replies as $reply): ?> <?php foreach ($post->replies as $reply): ?>

View File

@ -43,9 +43,7 @@
</nav> </nav>
<section class="max-w-2xl px-6 py-8 mx-auto"> <section class="max-w-2xl px-6 py-8 mx-auto">
<?= form_open(route_to('post-attempt-create', interact_as_actor()->username), [ <form action="<?= route_to('post-attempt-create', interact_as_actor()->username) ?>" method="POST" class="flex p-4 bg-white shadow rounded-xl">
'class' => 'flex p-4 bg-white shadow rounded-xl',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= view('_message_block') ?> <?= view('_message_block') ?>
@ -54,59 +52,32 @@
->avatar_image_url ?>" alt="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor()
->display_name ?>" class="w-12 h-12 mr-4 rounded-full" /> ->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
<div class="flex flex-col flex-1 min-w-0"> <div class="flex flex-col flex-1 min-w-0">
<?= form_textarea( <Forms.Textarea
[ name="message"
'id' => 'message', required="true"
'name' => 'message', placeholder="<?= lang('Post.form.message_placeholder') ?>"
'class' => 'form-textarea', rows="2" />
'required' => 'required', <Forms.Input
'placeholder' => lang('Post.form.message_placeholder'), name="episode_url"
], type="url"
old('message', '', false), placeholder="<?= lang('Post.form.episode_url_placeholder') . ' (' . lang('Common.optional') . ')' ?>" />
[ <Button variant="primary" size="small" type="submit" class="self-end mt-2"><?= lang('Post.form.submit') ?></Button>
'rows' => 2,
],
) ?>
<?= form_input([
'id' => 'episode_url',
'name' => 'episode_url',
'class' => 'form-input mb-2',
'placeholder' =>
lang('Post.form.episode_url_placeholder') .
' (' .
lang('Common.optional') .
')',
'type' => 'url',
]) ?>
<?= button(
lang('Post.form.submit'),
'',
[
'variant' => 'primary',
'size' => 'small',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
</div> </div>
<?= form_close() ?> </form>
<hr class="my-4 border-2 border-pine-100"> <hr class="my-4 border-2 border-pine-100">
<div class="space-y-8"> <div class="space-y-8">
<?php foreach ($posts as $post): ?> <?php foreach ($posts as $post): ?>
<?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, 'podcast' => $podcast,
]) ?> ]) ?>
<?php else: ?> <?php else: ?>
<?= view('podcast/_partials/post_authenticated', [ <?= view('podcast/_partials/post_authenticated', [
'post' => $post, 'post' => $post,
'podcast' => $podcast, 'podcast' => $podcast,
]) ?> ]) ?>
<?php endif; ?> <?php endif; ?>
<?php endforeach; ?> <?php endforeach; ?>
</div> </div>

View File

@ -88,9 +88,7 @@
<div class="tab-panels"> <div class="tab-panels">
<section id="comments" class="space-y-6 tab-panel"> <section id="comments" class="space-y-6 tab-panel">
<?= form_open(route_to('comment-attempt-create', $podcast->id, $episode->id), [ <form action="<?= route_to('comment-attempt-create', $podcast->id, $episode->id) ?>" method="POST" class="flex p-4">
'class' => 'flex p-4',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= view('_message_block') ?> <?= view('_message_block') ?>
@ -99,47 +97,23 @@
->avatar_image_url ?>" alt="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor()
->display_name ?>" class="w-12 h-12 mr-4 rounded-full" /> ->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
<div class="flex flex-col flex-1 min-w-0"> <div class="flex flex-col flex-1 min-w-0">
<?= form_textarea( <Forms.Textarea
[ name="message"
'id' => 'message', required="true"
'name' => 'message', placeholder="<?= lang('Comment.form.episode_message_placeholder') ?>"
'class' => 'form-textarea mb-2', rows="2" />
'required' => 'required', <Button class="self-end" variant="primary" size="small" type="submit"><?= lang('Comment.form.submit') ?></Button>
'placeholder' => lang(
'Comment.form.episode_message_placeholder',
),
],
old('message', '', false),
[
'rows' => 2,
],
) ?>
<?= button(
lang('Comment.form.submit'),
'',
[
'variant' => 'primary',
'size' => 'small',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
</div> </div>
<?= form_close() ?> </form>
<?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, 'podcast' => $podcast,
]) ?> ]) ?>
<?php endforeach; ?> <?php endforeach; ?>
</section> </section>
<section id="activity" class="space-y-8 tab-panel"> <section id="activity" class="space-y-8 tab-panel">
<?= form_open(route_to('post-attempt-create', $podcast->handle), [ <form action="<?= route_to('post-attempt-create', $podcast->handle) ?>" method="POST" class="flex p-4 bg-white shadow rounded-xl">
'class' => 'flex p-4 bg-white shadow rounded-xl',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= view('_message_block') ?> <?= view('_message_block') ?>
@ -148,41 +122,15 @@
->avatar_image_url ?>" alt="<?= interact_as_actor() ->avatar_image_url ?>" alt="<?= interact_as_actor()
->display_name ?>" class="w-12 h-12 mr-4 rounded-full" /> ->display_name ?>" class="w-12 h-12 mr-4 rounded-full" />
<div class="flex flex-col flex-1 min-w-0"> <div class="flex flex-col flex-1 min-w-0">
<?= form_textarea( <input name="episode_url" value="<?= $episode->link ?>" type="hidden" />
[ <Forms.Textarea
'id' => 'message', name="message"
'name' => 'message', placeholder="<?= lang('Post.form.episode_message_placeholder') ?>"
'class' => 'form-textarea mb-2', required="true"
'required' => 'required', rows="2" />
'placeholder' => lang( <Button variant="primary" size="small" type="submit" class="self-end"><?= lang('Post.form.submit') ?></Button>
'Post.form.episode_message_placeholder',
),
],
old('message', '', false),
[
'rows' => 2,
],
) ?>
<?= form_input([
'id' => 'episode_url',
'name' => 'episode_url',
'value' => $episode->link,
'type' => 'hidden',
]) ?>
<?= button(
lang('Post.form.submit'),
'',
[
'variant' => 'primary',
'size' => 'small',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
</div> </div>
<?= form_close() ?> </form>
<hr class="my-4 border border-pine-100"> <hr class="my-4 border border-pine-100">
<?php foreach ($episode->posts as $post): ?> <?php foreach ($episode->posts as $post): ?>
<?= view('podcast/_partials/post_authenticated', [ <?= view('podcast/_partials/post_authenticated', [

View File

@ -48,39 +48,18 @@
</header> </header>
<main class="w-full max-w-md px-4 mx-auto"> <main class="w-full max-w-md px-4 mx-auto">
<?= form_open(route_to('attempt-follow', $actor->username), [ <form action="<?= route_to('attempt-follow', $actor->username) ?>" method="POST" class="flex flex-col">
'method' => 'post',
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= view('_message_block') ?> <?= view('_message_block') ?>
<?= form_label( <Forms.Field
lang('Fediverse.your_handle'), name="handle"
'handle', label="<?= lang('Fediverse.your_handle') ?>"
[], hint="<?= lang('Fediverse.your_handle_hint') ?>"
lang('Fediverse.your_handle_hint'), required="true"
) ?> />
<?= form_input([ <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.follow.submit') ?></Button>
'id' => 'handle', </form>
'name' => 'handle',
'class' => 'form-input mb-4',
'required' => 'required',
'type' => 'text',
]) ?>
<?= button(
lang('Fediverse.follow.submit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
</main> </main>
<footer <footer

View File

@ -40,41 +40,17 @@
<main class="flex-1 max-w-xl px-4 pb-8 mx-auto -mt-24"> <main class="flex-1 max-w-xl px-4 pb-8 mx-auto -mt-24">
<?= $this->include('podcast/_partials/post') ?> <?= $this->include('podcast/_partials/post') ?>
<?= form_open( <form action="<?= route_to('post-attempt-remote-action', $post->id, $action) ?>" method="POST" class="flex flex-col mt-8">
route_to('post-attempt-remote-action', $post->id, $action), <?= csrf_field() ?>
[ <?= view('_message_block') ?>
'method' => 'post',
'class' => 'flex flex-col mt-8',
],
) ?>
<?= csrf_field() ?>
<?= view('_message_block') ?>
<?= form_label( <Forms.Field
lang('Fediverse.your_handle'), name="handle"
'handle', label="<?= lang('Fediverse.your_handle') ?>"
[], hint="<?= lang('Fediverse.your_handle_hint') ?>"
lang('Fediverse.your_handle_hint'), required="true" />
) ?>
<?= form_input([
'id' => 'handle',
'name' => 'handle',
'class' => 'form-input mb-4',
'required' => 'required',
'type' => 'text',
]) ?>
<?= button( <Button variant="primary" type="submit" class="self-end"><?= lang('Fediverse.' . $action . '.submit') ?></Button>
lang('Fediverse.' . $action . '.submit'), </form>
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
</main> </main>
</body> </body>

View File

@ -10,32 +10,15 @@
<p class="mb-4 text-gray-600"><?= lang('Auth.enterEmailForInstructions') ?></p> <p class="mb-4 text-gray-600"><?= lang('Auth.enterEmailForInstructions') ?></p>
<?= form_open(route_to('forgot'), [ <form action="<?= route_to('forgot') ?>" method="POST" class="flex flex-col">
'class' => 'flex flex-col', <?= csrf_field() ?>
]) ?>
<?= csrf_field() ?>
<?= form_label(lang('Auth.emailAddress'), 'email') ?> <Forms.Field
<?= form_input([ name="email"
'id' => 'email', label="<?= lang('Auth.emailAddress') ?>"
'name' => 'email', type="email"
'class' => 'form-input mb-4', required="true" />
'type' => 'email', <Button variant="primary" type="submit" class="self-end"><?= lang('Auth.sendInstructions') ?></Button>
'required' => 'required', </form>
]) ?>
<?= button(
lang('Auth.sendInstructions'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -8,42 +8,22 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('login'), [ <form actions="<?= route_to('login') ?>" method="POST" class="flex flex-col">
'class' => 'flex flex-col', <?= csrf_field() ?>
]) ?>
<?= csrf_field() ?>
<?= form_label(lang('Auth.emailOrUsername'), 'login') ?> <Forms.Field
<?= form_input([ name="login"
'id' => 'login', label="<?= lang('Auth.emailOrUsername') ?>"
'name' => 'login', required="true" />
'class' => 'form-input mb-4',
'required' => 'required',
]) ?>
<?= form_label(lang('Auth.password'), 'password') ?> <Forms.Field
<?= form_input([ name="password"
'id' => 'password', label="<?= lang('Auth.password') ?>"
'name' => 'password', type="password"
'class' => 'form-input mb-4', required="true" />
'type' => 'password',
'required' => 'required',
]) ?>
<Button variant="primary" type="submit" class="self-end"><?= lang('Auth.loginAction') ?></Button>
<?= button( </form>
lang('Auth.loginAction'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -8,57 +8,30 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('register'), [ <form action="<?= route_to('register') ?>" method="POST" class="flex flex-col">
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_label(lang('Auth.email'), 'email') ?> <Forms.Field
<?= form_input([ name="email"
'id' => 'email', label="<?= lang('Auth.email') ?>"
'name' => 'email', helper="<?= lang('Auth.weNeverShare') ?>"
'class' => 'form-input', type="email"
'value' => old('email'), required="true" />
'type' => 'email',
'required' => 'required',
'aria-describedby' => 'emailHelp',
]) ?>
<small id="emailHelp" class="mb-4 text-gray-700">
<?= lang('Auth.weNeverShare') ?>
</small>
<?= form_label(lang('Auth.username'), 'username') ?> <Forms.Field
<?= form_input([ name="username"
'id' => 'username', label="<?= lang('Auth.username') ?>"
'name' => 'username', required="true" />
'class' => 'form-input mb-4',
'value' => old('username'),
'required' => 'required',
]) ?>
<?= form_label(lang('Auth.password'), 'password') ?> <Forms.Field
<?= form_input([ name="password"
'id' => 'password', label="<?= lang('Auth.password') ?>"
'name' => 'password', required="true"
'class' => 'form-input mb-4', autocomplete="new-password" />
'type' => 'password',
'required' => 'required',
'autocomplete' => 'new-password',
]) ?>
<?= button( <Button variant="primary" type="submit" class="self-end"><?= lang('Auth.register') ?></Button>
lang('Auth.register'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -10,52 +10,30 @@
<p class="mb-4"><?= lang('Auth.enterCodeEmailPassword') ?></p> <p class="mb-4"><?= lang('Auth.enterCodeEmailPassword') ?></p>
<?= form_open(route_to('reset-password'), [ <form action="<?= route_to('reset-password') ?>" method="POST" class="flex flex-col">
'class' => 'flex flex-col',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<?= form_label(lang('Auth.token'), 'token') ?> <Forms.Field
<?= form_input([ name="token"
'id' => 'token', label="<?= lang('Auth.token') ?>"
'name' => 'token', value="<?= $token ?? '' ?>"
'class' => 'form-input mb-4', required="true" />
'value' => old('token', $token ?? ''),
'required' => 'required', <Forms.Field
]) ?> name="email"
label="<?= lang('Auth.email') ?>"
type="email"
required="true" />
<?= form_label(lang('Auth.email'), 'email') ?> <Forms.Field
<?= form_input([ name="password"
'id' => 'email', label="<?= lang('Auth.newPassword') ?>"
'name' => 'email', type="password"
'class' => 'form-input mb-4', required="true"
'value' => old('email'), autocomplete="new-password" />
'required' => 'required',
'type' => 'email',
]) ?>
<?= form_label(lang('Auth.newPassword'), 'password') ?> <Button variant="primary" type="submit" class="self-end"><?= lang('Auth.resetPassword') ?></Button>
<?= form_input([
'id' => 'password',
'name' => 'password',
'class' => 'form-input mb-4',
'type' => 'password',
'required' => 'required',
'autocomplete' => 'new-password',
]) ?>
<?= button( </form>
lang('Auth.resetPassword'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -16,7 +16,7 @@
<body class="flex flex-col min-h-screen mx-auto"> <body class="flex flex-col min-h-screen mx-auto">
<header class="border-b"> <header class="border-b">
<div class="container flex items-center justify-between px-2 py-4 mx-auto"> <div class="container flex items-center justify-between px-2 py-4 mx-auto">
Castopod installer <?= lang('Install.title') ?>
</div> </div>
</header> </header>
<main class="container flex flex-col items-center justify-center flex-1 px-4 py-10 mx-auto"> <main class="container flex flex-col items-center justify-center flex-1 px-4 py-10 mx-auto">

View File

@ -2,48 +2,33 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('cache-config'), [ <form action="<?= route_to('cache-config') ?>" method="POST" class="flex flex-col w-full max-w-sm gap-y-4">
'class' => 'flex flex-col max-w-sm w-full',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<h1 class="mb-4 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">3/4</span><?= lang( <div class="flex flex-col mb-2">
'Install.form.cache_config', <div class="flex items-center">
) ?></h1> <span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">3/4</span>
<Heading tagName="h1"><?= lang('Install.form.cache_config') ?></h1>
</div>
<p class="mb-4 text-sm text-gray-600"><?= lang( <p class="mt-2 text-sm text-gray-600"><?= lang(
'Install.form.cache_config_hint', 'Install.form.cache_config_hint',
) ?></p> ) ?></p>
</div>
<?= form_label(lang('Install.form.cache_handler'), 'db_prefix') ?> <Forms.Field
<?= form_dropdown( as="Select"
'cache_handler', name="cache_handler"
[ label="<?= lang('Install.form.cache_handler') ?>"
options="<?= esc(json_encode([
'file' => lang('Install.form.cacheHandlerOptions.file'), 'file' => lang('Install.form.cacheHandlerOptions.file'),
'redis' => lang('Install.form.cacheHandlerOptions.redis'), 'redis' => lang('Install.form.cacheHandlerOptions.redis'),
'predis' => lang('Install.form.cacheHandlerOptions.predis'), 'predis' => lang('Install.form.cacheHandlerOptions.predis'),
], ])) ?>"
[old('cache_handler', 'file')], selected="file"
[ required="true" />
'id' => 'cache_handler',
'name' => 'cache_handler',
'class' => 'form-select mb-6',
'value' => config('Database')
->default['DBPrefix'],
],
) ?>
<?= button( <Button variant="primary" class="self-end" iconRight="arrow-right" type="submit"><?= lang('Install.form.next') ?></Button>
lang('Install.form.next') . icon('arrow-right', 'ml-2'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> <?= form_close() ?>

View File

@ -2,56 +2,34 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('create-superadmin'), [ <form action="<?= route_to('create-superadmin') ?>" method="POST" class="flex flex-col w-full max-w-sm gap-y-4">
'class' => 'flex flex-col max-w-sm w-full',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<h1 class="mb-4 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">4/4</span><?= lang( <div class="flex items-center mb-2">
'Install.form.create_superadmin', <span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">4/4</span>
) ?></h1> <Heading tagName="h1"><?= lang('Install.form.create_superadmin') ?></Heading>
</div>
<?= form_label(lang('Install.form.email'), 'email') ?> <Forms.Field
<?= form_input([ name="email"
'id' => 'email', label="<?= lang('Install.form.email') ?>"
'name' => 'email', type="email"
'class' => 'form-input mb-4', required="true" />
'type' => 'email',
'required' => 'required',
'value' => old('email'),
]) ?>
<?= form_label(lang('Install.form.username'), 'username') ?> <Forms.Field
<?= form_input([ name="username"
'id' => 'username', label="<?= lang('Install.form.username') ?>"
'name' => 'username', required="true" />
'class' => 'form-input mb-4',
'required' => 'required',
'value' => old('username'),
]) ?>
<?= form_label(lang('Install.form.password'), 'password') ?> <Forms.Field
<?= form_input([ name="password"
'id' => 'password', label="<?= lang('Install.form.password') ?>"
'name' => 'password', type="password"
'class' => 'form-input mb-4', required="true"
'type' => 'password', autocomplete="new-password" />
'required' => 'required',
'autocomplete' => 'new-password',
]) ?>
<?= button( <Button variant="primary" type="submit" class="self-end" iconLeft="check"><?= lang('Install.form.submit') ?></Button>
icon('check', 'mr-2') . lang('Install.form.submit'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -2,84 +2,58 @@
<?= $this->section('content') ?> <?= $this->section('content') ?>
<?= form_open(route_to('database-config'), [ <form action="<?= route_to('database-config') ?>" method="POST" class="flex flex-col w-full max-w-sm gap-y-4" autocomplete="off">
'class' => 'flex flex-col max-w-sm w-full',
'autocomplete' => 'off',
]) ?>
<?= csrf_field() ?> <?= csrf_field() ?>
<h1 class="mb-2 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">2/4</span><?= lang( <div class="flex flex-col mb-2">
<div class="flex items-center">
<span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">2/4</span>
<Heading tagName="h1"><?= lang(
'Install.form.database_config', 'Install.form.database_config',
) ?></h1> ) ?></Heading>
</div>
<p class="mb-4 text-sm text-gray-600"><?= lang( <p class="mt-2 text-sm text-gray-600"><?= lang(
'Install.form.database_config_hint', 'Install.form.database_config_hint',
) ?></p> ) ?></p>
</div>
<?= form_label(lang('Install.form.db_hostname'), 'db_hostname') ?> <Forms.Field
<?= form_input([ name="db_hostname"
'id' => 'db_hostname', label="<?= lang('Install.form.db_hostname') ?>"
'name' => 'db_hostname', value="<?= config('Database')
'class' => 'form-input mb-4', ->default['hostname'] ?>"
'value' => old('db_hostname', config('Database')->default['hostname']), required="true" />
'required' => 'required',
]) ?>
<?= form_label(lang('Install.form.db_name'), 'db_name') ?> <Forms.Field
<?= form_input([ name="db_name"
'id' => 'db_name', label="<?= lang('Install.form.db_name') ?>"
'name' => 'db_name', value="<?= config('Database')->default['database'] ?>"
'class' => 'form-input mb-4', required="true" />
'value' => old('db_name', config('Database')->default['database']),
'required' => 'required',
]) ?>
<?= form_label(lang('Install.form.db_username'), 'db_username') ?> <Forms.Field
<?= form_input([ name="db_username"
'id' => 'db_username', label="<?= lang('Install.form.db_username') ?>"
'name' => 'db_username', value="<?= config('Database')->default['username'] ?>"
'class' => 'form-input mb-4', required="true"
'value' => old('db_username', config('Database')->default['username']), autocomplete="off" />
'required' => 'required',
'autocomplete' => 'off',
]) ?>
<?= form_label(lang('Install.form.db_password'), 'db_password') ?> <Forms.Field
<?= form_input([ name="db_password"
'id' => 'db_password', label="<?= lang('Install.form.db_password') ?>"
'name' => 'db_password', value="<?= config('Database')->default['password'] ?>"
'class' => 'form-input mb-4', type="password"
'value' => old('db_password', config('Database')->default['password']), required="true"
'type' => 'password', autocomplete="off" />
'required' => 'required',
'autocomplete' => 'off',
]) ?>
<?= form_label( <Forms.Field
lang('Install.form.db_prefix'), name="db_prefix"
'db_prefix', label="<?= lang('Install.form.db_prefix') ?>"
[], hint="<?= lang('Install.form.db_prefix_hint') ?>"
lang('Install.form.db_prefix_hint'), value="<?= config('Database')->default['DBPrefix'] ?>" />
) ?>
<?= form_input([
'id' => 'db_prefix',
'name' => 'db_prefix',
'class' => 'form-input mb-6',
'value' => old('db_prefix', config('Database')->default['DBPrefix']),
]) ?>
<?= button( <Button variant="primary" type="submit" class="self-end" iconRight="arrow-right"><?= lang('Install.form.next') ?></Button>
lang('Install.form.next') . icon('arrow-right', 'ml-2'),
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?> </form>
<?= $this->endSection() ?> <?= $this->endSection() ?>

View File

@ -1,84 +1,44 @@
<?= $this->extend('_layout') ?> <?= $this->extend('_layout') ?>
<?= $this->section('content') ?> <?= $this->section('content') ?>
adz
<form action="<?= '/' . <form action="<?= '/' . config('Install')->gateway . '/instance-config' ?>" class="flex flex-col w-full max-w-sm gap-y-4" method="post" accept-charset="utf-8">
config('Install')
->gateway .
'/instance-config' ?>" class="flex flex-col w-full max-w-sm" method="post" accept-charset="utf-8">
<?= csrf_field() ?> <?= csrf_field() ?>
<h1 class="mb-4 text-xl font-bold font-display"><span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">1/4</span><?= lang( <div class="flex items-center mb-4">
'Install.form.instance_config', <span class="inline-flex items-center justify-center w-12 h-12 mr-2 text-sm font-semibold tracking-wider border-4 rounded-full text-pine-700 border-pine-700">1/4</span>
) ?></h1> <Heading tagName="h1"><?= lang('Install.form.instance_config') ?></Heading>
<?= form_label(lang('Install.form.hostname'), 'hostname') ?> </div>
<?= form_input([
'id' => 'hostname',
'name' => 'hostname',
'class' => 'form-input mb-4',
'value' => old(
'hostname',
host_url() === null ? config('App')
->baseURL : host_url(),
),
'required' => 'required',
]) ?>
<Forms.Field
name="hostname"
label="<?= lang('Install.form.hostname') ?>"
value="<?= host_url() === null ? config('App')
->baseURL : host_url() ?>"
required="true" />
<?= form_label( <Forms.Field
lang('Install.form.media_base_url'), name="media_base_url"
'media_base_url', label="<?= lang('Install.form.media_base_url') ?>"
[], hint="<?= lang('Install.form.media_base_url_hint') ?>" />
lang('Install.form.media_base_url_hint'),
true,
) ?>
<?= form_input([
'id' => 'media_base_url',
'name' => 'media_base_url',
'class' => 'form-input mb-4',
'value' => old('media_base_url', ''),
]) ?>
<?= form_label( <Forms.Field
lang('Install.form.admin_gateway'), name="admin_gateway"
'admin_gateway', label="<?= lang('Install.form.admin_gateway') ?>"
[], hint="<?= lang('Install.form.admin_gateway_hint') ?>"
lang('Install.form.admin_gateway_hint'), value="<?= config('Admin')
) ?> ->gateway ?>"
<?= form_input([ required="true" />
'id' => 'admin_gateway',
'name' => 'admin_gateway',
'class' => 'form-input mb-4',
'value' => old('admin_gateway', config('Admin')->gateway),
'required' => 'required',
]) ?>
<?= form_label( <Forms.Field
lang('Install.form.auth_gateway'), name="auth_gateway"
'auth_gateway', label="<?= lang('Install.form.auth_gateway') ?>"
[], hint="<?= lang('Install.form.auth_gateway_hint') ?>"
lang('Install.form.auth_gateway_hint'), value="<?= config('Auth')
) ?> ->gateway ?>"
<?= form_input([ required="true" />
'id' => 'auth_gateway',
'name' => 'auth_gateway',
'class' => 'form-input mb-6',
'value' => old('auth_gateway', config('Auth')->gateway),
'required' => 'required',
]) ?>
<?= button( <Button class="self-end" variant="primary" type="submit" iconRight="arrow-right"><?= lang('Install.form.next') ?></Button>
lang('Install.form.next') . icon('arrow-right', 'ml-2'), </form>
'',
[
'variant' => 'primary',
],
[
'type' => 'submit',
'class' => 'self-end',
],
) ?>
<?= form_close() ?>
<?= $this->endSection() ?> <?= $this->endSection() ?>