88 - Add dark theme with toggle and remove dead Breeze navigation

This commit is contained in:
myrmidex 2026-08-10 19:40:22 +02:00
parent 0626a546c9
commit 6a9d909525
41 changed files with 443 additions and 532 deletions

View file

@ -1,2 +1,32 @@
@import 'tailwindcss';
@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);
}
}

View file

@ -1,5 +1,5 @@
<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.') }}
</div>

View file

@ -1,5 +1,5 @@
<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.') }}
</div>

View file

@ -1,7 +1,7 @@
<x-guest-layout>
<div class="mb-6 text-center">
<h2 class="text-2xl font-bold text-gray-900">Welcome back</h2>
<p class="mt-1 text-sm text-gray-500">Sign in to your account</p>
<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 dark:text-gray-400">Sign in to your account</p>
</div>
<!-- Session Status -->
@ -32,8 +32,8 @@
<!-- Remember Me -->
<div class="block mt-4">
<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">
<span class="ms-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
<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 dark:text-gray-300">{{ __('Remember me') }}</span>
</label>
</div>
@ -45,8 +45,8 @@
@if (Route::has('register'))
<div class="mt-6 text-center">
<span class="text-sm text-gray-500">Don't have an account?</span>
<a class="text-sm text-blue-600 hover:text-blue-800 font-medium ml-1" href="{{ route('register') }}">
<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 dark:text-blue-400" href="{{ route('register') }}">
{{ __('Sign up') }}
</a>
</div>

View file

@ -1,7 +1,7 @@
<x-guest-layout>
<div class="mb-6 text-center">
<h2 class="text-2xl font-bold text-gray-900">Create an account</h2>
<p class="mt-1 text-sm text-gray-500">Get started with FFR</p>
<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 dark:text-gray-400">Get started with FFR</p>
</div>
<form method="POST" action="{{ route('register') }}">
@ -47,8 +47,8 @@
</div>
<div class="mt-6 text-center">
<span class="text-sm text-gray-500">Already have an account?</span>
<a class="text-sm text-blue-600 hover:text-blue-800 font-medium ml-1" href="{{ route('login') }}">
<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 dark:text-blue-400" href="{{ route('login') }}">
{{ __('Sign in') }}
</a>
</div>

View file

@ -1,10 +1,10 @@
<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.') }}
</div>
@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.') }}
</div>
@endif
@ -23,7 +23,7 @@
<form method="POST" action="{{ route('logout') }}">
@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') }}
</button>
</form>

View file

@ -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

View file

@ -1,7 +1,7 @@
@props(['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 }}
</div>
@endif

View file

@ -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>

View file

@ -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>

View file

@ -18,10 +18,10 @@
<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="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">
<h3 id="modal-title" class="text-lg font-medium text-gray-900">{{ $title }}</h3>
<button type="button" wire:click="{{ $close }}" class="text-gray-400 hover:text-gray-600">
<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 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">
<path stroke-linecap="round" stroke-linejoin="round" d="M6 18 18 6M6 6l12 12" />
</svg>

View file

@ -1,7 +1,7 @@
@props(['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)
<li>{{ $message }}</li>
@endforeach

View file

@ -1,5 +1,5 @@
@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 }}
</label>

View file

@ -65,7 +65,7 @@ class="fixed inset-0 transform transition-all"
<div
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-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"

View file

@ -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>

View file

@ -2,9 +2,9 @@
<div class="mb-8 flex items-start justify-between">
<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)
<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
</div>
<div class="flex items-center space-x-3">

View file

@ -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>

View file

@ -1,6 +1,6 @@
@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-1 min-w-0">
<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)
<span class="h-2 w-2 rounded-full shrink-0 {{ $routeArticle->feed->displayColor()->dotClass() }}" aria-hidden="true"></span>
@endif
<span class="text-gray-900">{{ $routeArticle->feed?->name ?? 'Unknown feed' }}</span>
<span class="text-gray-400" aria-hidden="true">&rarr;</span>
<span class="text-gray-600">{{ $routeArticle->platformChannel?->name ?? 'Unknown channel' }}</span>
<span class="text-gray-900 dark:text-gray-100">{{ $routeArticle->feed?->name ?? 'Unknown feed' }}</span>
<span class="text-gray-400 dark:text-gray-500" aria-hidden="true">&rarr;</span>
<span class="text-gray-600 dark:text-gray-300">{{ $routeArticle->platformChannel?->name ?? 'Unknown channel' }}</span>
</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' }}
</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' }}
</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') }}
</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) --}}
@if ($tab === 'all')
@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
</span>
@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
</span>
@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
</span>
@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())
<button
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"
>
<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
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"
>
<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())
<button
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"
>
<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 }}"
target="_blank"
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"
>
<svg class="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">

