diff --git a/config/forum/frontend.php b/config/forum/frontend.php index 1f4cd6258..50f2f6cfc 100644 --- a/config/forum/frontend.php +++ b/config/forum/frontend.php @@ -23,7 +23,8 @@ return [ | */ - 'preset' => 'livewire-tailwind', + //'preset' => 'livewire-tailwind', + 'preset' => 'blade-tailwind', /* |-------------------------------------------------------------------------- diff --git a/package.json b/package.json index 565516673..390cbdde5 100644 --- a/package.json +++ b/package.json @@ -11,20 +11,25 @@ "@tailwindcss/forms": "^0.5.8", "@tailwindcss/vite": "^4.0.0", "autoprefixer": "^10.4.20", - "axios": "^1.7.7", + "axios": "^1.13.2", "lodash": "^4.17.21", "npm-check-updates": "^17.1.1", "postcss": "^8.4.44", "prettier": "^3.3.3", - "tailwindcss": "^3.4.10", + "tailwindcss": "^3.4.18", "vite": "^7.0", - "vue": "^3.4.38" + "vue": "^3.5.24" }, "dependencies": { "@fortawesome/fontawesome-free": "^6.6.0", - "@melloware/coloris": "^0.24.0", + "@melloware/coloris": "^0.24.2", + "@simonwep/pickr": "^1.9.1", + "alpinejs": "^3.15.2", "date-fns": "^3.6.0", + "feather-icons": "^4.29.2", + "laravel-echo": "^2.2.6", "laravel-vite-plugin": "^2.0", - "nested-sort": "^5.2.0" + "nested-sort": "^5.2.0", + "vuedraggable": "^4.1.0" } } diff --git a/resources/forum/blade-tailwind/css/forum.css b/resources/forum/blade-tailwind/css/forum.css new file mode 100644 index 000000000..6e72d22ce --- /dev/null +++ b/resources/forum/blade-tailwind/css/forum.css @@ -0,0 +1,35 @@ +@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap'); + +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + .forum { + font-family: "Open Sans", sans-serif; + font-optical-sizing: auto; + font-weight: 400; + font-style: normal; + font-variation-settings: "wdth" 100; + } + + h1 { + @apply text-4xl my-6; + } + + h2 { + @apply text-2xl; + } + + h3 { + @apply text-xl; + } + + a { + @apply text-blue-500; + } + + a:hover { + @apply text-blue-800; + } +} diff --git a/resources/forum/blade-tailwind/js/forum.js b/resources/forum/blade-tailwind/js/forum.js new file mode 100644 index 000000000..5ef3f53aa --- /dev/null +++ b/resources/forum/blade-tailwind/js/forum.js @@ -0,0 +1,154 @@ +import feather from 'feather-icons'; +import { createApp, ref, reactive, watch } from 'vue/dist/vue.esm-bundler.js'; +import axios from 'axios'; +import Pickr from '@simonwep/pickr'; +import draggable from 'vuedraggable/src/vuedraggable'; + +import '@simonwep/pickr/dist/themes/classic.min.css'; + +window.axios = axios; +window.Vue = { createApp, ref, reactive, watch }; +window.VueDraggable = draggable; + +document.addEventListener('DOMContentLoaded', function () { + createApp({ + setup() { + const isCollapsed = ref(true); + const isUserDropdownCollapsed = ref(true); + + window.addEventListener('click', event => { + const ignore = ['navbar-toggler', 'navbar-toggler-icon', 'dropdown-toggle']; + if (ignore.some(className => event.target.classList.contains(className))) return; + if (!isCollapsed.value) isCollapsed.value = true; + if (!isUserDropdownCollapsed.value) isUserDropdownCollapsed.value = true; + }); + + return { + isCollapsed, + isUserDropdownCollapsed, + }; + } + }).mount('.v-navbar'); + + function findModal(key) + { + const modal = document.querySelector(`[data-modal=${key}]`); + + if (!modal) throw `Attempted to open modal '${key}' but no such modal found.`; + + return modal; + } + + function openModal(modal) + { + setTimeout(function() + { + modal.classList.remove('hidden'); + modal.classList.add('flex'); + }, 200); + } + + document.querySelectorAll('[data-open-modal]').forEach(item => + { + item.addEventListener('click', event => + { + event.preventDefault(); + + openModal(findModal(event.currentTarget.dataset.openModal)); + }); + }); + + document.querySelectorAll('[data-close-modal]').forEach(modalClose => + { + modalClose.addEventListener('click', event => + { + event.preventDefault + + setTimeout(function() + { + modalClose.closest('[data-modal]').classList.remove('flex'); + modalClose.closest('[data-modal]').classList.add('hidden'); + }, 200); + }); + }); + + document.querySelectorAll('[data-dismiss]').forEach(item => + { + item.addEventListener('click', event => event.currentTarget.parentElement.style.display = 'none'); + }); + + const hash = window.location.hash.substr(1); + if (hash.startsWith('modal=')) + { + openModal(findModal(hash.replace('modal=',''))); + } + + feather.replace(); + + const input = document.querySelector('input[name=color_light_mode]'); + + if (!input) return; + + const pickr = Pickr.create({ + el: '.pickr', + theme: 'classic', + default: input.value || null, + + swatches: [ + window.defaultCategoryColor, + '#f44336', + '#e91e63', + '#9c27b0', + '#673ab7', + '#3f51b5', + '#2196f3', + '#03a9f4', + '#00bcd4', + '#009688', + '#4caf50', + '#8bc34a', + '#cddc39', + '#ffeb3b', + '#ffc107' + ], + + components: { + preview: true, + hue: true, + interaction: { + input: true, + save: true + } + }, + + strings: { + save: 'Apply' + } + }); + + pickr.on('save', instance => pickr.hide()) + .on('clear', instance => + { + input.value = ''; + input.dispatchEvent(new Event('change')); + }) + .on('cancel', instance => + { + const selectedColor = instance + .getSelectedColor() + .toHEXA() + .toString(); + + input.value = selectedColor; + input.dispatchEvent(new Event('change')); + }) + .on('change', (color, instance) => + { + const selectedColor = color + .toHEXA() + .toString(); + + input.value = selectedColor; + input.dispatchEvent(new Event('change')); + }); +}); diff --git a/resources/forum/blade-tailwind/views/category/index.blade.php b/resources/forum/blade-tailwind/views/category/index.blade.php new file mode 100644 index 000000000..93eeb6de4 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/index.blade.php @@ -0,0 +1,20 @@ +{{-- $category is passed as NULL to the master layout view to prevent it from showing in the breadcrumbs --}} +@extends ('forum::layouts.main', ['category' => null]) + +@section ('content') +
+

{{ trans('forum::general.index') }}

+ + @can ('createCategories') + + {{ trans('forum::categories.create') }} + + + @include ('forum::category.modals.create') + @endcan +
+ + @foreach ($categories as $category) + @include ('forum::category.partials.list', ['titleClass' => 'lead']) + @endforeach +@stop diff --git a/resources/forum/blade-tailwind/views/category/manage.blade.php b/resources/forum/blade-tailwind/views/category/manage.blade.php new file mode 100644 index 000000000..6a119a1b4 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/manage.blade.php @@ -0,0 +1,120 @@ +@extends ('forum::layouts.main', ['category' => null, 'thread' => null, 'breadcrumbs_append' => [trans('forum::general.manage')]]) + +@section ('content') +
+

{{ trans('forum::general.manage') }}

+ + @can ('createCategories') + + {{ trans('forum::categories.create') }} + + + @include ('forum::category.modals.create') + @endcan +
+ +
+ + + + + + +
+ +
+
+ + + + +@stop diff --git a/resources/forum/blade-tailwind/views/category/modals/create.blade.php b/resources/forum/blade-tailwind/views/category/modals/create.blade.php new file mode 100644 index 000000000..6d8301610 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/modals/create.blade.php @@ -0,0 +1,31 @@ +@component('forum::modal-form') + @slot('key', 'create-category') + @slot('title', trans('forum::categories.create')) + @slot('route', Forum::route('category.store')) + +
+ {{ trans('forum::general.title') }} + +
+
+ {{ trans('forum::general.description') }} + +
+
+
+ + +
+
+
+
+ + +
+
+ @include ('forum::category.partials.inputs.color') + + @slot('actions') + {{ trans('forum::general.create') }} + @endslot +@endcomponent diff --git a/resources/forum/blade-tailwind/views/category/modals/delete.blade.php b/resources/forum/blade-tailwind/views/category/modals/delete.blade.php new file mode 100644 index 000000000..e313edb40 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/modals/delete.blade.php @@ -0,0 +1,21 @@ +@component('forum::modal-form') + @slot('key', 'delete-category') + @slot('title', trans('forum::general.delete')) + @slot('route', Forum::route('category.delete', $category)) + @slot('method', 'DELETE') + + {{ trans('forum::general.generic_confirm') }} + + @if(!$category->isEmpty()) +
+ + +
+ @endif + + @slot('actions') + {{ trans('forum::general.delete') }} + @endslot +@endcomponent diff --git a/resources/forum/blade-tailwind/views/category/modals/edit.blade.php b/resources/forum/blade-tailwind/views/category/modals/edit.blade.php new file mode 100644 index 000000000..c5a6ce3a0 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/modals/edit.blade.php @@ -0,0 +1,40 @@ +@component('forum::modal-form') + @slot('key', 'edit-category') + @slot('title', trans('forum::general.edit')) + @slot('route', Forum::route('category.update', $category)) + @slot('method', 'PATCH') + +
+ {{ trans('forum::general.title') }} + +
+
+ {{ trans('forum::general.description') }} + +
+
+
+ + accepts_threads ? 'checked' : '' }}> + +
+
+
+
+ + is_private ? 'checked' : '' }} {{ $privateAncestor != null ? 'disabled' : '' }}> + +
+
+ @if ($privateAncestor != null) + + @endif + + @include ('forum::category.partials.inputs.color') + + @slot('actions') + {{ trans('forum::general.save') }} + @endslot +@endcomponent diff --git a/resources/forum/blade-tailwind/views/category/modals/mark-threads-as-read.blade.php b/resources/forum/blade-tailwind/views/category/modals/mark-threads-as-read.blade.php new file mode 100644 index 000000000..b2fc42d07 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/modals/mark-threads-as-read.blade.php @@ -0,0 +1,16 @@ +@component('forum::modal-form') + @slot('key', 'mark-threads-as-read') + @slot('title', trans('forum::categories.mark_read')) + @slot('route', Forum::route('unread.mark-as-read')) + @slot('method', 'PATCH') + + + +

