Release v1.4.0 #146
41 changed files with 443 additions and 532 deletions
|
|
@ -1,2 +1,32 @@
|
||||||
@import 'tailwindcss';
|
@import 'tailwindcss';
|
||||||
@plugin '@tailwindcss/forms';
|
@plugin '@tailwindcss/forms';
|
||||||
|
|
||||||
|
@custom-variant dark (&:where(.dark, .dark *));
|
||||||
|
|
||||||
|
[x-cloak] {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @tailwindcss/forms paints controls white; utilities on each tag would not cover option/placeholder. */
|
||||||
|
@layer base {
|
||||||
|
.dark :is(input, select, textarea):not([type='checkbox']):not([type='radio']) {
|
||||||
|
background-color: var(--color-gray-700);
|
||||||
|
border-color: var(--color-gray-600);
|
||||||
|
color: var(--color-gray-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark :is(input, select, textarea)::placeholder {
|
||||||
|
color: var(--color-gray-400);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark option {
|
||||||
|
background-color: var(--color-gray-700);
|
||||||
|
color: var(--color-gray-100);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Only the unchecked box; checked uses currentColor for the accent. */
|
||||||
|
.dark :is([type='checkbox'], [type='radio']):not(:checked) {
|
||||||
|
background-color: var(--color-gray-700);
|
||||||
|
border-color: var(--color-gray-600);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<x-guest-layout>
|
<x-guest-layout>
|
||||||
<div class="mb-4 text-sm text-gray-600">
|
<div class="mb-4 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __('This is a secure area of the application. Please confirm your password before continuing.') }}
|
{{ __('This is a secure area of the application. Please confirm your password before continuing.') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<x-guest-layout>
|
<x-guest-layout>
|
||||||
<div class="mb-4 text-sm text-gray-600">
|
<div class="mb-4 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
|
{{ __('Forgot your password? No problem. Just let us know your email address and we will email you a password reset link that will allow you to choose a new one.') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<x-guest-layout>
|
<x-guest-layout>
|
||||||
<div class="mb-6 text-center">
|
<div class="mb-6 text-center">
|
||||||
<h2 class="text-2xl font-bold text-gray-900">Welcome back</h2>
|
<h2 class="text-2xl font-bold text-gray-900 dark:text-gray-100">Welcome back</h2>
|
||||||
<p class="mt-1 text-sm text-gray-500">Sign in to your account</p>
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Sign in to your account</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Session Status -->
|
<!-- Session Status -->
|
||||||
|
|
@ -32,8 +32,8 @@
|
||||||
<!-- Remember Me -->
|
<!-- Remember Me -->
|
||||||
<div class="block mt-4">
|
<div class="block mt-4">
|
||||||
<label for="remember_me" class="inline-flex items-center">
|
<label for="remember_me" class="inline-flex items-center">
|
||||||
<input id="remember_me" type="checkbox" class="rounded-sm border-gray-300 text-blue-600 shadow-xs focus:ring-blue-500" name="remember">
|
<input id="remember_me" type="checkbox" class="rounded-sm border-gray-300 text-blue-600 shadow-xs focus:ring-blue-500 dark:border-gray-600 dark:text-blue-400" name="remember">
|
||||||
<span class="ms-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
|
<span class="ms-2 text-sm text-gray-600 dark:text-gray-300">{{ __('Remember me') }}</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -45,8 +45,8 @@
|
||||||
|
|
||||||
@if (Route::has('register'))
|
@if (Route::has('register'))
|
||||||
<div class="mt-6 text-center">
|
<div class="mt-6 text-center">
|
||||||
<span class="text-sm text-gray-500">Don't have an account?</span>
|
<span class="text-sm text-gray-500 dark:text-gray-400">Don't have an account?</span>
|
||||||
<a class="text-sm text-blue-600 hover:text-blue-800 font-medium ml-1" href="{{ route('register') }}">
|
<a class="text-sm text-blue-600 hover:text-blue-800 font-medium ml-1 dark:text-blue-400" href="{{ route('register') }}">
|
||||||
{{ __('Sign up') }}
|
{{ __('Sign up') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<x-guest-layout>
|
<x-guest-layout>
|
||||||
<div class="mb-6 text-center">
|
<div class="mb-6 text-center">
|
||||||
<h2 class="text-2xl font-bold text-gray-900">Create an account</h2>
|
<h2 class="text-2xl font-bold text-gray-900 dark:text-gray-100">Create an account</h2>
|
||||||
<p class="mt-1 text-sm text-gray-500">Get started with FFR</p>
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Get started with FFR</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form method="POST" action="{{ route('register') }}">
|
<form method="POST" action="{{ route('register') }}">
|
||||||
|
|
@ -47,8 +47,8 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 text-center">
|
<div class="mt-6 text-center">
|
||||||
<span class="text-sm text-gray-500">Already have an account?</span>
|
<span class="text-sm text-gray-500 dark:text-gray-400">Already have an account?</span>
|
||||||
<a class="text-sm text-blue-600 hover:text-blue-800 font-medium ml-1" href="{{ route('login') }}">
|
<a class="text-sm text-blue-600 hover:text-blue-800 font-medium ml-1 dark:text-blue-400" href="{{ route('login') }}">
|
||||||
{{ __('Sign in') }}
|
{{ __('Sign in') }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<x-guest-layout>
|
<x-guest-layout>
|
||||||
<div class="mb-4 text-sm text-gray-600">
|
<div class="mb-4 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
|
{{ __('Thanks for signing up! Before getting started, could you verify your email address by clicking on the link we just emailed to you? If you didn\'t receive the email, we will gladly send you another.') }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (session('status') == 'verification-link-sent')
|
@if (session('status') == 'verification-link-sent')
|
||||||
<div class="mb-4 font-medium text-sm text-green-600">
|
<div class="mb-4 font-medium text-sm text-green-600 dark:text-green-400">
|
||||||
{{ __('A new verification link has been sent to the email address you provided during registration.') }}
|
{{ __('A new verification link has been sent to the email address you provided during registration.') }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
<form method="POST" action="{{ route('logout') }}">
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
@csrf
|
@csrf
|
||||||
|
|
||||||
<button type="submit" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
<button type="submit" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:text-gray-300 dark:hover:text-gray-100">
|
||||||
{{ __('Log Out') }}
|
{{ __('Log Out') }}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
<svg viewBox="0 0 316 316" xmlns="http://www.w3.org/2000/svg" {{ $attributes }}>
|
|
||||||
<path d="M305.8 81.125C305.77 80.995 305.69 80.885 305.65 80.755C305.56 80.525 305.49 80.285 305.37 80.075C305.29 79.935 305.17 79.815 305.07 79.685C304.94 79.515 304.83 79.325 304.68 79.175C304.55 79.045 304.39 78.955 304.25 78.845C304.09 78.715 303.95 78.575 303.77 78.475L251.32 48.275C249.97 47.495 248.31 47.495 246.96 48.275L194.51 78.475C194.33 78.575 194.19 78.725 194.03 78.845C193.89 78.955 193.73 79.045 193.6 79.175C193.45 79.325 193.34 79.515 193.21 79.685C193.11 79.815 192.99 79.935 192.91 80.075C192.79 80.285 192.71 80.525 192.63 80.755C192.58 80.875 192.51 80.995 192.48 81.125C192.38 81.495 192.33 81.875 192.33 82.265V139.625L148.62 164.795V52.575C148.62 52.185 148.57 51.805 148.47 51.435C148.44 51.305 148.36 51.195 148.32 51.065C148.23 50.835 148.16 50.595 148.04 50.385C147.96 50.245 147.84 50.125 147.74 49.995C147.61 49.825 147.5 49.635 147.35 49.485C147.22 49.355 147.06 49.265 146.92 49.155C146.76 49.025 146.62 48.885 146.44 48.785L93.99 18.585C92.64 17.805 90.98 17.805 89.63 18.585L37.18 48.785C37 48.885 36.86 49.035 36.7 49.155C36.56 49.265 36.4 49.355 36.27 49.485C36.12 49.635 36.01 49.825 35.88 49.995C35.78 50.125 35.66 50.245 35.58 50.385C35.46 50.595 35.38 50.835 35.3 51.065C35.25 51.185 35.18 51.305 35.15 51.435C35.05 51.805 35 52.185 35 52.575V232.235C35 233.795 35.84 235.245 37.19 236.025L142.1 296.425C142.33 296.555 142.58 296.635 142.82 296.725C142.93 296.765 143.04 296.835 143.16 296.865C143.53 296.965 143.9 297.015 144.28 297.015C144.66 297.015 145.03 296.965 145.4 296.865C145.5 296.835 145.59 296.775 145.69 296.745C145.95 296.655 146.21 296.565 146.45 296.435L251.36 236.035C252.72 235.255 253.55 233.815 253.55 232.245V174.885L303.81 145.945C305.17 145.165 306 143.725 306 142.155V82.265C305.95 81.875 305.89 81.495 305.8 81.125ZM144.2 227.205L100.57 202.515L146.39 176.135L196.66 147.195L240.33 172.335L208.29 190.625L144.2 227.205ZM244.75 114.995V164.795L226.39 154.225L201.03 139.625V89.825L219.39 100.395L244.75 114.995ZM249.12 57.105L292.81 82.265L249.12 107.425L205.43 82.265L249.12 57.105ZM114.49 184.425L96.13 194.995V85.305L121.49 70.705L139.85 60.135V169.815L114.49 184.425ZM91.76 27.425L135.45 52.585L91.76 77.745L48.07 52.585L91.76 27.425ZM43.67 60.135L62.03 70.705L87.39 85.305V202.545V202.555V202.565C87.39 202.735 87.44 202.895 87.46 203.055C87.49 203.265 87.49 203.485 87.55 203.695V203.705C87.6 203.875 87.69 204.035 87.76 204.195C87.84 204.375 87.89 204.575 87.99 204.745C87.99 204.745 87.99 204.755 88 204.755C88.09 204.905 88.22 205.035 88.33 205.175C88.45 205.335 88.55 205.495 88.69 205.635L88.7 205.645C88.82 205.765 88.98 205.855 89.12 205.965C89.28 206.085 89.42 206.225 89.59 206.325C89.6 206.325 89.6 206.325 89.61 206.335C89.62 206.335 89.62 206.345 89.63 206.345L139.87 234.775V285.065L43.67 229.705V60.135ZM244.75 229.705L148.58 285.075V234.775L219.8 194.115L244.75 179.875V229.705ZM297.2 139.625L253.49 164.795V114.995L278.85 100.395L297.21 89.825V139.625H297.2Z"/>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 3 KiB |
|
|
@ -1,7 +1,7 @@
|
||||||
@props(['status'])
|
@props(['status'])
|
||||||
|
|
||||||
@if ($status)
|
@if ($status)
|
||||||
<div {{ $attributes->merge(['class' => 'font-medium text-sm text-green-600']) }}>
|
<div {{ $attributes->merge(['class' => 'font-medium text-sm text-green-600 dark:text-green-400']) }}>
|
||||||
{{ $status }}
|
{{ $status }}
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
<a {{ $attributes->merge(['class' => 'block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-hidden focus:bg-gray-100 transition duration-150 ease-in-out']) }}>{{ $slot }}</a>
|
|
||||||
|
|
@ -1,35 +0,0 @@
|
||||||
@props(['align' => 'right', 'width' => '48', 'contentClasses' => 'py-1 bg-white'])
|
|
||||||
|
|
||||||
@php
|
|
||||||
$alignmentClasses = match ($align) {
|
|
||||||
'left' => 'ltr:origin-top-left rtl:origin-top-right start-0',
|
|
||||||
'top' => 'origin-top',
|
|
||||||
default => 'ltr:origin-top-right rtl:origin-top-left end-0',
|
|
||||||
};
|
|
||||||
|
|
||||||
$width = match ($width) {
|
|
||||||
'48' => 'w-48',
|
|
||||||
default => $width,
|
|
||||||
};
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<div class="relative" x-data="{ open: false }" @click.outside="open = false" @close.stop="open = false">
|
|
||||||
<div @click="open = ! open">
|
|
||||||
{{ $trigger }}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div x-show="open"
|
|
||||||
x-transition:enter="transition ease-out duration-200"
|
|
||||||
x-transition:enter-start="opacity-0 scale-95"
|
|
||||||
x-transition:enter-end="opacity-100 scale-100"
|
|
||||||
x-transition:leave="transition ease-in duration-75"
|
|
||||||
x-transition:leave-start="opacity-100 scale-100"
|
|
||||||
x-transition:leave-end="opacity-0 scale-95"
|
|
||||||
class="absolute z-50 mt-2 {{ $width }} rounded-md shadow-lg {{ $alignmentClasses }}"
|
|
||||||
style="display: none;"
|
|
||||||
@click="open = false">
|
|
||||||
<div class="rounded-md ring-1 ring-black/5 {{ $contentClasses }}">
|
|
||||||
{{ $content }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -18,10 +18,10 @@
|
||||||
<div class="flex min-h-full items-center justify-center p-4">
|
<div class="flex min-h-full items-center justify-center p-4">
|
||||||
<div class="fixed inset-0 bg-gray-900/50 backdrop-blur-xs transition-opacity" wire:click="{{ $close }}"></div>
|
<div class="fixed inset-0 bg-gray-900/50 backdrop-blur-xs transition-opacity" wire:click="{{ $close }}"></div>
|
||||||
|
|
||||||
<div class="relative z-10 w-full {{ $maxWidthClass }} max-h-[90vh] overflow-y-auto rounded-lg bg-white p-6 text-left shadow-xl">
|
<div class="relative z-10 w-full {{ $maxWidthClass }} max-h-[90vh] overflow-y-auto rounded-lg bg-white dark:bg-gray-800 p-6 text-left shadow-xl">
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h3 id="modal-title" class="text-lg font-medium text-gray-900">{{ $title }}</h3>
|
<h3 id="modal-title" class="text-lg font-medium text-gray-900 dark:text-gray-100">{{ $title }}</h3>
|
||||||
<button type="button" wire:click="{{ $close }}" class="text-gray-400 hover:text-gray-600">
|
<button type="button" wire:click="{{ $close }}" class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300">
|
||||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
@props(['messages'])
|
@props(['messages'])
|
||||||
|
|
||||||
@if ($messages)
|
@if ($messages)
|
||||||
<ul {{ $attributes->merge(['class' => 'text-sm text-red-600 space-y-1']) }}>
|
<ul {{ $attributes->merge(['class' => 'text-sm text-red-600 dark:text-red-400 space-y-1']) }}>
|
||||||
@foreach ((array) $messages as $message)
|
@foreach ((array) $messages as $message)
|
||||||
<li>{{ $message }}</li>
|
<li>{{ $message }}</li>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
@props(['value'])
|
@props(['value'])
|
||||||
|
|
||||||
<label {{ $attributes->merge(['class' => 'block font-medium text-sm text-gray-700']) }}>
|
<label {{ $attributes->merge(['class' => 'block font-medium text-sm text-gray-700 dark:text-gray-200']) }}>
|
||||||
{{ $value ?? $slot }}
|
{{ $value ?? $slot }}
|
||||||
</label>
|
</label>
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ class="fixed inset-0 transform transition-all"
|
||||||
|
|
||||||
<div
|
<div
|
||||||
x-show="show"
|
x-show="show"
|
||||||
class="mb-6 bg-white rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full {{ $maxWidth }} sm:mx-auto"
|
class="mb-6 bg-white dark:bg-gray-800 rounded-lg overflow-hidden shadow-xl transform transition-all sm:w-full {{ $maxWidth }} sm:mx-auto"
|
||||||
x-transition:enter="ease-out duration-300"
|
x-transition:enter="ease-out duration-300"
|
||||||
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
|
||||||
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
@props(['active'])
|
|
||||||
|
|
||||||
@php
|
|
||||||
$classes = ($active ?? false)
|
|
||||||
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-medium leading-5 text-gray-900 focus:outline-hidden focus:border-indigo-700 transition duration-150 ease-in-out'
|
|
||||||
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-hidden focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out';
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<a {{ $attributes->merge(['class' => $classes]) }}>
|
|
||||||
{{ $slot }}
|
|
||||||
</a>
|
|
||||||
|
|
@ -2,9 +2,9 @@
|
||||||
|
|
||||||
<div class="mb-8 flex items-start justify-between">
|
<div class="mb-8 flex items-start justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h1 class="text-2xl font-bold text-gray-900">{{ $title }}</h1>
|
<h1 class="text-2xl font-bold text-gray-900 dark:text-gray-100">{{ $title }}</h1>
|
||||||
@if ($subtitle)
|
@if ($subtitle)
|
||||||
<p class="mt-1 text-sm text-gray-500">{{ $subtitle }}</p>
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">{{ $subtitle }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-3">
|
<div class="flex items-center space-x-3">
|
||||||
|
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
@props(['active'])
|
|
||||||
|
|
||||||
@php
|
|
||||||
$classes = ($active ?? false)
|
|
||||||
? 'block w-full ps-3 pe-4 py-2 border-l-4 border-indigo-400 text-start text-base font-medium text-indigo-700 bg-indigo-50 focus:outline-hidden focus:text-indigo-800 focus:bg-indigo-100 focus:border-indigo-700 transition duration-150 ease-in-out'
|
|
||||||
: 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-hidden focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out';
|
|
||||||
@endphp
|
|
||||||
|
|
||||||
<a {{ $attributes->merge(['class' => $classes]) }}>
|
|
||||||
{{ $slot }}
|
|
||||||
</a>
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
@props(['routeArticle', 'tab'])
|
@props(['routeArticle', 'tab'])
|
||||||
|
|
||||||
<div class="bg-white rounded-lg shadow-sm p-5" wire:key="ra-{{ $routeArticle->id }}">
|
<div class="bg-white rounded-lg shadow-sm p-5 dark:bg-gray-800" wire:key="ra-{{ $routeArticle->id }}">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<div
|
<div
|
||||||
|
|
@ -10,17 +10,17 @@ class="flex items-center flex-wrap gap-x-1.5 text-xs font-medium mb-1.5"
|
||||||
@if ($routeArticle->feed)
|
@if ($routeArticle->feed)
|
||||||
<span class="h-2 w-2 rounded-full shrink-0 {{ $routeArticle->feed->displayColor()->dotClass() }}" aria-hidden="true"></span>
|
<span class="h-2 w-2 rounded-full shrink-0 {{ $routeArticle->feed->displayColor()->dotClass() }}" aria-hidden="true"></span>
|
||||||
@endif
|
@endif
|
||||||
<span class="text-gray-900">{{ $routeArticle->feed?->name ?? 'Unknown feed' }}</span>
|
<span class="text-gray-900 dark:text-gray-100">{{ $routeArticle->feed?->name ?? 'Unknown feed' }}</span>
|
||||||
<span class="text-gray-400" aria-hidden="true">→</span>
|
<span class="text-gray-400 dark:text-gray-500" aria-hidden="true">→</span>
|
||||||
<span class="text-gray-600">{{ $routeArticle->platformChannel?->name ?? 'Unknown channel' }}</span>
|
<span class="text-gray-600 dark:text-gray-300">{{ $routeArticle->platformChannel?->name ?? 'Unknown channel' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="text-base font-medium text-gray-900 mb-1">
|
<h3 class="text-base font-medium text-gray-900 mb-1 dark:text-gray-100">
|
||||||
{{ $routeArticle->article->title ?? 'Untitled Article' }}
|
{{ $routeArticle->article->title ?? 'Untitled Article' }}
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm text-gray-600 mb-2 line-clamp-2">
|
<p class="text-sm text-gray-600 mb-2 line-clamp-2 dark:text-gray-300">
|
||||||
{{ $routeArticle->article->description ?? 'No description available' }}
|
{{ $routeArticle->article->description ?? 'No description available' }}
|
||||||
</p>
|
</p>
|
||||||
<div class="text-xs text-gray-500">
|
<div class="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{{ $routeArticle->created_at->format('M d, Y H:i') }}
|
{{ $routeArticle->created_at->format('M d, Y H:i') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -28,15 +28,15 @@ class="flex items-center flex-wrap gap-x-1.5 text-xs font-medium mb-1.5"
|
||||||
{{-- Status badge (All tab) --}}
|
{{-- Status badge (All tab) --}}
|
||||||
@if ($tab === 'all')
|
@if ($tab === 'all')
|
||||||
@if ($routeArticle->isApproved())
|
@if ($routeArticle->isApproved())
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300">
|
||||||
Approved
|
Approved
|
||||||
</span>
|
</span>
|
||||||
@elseif ($routeArticle->isRejected())
|
@elseif ($routeArticle->isRejected())
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300">
|
||||||
Rejected
|
Rejected
|
||||||
</span>
|
</span>
|
||||||
@else
|
@else
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300">
|
||||||
Pending
|
Pending
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -46,7 +46,7 @@ class="flex items-center flex-wrap gap-x-1.5 text-xs font-medium mb-1.5"
|
||||||
@if ($routeArticle->isPending())
|
@if ($routeArticle->isPending())
|
||||||
<button
|
<button
|
||||||
wire:click="approve({{ $routeArticle->id }})"
|
wire:click="approve({{ $routeArticle->id }})"
|
||||||
class="inline-flex items-center p-1.5 text-green-600 hover:text-green-800 hover:bg-green-50 rounded-md"
|
class="inline-flex items-center p-1.5 text-green-600 hover:text-green-800 hover:bg-green-50 rounded-md dark:text-green-400"
|
||||||
title="Approve"
|
title="Approve"
|
||||||
>
|
>
|
||||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -55,7 +55,7 @@ class="inline-flex items-center p-1.5 text-green-600 hover:text-green-800 hover:
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
wire:click="reject({{ $routeArticle->id }})"
|
wire:click="reject({{ $routeArticle->id }})"
|
||||||
class="inline-flex items-center p-1.5 text-red-600 hover:text-red-800 hover:bg-red-50 rounded-md"
|
class="inline-flex items-center p-1.5 text-red-600 hover:text-red-800 hover:bg-red-50 rounded-md dark:text-red-400"
|
||||||
title="Reject"
|
title="Reject"
|
||||||
>
|
>
|
||||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -65,7 +65,7 @@ class="inline-flex items-center p-1.5 text-red-600 hover:text-red-800 hover:bg-r
|
||||||
@elseif ($routeArticle->isRejected())
|
@elseif ($routeArticle->isRejected())
|
||||||
<button
|
<button
|
||||||
wire:click="restore({{ $routeArticle->id }})"
|
wire:click="restore({{ $routeArticle->id }})"
|
||||||
class="inline-flex items-center p-1.5 text-blue-600 hover:text-blue-800 hover:bg-blue-50 rounded-md"
|
class="inline-flex items-center p-1.5 text-blue-600 hover:text-blue-800 hover:bg-blue-50 rounded-md dark:text-blue-400"
|
||||||
title="Restore to pending"
|
title="Restore to pending"
|
||||||
>
|
>
|
||||||
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -80,7 +80,7 @@ class="inline-flex items-center p-1.5 text-blue-600 hover:text-blue-800 hover:bg
|
||||||
href="{{ $routeArticle->article->url }}"
|
href="{{ $routeArticle->article->url }}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="p-1.5 text-gray-400 hover:text-gray-600 rounded-md"
|
class="p-1.5 text-gray-400 hover:text-gray-600 rounded-md dark:text-gray-500 dark:hover:text-gray-300"
|
||||||
title="View original article"
|
title="View original article"
|
||||||
>
|
>
|
||||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
<button {{ $attributes->merge(['type' => 'button', 'class' => 'inline-flex items-center px-4 py-2 bg-white border border-gray-300 rounded-md font-semibold text-xs text-gray-700 uppercase tracking-widest shadow-xs hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-25 transition ease-in-out duration-150']) }}>
|
<button {{ $attributes->merge(['type' => 'button', 'class' => 'inline-flex items-center px-4 py-2 bg-white dark:bg-gray-700 border border-gray-300 dark:border-gray-600 rounded-md font-semibold text-xs text-gray-700 dark:text-gray-200 uppercase tracking-widest shadow-xs hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-25 transition ease-in-out duration-150']) }}>
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,3 @@
|
||||||
@props(['disabled' => false])
|
@props(['disabled' => false])
|
||||||
|
|
||||||
<input @disabled($disabled) {{ $attributes->merge(['class' => 'border-gray-300 focus:border-blue-500 focus:ring-blue-500 rounded-lg shadow-xs px-4 py-3']) }}>
|
<input @disabled($disabled) {{ $attributes->merge(['class' => 'border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-gray-100 focus:border-blue-500 focus:ring-blue-500 rounded-lg shadow-xs px-4 py-3']) }}>
|
||||||
|
|
|
||||||
25
resources/views/components/theme-toggle.blade.php
Normal file
25
resources/views/components/theme-toggle.blade.php
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
@props(['class' => ''])
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
x-data="{
|
||||||
|
dark: document.documentElement.classList.contains('dark'),
|
||||||
|
toggle() {
|
||||||
|
this.dark = !this.dark;
|
||||||
|
document.documentElement.classList.toggle('dark', this.dark);
|
||||||
|
localStorage.theme = this.dark ? 'dark' : 'light';
|
||||||
|
},
|
||||||
|
}"
|
||||||
|
@click="toggle()"
|
||||||
|
:aria-pressed="dark"
|
||||||
|
:title="dark ? 'Switch to light theme' : 'Switch to dark theme'"
|
||||||
|
:aria-label="dark ? 'Switch to light theme' : 'Switch to dark theme'"
|
||||||
|
{{ $attributes->merge(['class' => 'p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100 dark:text-gray-500 dark:hover:text-gray-300 dark:hover:bg-gray-700 focus:outline-hidden focus:ring-2 focus:ring-inset focus:ring-blue-500 '.$class]) }}
|
||||||
|
>
|
||||||
|
<svg x-show="!dark" x-cloak class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M21.752 15.002A9.718 9.718 0 0 1 18 15.75c-5.385 0-9.75-4.365-9.75-9.75 0-1.33.266-2.597.748-3.752A9.753 9.753 0 0 0 3 11.25C3 16.635 7.365 21 12.75 21a9.753 9.753 0 0 0 9.002-5.998Z" />
|
||||||
|
</svg>
|
||||||
|
<svg x-show="dark" x-cloak class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z" />
|
||||||
|
</svg>
|
||||||
|
</button>
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
<x-app-layout>
|
<x-app-layout>
|
||||||
<x-slot name="header">
|
<x-slot name="header">
|
||||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
<h2 class="font-semibold text-xl text-gray-800 leading-tight dark:text-gray-100">
|
||||||
{{ __('Dashboard') }}
|
{{ __('Dashboard') }}
|
||||||
</h2>
|
</h2>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|
||||||
<div class="py-12">
|
<div class="py-12">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||||
<div class="bg-white overflow-hidden shadow-xs sm:rounded-lg">
|
<div class="bg-white overflow-hidden shadow-xs sm:rounded-lg dark:bg-gray-800">
|
||||||
<div class="p-6 text-gray-900">
|
<div class="p-6 text-gray-900 dark:text-gray-100">
|
||||||
{{ __("You're logged in!") }}
|
{{ __("You're logged in!") }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
<title>{{ config('app.name') }}</title>
|
<title>{{ config('app.name') }}</title>
|
||||||
|
|
||||||
|
@include('layouts.theme-script')
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||||
|
|
@ -16,7 +18,7 @@
|
||||||
@livewireStyles
|
@livewireStyles
|
||||||
</head>
|
</head>
|
||||||
<body class="font-sans antialiased">
|
<body class="font-sans antialiased">
|
||||||
<div class="min-h-screen bg-gray-50" x-data="{ sidebarOpen: false }">
|
<div class="min-h-screen bg-gray-50 dark:bg-gray-900" x-data="{ sidebarOpen: false }">
|
||||||
<!-- Mobile overlay -->
|
<!-- Mobile overlay -->
|
||||||
<div
|
<div
|
||||||
x-show="sidebarOpen"
|
x-show="sidebarOpen"
|
||||||
|
|
@ -39,13 +41,13 @@ class="fixed inset-0 z-40 bg-gray-600/75 lg:hidden"
|
||||||
x-transition:leave="transition ease-in-out duration-300 transform"
|
x-transition:leave="transition ease-in-out duration-300 transform"
|
||||||
x-transition:leave-start="translate-x-0"
|
x-transition:leave-start="translate-x-0"
|
||||||
x-transition:leave-end="-translate-x-full"
|
x-transition:leave-end="-translate-x-full"
|
||||||
class="fixed inset-y-0 left-0 z-50 w-64 bg-white shadow-lg lg:hidden"
|
class="fixed inset-y-0 left-0 z-50 w-64 bg-white dark:bg-gray-800 shadow-lg lg:hidden"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between h-16 px-4 border-b border-gray-200">
|
<div class="flex items-center justify-between h-16 px-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h1 class="text-xl font-bold text-gray-900">FFR</h1>
|
<h1 class="text-xl font-bold text-gray-900 dark:text-gray-100">FFR</h1>
|
||||||
<button
|
<button
|
||||||
@click="sidebarOpen = false"
|
@click="sidebarOpen = false"
|
||||||
class="p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100"
|
class="p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100 dark:text-gray-500 dark:hover:text-gray-300 dark:hover:bg-gray-700"
|
||||||
>
|
>
|
||||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" />
|
||||||
|
|
@ -59,26 +61,27 @@ class="p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100"
|
||||||
|
|
||||||
<!-- Desktop sidebar -->
|
<!-- Desktop sidebar -->
|
||||||
<div class="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col">
|
<div class="hidden lg:fixed lg:inset-y-0 lg:flex lg:w-64 lg:flex-col">
|
||||||
<div class="flex flex-col flex-grow bg-white pt-5 pb-4 overflow-y-auto border-r border-gray-200">
|
<div class="flex flex-col flex-grow bg-white dark:bg-gray-800 pt-5 pb-4 overflow-y-auto border-r border-gray-200 dark:border-gray-700">
|
||||||
<div class="flex items-center shrink-0 px-4">
|
<div class="flex items-center shrink-0 px-4">
|
||||||
<h1 class="text-xl font-bold text-gray-900">FFR</h1>
|
<h1 class="text-xl font-bold text-gray-900 dark:text-gray-100">FFR</h1>
|
||||||
</div>
|
</div>
|
||||||
<nav class="mt-5 flex-1 px-2 bg-white">
|
<nav class="mt-5 flex-1 px-2 bg-white dark:bg-gray-800">
|
||||||
@include('layouts.navigation-items')
|
@include('layouts.navigation-items')
|
||||||
</nav>
|
</nav>
|
||||||
<div class="shrink-0 p-4 border-t border-gray-200">
|
<div class="shrink-0 p-4 border-t border-gray-200 dark:border-gray-700">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<p class="text-sm font-medium text-gray-900 truncate">
|
<p class="text-sm font-medium text-gray-900 dark:text-gray-100 truncate">
|
||||||
{{ Auth::user()->name }}
|
{{ Auth::user()->name }}
|
||||||
</p>
|
</p>
|
||||||
<form method="POST" action="{{ route('logout') }}" class="inline">
|
<form method="POST" action="{{ route('logout') }}" class="inline">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit" class="text-sm text-gray-500 hover:text-gray-700 truncate">
|
<button type="submit" class="text-sm text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-200 truncate">
|
||||||
Logout
|
Logout
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<x-theme-toggle class="shrink-0 ml-2" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -87,18 +90,21 @@ class="p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100"
|
||||||
<!-- Main content -->
|
<!-- Main content -->
|
||||||
<div class="lg:pl-64 flex flex-col flex-1">
|
<div class="lg:pl-64 flex flex-col flex-1">
|
||||||
<!-- Mobile header -->
|
<!-- Mobile header -->
|
||||||
<div class="sticky top-0 z-10 shrink-0 flex h-16 bg-white shadow-sm lg:hidden">
|
<div class="sticky top-0 z-10 shrink-0 flex h-16 bg-white dark:bg-gray-800 shadow-sm lg:hidden">
|
||||||
<button
|
<button
|
||||||
@click="sidebarOpen = true"
|
@click="sidebarOpen = true"
|
||||||
class="px-4 border-r border-gray-200 text-gray-500 focus:outline-hidden focus:ring-2 focus:ring-inset focus:ring-blue-500"
|
class="px-4 border-r border-gray-200 dark:border-gray-700 text-gray-500 dark:text-gray-400 focus:outline-hidden focus:ring-2 focus:ring-inset focus:ring-blue-500"
|
||||||
>
|
>
|
||||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div class="flex-1 px-4 flex justify-between items-center">
|
<div class="flex-1 px-4 flex justify-between items-center">
|
||||||
<h1 class="text-lg font-medium text-gray-900">FFR</h1>
|
<h1 class="text-lg font-medium text-gray-900 dark:text-gray-100">FFR</h1>
|
||||||
<livewire:notification-bell />
|
<div class="flex items-center gap-1">
|
||||||
|
<x-theme-toggle />
|
||||||
|
<livewire:notification-bell />
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
<title>{{ config('app.name') }}</title>
|
<title>{{ config('app.name') }}</title>
|
||||||
|
|
||||||
|
@include('layouts.theme-script')
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600,700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600,700&display=swap" rel="stylesheet" />
|
||||||
|
|
@ -15,7 +17,7 @@
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
@livewireStyles
|
@livewireStyles
|
||||||
</head>
|
</head>
|
||||||
<body class="font-sans text-gray-900 antialiased">
|
<body class="font-sans text-gray-900 dark:text-gray-100 antialiased">
|
||||||
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gradient-to-br from-blue-600 via-blue-700 to-indigo-800">
|
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gradient-to-br from-blue-600 via-blue-700 to-indigo-800">
|
||||||
<!-- Logo/Brand -->
|
<!-- Logo/Brand -->
|
||||||
<div class="mb-6">
|
<div class="mb-6">
|
||||||
|
|
@ -31,7 +33,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Card -->
|
<!-- Card -->
|
||||||
<div class="w-full sm:max-w-md px-6 py-8 bg-white shadow-xl rounded-2xl mx-4">
|
<div class="w-full sm:max-w-md px-6 py-8 bg-white dark:bg-gray-800 shadow-xl rounded-2xl mx-4">
|
||||||
{{ $slot }}
|
{{ $slot }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<a
|
<a
|
||||||
href="{{ route($item['route']) }}"
|
href="{{ route($item['route']) }}"
|
||||||
@click="sidebarOpen = false"
|
@click="sidebarOpen = false"
|
||||||
class="group flex items-center px-2 py-2 text-sm font-medium rounded-md mb-1 {{ request()->routeIs($item['route']) ? 'bg-blue-100 text-blue-700' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900' }}"
|
class="group flex items-center px-2 py-2 text-sm font-medium rounded-md mb-1 {{ request()->routeIs($item['route']) ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300' : 'text-gray-600 hover:bg-gray-50 hover:text-gray-900 dark:text-gray-400 dark:hover:bg-gray-700/50 dark:hover:text-gray-100' }}"
|
||||||
>
|
>
|
||||||
@switch($item['icon'])
|
@switch($item['icon'])
|
||||||
@case('home')
|
@case('home')
|
||||||
|
|
|
||||||
|
|
@ -1,100 +0,0 @@
|
||||||
<nav x-data="{ open: false }" class="bg-white border-b border-gray-100">
|
|
||||||
<!-- Primary Navigation Menu -->
|
|
||||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
|
||||||
<div class="flex justify-between h-16">
|
|
||||||
<div class="flex">
|
|
||||||
<!-- Logo -->
|
|
||||||
<div class="shrink-0 flex items-center">
|
|
||||||
<a href="{{ route('dashboard') }}">
|
|
||||||
<x-application-logo class="block h-9 w-auto fill-current text-gray-800" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Navigation Links -->
|
|
||||||
<div class="hidden space-x-8 sm:-my-px sm:ms-10 sm:flex">
|
|
||||||
<x-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
|
|
||||||
{{ __('Dashboard') }}
|
|
||||||
</x-nav-link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Settings Dropdown -->
|
|
||||||
<div class="hidden sm:flex sm:items-center sm:ms-6">
|
|
||||||
<x-dropdown align="right" width="48">
|
|
||||||
<x-slot name="trigger">
|
|
||||||
<button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-hidden transition ease-in-out duration-150">
|
|
||||||
<div>{{ Auth::user()->name }}</div>
|
|
||||||
|
|
||||||
<div class="ms-1">
|
|
||||||
<svg class="fill-current h-4 w-4" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
|
|
||||||
<path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
</x-slot>
|
|
||||||
|
|
||||||
<x-slot name="content">
|
|
||||||
<x-dropdown-link :href="route('profile.edit')">
|
|
||||||
{{ __('Profile') }}
|
|
||||||
</x-dropdown-link>
|
|
||||||
|
|
||||||
<!-- Authentication -->
|
|
||||||
<form method="POST" action="{{ route('logout') }}">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<x-dropdown-link :href="route('logout')"
|
|
||||||
onclick="event.preventDefault();
|
|
||||||
this.closest('form').submit();">
|
|
||||||
{{ __('Log Out') }}
|
|
||||||
</x-dropdown-link>
|
|
||||||
</form>
|
|
||||||
</x-slot>
|
|
||||||
</x-dropdown>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Hamburger -->
|
|
||||||
<div class="-me-2 flex items-center sm:hidden">
|
|
||||||
<button @click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-hidden focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out">
|
|
||||||
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
|
||||||
<path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
|
||||||
<path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
|
||||||
</svg>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Responsive Navigation Menu -->
|
|
||||||
<div :class="{'block': open, 'hidden': ! open}" class="hidden sm:hidden">
|
|
||||||
<div class="pt-2 pb-3 space-y-1">
|
|
||||||
<x-responsive-nav-link :href="route('dashboard')" :active="request()->routeIs('dashboard')">
|
|
||||||
{{ __('Dashboard') }}
|
|
||||||
</x-responsive-nav-link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Responsive Settings Options -->
|
|
||||||
<div class="pt-4 pb-1 border-t border-gray-200">
|
|
||||||
<div class="px-4">
|
|
||||||
<div class="font-medium text-base text-gray-800">{{ Auth::user()->name }}</div>
|
|
||||||
<div class="font-medium text-sm text-gray-500">{{ Auth::user()->email }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mt-3 space-y-1">
|
|
||||||
<x-responsive-nav-link :href="route('profile.edit')">
|
|
||||||
{{ __('Profile') }}
|
|
||||||
</x-responsive-nav-link>
|
|
||||||
|
|
||||||
<!-- Authentication -->
|
|
||||||
<form method="POST" action="{{ route('logout') }}">
|
|
||||||
@csrf
|
|
||||||
|
|
||||||
<x-responsive-nav-link :href="route('logout')"
|
|
||||||
onclick="event.preventDefault();
|
|
||||||
this.closest('form').submit();">
|
|
||||||
{{ __('Log Out') }}
|
|
||||||
</x-responsive-nav-link>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</nav>
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
|
|
||||||
<title>{{ config('app.name') }} - Setup</title>
|
<title>{{ config('app.name') }} - Setup</title>
|
||||||
|
|
||||||
|
@include('layouts.theme-script')
|
||||||
|
|
||||||
<!-- Fonts -->
|
<!-- Fonts -->
|
||||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600,700&display=swap" rel="stylesheet" />
|
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600,700&display=swap" rel="stylesheet" />
|
||||||
|
|
@ -15,7 +17,7 @@
|
||||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||||
@livewireStyles
|
@livewireStyles
|
||||||
</head>
|
</head>
|
||||||
<body class="font-sans text-gray-900 antialiased">
|
<body class="font-sans text-gray-900 dark:text-gray-100 antialiased">
|
||||||
<div class="min-h-screen flex flex-col items-center pt-6 sm:pt-12 bg-gradient-to-br from-blue-600 via-blue-700 to-indigo-800 relative">
|
<div class="min-h-screen flex flex-col items-center pt-6 sm:pt-12 bg-gradient-to-br from-blue-600 via-blue-700 to-indigo-800 relative">
|
||||||
<!-- User Menu -->
|
<!-- User Menu -->
|
||||||
@auth
|
@auth
|
||||||
|
|
@ -27,10 +29,10 @@
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
<div x-show="open" @click.away="open = false" x-transition class="absolute right-0 mt-2 w-48 bg-white rounded-lg shadow-lg py-1 z-50">
|
<div x-show="open" @click.away="open = false" x-transition class="absolute right-0 mt-2 w-48 bg-white dark:bg-gray-800 rounded-lg shadow-lg py-1 z-50">
|
||||||
<form method="POST" action="{{ route('logout') }}">
|
<form method="POST" action="{{ route('logout') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<button type="submit" class="block w-full text-left px-4 py-2 text-sm text-gray-700 hover:bg-gray-100">
|
<button type="submit" class="block w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-gray-700">
|
||||||
Log out
|
Log out
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
7
resources/views/layouts/theme-script.blade.php
Normal file
7
resources/views/layouts/theme-script.blade.php
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
<script>
|
||||||
|
document.documentElement.classList.toggle(
|
||||||
|
'dark',
|
||||||
|
localStorage.theme === 'dark'
|
||||||
|
|| (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches),
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
@ -16,22 +16,22 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
|
||||||
</x-page-header>
|
</x-page-header>
|
||||||
|
|
||||||
{{-- Tab bar --}}
|
{{-- Tab bar --}}
|
||||||
<div class="mb-6 border-b border-gray-200">
|
<div class="mb-6 border-b border-gray-200 dark:border-gray-700">
|
||||||
<nav class="-mb-px flex space-x-8">
|
<nav class="-mb-px flex space-x-8">
|
||||||
<button
|
<button
|
||||||
wire:click="setTab('pending')"
|
wire:click="setTab('pending')"
|
||||||
class="whitespace-nowrap pb-3 px-1 border-b-2 font-medium text-sm {{ $tab === 'pending' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}"
|
class="whitespace-nowrap pb-3 px-1 border-b-2 font-medium text-sm {{ $tab === 'pending' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-200 dark:hover:border-gray-600' }}"
|
||||||
>
|
>
|
||||||
Pending
|
Pending
|
||||||
@if ($pendingCount > 0)
|
@if ($pendingCount > 0)
|
||||||
<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
|
<span class="ml-2 inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300">
|
||||||
{{ $pendingCount }}
|
{{ $pendingCount }}
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
wire:click="setTab('all')"
|
wire:click="setTab('all')"
|
||||||
class="whitespace-nowrap pb-3 px-1 border-b-2 font-medium text-sm {{ $tab === 'all' ? 'border-blue-500 text-blue-600' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300' }}"
|
class="whitespace-nowrap pb-3 px-1 border-b-2 font-medium text-sm {{ $tab === 'all' ? 'border-blue-500 text-blue-600 dark:text-blue-400' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-200 dark:hover:border-gray-600' }}"
|
||||||
>
|
>
|
||||||
All
|
All
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -44,7 +44,7 @@ class="whitespace-nowrap pb-3 px-1 border-b-2 font-medium text-sm {{ $tab === 'a
|
||||||
<select
|
<select
|
||||||
wire:model.live="feedId"
|
wire:model.live="feedId"
|
||||||
aria-label="Filter by feed"
|
aria-label="Filter by feed"
|
||||||
class="w-56 shrink-0 pl-3 pr-10 py-2 border border-gray-300 rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-56 shrink-0 pl-3 pr-10 py-2 border border-gray-300 rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<option value="">All feeds</option>
|
<option value="">All feeds</option>
|
||||||
@foreach ($feedOptions as $feedOption)
|
@foreach ($feedOptions as $feedOption)
|
||||||
|
|
@ -57,7 +57,7 @@ class="w-56 shrink-0 pl-3 pr-10 py-2 border border-gray-300 rounded-md text-sm f
|
||||||
type="text"
|
type="text"
|
||||||
wire:model.live.debounce.300ms="search"
|
wire:model.live.debounce.300ms="search"
|
||||||
placeholder="Search articles..."
|
placeholder="Search articles..."
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -81,30 +81,30 @@ class="inline-flex items-center px-3 py-2 border border-transparent text-sm lead
|
||||||
@if ($pendingFeeds !== null && $pendingFeeds->isNotEmpty())
|
@if ($pendingFeeds !== null && $pendingFeeds->isNotEmpty())
|
||||||
@foreach ($pendingFeeds as $group)
|
@foreach ($pendingFeeds as $group)
|
||||||
@php($isExpanded = $group->isExpanded())
|
@php($isExpanded = $group->isExpanded())
|
||||||
<div class="bg-white rounded-lg shadow-sm overflow-hidden" wire:key="feed-group-{{ $group->feed->id }}">
|
<div class="bg-white rounded-lg shadow-sm overflow-hidden dark:bg-gray-800" wire:key="feed-group-{{ $group->feed->id }}">
|
||||||
<button
|
<button
|
||||||
wire:click="toggleFeed({{ $group->feed->id }})"
|
wire:click="toggleFeed({{ $group->feed->id }})"
|
||||||
type="button"
|
type="button"
|
||||||
class="w-full flex items-center gap-x-3 px-5 py-4 text-left hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-inset focus:ring-blue-500"
|
class="w-full flex items-center gap-x-3 px-5 py-4 text-left hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-inset focus:ring-blue-500 dark:hover:bg-gray-700/50"
|
||||||
id="feed-toggle-{{ $group->feed->id }}"
|
id="feed-toggle-{{ $group->feed->id }}"
|
||||||
aria-expanded="{{ $isExpanded ? 'true' : 'false' }}"
|
aria-expanded="{{ $isExpanded ? 'true' : 'false' }}"
|
||||||
aria-controls="feed-panel-{{ $group->feed->id }}"
|
aria-controls="feed-panel-{{ $group->feed->id }}"
|
||||||
>
|
>
|
||||||
<svg
|
<svg
|
||||||
class="h-4 w-4 shrink-0 text-gray-400 transition-transform {{ $isExpanded ? 'rotate-90' : '' }}"
|
class="h-4 w-4 shrink-0 text-gray-400 dark:text-gray-500 transition-transform {{ $isExpanded ? 'rotate-90' : '' }}"
|
||||||
fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"
|
fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"
|
||||||
>
|
>
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="h-2.5 w-2.5 rounded-full shrink-0 {{ $group->feed->displayColor()->dotClass() }}" aria-hidden="true"></span>
|
<span class="h-2.5 w-2.5 rounded-full shrink-0 {{ $group->feed->displayColor()->dotClass() }}" aria-hidden="true"></span>
|
||||||
<span class="text-sm font-semibold text-gray-900">{{ $group->feed->name }}</span>
|
<span class="text-sm font-semibold text-gray-900 dark:text-gray-100">{{ $group->feed->name }}</span>
|
||||||
<span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800">
|
<span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300">
|
||||||
{{ $group->count }}
|
{{ $group->count }}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
@if ($isExpanded)
|
@if ($isExpanded)
|
||||||
<div
|
<div
|
||||||
class="border-t border-gray-100 bg-gray-50 p-4 space-y-4"
|
class="border-t border-gray-100 bg-gray-50 p-4 space-y-4 dark:border-gray-700 dark:bg-gray-900"
|
||||||
id="feed-panel-{{ $group->feed->id }}"
|
id="feed-panel-{{ $group->feed->id }}"
|
||||||
role="region"
|
role="region"
|
||||||
aria-labelledby="feed-toggle-{{ $group->feed->id }}"
|
aria-labelledby="feed-toggle-{{ $group->feed->id }}"
|
||||||
|
|
@ -122,17 +122,17 @@ class="border-t border-gray-100 bg-gray-50 p-4 space-y-4"
|
||||||
@endforeach
|
@endforeach
|
||||||
@else
|
@else
|
||||||
<div class="text-center py-12">
|
<div class="text-center py-12">
|
||||||
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M19.5 14.25v-2.625a3.375 3.375 0 0 0-3.375-3.375h-1.5A1.125 1.125 0 0 1 13.5 7.125v-1.5a3.375 3.375 0 0 0-3.375-3.375H8.25m0 12.75h7.5m-7.5 3H12M10.5 2.25H5.625c-.621 0-1.125.504-1.125 1.125v17.25c0 .621.504 1.125 1.125 1.125h12.75c.621 0 1.125-.504 1.125-1.125V11.25a9 9 0 0 0-9-9Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<h3 class="mt-2 text-sm font-medium text-gray-900">
|
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
@if ($tab === 'pending')
|
@if ($tab === 'pending')
|
||||||
No pending articles
|
No pending articles
|
||||||
@else
|
@else
|
||||||
No articles found
|
No articles found
|
||||||
@endif
|
@endif
|
||||||
</h3>
|
</h3>
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
@if ($tab === 'pending' && $feedId !== null)
|
@if ($tab === 'pending' && $feedId !== null)
|
||||||
No pending articles for the selected feed.
|
No pending articles for the selected feed.
|
||||||
@elseif ($tab === 'pending')
|
@elseif ($tab === 'pending')
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
@forelse ($channels as $channel)
|
@forelse ($channels as $channel)
|
||||||
<div class="bg-white rounded-lg shadow-sm p-6" wire:key="channel-{{ $channel->id }}">
|
<div class="bg-white rounded-lg shadow-sm p-6 dark:bg-gray-800" wire:key="channel-{{ $channel->id }}">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
|
|
@ -22,7 +22,7 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex-1 min-w-0">
|
<div class="ml-4 flex-1 min-w-0">
|
||||||
<h3 class="text-lg font-medium text-gray-900 truncate">
|
<h3 class="text-lg font-medium text-gray-900 truncate dark:text-gray-100">
|
||||||
{{ $channel->display_name ?? $channel->name }}
|
{{ $channel->display_name ?? $channel->name }}
|
||||||
</h3>
|
</h3>
|
||||||
@if ($channel->platformInstance)
|
@if ($channel->platformInstance)
|
||||||
|
|
@ -37,7 +37,7 @@ class="text-sm text-blue-500 hover:underline">
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
wire:click="toggle({{ $channel->id }})"
|
wire:click="toggle({{ $channel->id }})"
|
||||||
class="p-1 rounded-full {{ $channel->is_active ? 'bg-green-100 text-green-600' : 'bg-gray-100 text-gray-400' }}"
|
class="p-1 rounded-full {{ $channel->is_active ? 'bg-green-100 text-green-600 dark:bg-green-900/30 dark:text-green-400' : 'bg-gray-100 text-gray-400 dark:bg-gray-700 dark:text-gray-500' }}"
|
||||||
title="{{ $channel->is_active ? 'Active - Click to disable' : 'Inactive - Click to enable' }}"
|
title="{{ $channel->is_active ? 'Active - Click to disable' : 'Inactive - Click to enable' }}"
|
||||||
>
|
>
|
||||||
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
|
@ -47,19 +47,19 @@ class="p-1 rounded-full {{ $channel->is_active ? 'bg-green-100 text-green-600' :
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($channel->description)
|
@if ($channel->description)
|
||||||
<p class="mt-3 text-sm text-gray-500 line-clamp-2">
|
<p class="mt-3 text-sm text-gray-500 line-clamp-2 dark:text-gray-400">
|
||||||
{{ $channel->description }}
|
{{ $channel->description }}
|
||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between mb-2">
|
||||||
<span class="text-sm font-medium text-gray-700">
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
Linked Accounts ({{ $channel->platformAccounts->count() }})
|
Linked Accounts ({{ $channel->platformAccounts->count() }})
|
||||||
</span>
|
</span>
|
||||||
<button
|
<button
|
||||||
wire:click="openAccountModal({{ $channel->id }})"
|
wire:click="openAccountModal({{ $channel->id }})"
|
||||||
class="text-sm text-blue-600 hover:text-blue-800"
|
class="text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
>
|
>
|
||||||
Manage
|
Manage
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -69,7 +69,7 @@ class="text-sm text-blue-600 hover:text-blue-800"
|
||||||
<div class="space-y-1">
|
<div class="space-y-1">
|
||||||
@foreach ($channel->platformAccounts->take(3) as $account)
|
@foreach ($channel->platformAccounts->take(3) as $account)
|
||||||
<div class="flex items-center justify-between text-sm">
|
<div class="flex items-center justify-between text-sm">
|
||||||
<span class="text-gray-600">{{ $account->username }}</span>
|
<span class="text-gray-600 dark:text-gray-300">{{ $account->username }}</span>
|
||||||
<button
|
<button
|
||||||
wire:click="detachAccount({{ $channel->id }}, {{ $account->id }})"
|
wire:click="detachAccount({{ $channel->id }}, {{ $account->id }})"
|
||||||
class="text-red-500 hover:text-red-700"
|
class="text-red-500 hover:text-red-700"
|
||||||
|
|
@ -82,30 +82,30 @@ class="text-red-500 hover:text-red-700"
|
||||||
</div>
|
</div>
|
||||||
@endforeach
|
@endforeach
|
||||||
@if ($channel->platformAccounts->count() > 3)
|
@if ($channel->platformAccounts->count() > 3)
|
||||||
<span class="text-xs text-gray-400">+{{ $channel->platformAccounts->count() - 3 }} more</span>
|
<span class="text-xs text-gray-400 dark:text-gray-500">+{{ $channel->platformAccounts->count() - 3 }} more</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<p class="text-sm text-gray-400">No accounts linked</p>
|
<p class="text-sm text-gray-400 dark:text-gray-500">No accounts linked</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4 flex items-center justify-between">
|
<div class="mt-4 flex items-center justify-between">
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $channel->is_active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800' }}">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $channel->is_active ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300' : 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200' }}">
|
||||||
{{ $channel->is_active ? 'Active' : 'Inactive' }}
|
{{ $channel->is_active ? 'Active' : 'Inactive' }}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-xs text-gray-500">
|
<span class="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{{ $channel->created_at->format('M d, Y') }}
|
{{ $channel->created_at->format('M d, Y') }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<div class="col-span-full text-center py-12">
|
<div class="col-span-full text-center py-12">
|
||||||
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5-3.9 19.5m-2.1-19.5-3.9 19.5" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5.25 8.25h15m-16.5 7.5h15m-1.8-13.5-3.9 19.5m-2.1-19.5-3.9 19.5" />
|
||||||
</svg>
|
</svg>
|
||||||
<h3 class="mt-2 text-sm font-medium text-gray-900">No channels</h3>
|
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">No channels</h3>
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
No platform channels have been configured yet.
|
No platform channels have been configured yet.
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|
@ -128,14 +128,14 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
<x-form-modal :title="'Manage Accounts for ' . ($managingChannel->display_name ?? $managingChannel->name)" close="closeAccountModal">
|
<x-form-modal :title="'Manage Accounts for ' . ($managingChannel->display_name ?? $managingChannel->name)" close="closeAccountModal">
|
||||||
@if ($availableAccounts->isNotEmpty())
|
@if ($availableAccounts->isNotEmpty())
|
||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<h4 class="text-sm font-medium text-gray-700 mb-2">Available Accounts</h4>
|
<h4 class="text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">Available Accounts</h4>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@foreach ($availableAccounts as $account)
|
@foreach ($availableAccounts as $account)
|
||||||
<div class="flex items-center justify-between p-2 border rounded-sm">
|
<div class="flex items-center justify-between p-2 border rounded-sm">
|
||||||
<span class="text-sm text-gray-900">{{ $account->username }}</span>
|
<span class="text-sm text-gray-900 dark:text-gray-100">{{ $account->username }}</span>
|
||||||
<button
|
<button
|
||||||
wire:click="attachAccount({{ $account->id }})"
|
wire:click="attachAccount({{ $account->id }})"
|
||||||
class="text-sm text-blue-600 hover:text-blue-800"
|
class="text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
>
|
>
|
||||||
Add
|
Add
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -144,13 +144,13 @@ class="text-sm text-blue-600 hover:text-blue-800"
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<p class="text-sm text-gray-500 mb-4">No available accounts to link.</p>
|
<p class="text-sm text-gray-500 mb-4 dark:text-gray-400">No available accounts to link.</p>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<button
|
<button
|
||||||
wire:click="closeAccountModal"
|
wire:click="closeAccountModal"
|
||||||
class="w-full inline-flex justify-center rounded-md border border-gray-300 shadow-xs px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
class="w-full inline-flex justify-center rounded-md border border-gray-300 shadow-xs px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700/50"
|
||||||
>
|
>
|
||||||
Close
|
Close
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -163,31 +163,31 @@ class="w-full inline-flex justify-center rounded-md border border-gray-300 shado
|
||||||
<x-form-modal title="Add Channel" close="closeCreateModal">
|
<x-form-modal title="Add Channel" close="closeCreateModal">
|
||||||
<form wire:submit="createChannel" class="space-y-4">
|
<form wire:submit="createChannel" class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label for="new-channel-instance" class="block text-sm font-medium text-gray-700">Platform Instance</label>
|
<label for="new-channel-instance" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Platform Instance</label>
|
||||||
<select
|
<select
|
||||||
id="new-channel-instance"
|
id="new-channel-instance"
|
||||||
wire:model.live="newPlatformInstanceId"
|
wire:model.live="newPlatformInstanceId"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<option value="">Select an instance</option>
|
<option value="">Select an instance</option>
|
||||||
@foreach ($platformInstances as $instance)
|
@foreach ($platformInstances as $instance)
|
||||||
<option value="{{ $instance->id }}">{{ $instance->name }}</option>
|
<option value="{{ $instance->id }}">{{ $instance->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('newPlatformInstanceId') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newPlatformInstanceId') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
@if ($communityLoadError)
|
@if ($communityLoadError)
|
||||||
<p class="mt-1 text-sm text-red-600">{{ $communityLoadError }}</p>
|
<p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $communityLoadError }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($availableCommunities)
|
@if ($availableCommunities)
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<label for="new-channel-community" class="block text-sm font-medium text-gray-700">Community</label>
|
<label for="new-channel-community" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Community</label>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="refreshCommunities"
|
wire:click="refreshCommunities"
|
||||||
class="text-xs text-blue-600 hover:text-blue-800"
|
class="text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
>
|
>
|
||||||
Refresh
|
Refresh
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -195,48 +195,48 @@ class="text-xs text-blue-600 hover:text-blue-800"
|
||||||
<select
|
<select
|
||||||
id="new-channel-community"
|
id="new-channel-community"
|
||||||
wire:model="newCommunityId"
|
wire:model="newCommunityId"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<option value="">Select a community</option>
|
<option value="">Select a community</option>
|
||||||
@foreach ($availableCommunities as $community)
|
@foreach ($availableCommunities as $community)
|
||||||
<option value="{{ $community['id'] }}">{{ $community['title'] }} ({{ $community['name'] }})</option>
|
<option value="{{ $community['id'] }}">{{ $community['title'] }} ({{ $community['name'] }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('newCommunityId') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newCommunityId') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="new-channel-language" class="block text-sm font-medium text-gray-700">Language <span class="text-gray-400">(optional)</span></label>
|
<label for="new-channel-language" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Language <span class="text-gray-400 dark:text-gray-500">(optional)</span></label>
|
||||||
<select
|
<select
|
||||||
id="new-channel-language"
|
id="new-channel-language"
|
||||||
wire:model="newLanguageId"
|
wire:model="newLanguageId"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<option value="">Select a language</option>
|
<option value="">Select a language</option>
|
||||||
@foreach ($languages as $language)
|
@foreach ($languages as $language)
|
||||||
<option value="{{ $language->id }}">{{ $language->name }}</option>
|
<option value="{{ $language->id }}">{{ $language->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('newLanguageId') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newLanguageId') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="new-channel-description" class="block text-sm font-medium text-gray-700">Description <span class="text-gray-400">(optional)</span></label>
|
<label for="new-channel-description" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Description <span class="text-gray-400 dark:text-gray-500">(optional)</span></label>
|
||||||
<textarea
|
<textarea
|
||||||
id="new-channel-description"
|
id="new-channel-description"
|
||||||
wire:model="newDescription"
|
wire:model="newDescription"
|
||||||
rows="2"
|
rows="2"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
></textarea>
|
></textarea>
|
||||||
@error('newDescription') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newDescription') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 flex justify-end space-x-3">
|
<div class="mt-6 flex justify-end space-x-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="closeCreateModal"
|
wire:click="closeCreateModal"
|
||||||
class="inline-flex justify-center rounded-md border border-gray-300 shadow-xs px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
class="inline-flex justify-center rounded-md border border-gray-300 shadow-xs px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700/50"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
<!-- System Statistics -->
|
<!-- System Statistics -->
|
||||||
<div class="mb-8">
|
<div class="mb-8">
|
||||||
<h2 class="text-lg font-semibold text-gray-900 mb-4">System Overview</h2>
|
<h2 class="text-lg font-semibold text-gray-900 mb-4 dark:text-gray-100">System Overview</h2>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
<!-- Active Feeds -->
|
<!-- Active Feeds -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-orange-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-orange-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -14,17 +14,17 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Active Feeds</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Active Feeds</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $systemStats['active_feeds'] }}
|
{{ $systemStats['active_feeds'] }}
|
||||||
<span class="text-sm font-normal text-gray-500">/{{ $systemStats['total_feeds'] }}</span>
|
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">/{{ $systemStats['total_feeds'] }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Platform Accounts -->
|
<!-- Platform Accounts -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -32,17 +32,17 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Platform Accounts</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Platform Accounts</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $systemStats['active_platform_accounts'] }}
|
{{ $systemStats['active_platform_accounts'] }}
|
||||||
<span class="text-sm font-normal text-gray-500">/{{ $systemStats['total_platform_accounts'] }}</span>
|
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">/{{ $systemStats['total_platform_accounts'] }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Platform Channels -->
|
<!-- Platform Channels -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-cyan-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-cyan-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -50,17 +50,17 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Platform Channels</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Platform Channels</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $systemStats['active_platform_channels'] }}
|
{{ $systemStats['active_platform_channels'] }}
|
||||||
<span class="text-sm font-normal text-gray-500">/{{ $systemStats['total_platform_channels'] }}</span>
|
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">/{{ $systemStats['total_platform_channels'] }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Active Routes -->
|
<!-- Active Routes -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-pink-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-pink-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -68,10 +68,10 @@
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Active Routes</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Active Routes</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $systemStats['active_routes'] }}
|
{{ $systemStats['active_routes'] }}
|
||||||
<span class="text-sm font-normal text-gray-500">/{{ $systemStats['total_routes'] }}</span>
|
<span class="text-sm font-normal text-gray-500 dark:text-gray-400">/{{ $systemStats['total_routes'] }}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -82,10 +82,10 @@
|
||||||
<!-- Article Statistics -->
|
<!-- Article Statistics -->
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center justify-between mb-4">
|
<div class="flex items-center justify-between mb-4">
|
||||||
<h2 class="text-lg font-semibold text-gray-900">Article Statistics</h2>
|
<h2 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Article Statistics</h2>
|
||||||
<select
|
<select
|
||||||
wire:model.live="period"
|
wire:model.live="period"
|
||||||
class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500"
|
class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:ring-blue-500 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
@foreach ($availablePeriods as $value => $label)
|
@foreach ($availablePeriods as $value => $label)
|
||||||
<option value="{{ $value }}">{{ $label }}</option>
|
<option value="{{ $value }}">{{ $label }}</option>
|
||||||
|
|
@ -94,7 +94,7 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
<!-- Articles Fetched -->
|
<!-- Articles Fetched -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-blue-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-blue-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -102,8 +102,8 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Articles Fetched</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Articles Fetched</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $articleStats['articles_fetched'] }}
|
{{ $articleStats['articles_fetched'] }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -111,7 +111,7 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Articles Published -->
|
<!-- Articles Published -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-green-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-green-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -119,8 +119,8 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Articles Published</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Articles Published</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $articleStats['articles_published'] }}
|
{{ $articleStats['articles_published'] }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -128,7 +128,7 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Published Rate -->
|
<!-- Published Rate -->
|
||||||
<div class="bg-white p-6 rounded-lg shadow-sm">
|
<div class="bg-white p-6 rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
<svg class="h-8 w-8 text-purple-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-8 w-8 text-purple-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -136,8 +136,8 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<p class="text-sm font-medium text-gray-500">Published Rate</p>
|
<p class="text-sm font-medium text-gray-500 dark:text-gray-400">Published Rate</p>
|
||||||
<p class="text-2xl font-semibold text-gray-900">
|
<p class="text-2xl font-semibold text-gray-900 dark:text-gray-100">
|
||||||
{{ $articleStats['published_percentage'] }}%
|
{{ $articleStats['published_percentage'] }}%
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
|
|
||||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||||
@forelse ($feeds as $feed)
|
@forelse ($feeds as $feed)
|
||||||
<div class="bg-white rounded-lg shadow-sm p-6" wire:key="feed-{{ $feed->id }}">
|
<div class="bg-white rounded-lg shadow-sm p-6 dark:bg-gray-800" wire:key="feed-{{ $feed->id }}">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="shrink-0">
|
<div class="shrink-0">
|
||||||
|
|
@ -28,11 +28,11 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex-1 min-w-0">
|
<div class="ml-4 flex-1 min-w-0">
|
||||||
<h3 class="text-lg font-medium text-gray-900 truncate">
|
<h3 class="text-lg font-medium text-gray-900 truncate dark:text-gray-100">
|
||||||
{{ $feed->name }}
|
{{ $feed->name }}
|
||||||
</h3>
|
</h3>
|
||||||
@if ($feed->description)
|
@if ($feed->description)
|
||||||
<p class="text-sm text-gray-500 line-clamp-2">
|
<p class="text-sm text-gray-500 line-clamp-2 dark:text-gray-400">
|
||||||
{{ $feed->description }}
|
{{ $feed->description }}
|
||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -40,7 +40,7 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
wire:click="toggle({{ $feed->id }})"
|
wire:click="toggle({{ $feed->id }})"
|
||||||
class="p-1 rounded-full {{ $feed->is_active ? 'bg-green-100 text-green-600' : 'bg-gray-100 text-gray-400' }}"
|
class="p-1 rounded-full {{ $feed->is_active ? 'bg-green-100 text-green-600 dark:bg-green-900/30 dark:text-green-400' : 'bg-gray-100 text-gray-400 dark:bg-gray-700 dark:text-gray-500' }}"
|
||||||
title="{{ $feed->is_active ? 'Active - Click to disable' : 'Inactive - Click to enable' }}"
|
title="{{ $feed->is_active ? 'Active - Click to disable' : 'Inactive - Click to enable' }}"
|
||||||
>
|
>
|
||||||
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
<svg class="h-5 w-5" fill="currentColor" viewBox="0 0 20 20">
|
||||||
|
|
@ -51,10 +51,10 @@ class="p-1 rounded-full {{ $feed->is_active ? 'bg-green-100 text-green-600' : 'b
|
||||||
|
|
||||||
<div class="mt-4 flex items-center justify-between">
|
<div class="mt-4 flex items-center justify-between">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $feed->is_active ? 'bg-green-100 text-green-800' : 'bg-gray-100 text-gray-800' }}">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $feed->is_active ? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300' : 'bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-200' }}">
|
||||||
{{ $feed->is_active ? 'Active' : 'Inactive' }}
|
{{ $feed->is_active ? 'Active' : 'Inactive' }}
|
||||||
</span>
|
</span>
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300">
|
||||||
{{ strtoupper($feed->type) }}
|
{{ strtoupper($feed->type) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -63,7 +63,7 @@ class="p-1 rounded-full {{ $feed->is_active ? 'bg-green-100 text-green-600' : 'b
|
||||||
href="{{ $feed->url }}"
|
href="{{ $feed->url }}"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener noreferrer"
|
rel="noopener noreferrer"
|
||||||
class="text-gray-400 hover:text-gray-600"
|
class="text-gray-400 hover:text-gray-600 dark:text-gray-500 dark:hover:text-gray-300"
|
||||||
title="Open feed URL"
|
title="Open feed URL"
|
||||||
>
|
>
|
||||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -73,17 +73,17 @@ class="text-gray-400 hover:text-gray-600"
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-3 text-xs text-gray-500">
|
<div class="mt-3 text-xs text-gray-500 dark:text-gray-400">
|
||||||
Created {{ $feed->created_at->format('M d, Y') }}
|
Created {{ $feed->created_at->format('M d, Y') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<div class="col-span-full text-center py-12">
|
<div class="col-span-full text-center py-12">
|
||||||
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-.75a7.5 7.5 0 0 0-7.5-7.5H4.5m0-6.75h.75c7.87 0 14.25 6.38 14.25 14.25v.75M6 18.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12.75 19.5v-.75a7.5 7.5 0 0 0-7.5-7.5H4.5m0-6.75h.75c7.87 0 14.25 6.38 14.25 14.25v.75M6 18.75a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<h3 class="mt-2 text-sm font-medium text-gray-900">No feeds</h3>
|
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">No feeds</h3>
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
No feeds have been configured yet.
|
No feeds have been configured yet.
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|
@ -106,62 +106,62 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
|
||||||
<x-form-modal title="Add Feed" close="closeCreateModal">
|
<x-form-modal title="Add Feed" close="closeCreateModal">
|
||||||
<form wire:submit="createFeed" class="space-y-4">
|
<form wire:submit="createFeed" class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label for="new-feed-name" class="block text-sm font-medium text-gray-700">Name</label>
|
<label for="new-feed-name" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Name</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="new-feed-name"
|
id="new-feed-name"
|
||||||
wire:model="newName"
|
wire:model="newName"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
/>
|
/>
|
||||||
@error('newName') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newName') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="new-feed-provider" class="block text-sm font-medium text-gray-700">Provider</label>
|
<label for="new-feed-provider" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Provider</label>
|
||||||
<select
|
<select
|
||||||
id="new-feed-provider"
|
id="new-feed-provider"
|
||||||
wire:model="newProvider"
|
wire:model="newProvider"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<option value="">Select a provider</option>
|
<option value="">Select a provider</option>
|
||||||
@foreach ($providers as $code => $provider)
|
@foreach ($providers as $code => $provider)
|
||||||
<option value="{{ $code }}">{{ $provider['name'] }}</option>
|
<option value="{{ $code }}">{{ $provider['name'] }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('newProvider') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newProvider') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="new-feed-language" class="block text-sm font-medium text-gray-700">Language</label>
|
<label for="new-feed-language" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Language</label>
|
||||||
<select
|
<select
|
||||||
id="new-feed-language"
|
id="new-feed-language"
|
||||||
wire:model="newLanguageId"
|
wire:model="newLanguageId"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<option value="">Select a language</option>
|
<option value="">Select a language</option>
|
||||||
@foreach ($languages as $language)
|
@foreach ($languages as $language)
|
||||||
<option value="{{ $language->id }}">{{ $language->name }}</option>
|
<option value="{{ $language->id }}">{{ $language->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('newLanguageId') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newLanguageId') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="new-feed-description" class="block text-sm font-medium text-gray-700">Description <span class="text-gray-400">(optional)</span></label>
|
<label for="new-feed-description" class="block text-sm font-medium text-gray-700 dark:text-gray-200">Description <span class="text-gray-400 dark:text-gray-500">(optional)</span></label>
|
||||||
<textarea
|
<textarea
|
||||||
id="new-feed-description"
|
id="new-feed-description"
|
||||||
wire:model="newDescription"
|
wire:model="newDescription"
|
||||||
rows="2"
|
rows="2"
|
||||||
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm"
|
class="mt-1 block w-full rounded-md border border-gray-300 shadow-xs focus:border-blue-500 focus:ring-blue-500 sm:text-sm dark:border-gray-600"
|
||||||
></textarea>
|
></textarea>
|
||||||
@error('newDescription') <p class="mt-1 text-sm text-red-600">{{ $message }}</p> @enderror
|
@error('newDescription') <p class="mt-1 text-sm text-red-600 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-6 flex justify-end space-x-3">
|
<div class="mt-6 flex justify-end space-x-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="closeCreateModal"
|
wire:click="closeCreateModal"
|
||||||
class="inline-flex justify-center rounded-md border border-gray-300 shadow-xs px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
|
class="inline-flex justify-center rounded-md border border-gray-300 shadow-xs px-4 py-2 bg-white text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 dark:hover:bg-gray-700/50"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="relative" x-data="{ open: false }">
|
<div class="relative" x-data="{ open: false }">
|
||||||
<button
|
<button
|
||||||
@click="open = !open"
|
@click="open = !open"
|
||||||
class="relative p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="relative p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-100 focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:text-gray-500 dark:hover:text-gray-300 dark:hover:bg-gray-700"
|
||||||
aria-label="Notifications"
|
aria-label="Notifications"
|
||||||
>
|
>
|
||||||
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -23,15 +23,15 @@ class="relative p-2 rounded-md text-gray-400 hover:text-gray-600 hover:bg-gray-1
|
||||||
x-transition:leave="transition ease-in duration-75"
|
x-transition:leave="transition ease-in duration-75"
|
||||||
x-transition:leave-start="opacity-100 scale-100"
|
x-transition:leave-start="opacity-100 scale-100"
|
||||||
x-transition:leave-end="opacity-0 scale-95"
|
x-transition:leave-end="opacity-0 scale-95"
|
||||||
class="absolute right-0 z-50 mt-2 w-80 bg-white rounded-lg shadow-lg ring-1 ring-black/5"
|
class="absolute right-0 z-50 mt-2 w-80 bg-white rounded-lg shadow-lg ring-1 ring-black/5 dark:bg-gray-800"
|
||||||
style="display: none;"
|
style="display: none;"
|
||||||
>
|
>
|
||||||
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-100">
|
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-100 dark:border-gray-700">
|
||||||
<h3 class="text-sm font-semibold text-gray-900">Notifications</h3>
|
<h3 class="text-sm font-semibold text-gray-900 dark:text-gray-100">Notifications</h3>
|
||||||
@if ($this->unreadCount > 0)
|
@if ($this->unreadCount > 0)
|
||||||
<button
|
<button
|
||||||
wire:click="markAllAsRead"
|
wire:click="markAllAsRead"
|
||||||
class="text-xs text-blue-600 hover:text-blue-800"
|
class="text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
>
|
>
|
||||||
Mark all as read
|
Mark all as read
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -41,7 +41,7 @@ class="text-xs text-blue-600 hover:text-blue-800"
|
||||||
<div class="max-h-96 overflow-y-auto">
|
<div class="max-h-96 overflow-y-auto">
|
||||||
@forelse ($this->notifications as $notification)
|
@forelse ($this->notifications as $notification)
|
||||||
<div
|
<div
|
||||||
class="px-4 py-3 border-b border-gray-50 last:border-b-0 {{ $notification->isRead() ? 'bg-white' : 'bg-blue-50' }}"
|
class="px-4 py-3 border-b border-gray-50 dark:border-gray-700 last:border-b-0 {{ $notification->isRead() ? 'bg-white dark:bg-gray-800' : 'bg-blue-50 dark:bg-blue-900/20' }}"
|
||||||
wire:key="notification-{{ $notification->id }}"
|
wire:key="notification-{{ $notification->id }}"
|
||||||
>
|
>
|
||||||
<div class="flex items-start gap-3">
|
<div class="flex items-start gap-3">
|
||||||
|
|
@ -61,14 +61,14 @@ class="px-4 py-3 border-b border-gray-50 last:border-b-0 {{ $notification->isRea
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<p class="text-sm font-medium text-gray-900">{{ $notification->title }}</p>
|
<p class="text-sm font-medium text-gray-900 dark:text-gray-100">{{ $notification->title }}</p>
|
||||||
<p class="text-sm text-gray-500 mt-0.5">{{ $notification->message }}</p>
|
<p class="text-sm text-gray-500 mt-0.5 dark:text-gray-400">{{ $notification->message }}</p>
|
||||||
<div class="flex items-center justify-between mt-1">
|
<div class="flex items-center justify-between mt-1">
|
||||||
<span class="text-xs text-gray-400">{{ $notification->created_at->diffForHumans() }}</span>
|
<span class="text-xs text-gray-400 dark:text-gray-500">{{ $notification->created_at->diffForHumans() }}</span>
|
||||||
@unless ($notification->isRead())
|
@unless ($notification->isRead())
|
||||||
<button
|
<button
|
||||||
wire:click="markAsRead({{ $notification->id }})"
|
wire:click="markAsRead({{ $notification->id }})"
|
||||||
class="text-xs text-blue-600 hover:text-blue-800"
|
class="text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
>
|
>
|
||||||
Mark read
|
Mark read
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -82,7 +82,7 @@ class="text-xs text-blue-600 hover:text-blue-800"
|
||||||
<svg class="mx-auto h-8 w-8 text-gray-300" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="mx-auto h-8 w-8 text-gray-300" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M14.857 17.082a23.848 23.848 0 0 0 5.454-1.31A8.967 8.967 0 0 1 18 9.75V9A6 6 0 0 0 6 9v.75a8.967 8.967 0 0 1-2.312 6.022c1.733.64 3.56 1.085 5.455 1.31m5.714 0a24.255 24.255 0 0 1-5.714 0m5.714 0a3 3 0 1 1-5.714 0" />
|
||||||
</svg>
|
</svg>
|
||||||
<p class="mt-2 text-sm text-gray-500">No notifications</p>
|
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">No notifications</p>
|
||||||
</div>
|
</div>
|
||||||
@endforelse
|
@endforelse
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,33 @@
|
||||||
<div class="w-full max-w-2xl px-4 sm:px-6 lg:px-8">
|
<div class="w-full max-w-2xl px-4 sm:px-6 lg:px-8">
|
||||||
<div class="w-full bg-white rounded-2xl shadow-xl p-8">
|
<div class="w-full bg-white rounded-2xl shadow-xl p-8 dark:bg-gray-800">
|
||||||
|
|
||||||
{{-- Step 1: Welcome --}}
|
{{-- Step 1: Welcome --}}
|
||||||
@if ($step === 1)
|
@if ($step === 1)
|
||||||
<div class="text-center">
|
<div class="text-center">
|
||||||
<h1 class="text-3xl font-bold text-gray-900 mb-2">Welcome to FFR</h1>
|
<h1 class="text-3xl font-bold text-gray-900 mb-2 dark:text-gray-100">Welcome to FFR</h1>
|
||||||
<p class="text-gray-600 mb-8">
|
<p class="text-gray-600 mb-8 dark:text-gray-300">
|
||||||
Let's get you set up! We'll help you configure your Lemmy account, add your first feed, and create a channel for posting.
|
Let's get you set up! We'll help you configure your Lemmy account, add your first feed, and create a channel for posting.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="space-y-4 text-left">
|
<div class="space-y-4 text-left">
|
||||||
<div class="flex items-center text-sm text-gray-600">
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-300">
|
||||||
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center mr-3 text-xs font-semibold">1</div>
|
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center mr-3 text-xs font-semibold">1</div>
|
||||||
<span>Connect your Lemmy account</span>
|
<span>Connect your Lemmy account</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center text-sm text-gray-600">
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-300">
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold">2</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold dark:text-gray-300">2</div>
|
||||||
<span>Configure a channel</span>
|
<span>Configure a channel</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center text-sm text-gray-600">
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-300">
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold">3</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold dark:text-gray-300">3</div>
|
||||||
<span>Add your first feed</span>
|
<span>Add your first feed</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center text-sm text-gray-600">
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-300">
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold">4</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold dark:text-gray-300">4</div>
|
||||||
<span>Create a route</span>
|
<span>Create a route</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center text-sm text-gray-600">
|
<div class="flex items-center text-sm text-gray-600 dark:text-gray-300">
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold">5</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center mr-3 text-xs font-semibold dark:text-gray-300">5</div>
|
||||||
<span>You're ready to go!</span>
|
<span>You're ready to go!</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -46,29 +46,29 @@ class="w-full bg-blue-600 text-white py-3 px-4 rounded-md hover:bg-blue-700 tran
|
||||||
{{-- Step 2: Platform Account --}}
|
{{-- Step 2: Platform Account --}}
|
||||||
@if ($step === 2)
|
@if ($step === 2)
|
||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<h1 class="text-2xl font-bold text-gray-900 mb-2">Connect Your Lemmy Account</h1>
|
<h1 class="text-2xl font-bold text-gray-900 mb-2 dark:text-gray-100">Connect Your Lemmy Account</h1>
|
||||||
<p class="text-gray-600">
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
{{ $existingAccount ? 'Your connected Lemmy account' : 'Enter your Lemmy instance details and login credentials' }}
|
{{ $existingAccount ? 'Your connected Lemmy account' : 'Enter your Lemmy instance details and login credentials' }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{{-- Progress indicator --}}
|
{{-- Progress indicator --}}
|
||||||
<div class="flex justify-center mt-6 space-x-2">
|
<div class="flex justify-center mt-6 space-x-2">
|
||||||
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">1</div>
|
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">1</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">2</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">2</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">3</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">3</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">4</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">4</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if (!empty($formErrors['general']))
|
@if (!empty($formErrors['general']))
|
||||||
<div class="p-3 bg-red-50 border border-red-200 rounded-md mt-6">
|
<div class="p-3 bg-red-50 border border-red-200 rounded-md mt-6 dark:bg-red-900/20 dark:border-red-800">
|
||||||
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
|
<p class="text-red-600 text-sm dark:text-red-400">{{ $formErrors['general'] }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($existingAccount)
|
@if ($existingAccount)
|
||||||
{{-- Account Card --}}
|
{{-- Account Card --}}
|
||||||
<div class="mt-8">
|
<div class="mt-8">
|
||||||
<div class="bg-green-50 border border-green-200 rounded-lg p-6 text-left">
|
<div class="bg-green-50 border border-green-200 rounded-lg p-6 text-left dark:bg-green-900/20 dark:border-green-800">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<div class="w-12 h-12 bg-green-500 text-white rounded-full flex items-center justify-center">
|
<div class="w-12 h-12 bg-green-500 text-white rounded-full flex items-center justify-center">
|
||||||
|
|
@ -77,8 +77,8 @@ class="w-full bg-blue-600 text-white py-3 px-4 rounded-md hover:bg-blue-700 tran
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4">
|
<div class="ml-4">
|
||||||
<h3 class="text-lg font-semibold text-gray-900">Account Connected</h3>
|
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">Account Connected</h3>
|
||||||
<div class="text-sm text-gray-600 mt-1">
|
<div class="text-sm text-gray-600 mt-1 dark:text-gray-300">
|
||||||
<p><strong>Username:</strong> {{ $existingAccount['username'] }}</p>
|
<p><strong>Username:</strong> {{ $existingAccount['username'] }}</p>
|
||||||
<p><strong>Instance:</strong> {{ str_replace('https://', '', $existingAccount['instance_url']) }}</p>
|
<p><strong>Instance:</strong> {{ str_replace('https://', '', $existingAccount['instance_url']) }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -87,7 +87,7 @@ class="w-full bg-blue-600 text-white py-3 px-4 rounded-md hover:bg-blue-700 tran
|
||||||
<button
|
<button
|
||||||
wire:click="deleteAccount"
|
wire:click="deleteAccount"
|
||||||
wire:confirm="Are you sure you want to remove this account? You will need to re-enter your credentials."
|
wire:confirm="Are you sure you want to remove this account? You will need to re-enter your credentials."
|
||||||
class="text-red-600 hover:text-red-800 p-2"
|
class="text-red-600 hover:text-red-800 p-2 dark:text-red-400"
|
||||||
title="Remove account"
|
title="Remove account"
|
||||||
>
|
>
|
||||||
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
|
|
@ -98,7 +98,7 @@ class="text-red-600 hover:text-red-800 p-2"
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between mt-6">
|
<div class="flex justify-between mt-6">
|
||||||
<button wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200">
|
<button wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200 dark:text-gray-300">
|
||||||
← Back
|
← Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -113,7 +113,7 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
{{-- Login Form --}}
|
{{-- Login Form --}}
|
||||||
<form wire:submit="createPlatformAccount" class="space-y-6 mt-8 text-left">
|
<form wire:submit="createPlatformAccount" class="space-y-6 mt-8 text-left">
|
||||||
<div>
|
<div>
|
||||||
<label for="instanceUrl" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="instanceUrl" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Lemmy Instance Domain
|
Lemmy Instance Domain
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -121,43 +121,43 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
id="instanceUrl"
|
id="instanceUrl"
|
||||||
wire:model="instanceUrl"
|
wire:model="instanceUrl"
|
||||||
placeholder="lemmy.world"
|
placeholder="lemmy.world"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<p class="text-sm text-gray-500 mt-1">Enter just the domain name (e.g., lemmy.world, belgae.social)</p>
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">Enter just the domain name (e.g., lemmy.world, belgae.social)</p>
|
||||||
@error('instanceUrl') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('instanceUrl') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="username" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="username" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Username
|
Username
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
id="username"
|
id="username"
|
||||||
wire:model="username"
|
wire:model="username"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
@error('username') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('username') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="password" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="password" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Password
|
Password
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
id="password"
|
id="password"
|
||||||
wire:model="password"
|
wire:model="password"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
@error('password') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('password') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200">
|
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200 dark:text-gray-300">
|
||||||
← Back
|
← Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -176,8 +176,8 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
{{-- Step 3: Channel --}}
|
{{-- Step 3: Channel --}}
|
||||||
@if ($step === 3)
|
@if ($step === 3)
|
||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<h1 class="text-2xl font-bold text-gray-900 mb-2">Configure Your Channel</h1>
|
<h1 class="text-2xl font-bold text-gray-900 mb-2 dark:text-gray-100">Configure Your Channel</h1>
|
||||||
<p class="text-gray-600">
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
Set up a Lemmy community where articles will be posted
|
Set up a Lemmy community where articles will be posted
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -185,25 +185,25 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
<div class="flex justify-center mt-6 space-x-2">
|
<div class="flex justify-center mt-6 space-x-2">
|
||||||
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
||||||
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">2</div>
|
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">2</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">3</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">3</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">4</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">4</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form wire:submit="createChannel" class="space-y-6 mt-8 text-left">
|
<form wire:submit="createChannel" class="space-y-6 mt-8 text-left">
|
||||||
@if (!empty($formErrors['general']))
|
@if (!empty($formErrors['general']))
|
||||||
<div class="p-3 bg-red-50 border border-red-200 rounded-md">
|
<div class="p-3 bg-red-50 border border-red-200 rounded-md dark:bg-red-900/20 dark:border-red-800">
|
||||||
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
|
<p class="text-red-600 text-sm dark:text-red-400">{{ $formErrors['general'] }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="platformInstanceId" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="platformInstanceId" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Platform Instance
|
Platform Instance
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="platformInstanceId"
|
id="platformInstanceId"
|
||||||
wire:model.live="platformInstanceId"
|
wire:model.live="platformInstanceId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select platform instance</option>
|
<option value="">Select platform instance</option>
|
||||||
|
|
@ -211,22 +211,22 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
<option value="{{ $instance->id }}">{{ $instance->name }} ({{ $instance->url }})</option>
|
<option value="{{ $instance->id }}">{{ $instance->name }} ({{ $instance->url }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('platformInstanceId') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('platformInstanceId') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
@if ($communityLoadError)
|
@if ($communityLoadError)
|
||||||
<p class="text-red-600 text-sm mt-1">{{ $communityLoadError }}</p>
|
<p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $communityLoadError }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@if ($availableCommunities)
|
@if ($availableCommunities)
|
||||||
<div>
|
<div>
|
||||||
<div class="flex items-center justify-between mb-2">
|
<div class="flex items-center justify-between mb-2">
|
||||||
<label for="channelCommunityId" class="block text-sm font-medium text-gray-700">
|
<label for="channelCommunityId" class="block text-sm font-medium text-gray-700 dark:text-gray-200">
|
||||||
Community
|
Community
|
||||||
</label>
|
</label>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="refreshCommunities"
|
wire:click="refreshCommunities"
|
||||||
class="text-xs text-blue-600 hover:text-blue-800"
|
class="text-xs text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
>
|
>
|
||||||
Refresh
|
Refresh
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -234,7 +234,7 @@ class="text-xs text-blue-600 hover:text-blue-800"
|
||||||
<select
|
<select
|
||||||
id="channelCommunityId"
|
id="channelCommunityId"
|
||||||
wire:model="channelCommunityId"
|
wire:model="channelCommunityId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select a community</option>
|
<option value="">Select a community</option>
|
||||||
|
|
@ -242,18 +242,18 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
<option value="{{ $community['id'] }}">{{ $community['title'] }} ({{ $community['name'] }})</option>
|
<option value="{{ $community['id'] }}">{{ $community['title'] }} ({{ $community['name'] }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('channelCommunityId') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('channelCommunityId') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="channelLanguageId" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="channelLanguageId" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Language
|
Language
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="channelLanguageId"
|
id="channelLanguageId"
|
||||||
wire:model="channelLanguageId"
|
wire:model="channelLanguageId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select language</option>
|
<option value="">Select language</option>
|
||||||
|
|
@ -261,11 +261,11 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
<option value="{{ $language->id }}">{{ $language->name }}</option>
|
<option value="{{ $language->id }}">{{ $language->name }}</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('channelLanguageId') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('channelLanguageId') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="channelDescription" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="channelDescription" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Description (Optional)
|
Description (Optional)
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
|
|
@ -273,13 +273,13 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
wire:model="channelDescription"
|
wire:model="channelDescription"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder="Brief description of this channel"
|
placeholder="Brief description of this channel"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
></textarea>
|
></textarea>
|
||||||
@error('channelDescription') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('channelDescription') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200">
|
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200 dark:text-gray-300">
|
||||||
← Back
|
← Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -297,8 +297,8 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
{{-- Step 4: Feed --}}
|
{{-- Step 4: Feed --}}
|
||||||
@if ($step === 4)
|
@if ($step === 4)
|
||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<h1 class="text-2xl font-bold text-gray-900 mb-2">Add Your First Feed</h1>
|
<h1 class="text-2xl font-bold text-gray-900 mb-2 dark:text-gray-100">Add Your First Feed</h1>
|
||||||
<p class="text-gray-600">
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
Choose from our supported news providers to monitor for new articles
|
Choose from our supported news providers to monitor for new articles
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -307,18 +307,18 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
||||||
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
||||||
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">3</div>
|
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">3</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">4</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">4</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form wire:submit="createFeed" class="space-y-6 mt-8 text-left">
|
<form wire:submit="createFeed" class="space-y-6 mt-8 text-left">
|
||||||
@if (!empty($formErrors['general']))
|
@if (!empty($formErrors['general']))
|
||||||
<div class="p-3 bg-red-50 border border-red-200 rounded-md">
|
<div class="p-3 bg-red-50 border border-red-200 rounded-md dark:bg-red-900/20 dark:border-red-800">
|
||||||
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
|
<p class="text-red-600 text-sm dark:text-red-400">{{ $formErrors['general'] }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="feedName" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="feedName" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Feed Name
|
Feed Name
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -326,16 +326,16 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
id="feedName"
|
id="feedName"
|
||||||
wire:model="feedName"
|
wire:model="feedName"
|
||||||
placeholder="My News Feed"
|
placeholder="My News Feed"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
@error('feedName') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('feedName') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="feedLanguageId" class="block text-sm font-medium text-gray-700 mb-2 flex items-center">
|
<label for="feedLanguageId" class="block text-sm font-medium text-gray-700 mb-2 flex items-center dark:text-gray-200">
|
||||||
Language
|
Language
|
||||||
<span class="ml-2 text-gray-400 cursor-help" title="Language matches your channel. Additional languages can be configured from the dashboard after setup.">
|
<span class="ml-2 text-gray-400 cursor-help dark:text-gray-500" title="Language matches your channel. Additional languages can be configured from the dashboard after setup.">
|
||||||
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
@ -344,21 +344,21 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
<select
|
<select
|
||||||
id="feedLanguageId"
|
id="feedLanguageId"
|
||||||
disabled
|
disabled
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md bg-gray-100 text-gray-600 cursor-not-allowed"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md bg-gray-100 text-gray-600 cursor-not-allowed dark:border-gray-600 dark:bg-gray-700 dark:text-gray-300"
|
||||||
>
|
>
|
||||||
<option>{{ $channelLanguage?->name ?? 'Unknown' }}</option>
|
<option>{{ $channelLanguage?->name ?? 'Unknown' }}</option>
|
||||||
</select>
|
</select>
|
||||||
<p class="text-sm text-gray-500 mt-1">Inherited from your channel</p>
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">Inherited from your channel</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="feedProvider" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="feedProvider" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
News Provider
|
News Provider
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="feedProvider"
|
id="feedProvider"
|
||||||
wire:model="feedProvider"
|
wire:model="feedProvider"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select news provider</option>
|
<option value="">Select news provider</option>
|
||||||
|
|
@ -367,13 +367,13 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@if ($feedProviders->isEmpty())
|
@if ($feedProviders->isEmpty())
|
||||||
<p class="text-sm text-amber-600 mt-1">No providers available for this language.</p>
|
<p class="text-sm text-amber-600 mt-1 dark:text-amber-400">No providers available for this language.</p>
|
||||||
@endif
|
@endif
|
||||||
@error('feedProvider') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('feedProvider') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="feedDescription" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="feedDescription" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Description (Optional)
|
Description (Optional)
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
|
|
@ -381,13 +381,13 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
wire:model="feedDescription"
|
wire:model="feedDescription"
|
||||||
rows="3"
|
rows="3"
|
||||||
placeholder="Brief description of this feed"
|
placeholder="Brief description of this feed"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
></textarea>
|
></textarea>
|
||||||
@error('feedDescription') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('feedDescription') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200">
|
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200 dark:text-gray-300">
|
||||||
← Back
|
← Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -405,8 +405,8 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
{{-- Step 5: Route --}}
|
{{-- Step 5: Route --}}
|
||||||
@if ($step === 5)
|
@if ($step === 5)
|
||||||
<div class="text-center mb-8">
|
<div class="text-center mb-8">
|
||||||
<h1 class="text-2xl font-bold text-gray-900 mb-2">Create Your First Route</h1>
|
<h1 class="text-2xl font-bold text-gray-900 mb-2 dark:text-gray-100">Create Your First Route</h1>
|
||||||
<p class="text-gray-600">
|
<p class="text-gray-600 dark:text-gray-300">
|
||||||
Connect your feed to a channel by creating a route. This tells FFR which articles to post where.
|
Connect your feed to a channel by creating a route. This tells FFR which articles to post where.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
@ -416,24 +416,24 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
||||||
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
<div class="w-6 h-6 bg-green-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">✓</div>
|
||||||
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">4</div>
|
<div class="w-6 h-6 bg-blue-500 text-white rounded-full flex items-center justify-center text-xs font-semibold">4</div>
|
||||||
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold">5</div>
|
<div class="w-6 h-6 bg-gray-300 text-gray-600 rounded-full flex items-center justify-center text-xs font-semibold dark:text-gray-300">5</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form wire:submit="createRoute" class="space-y-6 mt-8 text-left">
|
<form wire:submit="createRoute" class="space-y-6 mt-8 text-left">
|
||||||
@if (!empty($formErrors['general']))
|
@if (!empty($formErrors['general']))
|
||||||
<div class="p-3 bg-red-50 border border-red-200 rounded-md">
|
<div class="p-3 bg-red-50 border border-red-200 rounded-md dark:bg-red-900/20 dark:border-red-800">
|
||||||
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
|
<p class="text-red-600 text-sm dark:text-red-400">{{ $formErrors['general'] }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="routeFeedId" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="routeFeedId" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Select Feed
|
Select Feed
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="routeFeedId"
|
id="routeFeedId"
|
||||||
wire:model="routeFeedId"
|
wire:model="routeFeedId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select a feed</option>
|
<option value="">Select a feed</option>
|
||||||
|
|
@ -441,17 +441,17 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
<option value="{{ $feed->id }}">{{ $feed->name }} ({{ $feed->language?->short_code ?? '?' }})</option>
|
<option value="{{ $feed->id }}">{{ $feed->name }} ({{ $feed->language?->short_code ?? '?' }})</option>
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@error('routeFeedId') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('routeFeedId') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="routeChannelId" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="routeChannelId" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Select Channel
|
Select Channel
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="routeChannelId"
|
id="routeChannelId"
|
||||||
wire:model="routeChannelId"
|
wire:model="routeChannelId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select a channel</option>
|
<option value="">Select a channel</option>
|
||||||
|
|
@ -460,15 +460,15 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
@endforeach
|
@endforeach
|
||||||
</select>
|
</select>
|
||||||
@if ($channels->isEmpty())
|
@if ($channels->isEmpty())
|
||||||
<p class="text-sm text-gray-500 mt-1">
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">
|
||||||
No channels available. Please create a channel first.
|
No channels available. Please create a channel first.
|
||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
@error('routeChannelId') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('routeChannelId') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="routePriority" class="block text-sm font-medium text-gray-700 mb-2">
|
<label for="routePriority" class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">
|
||||||
Priority (1-100)
|
Priority (1-100)
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -478,16 +478,16 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
min="1"
|
min="1"
|
||||||
max="100"
|
max="100"
|
||||||
placeholder="50"
|
placeholder="50"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<p class="text-sm text-gray-500 mt-1">
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">
|
||||||
Higher priority routes are processed first (default: 50)
|
Higher priority routes are processed first (default: 50)
|
||||||
</p>
|
</p>
|
||||||
@error('routePriority') <p class="text-red-600 text-sm mt-1">{{ $message }}</p> @enderror
|
@error('routePriority') <p class="text-red-600 text-sm mt-1 dark:text-red-400">{{ $message }}</p> @enderror
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-between">
|
<div class="flex justify-between">
|
||||||
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200">
|
<button type="button" wire:click="previousStep" class="px-4 py-2 text-gray-600 hover:text-gray-800 transition duration-200 dark:text-gray-300">
|
||||||
← Back
|
← Back
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|
@ -511,8 +511,8 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 13l4 4L19 7"></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<h1 class="text-3xl font-bold text-gray-900 mb-2">Setup Complete!</h1>
|
<h1 class="text-3xl font-bold text-gray-900 mb-2 dark:text-gray-100">Setup Complete!</h1>
|
||||||
<p class="text-gray-600 mb-6">
|
<p class="text-gray-600 mb-6 dark:text-gray-300">
|
||||||
Great! You've successfully configured FFR. Your feeds will now be monitored and articles will be automatically posted to your configured channels.
|
Great! You've successfully configured FFR. Your feeds will now be monitored and articles will be automatically posted to your configured channels.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -526,18 +526,18 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="space-y-4 mb-8">
|
<div class="space-y-4 mb-8">
|
||||||
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4">
|
<div class="bg-blue-50 border border-blue-200 rounded-lg p-4 dark:bg-blue-900/20 dark:border-blue-800">
|
||||||
<h3 class="font-semibold text-blue-900 mb-2">What happens next?</h3>
|
<h3 class="font-semibold text-blue-900 mb-2">What happens next?</h3>
|
||||||
<ul class="text-sm text-blue-800 space-y-1 text-left">
|
<ul class="text-sm text-blue-800 space-y-1 text-left dark:text-blue-300">
|
||||||
<li>• Your feeds will be checked regularly for new articles</li>
|
<li>• Your feeds will be checked regularly for new articles</li>
|
||||||
<li>• New articles will be automatically posted to your channels</li>
|
<li>• New articles will be automatically posted to your channels</li>
|
||||||
<li>• You can monitor activity in the Articles and other sections</li>
|
<li>• You can monitor activity in the Articles and other sections</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
|
<div class="bg-yellow-50 border border-yellow-200 rounded-lg p-4 dark:bg-yellow-900/20 dark:border-yellow-800">
|
||||||
<h3 class="font-semibold text-yellow-900 mb-2">Want more control?</h3>
|
<h3 class="font-semibold text-yellow-900 mb-2">Want more control?</h3>
|
||||||
<p class="text-sm text-yellow-800 text-left mb-2">
|
<p class="text-sm text-yellow-800 text-left mb-2 dark:text-yellow-300">
|
||||||
You can add more feeds, channels, and configure settings from the dashboard.
|
You can add more feeds, channels, and configure settings from the dashboard.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -552,7 +552,7 @@ class="w-full bg-blue-600 text-white py-3 px-4 rounded-md hover:bg-blue-700 tran
|
||||||
{{ $isLoading ? 'Finishing...' : 'Go to Dashboard' }}
|
{{ $isLoading ? 'Finishing...' : 'Go to Dashboard' }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="text-sm text-gray-500">
|
<div class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
<a href="{{ route('articles') }}" class="hover:text-blue-600">View Articles</a>
|
<a href="{{ route('articles') }}" class="hover:text-blue-600">View Articles</a>
|
||||||
•
|
•
|
||||||
<a href="{{ route('feeds') }}" class="hover:text-blue-600">Manage Feeds</a>
|
<a href="{{ route('feeds') }}" class="hover:text-blue-600">Manage Feeds</a>
|
||||||
|
|
|
||||||
|
|
@ -13,22 +13,22 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
@forelse ($routes as $route)
|
@forelse ($routes as $route)
|
||||||
<div class="bg-white rounded-lg shadow-sm p-6" wire:key="route-{{ $route->feed_id }}-{{ $route->platform_channel_id }}">
|
<div class="bg-white rounded-lg shadow-sm p-6 dark:bg-gray-800" wire:key="route-{{ $route->feed_id }}-{{ $route->platform_channel_id }}">
|
||||||
<div class="flex items-start justify-between">
|
<div class="flex items-start justify-between">
|
||||||
<div class="flex-1 min-w-0">
|
<div class="flex-1 min-w-0">
|
||||||
<div class="flex items-center space-x-3 mb-2">
|
<div class="flex items-center space-x-3 mb-2">
|
||||||
<h3 class="text-lg font-medium text-gray-900">
|
<h3 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||||
{{ $route->feed?->name }} → {{ $route->platformChannel?->display_name ?? $route->platformChannel?->name }}
|
{{ $route->feed?->name }} → {{ $route->platformChannel?->display_name ?? $route->platformChannel?->name }}
|
||||||
</h3>
|
</h3>
|
||||||
@if ($route->is_active)
|
@if ($route->is_active)
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300">
|
||||||
<svg class="h-3 w-3 mr-1" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-3 w-3 mr-1" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
</svg>
|
</svg>
|
||||||
Active
|
Active
|
||||||
</span>
|
</span>
|
||||||
@else
|
@else
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-300">
|
||||||
<svg class="h-3 w-3 mr-1" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-3 w-3 mr-1" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="m9.75 9.75 4.5 4.5m0-4.5-4.5 4.5M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
||||||
</svg>
|
</svg>
|
||||||
|
|
@ -36,7 +36,7 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
|
||||||
</span>
|
</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center space-x-4 text-sm text-gray-600">
|
<div class="flex items-center space-x-4 text-sm text-gray-600 dark:text-gray-300">
|
||||||
<span>Priority: {{ $route->priority }}</span>
|
<span>Priority: {{ $route->priority }}</span>
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span>Feed: {{ $route->feed?->name }}</span>
|
<span>Feed: {{ $route->feed?->name }}</span>
|
||||||
|
|
@ -46,36 +46,36 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
|
||||||
<span>Created: {{ $route->created_at->format('M d, Y') }}</span>
|
<span>Created: {{ $route->created_at->format('M d, Y') }}</span>
|
||||||
@if ($route->auto_approve === true)
|
@if ($route->auto_approve === true)
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span class="text-green-600">Auto-approve: On</span>
|
<span class="text-green-600 dark:text-green-400">Auto-approve: On</span>
|
||||||
@elseif ($route->auto_approve === false)
|
@elseif ($route->auto_approve === false)
|
||||||
<span>•</span>
|
<span>•</span>
|
||||||
<span class="text-red-600">Auto-approve: Off</span>
|
<span class="text-red-600 dark:text-red-400">Auto-approve: Off</span>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
@if ($route->platformChannel?->description)
|
@if ($route->platformChannel?->description)
|
||||||
<p class="mt-2 text-sm text-gray-500">
|
<p class="mt-2 text-sm text-gray-500 dark:text-gray-400">
|
||||||
{{ $route->platformChannel->description }}
|
{{ $route->platformChannel->description }}
|
||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
@if ($route->keywords->isNotEmpty())
|
@if ($route->keywords->isNotEmpty())
|
||||||
<div class="mt-3">
|
<div class="mt-3">
|
||||||
<div class="flex items-center space-x-2 mb-2">
|
<div class="flex items-center space-x-2 mb-2">
|
||||||
<svg class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4 text-gray-500 dark:text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z" />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-sm font-medium text-gray-700">Keywords</span>
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Keywords</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-wrap gap-2">
|
<div class="flex flex-wrap gap-2">
|
||||||
@foreach ($route->keywords as $keyword)
|
@foreach ($route->keywords as $keyword)
|
||||||
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $keyword->is_active ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 text-gray-500' }}">
|
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium {{ $keyword->is_active ? 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300' : 'bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-400' }}">
|
||||||
{{ $keyword->keyword }}
|
{{ $keyword->keyword }}
|
||||||
</span>
|
</span>
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
<div class="mt-3 text-sm text-gray-400 italic">
|
<div class="mt-3 text-sm text-gray-400 italic dark:text-gray-500">
|
||||||
No keyword filters - matches all articles
|
No keyword filters - matches all articles
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -83,7 +83,7 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
|
||||||
<div class="flex items-center space-x-2 ml-4">
|
<div class="flex items-center space-x-2 ml-4">
|
||||||
<button
|
<button
|
||||||
wire:click="openEditModal({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
|
wire:click="openEditModal({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
|
||||||
class="p-2 text-gray-400 hover:text-gray-600 rounded-md"
|
class="p-2 text-gray-400 hover:text-gray-600 rounded-md dark:text-gray-500 dark:hover:text-gray-300"
|
||||||
title="Edit route"
|
title="Edit route"
|
||||||
>
|
>
|
||||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -92,11 +92,11 @@ class="p-2 text-gray-400 hover:text-gray-600 rounded-md"
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
wire:click="toggle({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
|
wire:click="toggle({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
|
||||||
class="p-2 text-gray-400 hover:text-gray-600 rounded-md"
|
class="p-2 text-gray-400 hover:text-gray-600 rounded-md dark:text-gray-500 dark:hover:text-gray-300"
|
||||||
title="{{ $route->is_active ? 'Deactivate route' : 'Activate route' }}"
|
title="{{ $route->is_active ? 'Deactivate route' : 'Activate route' }}"
|
||||||
>
|
>
|
||||||
@if ($route->is_active)
|
@if ($route->is_active)
|
||||||
<svg class="h-4 w-4 text-green-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4 text-green-600 dark:text-green-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M5.636 5.636a9 9 0 1 0 12.728 0M12 3v9" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M5.636 5.636a9 9 0 1 0 12.728 0M12 3v9" />
|
||||||
</svg>
|
</svg>
|
||||||
@else
|
@else
|
||||||
|
|
@ -108,7 +108,7 @@ class="p-2 text-gray-400 hover:text-gray-600 rounded-md"
|
||||||
<button
|
<button
|
||||||
wire:click="delete({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
|
wire:click="delete({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
|
||||||
wire:confirm="Are you sure you want to delete this route?"
|
wire:confirm="Are you sure you want to delete this route?"
|
||||||
class="p-2 text-gray-400 hover:text-red-600 rounded-md"
|
class="p-2 text-gray-400 hover:text-red-600 rounded-md dark:text-gray-500"
|
||||||
title="Delete route"
|
title="Delete route"
|
||||||
>
|
>
|
||||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -120,11 +120,11 @@ class="p-2 text-gray-400 hover:text-red-600 rounded-md"
|
||||||
</div>
|
</div>
|
||||||
@empty
|
@empty
|
||||||
<div class="text-center py-12">
|
<div class="text-center py-12">
|
||||||
<svg class="mx-auto h-12 w-12 text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="mx-auto h-12 w-12 text-gray-400 dark:text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M13.5 6H5.25A2.25 2.25 0 0 0 3 8.25v10.5A2.25 2.25 0 0 0 5.25 21h10.5A2.25 2.25 0 0 0 18 18.75V10.5m-10.5 6L21 3m0 0h-5.25M21 3v5.25" />
|
||||||
</svg>
|
</svg>
|
||||||
<h3 class="mt-2 text-sm font-medium text-gray-900">No routes</h3>
|
<h3 class="mt-2 text-sm font-medium text-gray-900 dark:text-gray-100">No routes</h3>
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
Get started by creating a new route to connect feeds with channels.
|
Get started by creating a new route to connect feeds with channels.
|
||||||
</p>
|
</p>
|
||||||
<div class="mt-6">
|
<div class="mt-6">
|
||||||
|
|
@ -147,13 +147,13 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
|
||||||
<x-form-modal title="Create New Route" close="closeCreateModal">
|
<x-form-modal title="Create New Route" close="closeCreateModal">
|
||||||
<form wire:submit="createRoute" class="space-y-4">
|
<form wire:submit="createRoute" class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label for="newFeedId" class="block text-sm font-medium text-gray-700 mb-1">
|
<label for="newFeedId" class="block text-sm font-medium text-gray-700 mb-1 dark:text-gray-200">
|
||||||
Feed
|
Feed
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="newFeedId"
|
id="newFeedId"
|
||||||
wire:model="newFeedId"
|
wire:model="newFeedId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select a feed</option>
|
<option value="">Select a feed</option>
|
||||||
|
|
@ -165,13 +165,13 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="newChannelId" class="block text-sm font-medium text-gray-700 mb-1">
|
<label for="newChannelId" class="block text-sm font-medium text-gray-700 mb-1 dark:text-gray-200">
|
||||||
Channel
|
Channel
|
||||||
</label>
|
</label>
|
||||||
<select
|
<select
|
||||||
id="newChannelId"
|
id="newChannelId"
|
||||||
wire:model="newChannelId"
|
wire:model="newChannelId"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
required
|
required
|
||||||
>
|
>
|
||||||
<option value="">Select a channel</option>
|
<option value="">Select a channel</option>
|
||||||
|
|
@ -183,7 +183,7 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label for="newPriority" class="block text-sm font-medium text-gray-700 mb-1">
|
<label for="newPriority" class="block text-sm font-medium text-gray-700 mb-1 dark:text-gray-200">
|
||||||
Priority
|
Priority
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -191,16 +191,16 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
|
||||||
id="newPriority"
|
id="newPriority"
|
||||||
wire:model="newPriority"
|
wire:model="newPriority"
|
||||||
min="0"
|
min="0"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<p class="text-sm text-gray-500 mt-1">Higher priority routes are processed first</p>
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">Higher priority routes are processed first</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="flex justify-end space-x-3 pt-4">
|
<div class="flex justify-end space-x-3 pt-4">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="closeCreateModal"
|
wire:click="closeCreateModal"
|
||||||
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50"
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 dark:text-gray-200 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700/50"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -218,18 +218,18 @@ class="px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transp
|
||||||
<!-- Edit Route Modal -->
|
<!-- Edit Route Modal -->
|
||||||
@if ($editingRoute)
|
@if ($editingRoute)
|
||||||
<x-form-modal title="Edit Route" close="closeEditModal">
|
<x-form-modal title="Edit Route" close="closeEditModal">
|
||||||
<div class="mb-4 p-3 bg-gray-50 rounded-md">
|
<div class="mb-4 p-3 bg-gray-50 rounded-md dark:bg-gray-900">
|
||||||
<p class="text-sm text-gray-600">
|
<p class="text-sm text-gray-600 dark:text-gray-300">
|
||||||
<strong>Feed:</strong> {{ $editingRoute->feed?->name }}
|
<strong>Feed:</strong> {{ $editingRoute->feed?->name }}
|
||||||
</p>
|
</p>
|
||||||
<p class="text-sm text-gray-600">
|
<p class="text-sm text-gray-600 dark:text-gray-300">
|
||||||
<strong>{{ $editingRoute->platformChannel?->platformInstance?->platform?->channelLabel() ?? 'Channel' }}:</strong> {{ $editingRoute->platformChannel?->display_name ?? $editingRoute->platformChannel?->name }}
|
<strong>{{ $editingRoute->platformChannel?->platformInstance?->platform?->channelLabel() ?? 'Channel' }}:</strong> {{ $editingRoute->platformChannel?->display_name ?? $editingRoute->platformChannel?->name }}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form wire:submit="updateRoute" class="space-y-4">
|
<form wire:submit="updateRoute" class="space-y-4">
|
||||||
<div>
|
<div>
|
||||||
<label for="editPriority" class="block text-sm font-medium text-gray-700 mb-1">
|
<label for="editPriority" class="block text-sm font-medium text-gray-700 mb-1 dark:text-gray-200">
|
||||||
Priority
|
Priority
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
|
|
@ -237,43 +237,43 @@ class="px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transp
|
||||||
id="editPriority"
|
id="editPriority"
|
||||||
wire:model="editPriority"
|
wire:model="editPriority"
|
||||||
min="0"
|
min="0"
|
||||||
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
>
|
>
|
||||||
<p class="text-sm text-gray-500 mt-1">Higher priority routes are processed first</p>
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">Higher priority routes are processed first</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Auto-approve -->
|
<!-- Auto-approve -->
|
||||||
<div>
|
<div>
|
||||||
<label class="block text-sm font-medium text-gray-700 mb-2">Auto-approve</label>
|
<label class="block text-sm font-medium text-gray-700 mb-2 dark:text-gray-200">Auto-approve</label>
|
||||||
<div class="flex items-center space-x-4">
|
<div class="flex items-center space-x-4">
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="" class="text-blue-600 focus:ring-blue-500">
|
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="" class="text-blue-600 focus:ring-blue-500 dark:text-blue-400">
|
||||||
<span class="ml-2 text-sm text-gray-700">Use global setting</span>
|
<span class="ml-2 text-sm text-gray-700 dark:text-gray-200">Use global setting</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="1" class="text-blue-600 focus:ring-blue-500">
|
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="1" class="text-blue-600 focus:ring-blue-500 dark:text-blue-400">
|
||||||
<span class="ml-2 text-sm text-gray-700">On</span>
|
<span class="ml-2 text-sm text-gray-700 dark:text-gray-200">On</span>
|
||||||
</label>
|
</label>
|
||||||
<label class="inline-flex items-center">
|
<label class="inline-flex items-center">
|
||||||
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="0" class="text-blue-600 focus:ring-blue-500">
|
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="0" class="text-blue-600 focus:ring-blue-500 dark:text-blue-400">
|
||||||
<span class="ml-2 text-sm text-gray-700">Off</span>
|
<span class="ml-2 text-sm text-gray-700 dark:text-gray-200">Off</span>
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-sm text-gray-500 mt-1">Override global approval setting for this route</p>
|
<p class="text-sm text-gray-500 mt-1 dark:text-gray-400">Override global approval setting for this route</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Keyword Management -->
|
<!-- Keyword Management -->
|
||||||
<div class="border-t pt-4">
|
<div class="border-t pt-4">
|
||||||
<div class="flex items-center space-x-2 mb-3">
|
<div class="flex items-center space-x-2 mb-3">
|
||||||
<svg class="h-4 w-4 text-gray-500" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4 text-gray-500 dark:text-gray-400" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9.568 3H5.25A2.25 2.25 0 0 0 3 5.25v4.318c0 .597.237 1.17.659 1.591l9.581 9.581c.699.699 1.78.872 2.607.33a18.095 18.095 0 0 0 5.223-5.223c.542-.827.369-1.908-.33-2.607L11.16 3.66A2.25 2.25 0 0 0 9.568 3Z" />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M6 6h.008v.008H6V6Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<span class="text-sm font-medium text-gray-700">Keywords</span>
|
<span class="text-sm font-medium text-gray-700 dark:text-gray-200">Keywords</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="$set('showKeywordInput', true)"
|
wire:click="$set('showKeywordInput', true)"
|
||||||
class="inline-flex items-center p-1 text-gray-400 hover:text-gray-600 rounded-sm"
|
class="inline-flex items-center p-1 text-gray-400 hover:text-gray-600 rounded-sm dark:text-gray-500 dark:hover:text-gray-300"
|
||||||
title="Add keyword"
|
title="Add keyword"
|
||||||
>
|
>
|
||||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -289,7 +289,7 @@ class="inline-flex items-center p-1 text-gray-400 hover:text-gray-600 rounded-sm
|
||||||
wire:model="newKeyword"
|
wire:model="newKeyword"
|
||||||
wire:keydown.enter.prevent="addKeyword"
|
wire:keydown.enter.prevent="addKeyword"
|
||||||
placeholder="Enter keyword..."
|
placeholder="Enter keyword..."
|
||||||
class="flex-1 px-2 py-1 border border-gray-300 rounded-sm text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500"
|
class="flex-1 px-2 py-1 border border-gray-300 rounded-sm text-sm focus:outline-hidden focus:ring-2 focus:ring-blue-500 dark:border-gray-600"
|
||||||
autofocus
|
autofocus
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
|
|
@ -302,7 +302,7 @@ class="px-3 py-1 bg-blue-600 text-white text-sm rounded-sm hover:bg-blue-700"
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="$set('showKeywordInput', false)"
|
wire:click="$set('showKeywordInput', false)"
|
||||||
class="px-3 py-1 bg-gray-200 text-gray-700 text-sm rounded-sm hover:bg-gray-300"
|
class="px-3 py-1 bg-gray-200 text-gray-700 text-sm rounded-sm hover:bg-gray-300 dark:bg-gray-700 dark:text-gray-200"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
@ -312,12 +312,12 @@ class="px-3 py-1 bg-gray-200 text-gray-700 text-sm rounded-sm hover:bg-gray-300"
|
||||||
@if ($editingKeywords->isNotEmpty())
|
@if ($editingKeywords->isNotEmpty())
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
@foreach ($editingKeywords as $keyword)
|
@foreach ($editingKeywords as $keyword)
|
||||||
<div class="flex items-center justify-between px-3 py-2 rounded-sm border {{ $keyword->is_active ? 'border-blue-200 bg-blue-50' : 'border-gray-200 bg-gray-50' }}">
|
<div class="flex items-center justify-between px-3 py-2 rounded-sm border {{ $keyword->is_active ? 'border-blue-200 bg-blue-50 dark:border-blue-800 dark:bg-blue-900/20' : 'border-gray-200 bg-gray-50 dark:border-gray-700 dark:bg-gray-900/40' }}">
|
||||||
<div class="flex items-center space-x-2">
|
<div class="flex items-center space-x-2">
|
||||||
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium {{ $keyword->is_active ? 'bg-blue-100 text-blue-800' : 'bg-gray-100 text-gray-500' }}">
|
<span class="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium {{ $keyword->is_active ? 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300' : 'bg-gray-100 text-gray-500 dark:bg-gray-700 dark:text-gray-400' }}">
|
||||||
{{ $keyword->keyword }}
|
{{ $keyword->keyword }}
|
||||||
</span>
|
</span>
|
||||||
<span class="text-xs text-gray-500">
|
<span class="text-xs text-gray-500 dark:text-gray-400">
|
||||||
{{ $keyword->is_active ? 'Active' : 'Inactive' }}
|
{{ $keyword->is_active ? 'Active' : 'Inactive' }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -325,7 +325,7 @@ class="px-3 py-1 bg-gray-200 text-gray-700 text-sm rounded-sm hover:bg-gray-300"
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="toggleKeyword({{ $keyword->id }})"
|
wire:click="toggleKeyword({{ $keyword->id }})"
|
||||||
class="text-sm text-blue-600 hover:text-blue-800"
|
class="text-sm text-blue-600 hover:text-blue-800 dark:text-blue-400"
|
||||||
title="{{ $keyword->is_active ? 'Deactivate keyword' : 'Activate keyword' }}"
|
title="{{ $keyword->is_active ? 'Deactivate keyword' : 'Activate keyword' }}"
|
||||||
>
|
>
|
||||||
{{ $keyword->is_active ? 'Deactivate' : 'Activate' }}
|
{{ $keyword->is_active ? 'Deactivate' : 'Activate' }}
|
||||||
|
|
@ -334,7 +334,7 @@ class="text-sm text-blue-600 hover:text-blue-800"
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="deleteKeyword({{ $keyword->id }})"
|
wire:click="deleteKeyword({{ $keyword->id }})"
|
||||||
wire:confirm="Are you sure you want to delete this keyword?"
|
wire:confirm="Are you sure you want to delete this keyword?"
|
||||||
class="text-red-600 hover:text-red-800"
|
class="text-red-600 hover:text-red-800 dark:text-red-400"
|
||||||
title="Delete keyword"
|
title="Delete keyword"
|
||||||
>
|
>
|
||||||
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
|
|
@ -347,7 +347,7 @@ class="text-red-600 hover:text-red-800"
|
||||||
</div>
|
</div>
|
||||||
@else
|
@else
|
||||||
@if (!$showKeywordInput)
|
@if (!$showKeywordInput)
|
||||||
<div class="text-sm text-gray-500 italic p-2 border border-gray-200 rounded-sm">
|
<div class="text-sm text-gray-500 italic p-2 border border-gray-200 rounded-sm dark:text-gray-400 dark:border-gray-700">
|
||||||
No keywords defined. This route will match all articles.
|
No keywords defined. This route will match all articles.
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -358,7 +358,7 @@ class="text-red-600 hover:text-red-800"
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
wire:click="closeEditModal"
|
wire:click="closeEditModal"
|
||||||
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50"
|
class="px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-md hover:bg-gray-50 dark:text-gray-200 dark:bg-gray-800 dark:border-gray-600 dark:hover:bg-gray-700/50"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -3,26 +3,26 @@
|
||||||
|
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<!-- Article Processing Settings -->
|
<!-- Article Processing Settings -->
|
||||||
<div class="bg-white rounded-lg shadow-sm">
|
<div class="bg-white rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="px-6 py-4 border-b border-gray-200">
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h2 class="text-lg font-medium text-gray-900 flex items-center">
|
<h2 class="text-lg font-medium text-gray-900 flex items-center dark:text-gray-100">
|
||||||
<svg class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M9.594 3.94c.09-.542.56-.94 1.11-.94h2.593c.55 0 1.02.398 1.11.94l.213 1.281c.063.374.313.686.645.87.074.04.147.083.22.127.325.196.72.257 1.075.124l1.217-.456a1.125 1.125 0 0 1 1.37.49l1.296 2.247a1.125 1.125 0 0 1-.26 1.431l-1.003.827c-.293.241-.438.613-.43.992a7.723 7.723 0 0 1 0 .255c-.008.378.137.75.43.991l1.004.827c.424.35.534.955.26 1.43l-1.298 2.247a1.125 1.125 0 0 1-1.369.491l-1.217-.456c-.355-.133-.75-.072-1.076.124a6.47 6.47 0 0 1-.22.128c-.331.183-.581.495-.644.869l-.213 1.281c-.09.543-.56.94-1.11.94h-2.594c-.55 0-1.019-.398-1.11-.94l-.213-1.281c-.062-.374-.312-.686-.644-.87a6.52 6.52 0 0 1-.22-.127c-.325-.196-.72-.257-1.076-.124l-1.217.456a1.125 1.125 0 0 1-1.369-.49l-1.297-2.247a1.125 1.125 0 0 1 .26-1.431l1.004-.827c.292-.24.437-.613.43-.991a6.932 6.932 0 0 1 0-.255c.007-.38-.138-.751-.43-.992l-1.004-.827a1.125 1.125 0 0 1-.26-1.43l1.297-2.247a1.125 1.125 0 0 1 1.37-.491l1.216.456c.356.133.751.072 1.076-.124.072-.044.146-.086.22-.128.332-.183.582-.495.644-.869l.214-1.28Z" />
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" />
|
||||||
</svg>
|
</svg>
|
||||||
Article Processing
|
Article Processing
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
Control how articles are processed and handled
|
Control how articles are processed and handled
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-6 py-4 space-y-4">
|
<div class="px-6 py-4 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-medium text-gray-900">
|
<h3 class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
Article Processing Enabled
|
Article Processing Enabled
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
Enable automatic fetching and processing of articles from feeds
|
Enable automatic fetching and processing of articles from feeds
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -44,10 +44,10 @@ class="shrink-0"
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-medium text-gray-900">
|
<h3 class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
Publishing Interval (minutes)
|
Publishing Interval (minutes)
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
Minimum time between publishing articles. Set to 0 for no delay.
|
Minimum time between publishing articles. Set to 0 for no delay.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -58,7 +58,7 @@ class="shrink-0"
|
||||||
min="0"
|
min="0"
|
||||||
max="1440"
|
max="1440"
|
||||||
step="1"
|
step="1"
|
||||||
class="w-24 rounded-md border border-gray-300 px-3 py-2 shadow-xs focus:border-indigo-500 focus:ring-indigo-500 text-sm"
|
class="w-24 rounded-md border border-gray-300 px-3 py-2 shadow-xs focus:border-indigo-500 focus:ring-indigo-500 text-sm dark:border-gray-600"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
wire:click="updateArticlePublishingInterval"
|
wire:click="updateArticlePublishingInterval"
|
||||||
|
|
@ -69,15 +69,15 @@ class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@error('articlePublishingInterval')
|
@error('articlePublishingInterval')
|
||||||
<p class="text-sm text-red-600">{{ $message }}</p>
|
<p class="text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||||||
@enderror
|
@enderror
|
||||||
|
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-medium text-gray-900">
|
<h3 class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
Publishing Approvals Required
|
Publishing Approvals Required
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
Require manual approval before articles are published to platforms
|
Require manual approval before articles are published to platforms
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -100,25 +100,25 @@ class="shrink-0"
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Feed Monitoring Settings -->
|
<!-- Feed Monitoring Settings -->
|
||||||
<div class="bg-white rounded-lg shadow-sm">
|
<div class="bg-white rounded-lg shadow-sm dark:bg-gray-800">
|
||||||
<div class="px-6 py-4 border-b border-gray-200">
|
<div class="px-6 py-4 border-b border-gray-200 dark:border-gray-700">
|
||||||
<h2 class="text-lg font-medium text-gray-900 flex items-center">
|
<h2 class="text-lg font-medium text-gray-900 flex items-center dark:text-gray-100">
|
||||||
<svg class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
<svg class="h-5 w-5 mr-2" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
|
||||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
|
<path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3.75m-9.303 3.376c-.866 1.5.217 3.374 1.948 3.374h14.71c1.73 0 2.813-1.874 1.948-3.374L13.949 3.378c-.866-1.5-3.032-1.5-3.898 0L2.697 16.126ZM12 15.75h.007v.008H12v-.008Z" />
|
||||||
</svg>
|
</svg>
|
||||||
Feed Monitoring
|
Feed Monitoring
|
||||||
</h2>
|
</h2>
|
||||||
<p class="mt-1 text-sm text-gray-500">
|
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">
|
||||||
Configure alerts for feeds that stop returning articles
|
Configure alerts for feeds that stop returning articles
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="px-6 py-4 space-y-4">
|
<div class="px-6 py-4 space-y-4">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<h3 class="text-sm font-medium text-gray-900">
|
<h3 class="text-sm font-medium text-gray-900 dark:text-gray-100">
|
||||||
Staleness Threshold (hours)
|
Staleness Threshold (hours)
|
||||||
</h3>
|
</h3>
|
||||||
<p class="text-sm text-gray-500">
|
<p class="text-sm text-gray-500 dark:text-gray-400">
|
||||||
Alert when a feed hasn't been fetched for this many hours. Set to 0 to disable.
|
Alert when a feed hasn't been fetched for this many hours. Set to 0 to disable.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -128,7 +128,7 @@ class="shrink-0"
|
||||||
wire:model="feedStalenessThreshold"
|
wire:model="feedStalenessThreshold"
|
||||||
min="0"
|
min="0"
|
||||||
step="1"
|
step="1"
|
||||||
class="w-24 rounded-md border border-gray-300 px-3 py-2 shadow-xs focus:border-indigo-500 focus:ring-indigo-500 text-sm"
|
class="w-24 rounded-md border border-gray-300 px-3 py-2 shadow-xs focus:border-indigo-500 focus:ring-indigo-500 text-sm dark:border-gray-600"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
wire:click="updateFeedStalenessThreshold"
|
wire:click="updateFeedStalenessThreshold"
|
||||||
|
|
@ -139,21 +139,21 @@ class="inline-flex items-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@error('feedStalenessThreshold')
|
@error('feedStalenessThreshold')
|
||||||
<p class="text-sm text-red-600">{{ $message }}</p>
|
<p class="text-sm text-red-600 dark:text-red-400">{{ $message }}</p>
|
||||||
@enderror
|
@enderror
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Status Messages -->
|
<!-- Status Messages -->
|
||||||
@if ($successMessage)
|
@if ($successMessage)
|
||||||
<div class="bg-green-50 border border-green-200 rounded-md p-4">
|
<div class="bg-green-50 border border-green-200 rounded-md p-4 dark:bg-green-900/20 dark:border-green-800">
|
||||||
<p class="text-green-600 text-sm">{{ $successMessage }}</p>
|
<p class="text-green-600 text-sm dark:text-green-400">{{ $successMessage }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
@if ($errorMessage)
|
@if ($errorMessage)
|
||||||
<div class="bg-red-50 border border-red-200 rounded-md p-4">
|
<div class="bg-red-50 border border-red-200 rounded-md p-4 dark:bg-red-900/20 dark:border-red-800">
|
||||||
<p class="text-red-600 text-sm">{{ $errorMessage }}</p>
|
<p class="text-red-600 text-sm dark:text-red-400">{{ $errorMessage }}</p>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
<x-app-layout>
|
<x-app-layout>
|
||||||
<x-slot name="header">
|
<x-slot name="header">
|
||||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
<h2 class="font-semibold text-xl text-gray-800 leading-tight dark:text-gray-100">
|
||||||
{{ __('Profile') }}
|
{{ __('Profile') }}
|
||||||
</h2>
|
</h2>
|
||||||
</x-slot>
|
</x-slot>
|
||||||
|
|
||||||
<div class="py-12">
|
<div class="py-12">
|
||||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
|
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
|
||||||
<div class="p-4 sm:p-8 bg-white shadow-sm sm:rounded-lg">
|
<div class="p-4 sm:p-8 bg-white shadow-sm sm:rounded-lg dark:bg-gray-800">
|
||||||
<div class="max-w-xl">
|
<div class="max-w-xl">
|
||||||
@include('profile.partials.update-profile-information-form')
|
@include('profile.partials.update-profile-information-form')
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4 sm:p-8 bg-white shadow-sm sm:rounded-lg">
|
<div class="p-4 sm:p-8 bg-white shadow-sm sm:rounded-lg dark:bg-gray-800">
|
||||||
<div class="max-w-xl">
|
<div class="max-w-xl">
|
||||||
@include('profile.partials.update-password-form')
|
@include('profile.partials.update-password-form')
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="p-4 sm:p-8 bg-white shadow-sm sm:rounded-lg">
|
<div class="p-4 sm:p-8 bg-white shadow-sm sm:rounded-lg dark:bg-gray-800">
|
||||||
<div class="max-w-xl">
|
<div class="max-w-xl">
|
||||||
@include('profile.partials.delete-user-form')
|
@include('profile.partials.delete-user-form')
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<section class="space-y-6">
|
<section class="space-y-6">
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-lg font-medium text-gray-900">
|
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||||
{{ __('Delete Account') }}
|
{{ __('Delete Account') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="mt-1 text-sm text-gray-600">
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }}
|
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Before deleting your account, please download any data or information that you wish to retain.') }}
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -19,11 +19,11 @@
|
||||||
@csrf
|
@csrf
|
||||||
@method('delete')
|
@method('delete')
|
||||||
|
|
||||||
<h2 class="text-lg font-medium text-gray-900">
|
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||||
{{ __('Are you sure you want to delete your account?') }}
|
{{ __('Are you sure you want to delete your account?') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="mt-1 text-sm text-gray-600">
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
|
{{ __('Once your account is deleted, all of its resources and data will be permanently deleted. Please enter your password to confirm you would like to permanently delete your account.') }}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<section>
|
<section>
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-lg font-medium text-gray-900">
|
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||||
{{ __('Update Password') }}
|
{{ __('Update Password') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="mt-1 text-sm text-gray-600">
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __('Ensure your account is using a long, random password to stay secure.') }}
|
{{ __('Ensure your account is using a long, random password to stay secure.') }}
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -40,7 +40,7 @@
|
||||||
x-show="show"
|
x-show="show"
|
||||||
x-transition
|
x-transition
|
||||||
x-init="setTimeout(() => show = false, 2000)"
|
x-init="setTimeout(() => show = false, 2000)"
|
||||||
class="text-sm text-gray-600"
|
class="text-sm text-gray-600 dark:text-gray-300"
|
||||||
>{{ __('Saved.') }}</p>
|
>{{ __('Saved.') }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
<section>
|
<section>
|
||||||
<header>
|
<header>
|
||||||
<h2 class="text-lg font-medium text-gray-900">
|
<h2 class="text-lg font-medium text-gray-900 dark:text-gray-100">
|
||||||
{{ __('Profile Information') }}
|
{{ __('Profile Information') }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p class="mt-1 text-sm text-gray-600">
|
<p class="mt-1 text-sm text-gray-600 dark:text-gray-300">
|
||||||
{{ __("Update your account's profile information and email address.") }}
|
{{ __("Update your account's profile information and email address.") }}
|
||||||
</p>
|
</p>
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -30,16 +30,16 @@
|
||||||
|
|
||||||
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
|
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
|
||||||
<div>
|
<div>
|
||||||
<p class="text-sm mt-2 text-gray-800">
|
<p class="text-sm mt-2 text-gray-800 dark:text-gray-100">
|
||||||
{{ __('Your email address is unverified.') }}
|
{{ __('Your email address is unverified.') }}
|
||||||
|
|
||||||
<button form="send-verification" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
|
<button form="send-verification" class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-hidden focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 dark:text-gray-300 dark:hover:text-gray-100">
|
||||||
{{ __('Click here to re-send the verification email.') }}
|
{{ __('Click here to re-send the verification email.') }}
|
||||||
</button>
|
</button>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
@if (session('status') === 'verification-link-sent')
|
@if (session('status') === 'verification-link-sent')
|
||||||
<p class="mt-2 font-medium text-sm text-green-600">
|
<p class="mt-2 font-medium text-sm text-green-600 dark:text-green-400">
|
||||||
{{ __('A new verification link has been sent to your email address.') }}
|
{{ __('A new verification link has been sent to your email address.') }}
|
||||||
</p>
|
</p>
|
||||||
@endif
|
@endif
|
||||||
|
|
@ -56,7 +56,7 @@
|
||||||
x-show="show"
|
x-show="show"
|
||||||
x-transition
|
x-transition
|
||||||
x-init="setTimeout(() => show = false, 2000)"
|
x-init="setTimeout(() => show = false, 2000)"
|
||||||
class="text-sm text-gray-600"
|
class="text-sm text-gray-600 dark:text-gray-300"
|
||||||
>{{ __('Saved.') }}</p>
|
>{{ __('Saved.') }}</p>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -321,7 +321,7 @@ public function test_pending_feed_badge_shows_total_count_not_page_count(): void
|
||||||
|
|
||||||
$html = (string) preg_replace('/\s+/', ' ', Livewire::test(Articles::class)->html());
|
$html = (string) preg_replace('/\s+/', ' ', Livewire::test(Articles::class)->html());
|
||||||
|
|
||||||
$this->assertStringContainsString('VRT News</span> <span class="ml-auto inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium bg-yellow-100 text-yellow-800"> 20 </span>', $html);
|
$this->assertMatchesRegularExpression('#VRT News</span> <span class="ml-auto[^"]*"> 20 </span>#', $html);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function test_expanding_a_feed_reveals_only_that_feeds_articles(): void
|
public function test_expanding_a_feed_reveals_only_that_feeds_articles(): void
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue