Private
Public Access
1
0

Add all files

This commit is contained in:
root
2025-11-30 11:57:22 +01:00
parent 2ee51cac4f
commit 044271db3d
1476 changed files with 142544 additions and 0 deletions

View File

@@ -0,0 +1,61 @@
<div class="container mx-auto px-4 py-8 sm:px-6 lg:px-8">
<h1 class="text-3xl lg:text-4xl font-extrabold text-color-base mt-4 mb-8">
{{ __('ticket.create_ticket') }}
</h1>
<div class="bg-background-secondary/70 border border-neutral/50 p-6 rounded-xl shadow-lg">
<h2 class="text-2xl font-bold text-color-base mb-6">{{ __('ticket.ticket_details') }}</h2>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<x-form.input wire:model="subject" label="{{ __('ticket.subject') }}" name="subject" required />
@if (count($departments) > 0)
<x-form.select wire:model="department" label="{{ __('ticket.department') }}" name="department" required>
<option value="">{{ __('ticket.select_department') }}</option>
@foreach ($departments as $departmentOption)
<option value="{{ $departmentOption }}">{{ $departmentOption }}</option>
@endforeach
</x-form.select>
@endif
<x-form.select wire:model="priority" label="{{ __('ticket.priority') }}" name="priority" required>
<option value="">{{ __('ticket.select_priority') }}</option>
<option value="low">{{ __('ticket.low') }}</option>
<option value="medium">{{ __('ticket.medium') }}</option>
<option value="high">{{ __('ticket.high') }}</option>
</x-form.select>
<x-form.select wire:model="service" label="{{ __('ticket.service') }}" name="service">
<option value="">{{ __('ticket.select_service') }}</option>
@foreach ($services as $product)
<option value="{{ $product->id }}">{{ $product->product->name }} ({{ ucfirst($product->status) }})
@if ($product->expires_at)
- {{ $product->expires_at->format('Y-m-d') }}
@endif
</option>
@endforeach
</x-form.select>
<div class="col-span-1 md:col-span-2"><p class="text-xs"><b>Disclaimer:</b> Please include as much information as possible. Our support team may take longer to respond if insufficient information is provided. This includes <b>hostnames</b>, IP addresses, error messages, and any troubleshooting steps already taken. Failure to do so may result in delays or closure of your ticket without resolution. This especially important when submitting a ticket on an account that has more than one product ordered as to ensure the right product is investigated by our support team.</p></div><div class="col-span-1 md:col-span-2"><hr/></div><div class="col-span-1 md:col-span-2"><div class="flex items-center bg-blue-500 text-white text-sm font-bold px-4 py-4 rounded-xl shadow-lg " role="alert">
<svg class="fill-current w-4 h-4 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M12.432 0c1.34 0 2.01.912 2.01 1.957 0 1.305-1.164 2.512-2.679 2.512-1.269 0-2.009-.75-1.974-1.99C9.789 1.436 10.67 0 12.432 0zM8.309 20c-1.058 0-1.833-.652-1.093-3.524l1.214-5.092c.211-.814.246-1.141 0-1.141-.317 0-1.689.562-2.502 1.117l-.528-.88c2.572-2.186 5.531-3.467 6.801-3.467 1.057 0 1.233 1.273.705 3.23l-1.391 5.352c-.246.945-.141 1.271.106 1.271.317 0 1.357-.392 2.379-1.207l.6.814C12.098 19.02 9.365 20 8.309 20z"/></svg>
<p>All account information must be accurate and verifiable in accordance with our <a href="https://virtnet.bond/tos" target="_blank">Terms of Service &#8599;</a>. Account details are reviewed with every support ticket submission to ensure compliance and service integrity. Providing false, inaccurate, or misleading information constitutes a violation of our Terms of Service and may result in immediate review, suspension, or termination of the account and all associated services without prior notice.</p>
</div><div><hr/></div></div><div class="col-span-1 md:col-span-2">
<label for="editor" class="block text-sm font-medium text-color-muted mb-2">Message</label>
<div wire:ignore>
<textarea id="editor" wire:model="message" placeholder="Your Message Here." class="form-input h-40"></textarea>
</div>
<x-easymde-editor wire:model="message" target-id="editor" />
</div>
</div>
<div class="flex justify-end mt-6">
<x-button.primary class="py-3 text-base font-bold transition-all transform rounded-lg shadow-lg hover:bg-primary focus:outline-none focus:ring-4 focus:ring-primary-500 hover:-translate-y-0.5" wire:click="create">
{{ __('ticket.create_ticket') }}
</x-button.primary>
</div>
</div>
</div>

View File