{{ trans('forum::general.generic_confirm') }}

+ + @slot('actions') + + {{ trans('forum::general.mark_read') }} + + @endslot +@endcomponent diff --git a/resources/forum/blade-tailwind/views/category/partials/inputs/color.blade.php b/resources/forum/blade-tailwind/views/category/partials/inputs/color.blade.php new file mode 100644 index 000000000..b142f1839 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/partials/inputs/color.blade.php @@ -0,0 +1,7 @@ +
+ +
+ +
diff --git a/resources/forum/blade-tailwind/views/category/partials/list.blade.php b/resources/forum/blade-tailwind/views/category/partials/list.blade.php new file mode 100644 index 000000000..b92a05463 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/partials/list.blade.php @@ -0,0 +1,75 @@ +
+
+
+
+
+ {{ $category->title }} +
+

{{ $category->description }}

+
+
+ @if ($category->accepts_threads) + + {{ trans_choice('forum::threads.thread', 2) }}: {{ $category->thread_count }} + + + {{ trans_choice('forum::posts.post', 2) }}: {{ $category->post_count }} + + @endif +
+
+ @if ($category->accepts_threads) + @if ($category->newestThread) +
+ {{ $category->newestThread->title }} + @include ('forum::partials.timestamp', ['carbon' => $category->newestThread->created_at]) +
+ @endif + @if ($category->latestActiveThread && $category->latestActiveThread->post_count > 1) +
+ Re: {{ $category->latestActiveThread->title }} + @include ('forum::partials.timestamp', ['carbon' => $category->latestActiveThread->lastPost->created_at]) +
+ @endif + @endif +
+
+
+ + @if ($category->children->count() > 0) +
+ @foreach ($category->children as $subcategory) +
+
+
+ {{ $subcategory->title }} +
{{ $subcategory->description }}
+
+
+ + {{ trans_choice('forum::threads.thread', 2) }}: {{ $subcategory->thread_count }} + + + {{ trans_choice('forum::posts.post', 2) }}: {{ $subcategory->post_count }} + +
+
+ @if ($subcategory->newestThread) +
+ {{ $subcategory->newestThread->title }} + @include ('forum::partials.timestamp', ['carbon' => $subcategory->newestThread->created_at]) +
+ @endif + @if ($subcategory->latestActiveThread && $subcategory->latestActiveThread->post_count > 1) +
+ Re: {{ $subcategory->latestActiveThread->title }} + @include ('forum::partials.timestamp', ['carbon' => $subcategory->latestActiveThread->lastPost->created_at]) +
+ @endif +
+
+
+ @endforeach +
+ @endif +
diff --git a/resources/forum/blade-tailwind/views/category/partials/options.blade.php b/resources/forum/blade-tailwind/views/category/partials/options.blade.php new file mode 100644 index 000000000..338024af2 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/partials/options.blade.php @@ -0,0 +1,12 @@ +@foreach ($categories as $cat) + @if (!isset($hide) || (isset($hide) && $cat->id != $hide->id)) + + @endif + + @if ($cat->children) + @include ('forum::category.partials.options', ['categories' => $cat->children]) + @endif +@endforeach diff --git a/resources/forum/blade-tailwind/views/category/show.blade.php b/resources/forum/blade-tailwind/views/category/show.blade.php new file mode 100644 index 000000000..e8f5591a7 --- /dev/null +++ b/resources/forum/blade-tailwind/views/category/show.blade.php @@ -0,0 +1,248 @@ +{{-- $thread is passed as NULL to the master layout view to prevent it from showing in the breadcrumbs --}} +@extends('forum::layouts.main', ['thread' => null]) + +@section('content') +
+