View file

@ -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 }}
</button>

View file

@ -1,3 +1,3 @@
@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']) }}>

View 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>

View file

@ -1,14 +1,14 @@
<x-app-layout>
<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') }}
</h2>
</x-slot>
<div class="py-12">
<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="p-6 text-gray-900">
<div class="bg-white overflow-hidden shadow-xs sm:rounded-lg dark:bg-gray-800">
<div class="p-6 text-gray-900 dark:text-gray-100">
{{ __("You're logged in!") }}
</div>
</div>

View file

@ -7,6 +7,8 @@
<title>{{ config('app.name') }}</title>
@include('layouts.theme-script')
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.bunny.net">
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
@ -16,7 +18,7 @@
@livewireStyles
</head>
<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 -->
<div
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-start="translate-x-0"
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">
<h1 class="text-xl font-bold text-gray-900">FFR</h1>
<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 dark:text-gray-100">FFR</h1>
<button
@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">
<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 -->
<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">
<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>
<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')
</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-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 }}
</p>
<form method="POST" action="{{ route('logout') }}" class="inline">
@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
</button>
</form>
</div>
<x-theme-toggle class="shrink-0 ml-2" />
</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 -->
<div class="lg:pl-64 flex flex-col flex-1">
<!-- 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
@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">
<path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5" />
</svg>
</button>
<div class="flex-1 px-4 flex justify-between items-center">
<h1 class="text-lg font-medium text-gray-900">FFR</h1>
<livewire:notification-bell />
<h1 class="text-lg font-medium text-gray-900 dark:text-gray-100">FFR</h1>
<div class="flex items-center gap-1">
<x-theme-toggle />
<livewire:notification-bell />
</div>
</div>
</div>

View file

@ -7,6 +7,8 @@
<title>{{ config('app.name') }}</title>
@include('layouts.theme-script')
<!-- Fonts -->
<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" />
@ -15,7 +17,7 @@
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
</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">
<!-- Logo/Brand -->
<div class="mb-6">
@ -31,7 +33,7 @@
</div>
<!-- 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 }}
</div>

View file

@ -13,7 +13,7 @@
<a
href="{{ route($item['route']) }}"
@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'])
@case('home')

View file

@ -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>

View file

@ -7,6 +7,8 @@
<title>{{ config('app.name') }} - Setup</title>
@include('layouts.theme-script')
<!-- Fonts -->
<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" />
@ -15,7 +17,7 @@
@vite(['resources/css/app.css', 'resources/js/app.js'])
@livewireStyles
</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">
<!-- User Menu -->
@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" />
</svg>
</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') }}">
@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
</button>
</form>

View 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>

View file

@ -16,22 +16,22 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
</x-page-header>
{{-- 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">
<button
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
@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 }}
</span>
@endif
</button>
<button
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
</button>
@ -44,7 +44,7 @@ class="whitespace-nowrap pb-3 px-1 border-b-2 font-medium text-sm {{ $tab === 'a
<select
wire:model.live="feedId"
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>
@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"
wire:model.live.debounce.300ms="search"
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>
@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())
@foreach ($pendingFeeds as $group)
@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
wire:click="toggleFeed({{ $group->feed->id }})"
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 }}"
aria-expanded="{{ $isExpanded ? 'true' : 'false' }}"
aria-controls="feed-panel-{{ $group->feed->id }}"
>
<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"
>
<path stroke-linecap="round" stroke-linejoin="round" d="m8.25 4.5 7.5 7.5-7.5 7.5" />
</svg>
<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="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="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 dark:bg-yellow-900/30 dark:text-yellow-300">
{{ $group->count }}
</span>
</button>
@if ($isExpanded)
<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 }}"
role="region"
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
@else
<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" />
</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')
No pending articles
@else
No articles found
@endif
</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)
No pending articles for the selected feed.
@elseif ($tab === 'pending')