@@ -0,0 +1,72 @@
<div class="container mx-auto px-4 py-8 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4 mb-8">
<x-navigation.link :href="route('tickets.create')" class="inline-flex items-center justify-center px-5 py-2 border border-transparent text-base font-medium rounded-full shadow-sm text-white bg-primary hover:bg-primary/90 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary transition-colors duration-200">
<x-ri-add-line class="size-5 mr-2" />
<span>{{ __('ticket.create_ticket') }}</span>
</x-navigation.link>
</div>
<h1 class="text-3xl lg:text-4xl font-extrabold text-color-base mt-4 mb-8">
{{ __('ticket.tickets') }}
</h1>
<div class="grid grid-cols-1 gap-6 md:gap-8">
@forelse ($tickets as $ticket)
<a href="{{ route('tickets.show', $ticket) }}" wire:navigate class="block group">
<div class="bg-gradient-to-br from-background-secondary/50 to-background-secondary/30 hover:bg-secondary/25 border border-neutral/50 p-6 rounded-xl shadow-lg
transition-all duration-300 hover:scale-[1.01] hover:shadow-xl hover:border-primary/50
flex flex-col md:flex-row items-start md:items-center justify-between gap-4">
<div class="flex items-start md:items-center gap-4 flex-grow">
<div class="bg-secondary/10 p-3 rounded-full flex-shrink-0 shadow-sm">
<x-ri-ticket-line class="size-6 text-secondary" />
</div>
<div class="flex flex-col">
<span class="text-xl font-bold text-color-base leading-tight group-hover:text-primary transition-colors duration-200">
{{ $ticket->subject }}
</span>
<p class="text-color-muted text-sm mt-1">
{{ __('ticket.last_activity') }}:
{{ $ticket->messages()->orderBy('created_at', 'desc')->first()->created_at->diffForHumans() }}
@if($ticket->department)
<span class="hidden md:inline"> - {{ $ticket->department }}</span>
@endif
</p>
</div>
</div>
<div class="flex items-center gap-3 flex-shrink-0 mt-3 md:mt-0">
<div class="text-sm font-semibold px-3 py-1 rounded-full flex items-center gap-1.5
@if ($ticket->status == 'open') text-success bg-success/20
@elseif($ticket->status == 'closed') text-inactive bg-inactive/20
@elseif($ticket->status == 'replied') text-info bg-info/20
@else text-warning bg-warning/20
@endif">
@if ($ticket->status == 'open')
<x-ri-add-circle-fill class="size-4" />
Open
@elseif($ticket->status == 'closed')
<x-ri-forbid-fill class="size-4" />
Closed
@elseif($ticket->status == 'replied')
<x-ri-chat-smile-2-fill class="size-4" />
Replied
@else
<x-ri-error-warning-fill class="size-4" />
{{ ucfirst($ticket->status) }}
@endif
</div>
<x-ri-arrow-right-s-line class="size-6 text-color-muted group-hover:text-primary transition-colors duration-200" />
</div>
</div>
</a>
@empty
<div class="bg-gradient-to-br from-background-secondary/50 to-background-secondary/30 rounded-xl shadow-lg p-6 lg:p-8 border border-neutral/50 text-center">
<x-ri-inbox-line class="size-16 text-color-muted mx-auto mb-4 opacity-60" />
<h3 class="text-xl font-bold text-color-base mb-2">No Tickets yet.</h3>
</div>
@endforelse
</div>
</div>

View File

