Skip to content

Commit 647c542

Browse files
committed
WIP Account Work
1 parent af54154 commit 647c542

File tree

5 files changed

+168
-38
lines changed

5 files changed

+168
-38
lines changed

app/Models/SupportTicket/Reply.php

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,16 @@ class Reply extends Model
2626
'note' => 'boolean',
2727
];
2828

29+
public function isFromAdmin(): Attribute
30+
{
31+
return Attribute::get(fn () => $this->user->is_admin)
32+
->shouldCache();
33+
}
34+
2935
public function isFromUser(): Attribute
3036
{
31-
return Attribute::get(fn () => $this->user_id === auth()->user()->id);
37+
return Attribute::get(fn () => $this->user_id === auth()->user()->id)
38+
->shouldCache();
3239
}
3340

3441
public function user(): BelongsTo

app/Models/User.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class User extends Authenticatable
2323

2424
protected $casts = [
2525
'email_verified_at' => 'datetime',
26+
'is_admin' => 'boolean',
2627
'password' => 'hashed',
2728
];
2829

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
return new class extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*/
12+
public function up(): void
13+
{
14+
Schema::table('users', function (Blueprint $table) {
15+
$table->boolean('is_admin')
16+
->after('remember_token')
17+
->default(false);
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*/
24+
public function down(): void
25+
{
26+
Schema::table('users', function (Blueprint $table) {
27+
$table->dropColumn('is_admin');
28+
});
29+
}
30+
};

resources/views/support/index.blade.php

Lines changed: 8 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@
99
</p>
1010
</header>
1111

12+
{{-- Additional Support Information --}}
13+
<div class="my-10 rounded-xl bg-gradient-to-br from-[#FFF0DC] to-[#E8EEFF] p-8 dark:from-blue-900/10 dark:to-[#4c407f]/25">
14+
<h2 class="mb-4 text-2xl font-medium">Need more help?</h2>
15+
<p class="text-lg text-gray-700 dark:text-gray-300">
16+
Check out our <a href="/docs" class="font-medium text-violet-600 hover:text-violet-700 dark:text-violet-400 dark:hover:text-violet-300">documentation</a> for comprehensive guides and tutorials to help you get the most out of NativePHP.
17+
</p>
18+
</div>
19+
1220
{{-- Support Grid --}}
1321
<div class="grid w-full grid-cols-1 gap-8 md:grid-cols-2">
1422

@@ -38,40 +46,6 @@ class="group flex w-full flex-col items-center rounded-xl bg-gray-100/80 p-8 tex
3846
<p class="mt-2 text-gray-600 dark:text-gray-400">Join the community and get real-time help</p>
3947
</a>
4048

41-
{{-- Email Box --}}
42-
<a href="mailto:[email protected]"
43-
class="group flex w-full flex-col items-center rounded-xl bg-gray-100/80 p-8 text-center transition duration-300 hover:-translate-y-1 hover:bg-gray-200/80 hover:shadow-lg dark:bg-gray-800/50 dark:hover:bg-gray-700/50 dark:hover:shadow-gray-900/30"
44-
aria-label="Contact us via email">
45-
<div class="mb-5 grid size-16 place-items-center rounded-full bg-white ring-1 ring-black/5 transition duration-300 group-hover:rotate-3 dark:bg-gray-900 dark:ring-white/10">
46-
<x-icons.email-document class="size-8" />
47-
</div>
48-
<h2 class="text-xl font-medium">Email</h2>
49-
<p class="mt-2 text-gray-600 dark:text-gray-400">Get in touch with our support team</p>
50-
</a>
51-
52-
{{-- Support Tickets Box --}}
53-
<a href="{{ route('support.tickets') }}"
54-
target="_blank"
55-
rel="noopener"
56-
class="group flex w-full flex-col items-center rounded-xl bg-gray-100/80 p-8 text-center transition duration-300 hover:-translate-y-1 hover:bg-gray-200/80 hover:shadow-lg dark:bg-gray-800/50 dark:hover:bg-gray-700/50 dark:hover:shadow-gray-900/30"
57-
aria-label="Submit a support ticket">
58-
<div class="mb-5 grid size-16 place-items-center rounded-full bg-white text-violet-500 ring-1 ring-black/5 transition duration-300 group-hover:-rotate-3 dark:bg-gray-900 dark:ring-white/10">
59-
<svg class="size-8" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
60-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192l-3.536 3.536M21 12a9 9 0 11-18 0 9 9 0 0118 0zm-5 0a4 4 0 11-8 0 4 4 0 018 0z" />
61-
</svg>
62-
</div>
63-
<h2 class="text-xl font-medium">Support Tickets</h2>
64-
<p class="mt-2 text-gray-600 dark:text-gray-400">Submit a detailed help request</p>
65-
</a>
66-
67-
</div>
68-
69-
{{-- Additional Support Information --}}
70-
<div class="mt-20 rounded-xl bg-gradient-to-br from-[#FFF0DC] to-[#E8EEFF] p-8 dark:from-blue-900/10 dark:to-[#4c407f]/25">
71-
<h2 class="mb-4 text-2xl font-medium">Need more help?</h2>
72-
<p class="text-lg text-gray-700 dark:text-gray-300">
73-
Check out our <a href="/docs" class="font-medium text-violet-600 hover:text-violet-700 dark:text-violet-400 dark:hover:text-violet-300">documentation</a> for comprehensive guides and tutorials to help you get the most out of NativePHP.
74-
</p>
7549
</div>
7650
</section>
7751
</x-layout>

resources/views/support/tickets/show.blade.php

Lines changed: 121 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<x-layout-three-columns>
2+
<div x-data="{ showReplyModal: false }">
23
{{-- Desktop Buttons - Hidden on Mobile --}}
34
<div class="hidden md:flex justify-between items-center mb-4">
45
<a href="/support/tickets" class="inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 rounded-lg hover:bg-gray-50 dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-700">
@@ -9,7 +10,11 @@
910
</a>
1011
<div class="flex space-x-3">
1112
@if($supportTicket->status !== \App\SupportTicket\Status::CLOSED)
12-
<button type="button" class="inline-flex items-center px-4 py-2 text-sm font-medium text-violet-700 bg-violet-100 border border-violet-200 rounded-lg hover:bg-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:border-violet-800 dark:hover:bg-violet-900/50">
13+
<button
14+
type="button"
15+
@click="showReplyModal = true"
16+
class="inline-flex items-center px-4 py-2 text-sm font-medium text-violet-700 bg-violet-100 border border-violet-200 rounded-lg hover:bg-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:border-violet-800 dark:hover:bg-violet-900/50"
17+
>
1318
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
1419
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/>
1520
</svg>
@@ -48,7 +53,14 @@
4853
<div class="flex flex-col w-full mb-6">
4954
<div class="relative w-full">
5055
<div class="{{ $reply->is_from_user ? 'bg-blue-100/50 dark:bg-blue-900/20 border-blue-200/50 dark:border-blue-800/30 mr-10' : 'bg-gray-100/70 dark:bg-gray-700/20 border-gray-200/50 dark:border-gray-700/30 ml-10' }} p-4 rounded-lg border">
51-
<p class="font-medium text-gray-900 dark:text-gray-100">{{ $reply->user->name }}</p>
56+
<p class="font-medium text-gray-900 dark:text-gray-100">
57+
{{ $reply->user->name }}
58+
@if($reply->is_from_user)
59+
<span class="text-sm text-gray-500 dark:text-gray-400">(You)</span>
60+
@elseif($reply->is_from_admin)
61+
<span class="text-sm text-gray-500 dark:text-gray-400">(Staff)</span>
62+
@endif
63+
</p>
5264
<p class="mt-1 text-gray-800 dark:text-gray-200">{{ $reply->message }}</p>
5365
</div>
5466
</div>
@@ -77,7 +89,11 @@
7789
</svg>
7890
Back
7991
</a>
80-
<button type="button" class="flex-1 inline-flex items-center justify-center px-3 py-2 text-sm font-medium text-violet-700 bg-violet-100 border border-violet-200 rounded-lg hover:bg-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:border-violet-800 dark:hover:bg-violet-900/50 mx-1">
92+
<button
93+
type="button"
94+
@click="showReplyModal = true"
95+
class="flex-1 inline-flex items-center justify-center px-3 py-2 text-sm font-medium text-violet-700 bg-violet-100 border border-violet-200 rounded-lg hover:bg-violet-200 dark:bg-violet-900/30 dark:text-violet-300 dark:border-violet-800 dark:hover:bg-violet-900/50 mx-1"
96+
>
8197
<svg class="w-4 h-4 mr-1" fill="none" stroke="currentColor" viewBox="0 0 24 24">
8298
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6"/>
8399
</svg>
@@ -98,4 +114,106 @@
98114
<form action="{{ route('support.tickets.close', $supportTicket) }}" method="POST" id="closeTicketForm">
99115
@csrf
100116
</form>
117+
118+
{{-- Reply Modal --}}
119+
<div
120+
x-show="showReplyModal"
121+
x-cloak
122+
class="fixed inset-0 z-50 overflow-y-auto"
123+
aria-labelledby="modal-title"
124+
role="dialog"
125+
aria-modal="true"
126+
>
127+
<div
128+
class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0"
129+
x-transition:enter="ease-out duration-300"
130+
x-transition:enter-start="opacity-0"
131+
x-transition:enter-end="opacity-100"
132+
x-transition:leave="ease-in duration-200"
133+
x-transition:leave-start="opacity-100"
134+
x-transition:leave-end="opacity-0"
135+
>
136+
{{-- Modal backdrop --}}
137+
<div
138+
class="fixed inset-0 bg-gray-500 bg-opacity-75 dark:bg-gray-900 dark:bg-opacity-75 transition-opacity"
139+
aria-hidden="true"
140+
@click="showReplyModal = false"
141+
></div>
142+
143+
{{-- Modal positioning trick --}}
144+
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">&#8203;</span>
145+
146+
{{-- Modal content --}}
147+
<div
148+
class="inline-block align-bottom bg-white dark:bg-gray-800 rounded-lg text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full"
149+
x-transition:enter="ease-out duration-300"
150+
x-transition:enter-start="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
151+
x-transition:enter-end="opacity-100 translate-y-0 sm:scale-100"
152+
x-transition:leave="ease-in duration-200"
153+
x-transition:leave-start="opacity-100 translate-y-0 sm:scale-100"
154+
x-transition:leave-end="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
155+
>
156+
<div class="absolute top-0 right-0 pt-4 pr-4">
157+
<button
158+
type="button"
159+
class="bg-white dark:bg-gray-800 rounded-md text-gray-400 hover:text-gray-500 dark:hover:text-gray-300 focus:outline-none"
160+
@click="showReplyModal = false"
161+
>
162+
<span class="sr-only">Close</span>
163+
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
164+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
165+
</svg>
166+
</button>
167+
</div>
168+
<div class="px-4 pt-5 pb-4 sm:p-6 sm:pb-4">
169+
<div class="sm:flex sm:items-start">
170+
<div class="mt-3 text-center sm:mt-0 sm:ml-4 sm:text-left w-full">
171+
<h3 class="text-lg leading-6 font-medium text-gray-900 dark:text-white" id="modal-title">
172+
Reply to Ticket #{{ $supportTicket->mask }}
173+
</h3>
174+
<div class="mt-4">
175+
<form action="#" method="POST">
176+
@csrf
177+
<div class="mb-4">
178+
<label for="message" class="block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2">
179+
Your message
180+
</label>
181+
<textarea
182+
id="message"
183+
name="message"
184+
rows="5"
185+
class="shadow-sm focus:ring-violet-500 focus:border-violet-500 block w-full sm:text-sm border-gray-300 dark:border-gray-600 dark:bg-gray-700 dark:text-white rounded-md"
186+
placeholder="Type your reply here..."
187+
required
188+
></textarea>
189+
</div>
190+
<div class="mt-5 sm:mt-6 sm:flex sm:flex-row-reverse">
191+
<button
192+
type="submit"
193+
class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-violet-600 text-base font-medium text-white hover:bg-violet-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-violet-500 sm:ml-3 sm:w-auto sm:text-sm dark:bg-violet-700 dark:hover:bg-violet-600"
194+
>
195+
Send Reply
196+
</button>
197+
<button
198+
type="button"
199+
class="mt-3 w-full inline-flex justify-center rounded-md border border-gray-300 shadow-sm px-4 py-2 bg-white text-base font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-violet-500 sm:mt-0 sm:w-auto sm:text-sm dark:bg-gray-800 dark:text-gray-300 dark:border-gray-600 dark:hover:bg-gray-700"
200+
@click="showReplyModal = false"
201+
>
202+
Cancel
203+
</button>
204+
</div>
205+
</form>
206+
</div>
207+
</div>
208+
</div>
209+
</div>
210+
</div>
211+
</div>
212+
</div>
213+
214+
{{-- Add Alpine.js x-cloak style to hide elements with x-cloak before Alpine initializes --}}
215+
<style>
216+
[x-cloak] { display: none !important; }
217+
</style>
218+
</div>
101219
</x-layout-three-columns>

0 commit comments

Comments
 (0)