View file

@ -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">
@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-center">
<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>
</div>
<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 }}
</h3>
@if ($channel->platformInstance)
@ -37,7 +37,7 @@ class="text-sm text-blue-500 hover:underline">
</div>
<button
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' }}"
>
<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>
@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 }}
</p>
@endif
<div class="mt-4">
<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() }})
</span>
<button
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
</button>
@ -69,7 +69,7 @@ class="text-sm text-blue-600 hover:text-blue-800"
<div class="space-y-1">
@foreach ($channel->platformAccounts->take(3) as $account)
<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
wire:click="detachAccount({{ $channel->id }}, {{ $account->id }})"
class="text-red-500 hover:text-red-700"
@ -82,30 +82,30 @@ class="text-red-500 hover:text-red-700"
</div>
@endforeach
@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
</div>
@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
</div>
<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' }}
</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') }}
</span>
</div>
</div>
@empty
<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" />
</svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No channels</h3>
<p class="mt-1 text-sm text-gray-500">
<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 dark:text-gray-400">
No platform channels have been configured yet.
</p>
<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">
@if ($availableAccounts->isNotEmpty())
<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">
@foreach ($availableAccounts as $account)
<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
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
</button>
@ -144,13 +144,13 @@ class="text-sm text-blue-600 hover:text-blue-800"
</div>
</div>
@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
<div class="mt-4">
<button
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
</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">
<form wire:submit="createChannel" class="space-y-4">
<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
id="new-channel-instance"
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>
@foreach ($platformInstances as $instance)
<option value="{{ $instance->id }}">{{ $instance->name }}</option>
@endforeach
</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)
<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
</div>
@if ($availableCommunities)
<div>
<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
type="button"
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
</button>
@ -195,48 +195,48 @@ class="text-xs text-blue-600 hover:text-blue-800"
<select
id="new-channel-community"
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>
@foreach ($availableCommunities as $community)
<option value="{{ $community['id'] }}">{{ $community['title'] }} ({{ $community['name'] }})</option>
@endforeach
</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>
@endif
<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
id="new-channel-language"
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>
@foreach ($languages as $language)
<option value="{{ $language->id }}">{{ $language->name }}</option>
@endforeach
</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>
<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
id="new-channel-description"
wire:model="newDescription"
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>
@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 class="mt-6 flex justify-end space-x-3">
<button
type="button"
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
</button>

View file

@ -3,10 +3,10 @@
<!-- System Statistics -->
<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">
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Active Feeds</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $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>
</div>
</div>
</div>
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Platform Accounts</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $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>
</div>
</div>
</div>
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Platform Channels</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $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>
</div>
</div>
</div>
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Active Routes</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $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>
</div>
</div>
@ -82,10 +82,10 @@
<!-- Article Statistics -->
<div>
<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
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)
<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 class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Articles Fetched</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $articleStats['articles_fetched'] }}
</p>
</div>
@ -111,7 +111,7 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
</div>
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Articles Published</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $articleStats['articles_published'] }}
</p>
</div>
@ -128,7 +128,7 @@ class="rounded-md border border-gray-300 text-sm focus:border-blue-500 focus:rin
</div>
<!-- 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="shrink-0">
<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>
</div>
<div class="ml-4">
<p class="text-sm font-medium text-gray-500">Published Rate</p>
<p class="text-2xl font-semibold text-gray-900">
<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 dark:text-gray-100">
{{ $articleStats['published_percentage'] }}%
</p>
</div>

View file