@@ -0,0 +1,112 @@
<div class="container mx-auto px-4 py-8 sm:px-6 lg:px-8">
<h1 class="text-3xl lg:text-4xl font-extrabold text-color-base mt-4 mb-2">
{{ __('ticket.tickets') }}
</h1>
<p class="text-lg text-color-muted font-light max-w-2xl mb-8">
Subject: {{ $ticket->subject }}
</p>
<div class="grid grid-cols-1 md:grid-cols-4 gap-6">
<div class="md:col-span-3 order-2 md:order-1">
<div class="bg-background-secondary/50 border border-neutral p-6 rounded-xl shadow-lg mb-6">
<div class="flex flex-col gap-5 max-h-[60vh] overflow-y-auto pr-4 custom-scrollbar" wire:poll.5s>
@foreach ($ticket->messages()->with('user')->get() as $index => $message)
<div
class="bg-background/10 border border-neutral/20 p-4 rounded-lg
w-full max-w-[80%] {{ $message->user_id === auth()->id() ? 'ml-auto bg-primary/10 border-primary/20' : 'mr-auto' }}
transition-all duration-200">
<div class="flex items-center justify-between mb-2">
<div>
<h3 class="font-semibold text-color-base text-lg">{{ $message->user->name }}</h3>
<p class="text-sm text-neutral-400">{{ $message->created_at->diffForHumans() }}</p>
</div>
</div>
<div class="mt-2 prose dark:prose-invert max-w-none text-color-base">
{!! Str::markdown(nl2br(e($message->message)), ['allow_unsafe_links' => false]) !!}
</div>
</div>
@endforeach
</div>
</div>
<div class="bg-background-secondary/70 border border-neutral p-6 rounded-xl shadow-lg mt-6">
<form wire:submit.prevent="save">
<div wire:ignore>
<textarea id="editor" class="form-input h-40"></textarea>
</div>
<x-easymde-editor />
<div class="flex justify-end mt-4">
<x-button.primary class="py-3 text-base font-bold transition-all transform rounded-lg shadow-lg hover:bg-primary focus:outline-none focus:ring-4 focus:ring-primary-500 hover:-translate-y-0.5">
{{ __('ticket.reply') }}
</x-button.primary>
</div>
</form>
</div>
</div>
<div class="md:col-span-1 order-1 md:order-2">
<div class="bg-background-secondary/50 border border-neutral p-6 rounded-xl shadow-lg">
<h2 class="text-xl font-bold text-color-base mb-4">{{ __('ticket.ticket_details') }}</h2>
<div class="space-y-4">
{{-- Subject --}}
<div class="flex flex-col">
<span class="text-sm font-medium text-neutral-400">{{ __('ticket.subject') }}:</span>
<span class="text-lg font-semibold text-color-base">{{ $ticket->subject }}</span>
</div>
{{-- Status --}}
<div class="flex flex-col">
<span class="text-sm font-medium text-neutral-400 mb-1">{{ __('ticket.status') }}:</span>
<div class="text-sm font-semibold px-3 py-1 rounded-full w-fit flex items-center gap-1.5
@if ($ticket->status == 'open') text-success bg-success/20
@elseif($ticket->status == 'closed') text-inactive bg-inactive/20
@elseif($ticket->status == 'replied') text-info bg-info/20
@else text-warning bg-warning/20
@endif">
@if ($ticket->status == 'open')
<x-ri-add-circle-fill class="size-4" />
Open
@elseif($ticket->status == 'closed')
<x-ri-forbid-fill class="size-4" />
Closed
@elseif($ticket->status == 'replied')
<x-ri-chat-smile-2-fill class="size-4" />
Replied
@else
<x-ri-error-warning-fill class="size-4" />
{{ ucfirst($ticket->status) }}
@endif
</div>
</div>
<div class="flex flex-col">
<span class="text-sm font-medium text-neutral-400">{{ __('ticket.priority') }}:</span>
<span class="text-base text-color-base">{{ ucfirst($ticket->priority) }}</span>
</div>
<div class="flex flex-col">
<span class="text-sm font-medium text-neutral-400">{{ __('ticket.created_at') }}:</span>
<span class="text-base text-color-base">{{ $ticket->created_at->format('d M Y, H:i') }} ({{ $ticket->created_at->diffForHumans() }})</span>
</div>
@if ($ticket->department)
<div class="flex flex-col">
<span class="text-sm font-medium text-neutral-400">{{ __('ticket.department') }}:</span>
<span class="text-base text-color-base">{{ $ticket->department }}</span>
</div>
@endif
@if ($ticket->service)
<div class="flex flex-col">
<span class="text-sm font-medium text-neutral-400">{{ __('ticket.service') }}:</span>
<span class="text-base text-color-base">
<a href="{{ route('services.show', $ticket->service) }}" class="text-primary font-bold hover:underline" wire:navigate>
{{ $ticket->service->product->name }}
</a>
</span>
</div>
@endif
</div>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,34 @@
<div class="space-y-4">
@foreach ($tickets as $ticket)
<a href="{{ route('tickets.show', $ticket) }}" wire:navigate>
<div class="bg-gradient-to-br from-background-secondary/50 to-background-secondary/30 border border-neutral p-4 rounded-lg mb-4">
<div class="flex items-center justify-between mb-2">
<div class="flex items-center gap-3">
<div class="bg-secondary/10 p-2 rounded-full">
<x-ri-ticket-line class="size-5 text-secondary" />
</div>
<span class="font-medium">{{ $ticket->subject }}</span>
</div>
<div class="size-5 rounded-full p-0.5
@if ($ticket->status == 'open') text-success bg-success/20
@elseif($ticket->status == 'closed') text-inactive bg-inactive/20
@else text-info bg-info/20
@endif"
@if ($ticket->status == 'open')
<x-ri-add-circle-fill />
@elseif($ticket->status == 'closed')
<x-ri-forbid-fill />
@elseif($ticket->status == 'replied')
<x-ri-chat-smile-2-fill />
@endif
</div>
</div>
<p class="text-base text-sm">
{{ __('ticket.last_activity') }}
{{ $ticket->messages()->orderBy('created_at', 'desc')->first()->created_at->diffForHumans() }}
{{ $ticket->department ? ' - ' . $ticket->department : '' }}
</p>
</div>
</a>
@endforeach
</div>