added support for legacy tickets
This commit is contained in:
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
return [
|
||||
'route_prefix' => env('HELPDESK_ROUTE_PREFIX', 'admin/helpdesk'),
|
||||
'middleware' => ['web', 'auth'],
|
||||
'legacy_connection' => env('HELPDESK_LEGACY_DB_CONNECTION', config('database.default')),
|
||||
'disk' => env('HELPDESK_ATTACHMENTS_DISK', 'local'),
|
||||
'max_upload_kb' => (int) env('HELPDESK_MAX_UPLOAD_KB', 10240),
|
||||
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Console;
|
||||
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Database\ConnectionInterface;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Modules\Helpdesk\Models\LegacyCategory;
|
||||
use Modules\Helpdesk\Models\LegacyComment;
|
||||
use Modules\Helpdesk\Models\LegacyTicket;
|
||||
use Throwable;
|
||||
|
||||
final class ImportLegacyHelpdeskCommand extends Command
|
||||
{
|
||||
protected $signature = 'helpdesk:import-legacy {--connection= : Laravel database connection containing the old tickets tables} {--fresh : Clear previously imported legacy records first}';
|
||||
protected $description = 'Import the old Helpdesk tickets and categories into the read-only Legacy System';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$connectionName = (string) ($this->option('connection') ?: config('helpdesk.legacy_connection', config('database.default')));
|
||||
$source = DB::connection($connectionName);
|
||||
$schema = Schema::connection($connectionName);
|
||||
|
||||
foreach (['tickets', 'tickets_categories'] as $table) {
|
||||
if (! $schema->hasTable($table)) {
|
||||
$this->error("Source table {$table} was not found on connection [{$connectionName}].");
|
||||
return self::FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->option('fresh')) {
|
||||
LegacyComment::query()->delete();
|
||||
LegacyTicket::query()->delete();
|
||||
LegacyCategory::query()->delete();
|
||||
}
|
||||
|
||||
$this->importCategories($source);
|
||||
$this->importTickets($source, $schema);
|
||||
$this->importComments($source, $schema);
|
||||
$this->refreshCategoryCounts();
|
||||
|
||||
$this->info(sprintf('Legacy import complete: %d tickets, %d categories, %d comments.', LegacyTicket::count(), LegacyCategory::count(), LegacyComment::count()));
|
||||
return self::SUCCESS;
|
||||
}
|
||||
|
||||
private function importCategories(ConnectionInterface $source): void
|
||||
{
|
||||
$source->table('tickets_categories')->orderBy('id')->chunk(500, function ($rows): void {
|
||||
foreach ($rows as $row) {
|
||||
LegacyCategory::updateOrCreate(['legacy_id' => $row->id], ['name' => (string) $row->name, 'color' => $row->color ?? null]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function importTickets(ConnectionInterface $source, $schema): void
|
||||
{
|
||||
$columns = collect($schema->getColumnListing('tickets'));
|
||||
$lookups = [
|
||||
'category' => $this->lookup($source, $schema, 'tickets_categories'),
|
||||
'status' => $this->lookup($source, $schema, 'tickets_statuses'),
|
||||
'priority' => $this->lookup($source, $schema, 'tickets_priorities'),
|
||||
'project' => $this->lookup($source, $schema, 'projects'),
|
||||
'user' => $this->lookup($source, $schema, 'users'),
|
||||
];
|
||||
|
||||
$source->table('tickets')->orderBy('id')->chunk(250, function ($rows) use ($columns, $lookups): void {
|
||||
foreach ($rows as $row) {
|
||||
$data = (array) $row;
|
||||
LegacyTicket::updateOrCreate(['legacy_id' => $row->id], [
|
||||
'reference' => $data['reference'] ?? null,
|
||||
'subject' => (string) ($data['subject'] ?? 'Legacy ticket #'.$row->id),
|
||||
'content' => $data['content'] ?? null,
|
||||
'html_content' => $data['htmlcontent'] ?? null,
|
||||
'legacy_category_id' => $data['category_id'] ?? null,
|
||||
'category_name' => $lookups['category'][$data['category_id'] ?? 0] ?? null,
|
||||
'status_name' => $lookups['status'][$data['status_id'] ?? 0] ?? null,
|
||||
'priority_name' => $lookups['priority'][$data['priority_id'] ?? 0] ?? null,
|
||||
'requester_name' => $lookups['user'][$data['user_id'] ?? 0] ?? null,
|
||||
'agent_name' => $lookups['user'][$data['agent_id'] ?? 0] ?? null,
|
||||
'project_name' => $lookups['project'][$data['project_id'] ?? 0] ?? null,
|
||||
'legacy_created_at' => $data['created_at'] ?? null,
|
||||
'legacy_updated_at' => $data['updated_at'] ?? null,
|
||||
'completed_at' => $data['completed_at'] ?? null,
|
||||
'archived_at' => $data['archived_at'] ?? null,
|
||||
'legacy_data' => $data,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function importComments(ConnectionInterface $source, $schema): void
|
||||
{
|
||||
if (! $schema->hasTable('tickets_comments')) return;
|
||||
$users = $this->lookup($source, $schema, 'users');
|
||||
$source->table('tickets_comments')->orderBy('id')->chunk(500, function ($rows) use ($users): void {
|
||||
foreach ($rows as $row) {
|
||||
$data = (array) $row;
|
||||
LegacyComment::updateOrCreate(['legacy_id' => $row->id], [
|
||||
'legacy_ticket_id' => $data['ticket_id'],
|
||||
'author_name' => $users[$data['user_id'] ?? 0] ?? null,
|
||||
'content' => $data['content'] ?? null,
|
||||
'html_content' => $data['htmlcontent'] ?? null,
|
||||
'legacy_created_at' => $data['created_at'] ?? null,
|
||||
'legacy_updated_at' => $data['updated_at'] ?? null,
|
||||
]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private function lookup(ConnectionInterface $source, $schema, string $table): array
|
||||
{
|
||||
if (! $schema->hasTable($table)) return [];
|
||||
$columns = $schema->getColumnListing($table);
|
||||
$nameColumn = in_array('name', $columns, true) ? 'name' : (in_array('username', $columns, true) ? 'username' : null);
|
||||
if ($nameColumn === null) return [];
|
||||
try { return $source->table($table)->pluck($nameColumn, 'id')->map(fn ($v) => (string) $v)->all(); } catch (Throwable) { return []; }
|
||||
}
|
||||
|
||||
private function refreshCategoryCounts(): void
|
||||
{
|
||||
LegacyCategory::query()->each(function (LegacyCategory $category): void {
|
||||
$category->update(['ticket_count' => LegacyTicket::query()->where('legacy_category_id', $category->legacy_id)->count()]);
|
||||
});
|
||||
}
|
||||
}
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
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('helpdesk_legacy_categories', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('legacy_id')->unique();
|
||||
$table->string('name');
|
||||
$table->string('color', 32)->nullable();
|
||||
$table->unsignedInteger('ticket_count')->default(0);
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('helpdesk_legacy_tickets', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('legacy_id')->unique();
|
||||
$table->string('reference')->nullable()->index();
|
||||
$table->string('subject');
|
||||
$table->longText('content')->nullable();
|
||||
$table->longText('html_content')->nullable();
|
||||
$table->unsignedBigInteger('legacy_category_id')->nullable()->index();
|
||||
$table->string('category_name')->nullable();
|
||||
$table->string('status_name')->nullable();
|
||||
$table->string('priority_name')->nullable();
|
||||
$table->string('requester_name')->nullable();
|
||||
$table->string('agent_name')->nullable();
|
||||
$table->string('project_name')->nullable();
|
||||
$table->timestamp('legacy_created_at')->nullable()->index();
|
||||
$table->timestamp('legacy_updated_at')->nullable();
|
||||
$table->timestamp('completed_at')->nullable();
|
||||
$table->timestamp('archived_at')->nullable();
|
||||
$table->json('legacy_data')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create('helpdesk_legacy_comments', function (Blueprint $table): void {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger('legacy_id')->unique();
|
||||
$table->unsignedBigInteger('legacy_ticket_id')->index();
|
||||
$table->string('author_name')->nullable();
|
||||
$table->longText('content')->nullable();
|
||||
$table->longText('html_content')->nullable();
|
||||
$table->timestamp('legacy_created_at')->nullable();
|
||||
$table->timestamp('legacy_updated_at')->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('helpdesk_legacy_comments');
|
||||
Schema::dropIfExists('helpdesk_legacy_tickets');
|
||||
Schema::dropIfExists('helpdesk_legacy_categories');
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Http\Controllers;
|
||||
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Helpdesk\Models\LegacyCategory;
|
||||
use Modules\Helpdesk\Models\LegacyTicket;
|
||||
|
||||
final class LegacySystemController
|
||||
{
|
||||
public function tickets(Request $request): View
|
||||
{
|
||||
$search = trim((string) $request->query('search', ''));
|
||||
$category = $request->integer('category');
|
||||
|
||||
$tickets = LegacyTicket::query()
|
||||
->when($search !== '', fn ($query) => $query->where(function ($q) use ($search): void {
|
||||
$q->where('reference', 'like', "%{$search}%")
|
||||
->orWhere('subject', 'like', "%{$search}%")
|
||||
->orWhere('requester_name', 'like', "%{$search}%");
|
||||
}))
|
||||
->when($category > 0, fn ($query) => $query->where('legacy_category_id', $category))
|
||||
->orderByDesc('legacy_created_at')
|
||||
->orderByDesc('legacy_id')
|
||||
->paginate(30)
|
||||
->withQueryString();
|
||||
|
||||
return view('helpdesk::legacy.tickets', [
|
||||
'tickets' => $tickets,
|
||||
'categories' => LegacyCategory::query()->orderBy('name')->get(),
|
||||
'search' => $search,
|
||||
'selectedCategory' => $category,
|
||||
]);
|
||||
}
|
||||
|
||||
public function show(LegacyTicket $ticket): View
|
||||
{
|
||||
$ticket->load('comments');
|
||||
return view('helpdesk::legacy.show', compact('ticket'));
|
||||
}
|
||||
|
||||
public function categories(): View
|
||||
{
|
||||
return view('helpdesk::legacy.categories', [
|
||||
'categories' => LegacyCategory::query()->orderBy('name')->paginate(50),
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
final class LegacyCategory extends Model
|
||||
{
|
||||
protected $table = 'helpdesk_legacy_categories';
|
||||
protected $guarded = [];
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
final class LegacyComment extends Model
|
||||
{
|
||||
protected $table = 'helpdesk_legacy_comments';
|
||||
protected $guarded = [];
|
||||
protected $casts = ['legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime'];
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Modules\Helpdesk\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
final class LegacyTicket extends Model
|
||||
{
|
||||
protected $table = 'helpdesk_legacy_tickets';
|
||||
protected $guarded = [];
|
||||
protected $casts = ['legacy_data' => 'array', 'legacy_created_at' => 'datetime', 'legacy_updated_at' => 'datetime', 'completed_at' => 'datetime', 'archived_at' => 'datetime'];
|
||||
|
||||
public function comments(): HasMany
|
||||
{
|
||||
return $this->hasMany(LegacyComment::class, 'legacy_ticket_id', 'legacy_id')->orderBy('legacy_created_at');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<x-layouts::app :title="__('Legacy Categories')">
|
||||
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6">
|
||||
<div class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><div class="bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950 px-6 py-7 text-white"><p class="text-xs font-semibold uppercase tracking-[0.28em] text-blue-200">Legacy System</p><h1 class="mt-2 text-3xl font-semibold tracking-tight">Legacy Categories</h1><p class="mt-2 text-sm text-blue-100/90">Categories retained from the previous Helpdesk.</p></div></div>
|
||||
<div class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><table class="w-full text-left text-sm"><thead class="border-b border-zinc-200 bg-zinc-50 text-xs uppercase text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800/60"><tr><th class="px-5 py-3">Category</th><th class="px-5 py-3">Legacy ID</th><th class="px-5 py-3 text-right">Tickets</th></tr></thead><tbody class="divide-y divide-zinc-200 dark:divide-zinc-800">@forelse($categories as $category)<tr><td class="px-5 py-4"><a class="font-semibold text-blue-600 hover:underline" href="{{ route('helpdesk.legacy.tickets', ['category' => $category->legacy_id]) }}" wire:navigate>{{ $category->name }}</a></td><td class="px-5 py-4 text-zinc-500">{{ $category->legacy_id }}</td><td class="px-5 py-4 text-right">{{ $category->ticket_count }}</td></tr>@empty<tr><td colspan="3" class="px-5 py-10 text-center text-zinc-500">No legacy categories have been imported.</td></tr>@endforelse</tbody></table>@if($categories->hasPages())<div class="border-t border-zinc-200 p-4 dark:border-zinc-700">{{ $categories->links() }}</div>@endif</div>
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
@@ -0,0 +1,6 @@
|
||||
<x-layouts::app :title="$ticket->reference ?: 'Legacy Ticket #'.$ticket->legacy_id">
|
||||
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6">
|
||||
<div class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><div class="bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950 px-6 py-7 text-white"><div class="flex items-start justify-between gap-4"><div><p class="text-xs font-semibold uppercase tracking-[0.28em] text-blue-200">Legacy System · Read only</p><h1 class="mt-2 text-3xl font-semibold tracking-tight">{{ $ticket->subject }}</h1><p class="mt-2 text-sm text-blue-100/90">{{ $ticket->reference ?: 'Legacy ticket #'.$ticket->legacy_id }}</p></div><a href="{{ route('helpdesk.legacy.tickets') }}" wire:navigate class="hd-btn hd-btn-blue"><i class="fa-solid fa-arrow-left"></i><span>Legacy Tickets</span></a></div></div></div>
|
||||
<div class="grid gap-6 xl:grid-cols-[1fr_320px]"><div class="space-y-6"><section class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><h2 class="mb-4 text-lg font-semibold">Original request</h2><div class="prose max-w-none dark:prose-invert">{!! $ticket->html_content ?: nl2br(e($ticket->content ?: 'No content recorded.')) !!}</div></section>@if($ticket->comments->isNotEmpty())<section class="rounded-2xl border border-zinc-200 bg-white p-6 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><h2 class="mb-4 text-lg font-semibold">Comments</h2><div class="space-y-4">@foreach($ticket->comments as $comment)<article class="rounded-xl border border-zinc-200 p-4 dark:border-zinc-700"><div class="mb-2 flex justify-between text-xs text-zinc-500"><strong>{{ $comment->author_name ?: 'Legacy user' }}</strong><span>{{ $comment->legacy_created_at?->format('d M Y H:i') }}</span></div><div class="prose max-w-none text-sm dark:prose-invert">{!! $comment->html_content ?: nl2br(e($comment->content ?: '')) !!}</div></article>@endforeach</div></section>@endif</div><aside><div class="rounded-2xl border border-zinc-200 bg-white p-5 shadow-sm dark:border-zinc-700 dark:bg-zinc-900"><h2 class="mb-4 font-semibold">Legacy details</h2><dl class="space-y-3 text-sm">@foreach(['Category'=>$ticket->category_name,'Status'=>$ticket->status_name,'Priority'=>$ticket->priority_name,'Requester'=>$ticket->requester_name,'Agent'=>$ticket->agent_name,'Project'=>$ticket->project_name] as $label=>$value)<div><dt class="text-xs uppercase tracking-wide text-zinc-500">{{ $label }}</dt><dd class="mt-1 font-medium">{{ $value ?: '—' }}</dd></div>@endforeach<div><dt class="text-xs uppercase tracking-wide text-zinc-500">Created</dt><dd class="mt-1 font-medium">{{ $ticket->legacy_created_at?->format('d M Y H:i') ?: '—' }}</dd></div></dl></div></aside></div>
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
@@ -0,0 +1,78 @@
|
||||
<x-layouts::app :title="__('Legacy Tickets')">
|
||||
<div class="hd-helpdesk-surface hd-mobile-ready space-y-6">
|
||||
<div class="overflow-hidden rounded-3xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div class="bg-gradient-to-br from-slate-950 via-slate-900 to-blue-950 px-6 py-7 text-white">
|
||||
<p class="text-xs font-semibold uppercase tracking-[0.28em] text-blue-200">Legacy System</p>
|
||||
<h1 class="mt-2 text-3xl font-semibold tracking-tight">Legacy Tickets</h1>
|
||||
<p class="mt-2 text-sm text-blue-100/90">Historical tickets from the previous Helpdesk. These records are read-only.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-2xl border border-zinc-200 bg-white p-4 shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<form class="grid gap-3 md:grid-cols-[1fr_260px_auto]" method="GET">
|
||||
<input class="hd-ticket-search" type="search" name="search" value="{{ $search }}" placeholder="Search reference, subject or requester">
|
||||
<select class="hd-select" name="category"><option value="">All legacy categories</option>@foreach($categories as $category)<option value="{{ $category->legacy_id }}" @selected($selectedCategory === $category->legacy_id)>{{ $category->name }}</option>@endforeach</select>
|
||||
<button class="hd-btn hd-btn-blue" type="submit"><i class="fa-solid fa-magnifying-glass"></i><span>Search</span></button>
|
||||
</form>
|
||||
</div>
|
||||
<div class="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-zinc-700 dark:bg-zinc-900">
|
||||
<div class="overflow-x-auto"><table class="w-full text-left text-sm"><thead class="border-b border-zinc-200 bg-zinc-50 text-xs uppercase text-zinc-500 dark:border-zinc-700 dark:bg-zinc-800/60"><tr><th class="px-5 py-3">Reference</th><th class="px-5 py-3">Subject</th><th class="px-5 py-3">Category</th><th class="px-5 py-3">Status</th><th class="px-5 py-3">Requester</th><th class="px-5 py-3">Created</th></tr></thead><tbody class="divide-y divide-zinc-200 dark:divide-zinc-800">@forelse($tickets as $ticket)
|
||||
<tr class="transition-colors dark:hover:bg-zinc-800/30">
|
||||
<td class="px-5 py-4"><a class="font-semibold text-blue-600 hover:underline" href="{{ route('helpdesk.legacy.tickets.show', $ticket) }}" wire:navigate>{{ $ticket->reference ?: '#'.$ticket->legacy_id }}</a></td><td class="px-5 py-4 font-medium">{{ $ticket->subject }}</td><td class="px-5 py-4">{{ $ticket->category_name ?: '—' }}</td><td class="px-5 py-4">{{ $ticket->status_name ?: '—' }}</td><td class="px-5 py-4">{{ $ticket->requester_name ?: '—' }}</td><td class="px-5 py-4 text-zinc-500">{{ $ticket->legacy_created_at?->format('d M Y H:i') ?: '—' }}</td></tr>@empty<tr><td class="px-5 py-10 text-center text-zinc-500" colspan="6">No legacy tickets have been imported.</td></tr>@endforelse</tbody></table></div>
|
||||
@if($tickets->hasPages())
|
||||
<div class="flex items-center justify-between border-t border-zinc-800 px-5 py-4">
|
||||
|
||||
{{-- Previous --}}
|
||||
@if($tickets->onFirstPage())
|
||||
<span
|
||||
class="inline-flex cursor-not-allowed items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-600"
|
||||
>
|
||||
<i class="fa-solid fa-chevron-left mr-2 text-xs"></i>
|
||||
Previous
|
||||
</span>
|
||||
@else
|
||||
<a
|
||||
href="{{ $tickets->previousPageUrl() }}"
|
||||
class="inline-flex items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-300 transition hover:border-zinc-600 hover:bg-zinc-800 hover:text-white"
|
||||
wire:navigate
|
||||
>
|
||||
<i class="fa-solid fa-chevron-left mr-2 text-xs"></i>
|
||||
Previous
|
||||
</a>
|
||||
@endif
|
||||
|
||||
{{-- Page information --}}
|
||||
<div class="text-sm text-zinc-500">
|
||||
Page
|
||||
<span class="font-semibold text-zinc-300">
|
||||
{{ $tickets->currentPage() }}
|
||||
</span>
|
||||
of
|
||||
<span class="font-semibold text-zinc-300">
|
||||
{{ $tickets->lastPage() }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{{-- Next --}}
|
||||
@if($tickets->hasMorePages())
|
||||
<a
|
||||
href="{{ $tickets->nextPageUrl() }}"
|
||||
class="inline-flex items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-300 transition hover:border-zinc-600 hover:bg-zinc-800 hover:text-white"
|
||||
wire:navigate
|
||||
>
|
||||
Next
|
||||
<i class="fa-solid fa-chevron-right ml-2 text-xs"></i>
|
||||
</a>
|
||||
@else
|
||||
<span
|
||||
class="inline-flex cursor-not-allowed items-center rounded-lg border border-zinc-700 bg-zinc-900 px-4 py-2 text-sm font-medium text-zinc-600"
|
||||
>
|
||||
Next
|
||||
<i class="fa-solid fa-chevron-right ml-2 text-xs"></i>
|
||||
</span>
|
||||
@endif
|
||||
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</x-layouts::app>
|
||||
@@ -5,6 +5,7 @@ declare(strict_types=1);
|
||||
use Illuminate\Support\Facades\Route;
|
||||
use Modules\Helpdesk\Http\Controllers\AttachmentDownloadController;
|
||||
use Modules\Helpdesk\Http\Controllers\HelpdeskController;
|
||||
use Modules\Helpdesk\Http\Controllers\LegacySystemController;
|
||||
use Modules\Helpdesk\Http\Controllers\TicketAttachmentStoreController;
|
||||
use Modules\Helpdesk\Http\Controllers\TicketBoardController;
|
||||
use Modules\Helpdesk\Http\Controllers\TicketCommentDeleteController;
|
||||
@@ -28,6 +29,10 @@ Route::get('/', HelpdeskController::class)->name('index');
|
||||
Route::get('/settings', SettingsManager::class)->name('settings');
|
||||
Route::get('/kanban', KanbanBoard::class)->name('kanban');
|
||||
|
||||
Route::get('/legacy/tickets', [LegacySystemController::class, 'tickets'])->name('legacy.tickets');
|
||||
Route::get('/legacy/tickets/{ticket}', [LegacySystemController::class, 'show'])->name('legacy.tickets.show');
|
||||
Route::get('/legacy/categories', [LegacySystemController::class, 'categories'])->name('legacy.categories');
|
||||
|
||||
Route::get('/tickets', TicketIndex::class)->name('tickets.index');
|
||||
Route::get('/tickets/archived', ArchivedTicketIndex::class)->name('tickets.archived');
|
||||
Route::post('/tickets', TicketStoreController::class)->name('tickets.store');
|
||||
|
||||
Reference in New Issue
Block a user