@ -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">
@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-center">
<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
</div>
<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 }}
</h3>
@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 }}
</p>
@endif
@ -40,7 +40,7 @@ class="inline-flex items-center px-4 py-2 bg-blue-600 text-white text-sm font-me
</div>
<button
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' }}"
>
<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="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' }}
</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) }}
</span>
</div>
@ -63,7 +63,7 @@ class="p-1 rounded-full {{ $feed->is_active ? 'bg-green-100 text-green-600' : 'b
href="{{ $feed->url }}"
target="_blank"
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"
>
<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
</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') }}
</div>
</div>
@empty
<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" />
</svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No feeds</h3>
<p class="mt-1 text-sm text-gray-500">
<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 dark:text-gray-400">
No feeds have been configured yet.
</p>
<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">
<form wire:submit="createFeed" class="space-y-4">
<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
type="text"
id="new-feed-name"
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>
<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
id="new-feed-provider"
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>
@foreach ($providers as $code => $provider)
<option value="{{ $code }}">{{ $provider['name'] }}</option>
@endforeach
</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>
<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
id="new-feed-language"
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>
@foreach ($languages as $language)
<option value="{{ $language->id }}">{{ $language->name }}</option>
@endforeach
</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>
<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
id="new-feed-description"
wire:model="newDescription"
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>
@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 class="mt-6 flex justify-end space-x-3">
<button
type="button"
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
</button>

View file

@ -1,7 +1,7 @@
<div class="relative" x-data="{ open: false }">
<button
@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"
>
<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-start="opacity-100 scale-100"
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;"
>
<div class="flex items-center justify-between px-4 py-3 border-b border-gray-100">
<h3 class="text-sm font-semibold text-gray-900">Notifications</h3>
<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 dark:text-gray-100">Notifications</h3>
@if ($this->unreadCount > 0)
<button
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
</button>
@ -41,7 +41,7 @@ class="text-xs text-blue-600 hover:text-blue-800"
<div class="max-h-96 overflow-y-auto">
@forelse ($this->notifications as $notification)
<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 }}"
>
<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
</div>
<div class="flex-1 min-w-0">
<p class="text-sm font-medium text-gray-900">{{ $notification->title }}</p>
<p class="text-sm text-gray-500 mt-0.5">{{ $notification->message }}</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 dark:text-gray-400">{{ $notification->message }}</p>
<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())
<button
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
</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">
<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>
<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>
@endforelse
</div>

View file

@ -1,33 +1,33 @@
<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 --}}
@if ($step === 1)
<div class="text-center">
<h1 class="text-3xl font-bold text-gray-900 mb-2">Welcome to FFR</h1>
<p class="text-gray-600 mb-8">
<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 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.
</p>
<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>
<span>Connect your Lemmy account</span>
</div>
<div class="flex items-center text-sm text-gray-600">
<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="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 dark:text-gray-300">2</div>
<span>Configure a channel</span>
</div>
<div class="flex items-center text-sm text-gray-600">
<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="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 dark:text-gray-300">3</div>
<span>Add your first feed</span>
</div>
<div class="flex items-center text-sm text-gray-600">
<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="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 dark:text-gray-300">4</div>
<span>Create a route</span>
</div>
<div class="flex items-center text-sm text-gray-600">
<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="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 dark:text-gray-300">5</div>
<span>You're ready to go!</span>
</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 --}}
@if ($step === 2)
<div class="text-center mb-8">
<h1 class="text-2xl font-bold text-gray-900 mb-2">Connect Your Lemmy Account</h1>
<p class="text-gray-600">
<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 dark:text-gray-300">
{{ $existingAccount ? 'Your connected Lemmy account' : 'Enter your Lemmy instance details and login credentials' }}
</p>
{{-- Progress indicator --}}
<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-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">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">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">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">4</div>
</div>
@if (!empty($formErrors['general']))
<div class="p-3 bg-red-50 border border-red-200 rounded-md mt-6">
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
<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 dark:text-red-400">{{ $formErrors['general'] }}</p>
</div>
@endif
@if ($existingAccount)
{{-- Account Card --}}
<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-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>
</div>
<div class="ml-4">
<h3 class="text-lg font-semibold text-gray-900">Account Connected</h3>
<div class="text-sm text-gray-600 mt-1">
<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 dark:text-gray-300">
<p><strong>Username:</strong> {{ $existingAccount['username'] }}</p>
<p><strong>Instance:</strong> {{ str_replace('https://', '', $existingAccount['instance_url']) }}</p>
</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
wire:click="deleteAccount"
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"
>
<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 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
</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 --}}
<form wire:submit="createPlatformAccount" class="space-y-6 mt-8 text-left">
<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
</label>
<input
@ -121,43 +121,43 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
id="instanceUrl"
wire:model="instanceUrl"
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
>
<p class="text-sm text-gray-500 mt-1">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
<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 dark:text-red-400">{{ $message }}</p> @enderror
</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
</label>
<input
type="text"
id="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
>
@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>
<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
</label>
<input
type="password"
id="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
>
@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 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
</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 --}}
@if ($step === 3)
<div class="text-center mb-8">
<h1 class="text-2xl font-bold text-gray-900 mb-2">Configure Your Channel</h1>
<p class="text-gray-600">
<h1 class="text-2xl font-bold text-gray-900 mb-2 dark:text-gray-100">Configure Your Channel</h1>
<p class="text-gray-600 dark:text-gray-300">
Set up a Lemmy community where articles will be posted
</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="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-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">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">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">4</div>
</div>
<form wire:submit="createChannel" class="space-y-6 mt-8 text-left">
@if (!empty($formErrors['general']))
<div class="p-3 bg-red-50 border border-red-200 rounded-md">
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
<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 dark:text-red-400">{{ $formErrors['general'] }}</p>
</div>
@endif
<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
</label>
<select
id="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
>
<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>
@endforeach
</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)
<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
</div>
@if ($availableCommunities)
<div>
<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
</label>
<button
type="button"
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
</button>
@ -234,7 +234,7 @@ class="text-xs text-blue-600 hover:text-blue-800"
<select
id="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
>
<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>
@endforeach
</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>
@endif
<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
</label>
<select
id="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
>
<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>
@endforeach
</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>
<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)
</label>
<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"
rows="3"
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>
@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 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
</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 --}}
@if ($step === 4)
<div class="text-center mb-8">
<h1 class="text-2xl font-bold text-gray-900 mb-2">Add Your First Feed</h1>
<p class="text-gray-600">
<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 dark:text-gray-300">
Choose from our supported news providers to monitor for new articles
</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-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>
<form wire:submit="createFeed" class="space-y-6 mt-8 text-left">
@if (!empty($formErrors['general']))
<div class="p-3 bg-red-50 border border-red-200 rounded-md">
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
<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 dark:text-red-400">{{ $formErrors['general'] }}</p>
</div>
@endif
<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
</label>
<input
@ -326,16 +326,16 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
id="feedName"
wire:model="feedName"
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
>
@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>
<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
<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">
<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>
@ -344,21 +344,21 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
<select
id="feedLanguageId"
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>
</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>
<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
</label>
<select
id="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
>
<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
</select>
@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
@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>
<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)
</label>
<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"
rows="3"
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>
@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 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
</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 --}}
@if ($step === 5)
<div class="text-center mb-8">
<h1 class="text-2xl font-bold text-gray-900 mb-2">Create Your First Route</h1>
<p class="text-gray-600">
<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 dark:text-gray-300">
Connect your feed to a channel by creating a route. This tells FFR which articles to post where.
</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-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>
<form wire:submit="createRoute" class="space-y-6 mt-8 text-left">
@if (!empty($formErrors['general']))
<div class="p-3 bg-red-50 border border-red-200 rounded-md">
<p class="text-red-600 text-sm">{{ $formErrors['general'] }}</p>
<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 dark:text-red-400">{{ $formErrors['general'] }}</p>
</div>
@endif
<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
</label>
<select
id="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
>
<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>
@endforeach
</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>
<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
</label>
<select
id="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
>
<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
</select>
@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.
</p>
@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>
<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)
</label>
<input
@ -478,16 +478,16 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
min="1"
max="100"
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)
</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 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
</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>
</svg>
</div>
<h1 class="text-3xl font-bold text-gray-900 mb-2">Setup Complete!</h1>
<p class="text-gray-600 mb-6">
<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 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.
</p>
</div>
@ -526,18 +526,18 @@ class="bg-blue-600 text-white py-2 px-6 rounded-md hover:bg-blue-700 transition
</div>
<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>
<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> New articles will be automatically posted to your channels</li>
<li> You can monitor activity in the Articles and other sections</li>
</ul>
</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>
<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.
</p>
</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' }}
</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('feeds') }}" class="hover:text-blue-600">Manage Feeds</a>

View file

@ -13,22 +13,22 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
<div class="space-y-6">
@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-1 min-w-0">
<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 }}
</h3>
@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">
<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>
Active
</span>
@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">
<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>
@ -36,7 +36,7 @@ class="inline-flex items-center px-4 py-2 border border-transparent text-sm font
</span>
@endif
</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>&bull;</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>
@if ($route->auto_approve === true)
<span>&bull;</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)
<span>&bull;</span>
<span class="text-red-600">Auto-approve: Off</span>
<span class="text-red-600 dark:text-red-400">Auto-approve: Off</span>
@endif
</div>
@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 }}
</p>
@endif
@if ($route->keywords->isNotEmpty())
<div class="mt-3">
<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="M6 6h.008v.008H6V6Z" />
</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 class="flex flex-wrap gap-2">
@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 }}
</span>
@endforeach
</div>
</div>
@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
</div>
@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">
<button
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"
>
<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
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' }}"
>
@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" />
</svg>
@else
@ -108,7 +108,7 @@ class="p-2 text-gray-400 hover:text-gray-600 rounded-md"
<button
wire:click="delete({{ $route->feed_id }}, {{ $route->platform_channel_id }})"
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"
>
<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>
@empty
<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" />
</svg>
<h3 class="mt-2 text-sm font-medium text-gray-900">No routes</h3>
<p class="mt-1 text-sm text-gray-500">
<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 dark:text-gray-400">
Get started by creating a new route to connect feeds with channels.
</p>
<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">
<form wire:submit="createRoute" class="space-y-4">
<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
</label>
<select
id="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
>
<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>
<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
</label>
<select
id="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
>
<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>
<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
</label>
<input
@ -191,16 +191,16 @@ class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-hidden f
id="newPriority"
wire:model="newPriority"
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 class="flex justify-end space-x-3 pt-4">
<button
type="button"
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
</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 -->
@if ($editingRoute)
<x-form-modal title="Edit Route" close="closeEditModal">
<div class="mb-4 p-3 bg-gray-50 rounded-md">
<p class="text-sm text-gray-600">
<div class="mb-4 p-3 bg-gray-50 rounded-md dark:bg-gray-900">
<p class="text-sm text-gray-600 dark:text-gray-300">
<strong>Feed:</strong> {{ $editingRoute->feed?->name }}
</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 }}
</p>
</div>
<form wire:submit="updateRoute" class="space-y-4">
<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
</label>
<input
@ -237,43 +237,43 @@ class="px-4 py-2 text-sm font-medium text-white bg-blue-600 border border-transp
id="editPriority"
wire:model="editPriority"
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>
<!-- Auto-approve -->
<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">
<label class="inline-flex items-center">
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="" class="text-blue-600 focus:ring-blue-500">
<span class="ml-2 text-sm text-gray-700">Use global setting</span>
<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 dark:text-gray-200">Use global setting</span>
</label>
<label class="inline-flex items-center">
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="1" class="text-blue-600 focus:ring-blue-500">
<span class="ml-2 text-sm text-gray-700">On</span>
<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 dark:text-gray-200">On</span>
</label>
<label class="inline-flex items-center">
<input type="radio" wire:model="editAutoApprove" name="editAutoApprove" value="0" class="text-blue-600 focus:ring-blue-500">
<span class="ml-2 text-sm text-gray-700">Off</span>
<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 dark:text-gray-200">Off</span>
</label>
</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>
<!-- Keyword Management -->
<div class="border-t pt-4">
<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="M6 6h.008v.008H6V6Z" />
</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
type="button"
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"
>
<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:keydown.enter.prevent="addKeyword"
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
>
<button
@ -302,7 +302,7 @@ class="px-3 py-1 bg-blue-600 text-white text-sm rounded-sm hover:bg-blue-700"
<button
type="button"
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
</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())
<div class="space-y-2">
@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">
<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 }}
</span>
<span class="text-xs text-gray-500">
<span class="text-xs text-gray-500 dark:text-gray-400">
{{ $keyword->is_active ? 'Active' : 'Inactive' }}
</span>
</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
type="button"
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' }}"
>
{{ $keyword->is_active ? 'Deactivate' : 'Activate' }}
@ -334,7 +334,7 @@ class="text-sm text-blue-600 hover:text-blue-800"
type="button"
wire:click="deleteKeyword({{ $keyword->id }})"
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"
>
<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>
@else
@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.
</div>
@endif
@ -358,7 +358,7 @@ class="text-red-600 hover:text-red-800"
<button
type="button"
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
</button>

