move into sonardesk
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<?php
|
||||
|
||||
return ['name' => 'Tags'];
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('tags', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('slug')->unique();
|
||||
$table->text('description')->nullable();
|
||||
$table->unsignedInteger('usage_count')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('tags');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Tags\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\RedirectResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\View\View;
|
||||
use Modules\Tags\Models\Tag;
|
||||
|
||||
final class TagController extends Controller
|
||||
{
|
||||
public function index(): View
|
||||
{
|
||||
return view('tags::admin.index', ['records' => Tag::orderByDesc('usage_count')->paginate(30)]);
|
||||
}
|
||||
|
||||
public function create(): View
|
||||
{
|
||||
return view('tags::admin.form');
|
||||
}
|
||||
|
||||
public function store(Request $request): RedirectResponse
|
||||
{
|
||||
Tag::create($request->validate(['name' => ['required', 'string', 'max:255'], 'slug' => ['required', 'string', 'max:255', 'unique:tags,slug'], 'description' => ['nullable', 'string']]));
|
||||
|
||||
return redirect()->route('administration.tags.index')->with('status', 'Tag created.');
|
||||
}
|
||||
|
||||
public function edit(Tag $tag): View
|
||||
{
|
||||
return view('tags::admin.form', ['record' => $tag]);
|
||||
}
|
||||
|
||||
public function update(Request $request, Tag $tag): RedirectResponse
|
||||
{
|
||||
$tag->update($request->validate(['name' => ['required', 'string', 'max:255'], 'slug' => ['required', 'string', 'max:255', 'unique:tags,slug,'.$tag->id], 'description' => ['nullable', 'string']]));
|
||||
|
||||
return redirect()->route('administration.tags.index')->with('status', 'Tag updated.');
|
||||
}
|
||||
|
||||
public function destroy(Tag $tag): RedirectResponse
|
||||
{
|
||||
$tag->delete();
|
||||
|
||||
return back()->with('status', 'Tag deleted.');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Tags\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
final class Tag extends Model
|
||||
{
|
||||
protected $fillable = ['name', 'slug', 'description', 'usage_count'];
|
||||
|
||||
protected function casts(): array
|
||||
{
|
||||
return ['usage_count' => 'integer'];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Tags\Providers;
|
||||
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
final class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function boot(): void
|
||||
{
|
||||
parent::boot();
|
||||
Route::middleware('web')->group(module_path('Tags', 'Routes/web.php'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Tags\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
final class TagsServiceProvider extends ServiceProvider
|
||||
{
|
||||
public function register(): void
|
||||
{
|
||||
$this->app->register(RouteServiceProvider::class);
|
||||
$this->mergeConfigFrom(module_path('Tags', 'Config/config.php'), 'tags');
|
||||
}
|
||||
|
||||
public function boot(): void
|
||||
{
|
||||
$this->loadMigrationsFrom(module_path('Tags', 'Database/Migrations'));
|
||||
$this->loadViewsFrom(module_path('Tags', 'Resources/views'), 'tags');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.app :title="isset($record) ? 'Edit tag' : 'Create tag'"><form method="POST" action="{{ isset($record) ? route('administration.tags.update',$record) : route('administration.tags.store') }}" class="max-w-3xl space-y-5">@csrf @isset($record) @method('PUT') @endisset <flux:input name="name" label="Name" value="{{ old('name',$record->name ?? '') }}" required/><flux:input name="slug" label="Slug" value="{{ old('slug',$record->slug ?? '') }}" required/><flux:textarea name="description" label="Description">{{ old('description',$record->description ?? '') }}</flux:textarea><flux:button type="submit" variant="primary">Save</flux:button></form></x-layouts.app>
|
||||
@@ -0,0 +1 @@
|
||||
<x-layouts.app :title="__('Tags')"><div class="flex items-center justify-between mb-6"><div><h1 class="text-2xl font-semibold">Tags</h1><p class="text-sm text-zinc-500">Manage publishing tags.</p></div><flux:button variant="primary" :href="route('administration.tags.create')" wire:navigate>Create</flux:button></div>@if(session('status'))<div class="mb-4 rounded border border-green-300 bg-green-50 p-3 text-green-800">{{ session('status') }}</div>@endif<div class="overflow-hidden rounded-xl border border-zinc-200 bg-white"><table class="w-full text-sm"><thead class="bg-zinc-50"><tr><th class="p-3 text-left">Name / title</th><th class="p-3 text-left">Status</th><th class="p-3 text-right">Actions</th></tr></thead><tbody>@forelse($records as $record)<tr class="border-t"><td class="p-3 font-medium">{{ $record->title ?? $record->name }}</td><td class="p-3">{{ $record->status ?? ($record->is_active ? 'Active' : 'Inactive') }}</td><td class="p-3 text-right"><flux:button size="sm" :href="route('administration.tags.edit', $record)" wire:navigate>Edit</flux:button><form class="inline" method="POST" action="{{ route('administration.tags.destroy', $record) }}">@csrf @method('DELETE')<flux:button size="sm" variant="danger" type="submit">Delete</flux:button></form></td></tr>@empty<tr><td colspan="3" class="p-6 text-center text-zinc-500">No records yet.</td></tr>@endforelse</tbody></table></div><div class="mt-4">{{ $records->links() }}</div></x-layouts.app>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Tags\Http\Controllers\TagController;
|
||||
|
||||
Route::middleware(['auth', 'verified'])->prefix('administration/tags')->name('administration.tags.')->group(function (): void {
|
||||
Route::get('/', [TagController::class, 'index'])->name('index');
|
||||
Route::get('/create', [TagController::class, 'create'])->name('create');
|
||||
Route::post('/', [TagController::class, 'store'])->name('store');
|
||||
Route::get('/{tag}/edit', [TagController::class, 'edit'])->name('edit');
|
||||
Route::match(['put', 'patch'], '/{tag}', [TagController::class, 'update'])->name('update');
|
||||
Route::delete('/{tag}', [TagController::class, 'destroy'])->name('destroy');
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Tags\Tests\Feature;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
final class ModuleBootTest extends TestCase
|
||||
{
|
||||
public function test_module_configuration_is_available(): void
|
||||
{
|
||||
$this->assertSame('Tags', config('tags.name'));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "Tags",
|
||||
"alias": "tags",
|
||||
"version": "1.0.0",
|
||||
"description": "Tags publishing module.",
|
||||
"keywords": ["publishing", "tags"],
|
||||
"priority": 30,
|
||||
"providers": ["Modules\\Tags\\Providers\\TagsServiceProvider"],
|
||||
"aliases": {},
|
||||
"files": [],
|
||||
"requires": ["Core", "Administration"]
|
||||
}
|
||||
Reference in New Issue
Block a user