Adds new green color palette, removes any requirement of a remote calendar description as validation, fixes language settings pane
This commit is contained in:
parent
1a92f09e3b
commit
6242a9772a
@ -28,6 +28,7 @@ class SubscriptionController extends Controller
|
|||||||
|
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
|
/* validate the submission */
|
||||||
$data = $request->validate([
|
$data = $request->validate([
|
||||||
'source' => 'required|url',
|
'source' => 'required|url',
|
||||||
'displayname' => 'nullable|string|max:255',
|
'displayname' => 'nullable|string|max:255',
|
||||||
@ -35,25 +36,26 @@ class SubscriptionController extends Controller
|
|||||||
'refreshrate' => 'nullable|string|max:10',
|
'refreshrate' => 'nullable|string|max:10',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$principalUri = $request->user()->uri;
|
/* normalize hard to check against this url */
|
||||||
$source = rtrim(trim($data['source']), '/');
|
$source = rtrim(trim($data['source']), '/');
|
||||||
$desc = 'Remote feed: '.$source;
|
|
||||||
|
|
||||||
/* if they already subscribed to this exact feed, don’t create duplicates */
|
/* set the principal URI */
|
||||||
if (Subscription::where('principaluri', $principalUri)->where('source', $source)->exists()) {
|
$principalUri = $request->user()->uri;
|
||||||
|
|
||||||
|
/* check for existing subscriptions */
|
||||||
|
$already = Subscription::query()
|
||||||
|
->where('principaluri', $principalUri)
|
||||||
|
->where('source', $source)
|
||||||
|
->exists();
|
||||||
|
|
||||||
|
if ($already) {
|
||||||
return Redirect::route('calendar.index')->with('toast', [
|
return Redirect::route('calendar.index')->with('toast', [
|
||||||
'message' => __('You are already subscribed to that calendar.'),
|
'message' => __('You are already subscribed to that calendar.'),
|
||||||
'type' => 'info',
|
'type' => 'info',
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$sub = DB::transaction(function () use ($request, $data, $principalUri, $source, $desc) {
|
$sub = DB::transaction(function () use ($data, $principalUri, $source) {
|
||||||
|
|
||||||
/* check if a mirror instance already exists */
|
|
||||||
$existingInstance = CalendarInstance::where('principaluri', $principalUri)
|
|
||||||
->where('description', $desc)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
|
|
||||||
/* create the calendarsubscriptions record */
|
/* create the calendarsubscriptions record */
|
||||||
$sub = Subscription::create([
|
$sub = Subscription::create([
|
||||||
@ -66,36 +68,24 @@ class SubscriptionController extends Controller
|
|||||||
'lastmodified' => now()->timestamp,
|
'lastmodified' => now()->timestamp,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// choose the calendar container
|
// create new empty calendar container
|
||||||
if ($existingInstance) {
|
$calId = Calendar::create([
|
||||||
$calId = $existingInstance->calendarid;
|
'synctoken' => 1,
|
||||||
|
'components' => 'VEVENT',
|
||||||
|
])->id;
|
||||||
|
|
||||||
// keep the mirror instance’s user-facing bits up to date
|
// create mirror calendarinstance row (description can be user-editable, not relied on)
|
||||||
$existingInstance->update([
|
CalendarInstance::create([
|
||||||
'displayname' => $sub->displayname,
|
'calendarid' => $calId,
|
||||||
'calendarcolor' => $sub->calendarcolor,
|
'principaluri' => $principalUri,
|
||||||
'timezone' => config('app.timezone', 'UTC'),
|
'uri' => (string) Str::uuid(),
|
||||||
]);
|
'displayname' => $sub->displayname,
|
||||||
} else {
|
'description' => 'Remote feed: '.$source, // informational only
|
||||||
// create new empty calendar container
|
'calendarcolor' => $sub->calendarcolor,
|
||||||
$calId = Calendar::create([
|
'timezone' => config('app.timezone', 'UTC'),
|
||||||
'synctoken' => 1,
|
]);
|
||||||
'components' => 'VEVENT',
|
|
||||||
])->id;
|
|
||||||
|
|
||||||
// create mirror calendarinstance row
|
// meta entry
|
||||||
CalendarInstance::create([
|
|
||||||
'calendarid' => $calId,
|
|
||||||
'principaluri' => $sub->principaluri,
|
|
||||||
'uri' => Str::uuid(),
|
|
||||||
'displayname' => $sub->displayname,
|
|
||||||
'description' => $desc,
|
|
||||||
'calendarcolor' => $sub->calendarcolor,
|
|
||||||
'timezone' => config('app.timezone', 'UTC'),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// upsert our calendar_meta entry by calendar_id (since that’s your pk)
|
|
||||||
CalendarMeta::updateOrCreate(
|
CalendarMeta::updateOrCreate(
|
||||||
['calendar_id' => $calId],
|
['calendar_id' => $calId],
|
||||||
[
|
[
|
||||||
@ -114,12 +104,10 @@ class SubscriptionController extends Controller
|
|||||||
// sync immediately so events appear without waiting for the */10 dispatcher
|
// sync immediately so events appear without waiting for the */10 dispatcher
|
||||||
SyncSubscription::dispatch($sub)->afterCommit();
|
SyncSubscription::dispatch($sub)->afterCommit();
|
||||||
|
|
||||||
return redirect()
|
return Redirect::route('calendar.index')->with('toast', [
|
||||||
->route('calendar.index')
|
'message' => __('Subscription added! Syncing events now...'),
|
||||||
->with('toast', [
|
'type' => 'success',
|
||||||
'message' => __('Subscription added! Syncing events now...'),
|
]);
|
||||||
'type' => 'success',
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function edit(Subscription $subscription)
|
public function edit(Subscription $subscription)
|
||||||
|
|||||||
@ -188,27 +188,19 @@ class SyncSubscription implements ShouldQueue
|
|||||||
return (int) $meta->calendar_id;
|
return (int) $meta->calendar_id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$desc = $this->mirrorDescription($source);
|
// create a new master calendar in `calendars`
|
||||||
|
|
||||||
$existing = CalendarInstance::where('principaluri', $this->subscription->principaluri)
|
|
||||||
->where('description', $desc)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
if ($existing) {
|
|
||||||
return (int) $existing->calendarid;
|
|
||||||
}
|
|
||||||
|
|
||||||
$calendar = Calendar::create([
|
$calendar = Calendar::create([
|
||||||
'synctoken' => 1,
|
'synctoken' => 1,
|
||||||
'components' => 'VEVENT',
|
'components' => 'VEVENT',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// create the per-user instance (description is display-only; never used for lookup)
|
||||||
CalendarInstance::create([
|
CalendarInstance::create([
|
||||||
'calendarid' => $calendar->id,
|
'calendarid' => $calendar->id,
|
||||||
'principaluri' => $this->subscription->principaluri,
|
'principaluri' => $this->subscription->principaluri,
|
||||||
'uri' => (string) Str::uuid(),
|
'uri' => (string) Str::uuid(),
|
||||||
'displayname' => $this->subscription->displayname,
|
'displayname' => $this->subscription->displayname,
|
||||||
'description' => $desc,
|
'description' => $this->mirrorDescription($source),
|
||||||
'calendarcolor' => $meta->color ?? '#1a1a1a',
|
'calendarcolor' => $meta->color ?? '#1a1a1a',
|
||||||
'timezone' => config('app.timezone', 'UTC'),
|
'timezone' => config('app.timezone', 'UTC'),
|
||||||
]);
|
]);
|
||||||
|
|||||||
@ -26,7 +26,7 @@ return [
|
|||||||
],
|
],
|
||||||
'language_region' => [
|
'language_region' => [
|
||||||
'title' => 'Language and region',
|
'title' => 'Language and region',
|
||||||
'subtitle' => 'Choose your default language, region, and formatting preferences for calendars. These affect how dates and times are displayed throughout Kithkin.',
|
'subtitle' => 'Choose your default language, region, and formatting preferences. These affect how dates and times are displayed in your calendars and events.',
|
||||||
],
|
],
|
||||||
'my_calendars' => 'Settings for my calendars',
|
'my_calendars' => 'Settings for my calendars',
|
||||||
'subscribe' => [
|
'subscribe' => [
|
||||||
|
|||||||
@ -17,11 +17,23 @@ return [
|
|||||||
'calendars' => 'Calendars',
|
'calendars' => 'Calendars',
|
||||||
'cancel' => 'Cancel',
|
'cancel' => 'Cancel',
|
||||||
'cancel_funny' => 'Get me out of here',
|
'cancel_funny' => 'Get me out of here',
|
||||||
|
'date' => 'Date',
|
||||||
|
'date_select' => 'Select a date',
|
||||||
|
'date_format' => 'Date format',
|
||||||
|
'date_format_select' => 'Select a date format',
|
||||||
'event' => 'Event',
|
'event' => 'Event',
|
||||||
'events' => 'Events',
|
'events' => 'Events',
|
||||||
|
'language' => 'Language',
|
||||||
|
'language_select' => 'Select a language',
|
||||||
'password' => 'Password',
|
'password' => 'Password',
|
||||||
|
'region' => 'Region',
|
||||||
|
'region_select' => 'Select a region',
|
||||||
'save_changes' => 'Save changes',
|
'save_changes' => 'Save changes',
|
||||||
'settings' => 'Settings',
|
'settings' => 'Settings',
|
||||||
|
'time' => 'Time',
|
||||||
|
'time_select' => 'Select a time',
|
||||||
|
'time_format' => 'Time format',
|
||||||
|
'time_format_select' => 'Select a time format',
|
||||||
'timezone' => 'Time zone',
|
'timezone' => 'Time zone',
|
||||||
'timezone_select' => 'Select a time zone',
|
'timezone_select' => 'Select a time zone',
|
||||||
|
|
||||||
|
|||||||
@ -125,6 +125,23 @@ main {
|
|||||||
@apply flex items-center h-20 min-h-20 px-6 2xl:px-8;
|
@apply flex items-center h-20 min-h-20 px-6 2xl:px-8;
|
||||||
@apply backdrop-blur-xs sticky top-0 z-1 shrink-0;
|
@apply backdrop-blur-xs sticky top-0 z-1 shrink-0;
|
||||||
background-color: rgba(255, 255, 255, 0.9);
|
background-color: rgba(255, 255, 255, 0.9);
|
||||||
|
|
||||||
|
a.app-return {
|
||||||
|
@apply flex flex-row gap-2 items-center;
|
||||||
|
|
||||||
|
> svg {
|
||||||
|
@apply opacity-0 invisible -translate-x-1 text-white mt-1;
|
||||||
|
transition:
|
||||||
|
color 150ms ease-in,
|
||||||
|
opacity 150ms ease-in,
|
||||||
|
visibility 150ms ease-in,
|
||||||
|
translate 150ms ease-in;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover > svg {
|
||||||
|
@apply opacity-100 visible translate-x-0 text-secondary;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .aside-inset {
|
> .aside-inset {
|
||||||
@ -248,11 +265,11 @@ main {
|
|||||||
@keyframes title-drop {
|
@keyframes title-drop {
|
||||||
from {
|
from {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: translateY(-1rem);
|
transform: translateX(-0.5rem);
|
||||||
}
|
}
|
||||||
to {
|
to {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: translateY(0);
|
transform: translateX(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,6 +18,7 @@
|
|||||||
--color-primary-hover: #000000;
|
--color-primary-hover: #000000;
|
||||||
--color-secondary: #555;
|
--color-secondary: #555;
|
||||||
--color-secondary-hover: #444;
|
--color-secondary-hover: #444;
|
||||||
|
|
||||||
--color-cyan-50: oklch(98.97% 0.015 196.79);
|
--color-cyan-50: oklch(98.97% 0.015 196.79);
|
||||||
--color-cyan-100: oklch(97.92% 0.03 196.61);
|
--color-cyan-100: oklch(97.92% 0.03 196.61);
|
||||||
--color-cyan-200: oklch(95.79% 0.063 196.12);
|
--color-cyan-200: oklch(95.79% 0.063 196.12);
|
||||||
@ -30,6 +31,19 @@
|
|||||||
--color-cyan-800: oklch(59.15% 0.101 194.76);
|
--color-cyan-800: oklch(59.15% 0.101 194.76);
|
||||||
--color-cyan-900: oklch(49.05% 0.084 194.76);
|
--color-cyan-900: oklch(49.05% 0.084 194.76);
|
||||||
--color-cyan-950: oklch(43.96% 0.075 194.76);
|
--color-cyan-950: oklch(43.96% 0.075 194.76);
|
||||||
|
|
||||||
|
--color-green-50: oklch(0.975 0.014 162.33);
|
||||||
|
--color-green-100: oklch(0.953 0.029 163.16);
|
||||||
|
--color-green-200: oklch(0.907 0.058 162.25);
|
||||||
|
--color-green-300: oklch(0.864 0.085 160.81);
|
||||||
|
--color-green-400: oklch(0.821 0.112 159.55);
|
||||||
|
--color-green-500: oklch(0.782 0.136 157.79); /* #61d296 as 500 */
|
||||||
|
--color-green-600: oklch(0.734 0.161 155.16);
|
||||||
|
--color-green-700: oklch(0.624 0.137 155.13);
|
||||||
|
--color-green-800: oklch(0.507 0.108 155.72);
|
||||||
|
--color-green-900: oklch(0.382 0.078 156.05);
|
||||||
|
--color-green-950: oklch(0.319 0.063 156.43);
|
||||||
|
|
||||||
--color-magenta-50: oklch(96.93% 0.027 325.87);
|
--color-magenta-50: oklch(96.93% 0.027 325.87);
|
||||||
--color-magenta-100: oklch(93.76% 0.056 326.06);
|
--color-magenta-100: oklch(93.76% 0.056 326.06);
|
||||||
--color-magenta-200: oklch(87.58% 0.117 326.54);
|
--color-magenta-200: oklch(87.58% 0.117 326.54);
|
||||||
@ -42,6 +56,7 @@
|
|||||||
--color-magenta-800: oklch(47.69% 0.219 328.37);
|
--color-magenta-800: oklch(47.69% 0.219 328.37);
|
||||||
--color-magenta-900: oklch(40.42% 0.186 328.37);
|
--color-magenta-900: oklch(40.42% 0.186 328.37);
|
||||||
--color-magenta-950: oklch(36.79% 0.169 328.37);
|
--color-magenta-950: oklch(36.79% 0.169 328.37);
|
||||||
|
|
||||||
--color-red-50: oklch(0.975 0.012 23.84);
|
--color-red-50: oklch(0.975 0.012 23.84);
|
||||||
--color-red-100: oklch(0.951 0.024 20.79);
|
--color-red-100: oklch(0.951 0.024 20.79);
|
||||||
--color-red-200: oklch(0.895 0.055 23.81);
|
--color-red-200: oklch(0.895 0.055 23.81);
|
||||||
@ -56,6 +71,8 @@
|
|||||||
|
|
||||||
--border-width-md: 1.5px;
|
--border-width-md: 1.5px;
|
||||||
|
|
||||||
|
--outline-width-md: 1.5px;
|
||||||
|
|
||||||
--radius-xs: 0.25rem;
|
--radius-xs: 0.25rem;
|
||||||
--radius-sm: 0.375rem;
|
--radius-sm: 0.375rem;
|
||||||
--radius-md: 0.6667rem;
|
--radius-md: 0.6667rem;
|
||||||
|
|||||||
@ -2,6 +2,7 @@ button,
|
|||||||
.button {
|
.button {
|
||||||
@apply relative inline-flex items-center cursor-pointer gap-2 rounded-md h-11 px-4 text-lg font-medium;
|
@apply relative inline-flex items-center cursor-pointer gap-2 rounded-md h-11 px-4 text-lg font-medium;
|
||||||
/*transition: background-color 125ms ease-in-out; */
|
/*transition: background-color 125ms ease-in-out; */
|
||||||
|
@apply focus:outline-md focus:outline-offset-2 focus:outline-secondary;
|
||||||
--button-border: var(--color-primary);
|
--button-border: var(--color-primary);
|
||||||
--button-accent: var(--color-primary-hover);
|
--button-accent: var(--color-primary-hover);
|
||||||
|
|
||||||
@ -16,7 +17,11 @@ button,
|
|||||||
}
|
}
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
box-shadow: none;
|
@apply shadow-none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
@apply shadow-none outline-none;
|
||||||
left: 2.5px;
|
left: 2.5px;
|
||||||
top: 2.5px;
|
top: 2.5px;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,7 @@ dl.toasts {
|
|||||||
@apply h-0 invisible overflow-hidden;
|
@apply h-0 invisible overflow-hidden;
|
||||||
|
|
||||||
&.success + dd {
|
&.success + dd {
|
||||||
@apply bg-green-500 text-white;
|
@apply bg-green-500 text-primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.error + dd {
|
&.error + dd {
|
||||||
|
|||||||
1
resources/svg/icons/return.svg
Normal file
1
resources/svg/icons/return.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-undo2-icon lucide-undo-2"><path d="M9 14 4 9l5-5"/><path d="M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11"/></svg>
|
||||||
|
After Width: | Height: | Size: 327 B |
@ -2,7 +2,10 @@
|
|||||||
|
|
||||||
<x-slot name="aside">
|
<x-slot name="aside">
|
||||||
<h1>
|
<h1>
|
||||||
{{ __('common.calendar') }}
|
<a href="{{ route('calendar.index') }}" class="app-return">
|
||||||
|
<span>{{ __('common.calendar') }}</span>
|
||||||
|
<x-icon-return width="20" />
|
||||||
|
</a>
|
||||||
</h1>
|
</h1>
|
||||||
<x-menu.calendar-settings :calendars="$calendars" />
|
<x-menu.calendar-settings :calendars="$calendars" />
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|||||||
@ -9,70 +9,67 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="post"
|
<form method="post" action="{{ route('calendar.settings.language.store') }}" class="settings">
|
||||||
action="{{ route('calendar.settings.language.store') }}"
|
|
||||||
class="form-grid-1 mt-8">
|
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
<div>
|
<div class="input-row input-row--1-1">
|
||||||
<label for="language">{{ __('Language') }}</label>
|
<div class="input-cell">
|
||||||
<select id="language" name="language">
|
<x-input.label for="language" :value="__('common.language')" />
|
||||||
@foreach(($options['languages'] ?? []) as $value => $label)
|
<x-input.select
|
||||||
<option value="{{ $value }}" @selected(old('language', $values['language'] ?? '') === $value)>
|
id="language"
|
||||||
{{ $label }}
|
name="language"
|
||||||
</option>
|
placeholder="{{ __('common.language_select') }}"
|
||||||
@endforeach
|
:value="$values['language']"
|
||||||
</select>
|
:options="$options['languages']"
|
||||||
@error('language')
|
:selected="old('language', $values['language'])"
|
||||||
<div class="text-danger">{{ $message }}</div>
|
/>
|
||||||
@enderror
|
<x-input.error :messages="$errors->get('language')" />
|
||||||
|
</div>
|
||||||
|
<div class="input-cell">
|
||||||
|
<x-input.label for="region" :value="__('common.region')" />
|
||||||
|
<x-input.select
|
||||||
|
id="region"
|
||||||
|
name="region"
|
||||||
|
placeholder="{{ __('common.region_select') }}"
|
||||||
|
:value="$values['region']"
|
||||||
|
:options="$options['regions']"
|
||||||
|
:selected="old('region', $values['region'])"
|
||||||
|
/>
|
||||||
|
<x-input.error :messages="$errors->get('region')" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="input-row input-row--1-1">
|
||||||
<label for="region">{{ __('Region') }}</label>
|
<div class="input-cell">
|
||||||
<select id="region" name="region">
|
<x-input.label for="date_format" :value="__('common.date_format')" />
|
||||||
@foreach(($options['regions'] ?? []) as $value => $label)
|
<x-input.select
|
||||||
<option value="{{ $value }}" @selected(old('region', $values['region'] ?? '') === $value)>
|
id="date_format"
|
||||||
{{ $label }}
|
name="date_format"
|
||||||
</option>
|
placeholder="{{ __('common.date_format_select') }}"
|
||||||
@endforeach
|
:value="$values['date_format']"
|
||||||
</select>
|
:options="$options['date_formats']"
|
||||||
@error('region')
|
:selected="old('date_format', $values['date_format'])"
|
||||||
<div class="text-danger">{{ $message }}</div>
|
/>
|
||||||
@enderror
|
<x-input.error :messages="$errors->get('date_format')" />
|
||||||
|
</div>
|
||||||
|
<div class="input-cell">
|
||||||
|
<x-input.label for="time_format" :value="__('common.time_format')" />
|
||||||
|
<x-input.select
|
||||||
|
id="time_format"
|
||||||
|
name="time_format"
|
||||||
|
placeholder="{{ __('common.time_format_select') }}"
|
||||||
|
:value="$values['time_format']"
|
||||||
|
:options="$options['time_formats']"
|
||||||
|
:selected="old('time_format', $values['time_format'])"
|
||||||
|
/>
|
||||||
|
<x-input.error :messages="$errors->get('time_format')" />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div class="input-row input-row--actions input-row--start sticky-bottom">
|
||||||
<label for="date_format">{{ __('Date format') }}</label>
|
<x-button variant="primary" type="submit">{{ __('common.save_changes') }}</x-button>
|
||||||
<select id="date_format" name="date_format">
|
<x-button type="anchor"
|
||||||
@foreach(($options['date_formats'] ?? []) as $value => $label)
|
variant="tertiary"
|
||||||
<option value="{{ $value }}" @selected(old('date_format', $values['date_format'] ?? '') === $value)>
|
href="{{ route('calendar.settings.language') }}">{{ __('common.cancel') }}</x-button>
|
||||||
{{ $label }}
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
@error('date_format')
|
|
||||||
<div class="text-danger">{{ $message }}</div>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<label for="time_format">{{ __('Time format') }}</label>
|
|
||||||
<select id="time_format" name="time_format">
|
|
||||||
@foreach(($options['time_formats'] ?? []) as $value => $label)
|
|
||||||
<option value="{{ $value }}" @selected(old('time_format', $values['time_format'] ?? '') === $value)>
|
|
||||||
{{ $label }}
|
|
||||||
</option>
|
|
||||||
@endforeach
|
|
||||||
</select>
|
|
||||||
@error('time_format')
|
|
||||||
<div class="text-danger">{{ $message }}</div>
|
|
||||||
@enderror
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex gap-4">
|
|
||||||
<x-button variant="primary" type="submit">{{ __('Save') }}</x-button>
|
|
||||||
<a href="{{ route('calendar.index') }}"
|
|
||||||
class="button button--secondary">{{ __('Cancel and go back') }}</a>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user