View file

@ -3,26 +3,26 @@
<div class="space-y-6">
<!-- Article Processing Settings -->
<div class="bg-white rounded-lg shadow-sm">
<div class="px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900 flex items-center">
<div class="bg-white rounded-lg shadow-sm dark:bg-gray-800">
<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 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">
<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" />
</svg>
Article Processing
</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
</p>
</div>
<div class="px-6 py-4 space-y-4">
<div class="flex items-center justify-between">
<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
</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
</p>
</div>
@ -44,10 +44,10 @@ class="shrink-0"
<div class="flex items-center justify-between">
<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)
</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.
</p>
</div>
@ -58,7 +58,7 @@ class="shrink-0"
min="0"
max="1440"
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
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>
@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
<div class="flex items-center justify-between">
<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
</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
</p>
</div>
@ -100,25 +100,25 @@ class="shrink-0"
</div>
<!-- Feed Monitoring Settings -->
<div class="bg-white rounded-lg shadow-sm">
<div class="px-6 py-4 border-b border-gray-200">
<h2 class="text-lg font-medium text-gray-900 flex items-center">
<div class="bg-white rounded-lg shadow-sm dark:bg-gray-800">
<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 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">
<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>
Feed Monitoring
</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
</p>
</div>
<div class="px-6 py-4 space-y-4">
<div class="flex items-center justify-between">
<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)
</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.
</p>
</div>
@ -128,7 +128,7 @@ class="shrink-0"
wire:model="feedStalenessThreshold"
min="0"
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
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>
@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
</div>
</div>
<!-- Status Messages -->
@if ($successMessage)
<div class="bg-green-50 border border-green-200 rounded-md p-4">
<p class="text-green-600 text-sm">{{ $successMessage }}</p>
<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 dark:text-green-400">{{ $successMessage }}</p>
</div>
@endif
@if ($errorMessage)
<div class="bg-red-50 border border-red-200 rounded-md p-4">
<p class="text-red-600 text-sm">{{ $errorMessage }}</p>
<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 dark:text-red-400">{{ $errorMessage }}</p>
</div>
@endif
</div>

View file

@ -1,25 +1,25 @@
<x-app-layout>
<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') }}
</h2>
</x-slot>
<div class="py-12">
<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">
@include('profile.partials.update-profile-information-form')
</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">
@include('profile.partials.update-password-form')
</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">
@include('profile.partials.delete-user-form')
</div>

View file

@ -1,10 +1,10 @@
<section class="space-y-6">
<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') }}
</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.') }}
</p>
</header>
@ -19,11 +19,11 @@
@csrf
@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?') }}
</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.') }}
</p>

View file

@ -1,10 +1,10 @@
<section>
<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') }}
</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.') }}
</p>
</header>
@ -40,7 +40,7 @@
x-show="show"
x-transition
x-init="setTimeout(() => show = false, 2000)"
class="text-sm text-gray-600"
class="text-sm text-gray-600 dark:text-gray-300"
>{{ __('Saved.') }}</p>
@endif
</div>

View file

@ -1,10 +1,10 @@
<section>
<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') }}
</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.") }}
</p>
</header>
@ -30,16 +30,16 @@
@if ($user instanceof \Illuminate\Contracts\Auth\MustVerifyEmail && ! $user->hasVerifiedEmail())
<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.') }}
<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.') }}
</button>
</p>
@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.') }}
</p>
@endif
@ -56,7 +56,7 @@
x-show="show"
x-transition
x-init="setTimeout(() => show = false, 2000)"
class="text-sm text-gray-600"
class="text-sm text-gray-600 dark:text-gray-300"
>{{ __('Saved.') }}</p>
@endif
</div>

View file

@ -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());
$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