+ {{ $category->title }}   + @if ($category->description) + {{ $category->description }} + @endif +

+
+ +
+
+ @if ($category->accepts_threads) + @can ('createThreads', $category) + {{ trans('forum::threads.new_thread') }} + @endcan + @endif + + + @can ('editCategories') + @can ('edit', $category) + + {{ trans('forum::general.edit') }} + + @endcan + @endcan + +
+ + @if (!$category->children->isEmpty()) + @foreach ($category->children as $subcategory) + @include ('forum::category.partials.list', ['category' => $subcategory]) + @endforeach + @endif + + @if ($category->accepts_threads) + @if (!$threads->isEmpty()) +
+ {{ $threads->links('forum::pagination') }} +
+ + @if (count($selectableThreadIds) > 0) + @can ('manageThreads', $category) +
+ @csrf + + +
+
+ + +
+
+ @endcan + @endif + +
+ @foreach ($threads as $thread) + @include ('forum::thread.partials.list') + @endforeach +
+ + @if (count($selectableThreadIds) > 0) + @can ('manageThreads', $category) +
+
+
+ {{ trans('forum::general.with_selection') }} +
+
+
+
+ {{ trans_choice('forum::general.actions', 1) }} +
+ + + @can ('deleteThreads', $category) + + @endcan + @can ('restoreThreads', $category) + + @endcan + @can ('moveThreadsFrom', $category) + + @endcan + @can ('lockThreads', $category) + + + @endcan + @can ('pinThreads', $category) + + + @endcan + +
+ +
+
+ +
+ + @include ('forum::category.partials.options', [ + 'categories' => $threadDestinationCategories, + 'hide' => $category + ]) + +
+ + @if (config('forum.general.soft_deletes')) +
+ + +
+ @endif + +
+ +
+
+
+
+
+ @endcan + @endif + @else +
+
+ {{ trans('forum::threads.none_found') }} + @can ('createThreads', $category) +
+ {{ trans('forum::threads.post_the_first') }} + @endcan +
+
+ @endif + +
+
+ {{ $threads->links('forum::pagination') }} +
+
+ @if ($category->accepts_threads) + @can ('createThreads', $category) + {{ trans('forum::threads.new_thread') }} + @endcan + @endif +
+
+ @endif +
+ + @if (!$threads->isEmpty()) + @can ('markThreadsAsRead') +
+ + {{ trans('forum::general.mark_read') }} + +
+ + @include ('forum::category.modals.mark-threads-as-read') + @endcan + @endif + + @can ('editCategories') + @can ('edit', $category) + @include ('forum::category.modals.edit') + @endcan + @endcan + @can ('deleteCategories') + @can ('delete', $category) + @include ('forum::category.modals.delete') + @endcan + @endcan + + +@stop diff --git a/resources/forum/blade-tailwind/views/components/badge.blade.php b/resources/forum/blade-tailwind/views/components/badge.blade.php new file mode 100644 index 000000000..652c1cc0b --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/badge.blade.php @@ -0,0 +1,27 @@ +@props([ + 'type' => 'default' +]) + +@php +switch($type) { + case('info'): + $color = 'bg-blue-500'; + break; + + case('danger'): + $color = 'bg-red-500'; + break; + + case('warning'): + $color = 'bg-orange-500'; + break; + + default: + $color = 'bg-gray-400'; + break; +} +@endphp + +merge(['class' => "$color rounded-full px-2 py-1 text-white text-xs font-semibold"]) }}> + {{ $slot }} + diff --git a/resources/forum/blade-tailwind/views/components/button-group.blade.php b/resources/forum/blade-tailwind/views/components/button-group.blade.php new file mode 100644 index 000000000..008539dc3 --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/button-group.blade.php @@ -0,0 +1,3 @@ +
+ {{ $slot }} +
diff --git a/resources/forum/blade-tailwind/views/components/button-link.blade.php b/resources/forum/blade-tailwind/views/components/button-link.blade.php new file mode 100644 index 000000000..6968d4e44 --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/button-link.blade.php @@ -0,0 +1,3 @@ +merge(['class' => 'bg-blue-500 hover:bg-blue-400 text-white font-semibold hover:text-white px-3 py-2 rounded-md inline-block']) }}> + {{ $slot }} + diff --git a/resources/forum/blade-tailwind/views/components/button-secondary.blade.php b/resources/forum/blade-tailwind/views/components/button-secondary.blade.php new file mode 100644 index 000000000..519f991fa --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/button-secondary.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/forum/blade-tailwind/views/components/button.blade.php b/resources/forum/blade-tailwind/views/components/button.blade.php new file mode 100644 index 000000000..afccd7b4e --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/button.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/forum/blade-tailwind/views/components/input.blade.php b/resources/forum/blade-tailwind/views/components/input.blade.php new file mode 100644 index 000000000..2e221f669 --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/input.blade.php @@ -0,0 +1 @@ +merge(['type' => 'text', 'class' => 'px-3 py-1 border-gray-300 focus:border-blue-500 focus:ring-blue-500 rounded-md border shadow-sm']) }}> diff --git a/resources/forum/blade-tailwind/views/components/label.blade.php b/resources/forum/blade-tailwind/views/components/label.blade.php new file mode 100644 index 000000000..4d9a6b565 --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/label.blade.php @@ -0,0 +1,3 @@ + diff --git a/resources/forum/blade-tailwind/views/components/select.blade.php b/resources/forum/blade-tailwind/views/components/select.blade.php new file mode 100644 index 000000000..2df5e15da --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/select.blade.php @@ -0,0 +1,5 @@ +
+ +
diff --git a/resources/forum/blade-tailwind/views/components/textarea.blade.php b/resources/forum/blade-tailwind/views/components/textarea.blade.php new file mode 100644 index 000000000..01483e3bd --- /dev/null +++ b/resources/forum/blade-tailwind/views/components/textarea.blade.php @@ -0,0 +1 @@ + diff --git a/resources/forum/blade-tailwind/views/layouts/main.blade.php b/resources/forum/blade-tailwind/views/layouts/main.blade.php new file mode 100644 index 000000000..82e34d8fd --- /dev/null +++ b/resources/forum/blade-tailwind/views/layouts/main.blade.php @@ -0,0 +1,97 @@ + + + + + + + + @if (isset($thread_title)) + {{ $thread_title }} — + @endif + @if (isset($category)) + {{ $category->title }} — + @endif + {{ trans('forum::general.home_title') }} + + + @vite(['resources/forum/blade-tailwind/css/forum.css', 'resources/forum/blade-tailwind/js/forum.js']) + + + + +
+ @include ('forum::partials.breadcrumbs') + @include ('forum::partials.alerts') + + @yield('content') +
+ + @yield('footer') + + + + diff --git a/resources/forum/blade-tailwind/views/modal-form.blade.php b/resources/forum/blade-tailwind/views/modal-form.blade.php new file mode 100644 index 000000000..35d368f2c --- /dev/null +++ b/resources/forum/blade-tailwind/views/modal-form.blade.php @@ -0,0 +1,30 @@ + diff --git a/resources/forum/blade-tailwind/views/pagination.blade.php b/resources/forum/blade-tailwind/views/pagination.blade.php new file mode 100644 index 000000000..63c6f56b5 --- /dev/null +++ b/resources/forum/blade-tailwind/views/pagination.blade.php @@ -0,0 +1,46 @@ +@if ($paginator->hasPages()) + +@endif diff --git a/resources/forum/blade-tailwind/views/partials/alert.blade.php b/resources/forum/blade-tailwind/views/partials/alert.blade.php new file mode 100644 index 000000000..e3c1b5dee --- /dev/null +++ b/resources/forum/blade-tailwind/views/partials/alert.blade.php @@ -0,0 +1,18 @@ +@php +$colorClasses = match ($type) { + 'primary', '', null => 'bg-blue-100 text-blue-700', + 'success', '', null => 'bg-green-100 text-green-700', + 'danger' => 'bg-orange-100 text-orange-700' +}; +@endphp + +
+
+ {!! $message !!} +
+ +
diff --git a/resources/forum/blade-tailwind/views/partials/alerts.blade.php b/resources/forum/blade-tailwind/views/partials/alerts.blade.php new file mode 100644 index 000000000..e2a0e35a9 --- /dev/null +++ b/resources/forum/blade-tailwind/views/partials/alerts.blade.php @@ -0,0 +1,11 @@ +@if (Session::has('alerts')) + @foreach (Session::get('alerts') as $alert) + @include ('forum::partials.alert', $alert) + @endforeach +@endif + +@if (isset($errors) && !$errors->isEmpty()) + @foreach ($errors->all() as $error) + @include ('forum::partials.alert', ['type' => 'danger', 'message' => $error]) + @endforeach +@endif diff --git a/resources/forum/blade-tailwind/views/partials/breadcrumb-categories.blade.php b/resources/forum/blade-tailwind/views/partials/breadcrumb-categories.blade.php new file mode 100644 index 000000000..521e55241 --- /dev/null +++ b/resources/forum/blade-tailwind/views/partials/breadcrumb-categories.blade.php @@ -0,0 +1,4 @@ +@if ($category->parent !== null) + @include ('forum::partials.breadcrumb-categories', ['category' => $category->parent]) +@endif +
  • {{ $category->title }}
  • diff --git a/resources/forum/blade-tailwind/views/partials/breadcrumbs.blade.php b/resources/forum/blade-tailwind/views/partials/breadcrumbs.blade.php new file mode 100644 index 000000000..b60634275 --- /dev/null +++ b/resources/forum/blade-tailwind/views/partials/breadcrumbs.blade.php @@ -0,0 +1,16 @@ + diff --git a/resources/forum/blade-tailwind/views/partials/timestamp.blade.php b/resources/forum/blade-tailwind/views/partials/timestamp.blade.php new file mode 100644 index 000000000..c01cce7a9 --- /dev/null +++ b/resources/forum/blade-tailwind/views/partials/timestamp.blade.php @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/forum/blade-tailwind/views/post/confirm-delete.blade.php b/resources/forum/blade-tailwind/views/post/confirm-delete.blade.php new file mode 100644 index 000000000..ae71f083f --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/confirm-delete.blade.php @@ -0,0 +1,37 @@ +@extends ('forum::layouts.main', ['breadcrumbs_append' => [trans_choice('forum::posts.delete', 1)]]) + +@section ('content') +
    +

    {{ trans_choice('forum::posts.delete', 1) }}

    + +
    + + @include ('forum::post.partials.list', ['post' => $post, 'single' => true]) + +
    + @csrf + @method('DELETE') + +
    +
    + + @if (config('forum.general.soft_deletes')) +
    + + +
    + @else + {{ trans('forum::general.generic_confirm') }} + @endif +
    +
    + +
    + {{ trans('forum::general.cancel') }} + {{ trans('forum::general.delete') }} +
    +
    +
    +@stop diff --git a/resources/forum/blade-tailwind/views/post/confirm-restore.blade.php b/resources/forum/blade-tailwind/views/post/confirm-restore.blade.php new file mode 100644 index 000000000..66d4deb9c --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/confirm-restore.blade.php @@ -0,0 +1,29 @@ +@extends ('forum::layouts.main', ['breadcrumbs_append' => [trans_choice('forum::posts.restore', 1)]]) + +@section ('content') +
    +

    {{ trans_choice('forum::posts.restore', 1) }}

    + +
    + + @include ('forum::post.partials.list', ['post' => $post, 'single' => true]) + +
    + @csrf + @method('POST') + +
    +
    + {{ trans('forum::general.generic_confirm') }} +
    +
    + +
    + {{ trans('forum::general.cancel') }} + + {{ trans('forum::general.restore') }} + +
    +
    +
    +@stop diff --git a/resources/forum/blade-tailwind/views/post/create.blade.php b/resources/forum/blade-tailwind/views/post/create.blade.php new file mode 100644 index 000000000..46bd4e78a --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/create.blade.php @@ -0,0 +1,32 @@ +@extends ('forum::layouts.main', ['breadcrumbs_append' => [trans('forum::general.new_reply')]]) + +@section ('content') +
    +

    {{ trans('forum::general.new_reply') }} ({{ $thread->title }})

    + + @if ($post !== null && !$post->trashed()) +
    {{ trans('forum::general.replying_to', ['item' => $post->authorName]) }}:
    + + @include ('forum::post.partials.quote') + @endif + +
    + +
    + {!! csrf_field() !!} + + @if ($post !== null) + + @endif + +
    + {{ old('content') }} +
    + +
    + {{ trans('forum::general.cancel') }} + {{ trans('forum::general.reply') }} +
    +
    +
    +@stop diff --git a/resources/forum/blade-tailwind/views/post/edit.blade.php b/resources/forum/blade-tailwind/views/post/edit.blade.php new file mode 100644 index 000000000..295b79487 --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/edit.blade.php @@ -0,0 +1,29 @@ +@extends ('forum::layouts.main', ['breadcrumbs_append' => [trans('forum::posts.edit')]]) + +@section ('content') +
    +

    {{ trans('forum::posts.edit') }} ({{ $thread->title }})

    + +
    + + @if ($post->parent) +

    {{ trans('forum::general.response_to', ['item' => $post->parent->authorName]) }}...

    + + @include ('forum::post.partials.list', ['post' => $post->parent, 'single' => true]) + @endif + +
    + @csrf + @method('PATCH') + +
    + {{ old('content') !== null ? old('content') : $post->content }} +
    + +
    + {{ trans('forum::general.cancel') }} + {{ trans('forum::general.save') }} +
    +
    +
    +@stop diff --git a/resources/forum/blade-tailwind/views/post/partials/actions.blade.php b/resources/forum/blade-tailwind/views/post/partials/actions.blade.php new file mode 100644 index 000000000..e7eb921ac --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/partials/actions.blade.php @@ -0,0 +1,23 @@ +
    +
    + + {{ trans('forum::posts.actions') }} +
    +
    +
    +
    + + +
    +
    + +
    +
    diff --git a/resources/forum/blade-tailwind/views/post/partials/list.blade.php b/resources/forum/blade-tailwind/views/post/partials/list.blade.php new file mode 100644 index 000000000..ecf26f53d --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/partials/list.blade.php @@ -0,0 +1,70 @@ +
    trashed())id="post-{{ $post->sequence }}"@endif + class="bg-white border mb-2 rounded-md {{ $post->trashed() || $thread->trashed() ? 'opacity-50' : '' }}" + :class="{ 'border-blue-500': state.selectedPosts.includes({{ $post->id }}) }"> +
    + @if (!isset($single) || !$single) + + #{{ $post->sequence }} + @if ($post->sequence != 1) + @can ('deletePosts', $post->thread) + @can ('delete', $post) + + @endcan + @endcan + @endif + + @endif + +
    + {{ $post->authorName }} + + @include ('forum::partials.timestamp', ['carbon' => $post->created_at]) + @if ($post->hasBeenUpdated()) + ({{ trans('forum::general.last_updated') }} @include ('forum::partials.timestamp', ['carbon' => $post->updated_at])) + @endif + +
    +
    +
    + @if ($post->parent !== null) + @include ('forum::post.partials.quote', ['post' => $post->parent]) + @endif + + @if ($post->trashed()) + @can ('viewTrashedPosts') + {!! Forum::render($post->content) !!} +
    + @endcan + {{ trans('forum::general.deleted') }} + @else + {!! Forum::render($post->content) !!} + @endif + + @if (!isset($single) || !$single) +
    + @if (!$post->trashed()) + {{ trans('forum::general.permalink') }} + @if ($post->sequence != 1) + @can ('deletePosts', $post->thread) + @can ('delete', $post) + {{ trans('forum::general.delete') }} + @endcan + @endcan + @endif + @can ('edit', $post) + {{ trans('forum::general.edit') }} + @endcan + @can ('reply', $post->thread) + {{ trans('forum::general.reply') }} + @endcan + @else + @can ('restorePosts', $post->thread) + @can ('restore', $post) + {{ trans('forum::general.restore') }} + @endcan + @endcan + @endif +
    + @endif +
    +
    diff --git a/resources/forum/blade-tailwind/views/post/partials/quote.blade.php b/resources/forum/blade-tailwind/views/post/partials/quote.blade.php new file mode 100644 index 000000000..9c7649f9e --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/partials/quote.blade.php @@ -0,0 +1,13 @@ +
    +
    +
    + + #{{ $post->sequence }} + +
    + {{ $post->authorName }} {{ $post->posted }} +
    +
    + {!! \Illuminate\Support\Str::limit(Forum::render($post->content)) !!} +
    +
    diff --git a/resources/forum/blade-tailwind/views/post/show.blade.php b/resources/forum/blade-tailwind/views/post/show.blade.php new file mode 100644 index 000000000..9e1d1b056 --- /dev/null +++ b/resources/forum/blade-tailwind/views/post/show.blade.php @@ -0,0 +1,14 @@ +@extends ('forum::layouts.main', ['breadcrumbs_append' => [trans('forum::posts.view')]]) + +@section ('content') +
    +
    +

    {{ trans('forum::posts.view') }} ({{ $thread->title }})

    + {{ trans('forum::threads.view') }} +
    + +
    + + @include ('forum::post.partials.list', ['post' => $post, 'single' => true]) +
    +@stop diff --git a/resources/forum/blade-tailwind/views/thread/create.blade.php b/resources/forum/blade-tailwind/views/thread/create.blade.php new file mode 100644 index 000000000..d9effc59f --- /dev/null +++ b/resources/forum/blade-tailwind/views/thread/create.blade.php @@ -0,0 +1,25 @@ +@extends ('forum::layouts.main', ['breadcrumbs_append' => [trans('forum::threads.new_thread')]]) + +@section ('content') +
    +

    {{ trans('forum::threads.new_thread') }} ({{ $category->title }})

    + +
    + @csrf + +
    + {{ trans('forum::general.title') }} + +
    + +
    + {{ old('content') }} +
    + +
    + {{ trans('forum::general.cancel') }} + {{ trans('forum::general.create') }} +
    +
    +
    +@stop diff --git a/resources/forum/blade-tailwind/views/thread/modals/mark-as-read.blade.php b/resources/forum/blade-tailwind/views/thread/modals/mark-as-read.blade.php new file mode 100644 index 000000000..8c196ac65 --- /dev/null +++ b/resources/forum/blade-tailwind/views/thread/modals/mark-as-read.blade.php @@ -0,0 +1,14 @@ +@component('forum::modal-form') + @slot('key', 'mark-as-read') + @slot('title', trans('forum::general.mark_read')) + @slot('route', Forum::route('unread.mark-as-read')) + @slot('method', 'PATCH') + +

    {{ trans('forum::general.generic_confirm') }}

    + + @slot('actions') + + {{ trans('forum::general.mark_read') }} + + @endslot +@endcomponent diff --git a/resources/forum/blade-tailwind/views/thread/partials/list.blade.php b/resources/forum/blade-tailwind/views/thread/partials/list.blade.php new file mode 100644 index 000000000..a30f82fa3 --- /dev/null +++ b/resources/forum/blade-tailwind/views/thread/partials/list.blade.php @@ -0,0 +1,52 @@ +
    +
    +
    + + {{ $thread->title }} + +
    + {{ $thread->authorName }} + @include ('forum::partials.timestamp', ['carbon' => $thread->created_at]) + + @if (!isset($category)) +
    + {{ $thread->category->title }} + @endif +
    + +
    + @if ($thread->pinned) + {{ trans('forum::threads.pinned') }} + @endif + @if ($thread->locked) + {{ trans('forum::threads.locked') }} + @endif + @if ($thread->userReadStatus !== null && !$thread->trashed()) + {{ trans($thread->userReadStatus) }} + @endif + @if ($thread->trashed()) + {{ trans('forum::general.deleted') }} + @endif + + {{ trans('forum::general.replies') }}: + {{ $thread->reply_count }} + +
    + + @if ($thread->lastPost) +
    + {{ trans('forum::posts.view') }} » +
    + {{ $thread->lastPost->authorName }} + @include ('forum::partials.timestamp', ['carbon' => $thread->lastPost->created_at]) +
    +
    + @endif + + @if (isset($category) && isset($selectableThreadIds) && in_array($thread->id, $selectableThreadIds)) +
    + +
    + @endif +
    +
    diff --git a/resources/forum/blade-tailwind/views/thread/recent.blade.php b/resources/forum/blade-tailwind/views/thread/recent.blade.php new file mode 100644 index 000000000..b96988453 --- /dev/null +++ b/resources/forum/blade-tailwind/views/thread/recent.blade.php @@ -0,0 +1,21 @@ +@extends ('forum::layouts.main', ['thread' => null, 'breadcrumbs_append' => [trans('forum::threads.recent')]]) + +@section ('content') +
    +

    {{ trans('forum::threads.recent') }}

    + + @if (!$threads->isEmpty()) +
    + @foreach ($threads as $thread) + @include ('forum::thread.partials.list') + @endforeach +
    + @else +
    +
    + {{ trans('forum::threads.none_found') }} +
    +
    + @endif +
    +@stop diff --git a/resources/forum/blade-tailwind/views/thread/show.blade.php b/resources/forum/blade-tailwind/views/thread/show.blade.php new file mode 100644 index 000000000..0e8afc3bd --- /dev/null +++ b/resources/forum/blade-tailwind/views/thread/show.blade.php @@ -0,0 +1,391 @@ +@extends ('forum::layouts.main', ['thread' => null, 'breadcrumbs_append' => [$thread->title], 'thread_title' => $thread->title]) + +@section ('content') +
    +
    +

    {{ $thread->title }}

    + +
    + @if (Gate::allows('deleteThreads', $thread->category) && Gate::allows('delete', $thread)) + @if ($thread->trashed()) + + {{ trans('forum::general.perma_delete') }} + + @else + + {{ trans('forum::general.delete') }} + + @endif + @endif + @if ($thread->trashed() && Gate::allows('restoreThreads', $thread->category) && Gate::allows('restore', $thread)) + + {{ trans('forum::general.restore') }} + + @endif + + @if (Gate::allows('lockThreads', $category) + || Gate::allows('pinThreads', $category) + || Gate::allows('rename', $thread) + || Gate::allows('moveThreadsFrom', $category)) + + @if (!$thread->trashed()) + @can ('lockThreads', $category) + @if ($thread->locked) + + {{ trans('forum::threads.unlock') }} + + @else + + {{ trans('forum::threads.lock') }} + + @endif + @endcan + @can ('pinThreads', $category) + @if ($thread->pinned) + + {{ trans('forum::threads.unpin') }} + + @else + + {{ trans('forum::threads.pin') }} + + @endif + @endcan + @can ('rename', $thread) + + {{ trans('forum::general.rename') }} + + @endcan + @can ('moveThreadsFrom', $category) + + {{ trans('forum::general.move') }} + + @endcan + @endif + + @endcan +
    +
    + +
    + @if ($thread->trashed()) + {{ trans('forum::general.deleted') }} + @endif + @if ($thread->pinned) + {{ trans('forum::threads.pinned') }} + @endif + @if ($thread->locked) + {{ trans('forum::threads.locked') }} + @endif +
    + + @if ((count($posts) > 1 || $posts->currentPage() > 1) && (Gate::allows('deletePosts', $thread) || Gate::allows('restorePosts', $thread)) && count($selectablePosts) > 0) +
    + @csrf + + @endif + +
    +
    + {{ $posts->links('forum::pagination') }} +
    +
    + @if (!$thread->trashed()) + @can ('reply', $thread) + + + {{ trans('forum::general.new_reply') }} + + + {{ trans('forum::general.quick_reply') }} + + + @endcan + @endif +
    +
    + + @if ((count($posts) > 1 || $posts->currentPage() > 1) && (Gate::allows('deletePosts', $thread) || Gate::allows('restorePosts', $thread)) && count($selectablePosts) > 0) +
    +
    + + +
    +
    + @endif + + @foreach ($posts as $post) + @include ('forum::post.partials.list', compact('post')) + @endforeach + + @if ((count($posts) > 1 || $posts->currentPage() > 1) && (Gate::allows('deletePosts', $thread) || Gate::allows('restorePosts', $thread)) && count($selectablePosts) > 0) +
    +
    +
    + {{ trans('forum::general.with_selection') }} +
    +
    +
    +
    + {{ trans_choice('forum::general.actions', 1) }} +
    + + + + + +
    + + @if (config('forum.general.soft_deletes')) +
    + + +
    + @endif + +
    + {{ trans('forum::general.proceed') }} +
    +
    +
    +
    +
    + @endif + + {{ $posts->links('forum::pagination') }} + + @if (!$thread->trashed()) + @can ('reply', $thread) +

    {{ trans('forum::general.quick_reply') }}

    +
    +
    + @csrf + +
    + {{ old('content') }} +
    + +
    + {{ trans('forum::general.reply') }} +
    +
    +
    + @endcan + @endif +
    + + @if ($thread->trashed() && Gate::allows('restoreThreads', $thread->category) && Gate::allows('restore', $thread)) + @component('forum::modal-form') + @slot('key', 'restore-thread') + @slot('title', '' . trans('forum::general.restore')) + @slot('route', Forum::route('thread.restore', $thread)) + @slot('method', 'POST') + + {{ trans('forum::general.generic_confirm') }} + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @endif + + @if (Gate::allows('deleteThreads', $thread->category) && Gate::allows('delete', $thread)) + @component('forum::modal-form') + @slot('key', 'delete-thread') + @slot('title', '' . trans('forum::threads.delete')) + @slot('route', Forum::route('thread.delete', $thread)) + @slot('method', 'DELETE') + + @if (config('forum.general.soft_deletes')) +
    + + +
    + @else + {{ trans('forum::general.generic_confirm') }} + @endif + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + + @if (config('forum.general.soft_deletes')) + @component('forum::modal-form') + @slot('key', 'perma-delete-thread') + @slot('title', '' . trans_choice('forum::threads.perma_delete', 1)) + @slot('route', Forum::route('thread.delete', $thread)) + @slot('method', 'DELETE') + + + + {{ trans('forum::general.generic_confirm') }} + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @endif + @endif + + @if (!$thread->trashed()) + @can ('lockThreads', $category) + @if ($thread->locked) + @component('forum::modal-form') + @slot('key', 'unlock-thread') + @slot('title', ' ' . trans('forum::threads.unlock')) + @slot('route', Forum::route('thread.unlock', $thread)) + @slot('method', 'POST') + + {{ trans('forum::general.generic_confirm') }} + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @else + @component('forum::modal-form') + @slot('key', 'lock-thread') + @slot('title', ' ' . trans('forum::threads.lock')) + @slot('route', Forum::route('thread.lock', $thread)) + @slot('method', 'POST') + + {{ trans('forum::general.generic_confirm') }} + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @endif + @endcan + + @can ('pinThreads', $category) + @if ($thread->pinned) + @component('forum::modal-form') + @slot('key', 'unpin-thread') + @slot('title', ' ' . trans('forum::threads.unpin')) + @slot('route', Forum::route('thread.unpin', $thread)) + @slot('method', 'POST') + + {{ trans('forum::general.generic_confirm') }} + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @else + @component('forum::modal-form') + @slot('key', 'pin-thread') + @slot('title', ' ' . trans('forum::threads.pin')) + @slot('route', Forum::route('thread.pin', $thread)) + @slot('method', 'POST') + + {{ trans('forum::general.generic_confirm') }} + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @endif + @endcan + + @can ('rename', $thread) + @component('forum::modal-form') + @slot('key', 'rename-thread') + @slot('title', ' ' . trans('forum::general.rename')) + @slot('route', Forum::route('thread.rename', $thread)) + @slot('method', 'POST') + +
    + {{ trans('forum::general.title') }} + +
    + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @endcan + + @can ('moveThreadsFrom', $category) + @component('forum::modal-form') + @slot('key', 'move-thread') + @slot('title', ' ' . trans('forum::general.move')) + @slot('route', Forum::route('thread.move', $thread)) + @slot('method', 'POST') + +
    +
    + +
    + +
    + + @slot('actions') + {{ trans('forum::general.proceed') }} + @endslot + @endcomponent + @endcan + @endif + + +@stop diff --git a/resources/forum/blade-tailwind/views/thread/unread.blade.php b/resources/forum/blade-tailwind/views/thread/unread.blade.php new file mode 100644 index 000000000..560ac0edd --- /dev/null +++ b/resources/forum/blade-tailwind/views/thread/unread.blade.php @@ -0,0 +1,31 @@ +@extends ('forum::layouts.main', ['thread' => null, 'breadcrumbs_append' => [trans('forum::threads.unread_updated')]]) + +@section ('content') +
    +

    {{ trans('forum::threads.unread_updated') }}

    + + @if (!$threads->isEmpty()) +
    + @foreach ($threads as $thread) + @include ('forum::thread.partials.list') + @endforeach +
    + @else +
    + {{ trans('forum::threads.none_found') }} +
    + @endif +
    + + @if (!$threads->isEmpty()) + @can ('markThreadsAsRead') +
    + + {{ trans('forum::general.mark_read') }} + +
    + + @include ('forum::thread.modals.mark-as-read') + @endcan + @endif +@stop diff --git a/resources/forum/livewire-tailwind/views/pages/category/create.blade.php b/resources/forum/livewire-tailwind/views/pages/category/create.blade.php index af65f9781..9cc159743 100644 --- a/resources/forum/livewire-tailwind/views/pages/category/create.blade.php +++ b/resources/forum/livewire-tailwind/views/pages/category/create.blade.php @@ -19,13 +19,13 @@ wire:model="description" /> diff --git a/resources/forum/livewire-tailwind/views/pages/category/edit.blade.php b/resources/forum/livewire-tailwind/views/pages/category/edit.blade.php index 1261410c3..d2eb5c846 100644 --- a/resources/forum/livewire-tailwind/views/pages/category/edit.blade.php +++ b/resources/forum/livewire-tailwind/views/pages/category/edit.blade.php @@ -20,13 +20,13 @@ wire:model="description" /> diff --git a/vite.config.js b/vite.config.js index 7bc1aa0d5..b8b536158 100644 --- a/vite.config.js +++ b/vite.config.js @@ -9,6 +9,8 @@ export default defineConfig({ 'resources/js/app.js', 'resources/forum/livewire-tailwind/css/forum.css', 'resources/forum/livewire-tailwind/js/forum.js', + 'resources/forum/blade-tailwind/css/forum.css', + 'resources/forum/blade-tailwind/js/forum.js', ], refresh: true, }),