Skip to content

Commit a8fe7b2

Browse files
committed
feat: added admin contact messages view
1 parent 370d429 commit a8fe7b2

30 files changed

+654
-17
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace App\Actions\Admin\CMS;
4+
5+
use App\Models\ContactMessage;
6+
use App\Traits\CustomControllerResponsesTrait;
7+
use App\Traits\ThemesTrait;
8+
use Illuminate\Http\Request;
9+
use Lorisleiva\Actions\Concerns\AsAction;
10+
11+
class ContactMessagesDelete
12+
{
13+
use AsAction;
14+
use ThemesTrait;
15+
use CustomControllerResponsesTrait;
16+
17+
public function asController(Request $request, $id)
18+
{
19+
$item = ContactMessage::findOrFail($id);
20+
$resp = $item->delete();
21+
22+
return $this->respJuicer($resp);
23+
}
24+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace App\Actions\Admin\Cms;
4+
5+
use App\Http\Resources\ContactMessageResourceCollection;
6+
use App\Models\ContactMessage;
7+
use App\Traits\CustomControllerResponsesTrait;
8+
use App\Traits\ThemesTrait;
9+
use Illuminate\Http\Request;
10+
use Lorisleiva\Actions\Concerns\AsAction;
11+
12+
class ContactMessages
13+
{
14+
use AsAction;
15+
use ThemesTrait;
16+
use CustomControllerResponsesTrait;
17+
18+
public function asController(Request $request)
19+
{
20+
$messages = ContactMessage::paginate(pagination('s'));
21+
22+
ContactMessage::whereIn('id', $messages->whereNull('last_read_at')->pluck('id')->toArray())
23+
->update([
24+
'last_read_at' => now()
25+
]);
26+
27+
$data = new ContactMessageResourceCollection($messages->fresh());
28+
29+
return $request->wantsJson()
30+
? $data
31+
: $this->generateBackendPage('Cms/ContactMessages', [
32+
'messages' => $data,
33+
]);
34+
35+
}
36+
}

app/Actions/Admin/Dashboard.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function asController()
1616
return redirect()->route('user.dashboard');
1717
}
1818

19-
return $this->generateBackendPage('Admin/Dashboard', [
19+
return $this->generateBackendPage('Dashboard', [
2020
'title' => "Welcome Back, " . doe()->full_name,
2121
]);
2222
}

app/Actions/Admin/Settings/Configurations.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function asController(Request $request)
1919
$data = Configuration::get();
2020

2121
if($request->isMethod('get')) {
22-
return $this->generateBackendPage('Admin/Settings/Configurations', [
22+
return $this->generateBackendPage('Settings/Configurations', [
2323
'configurations' => $data,
2424
]);
2525
}

app/Actions/Admin/Settings/ResetSystem.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ public function asController(Request $request)
5050

5151
if($request->isMethod('get')) {
5252

53-
return $this->generateBackendPage('Admin/Settings/ResetSystem', [
53+
return $this->generateBackendPage('Settings/ResetSystem', [
5454
'actions' => $actions,
5555
]);
5656
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\Resources\Json\JsonResource;
7+
8+
class ContactMessageResource extends JsonResource
9+
{
10+
/**
11+
* Transform the resource into an array.
12+
*
13+
* @return array<string, mixed>
14+
*/
15+
public function toArray(Request $request): array
16+
{
17+
return [
18+
'id' => (int) $this->id,
19+
'user_id' => $this->user_id,
20+
'name' => $this->name,
21+
'email' => $this->email,
22+
'phone' => $this->phone,
23+
'subject' => $this->subject,
24+
'body' => $this->body,
25+
'ip_address' => $this->ip_address,
26+
27+
// dates
28+
'created_at' => eclair($this->created_at),
29+
'created_at_w3c' => eclair($this->created_at, true, true),
30+
31+
//
32+
'user' => new UserSlimResource($this->whenLoaded('user')),
33+
34+
$this->mergeWhen(doe()->isAdmin, function() {
35+
return [
36+
'site_domain' => $this->site_domain,
37+
'last_read_at' => eclair($this->last_read_at),
38+
'last_read_at_w3c' => eclair($this->last_read_at, true, true),
39+
];
40+
}),
41+
];
42+
}
43+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use App\Library\Datatable;
6+
use Illuminate\Http\Request;
7+
use Illuminate\Http\Resources\Json\ResourceCollection;
8+
9+
class ContactMessageResourceCollection extends ResourceCollection
10+
{
11+
/**
12+
* Define the headers and consequently values for the datatable
13+
*/
14+
protected $headers = [
15+
['text' => '#', 'value' => 'id'],
16+
'name', 'contact',
17+
['text' => 'Message', 'value' => 'body'],
18+
'actions'
19+
];
20+
21+
/**
22+
* Transform the resource collection into an array.
23+
*
24+
* @param \Illuminate\Http\Request
25+
* @return array
26+
*/
27+
public function toArray($request)
28+
{
29+
return [
30+
'data' => $this->collection,
31+
32+
'headers' => (new Datatable)->headers($this->headers)
33+
];
34+
}
35+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace App\Http\Resources;
4+
5+
use Illuminate\Http\Request;
6+
use Illuminate\Http\Resources\Json\JsonResource;
7+
8+
class UserSlimResource extends JsonResource
9+
{
10+
/**
11+
* Transform the resource into an array.
12+
*
13+
* @return array<string, mixed>
14+
*/
15+
public function toArray(Request $request): array
16+
{
17+
return [
18+
'id' => (int) $this->id,
19+
'name' => $this->name,
20+
'aka' => $this->aka,
21+
'email' => $this->email,
22+
'full_name' => $this->full_name,
23+
'phone' => $this->phone,
24+
'status' => $this->status,
25+
26+
// relationships
27+
'role' => $this->role,
28+
29+
// links
30+
'avatar_url' => $this->avatar_url,
31+
];
32+
}
33+
}

app/Library/Datatable.php

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
<?php
2+
3+
namespace App\Library;
4+
5+
use Illuminate\Support\Str;
6+
7+
class Datatable
8+
{
9+
protected $headers = [];
10+
11+
/**
12+
| To make the headers more easier and accommodating to several styles, I have made them accept
13+
| uni and multi-dimensional arrays (to level 1). In cases where a value is hidden inside
14+
| a relationship e.g. props.item.patient.full_name, you can specify the 'value' as 'patient.full_name'
15+
| and the search will just work!
16+
|
17+
| Here is a sample header member
18+
|
19+
| protected $headers = [
20+
| ['text' => "patient Name", 'value' => 'patient.full_name'],
21+
| ['text' => "Admission Type", 'sortable' => false, 'value' => 'admission type'],
22+
| "Authorized Amount", "Date", "actions"
23+
| ];
24+
|
25+
| or even
26+
| 'name', ['text' => 'amount', 'align' => 'right'], 'type', ['text' => 'used?', 'value' => 'used'], 'actions'
27+
|
28+
| Available Header attributes - From Vuetify v2
29+
| {
30+
| text: string
31+
| value: string
32+
| align?: 'start' | 'center' | 'end'
33+
| sortable?: boolean
34+
| filterable?: boolean
35+
| groupable?: boolean
36+
| divider?: boolean
37+
| class?: string | string[]
38+
| width?: string | number
39+
| filter?: (value: any, search: string, item: any) => boolean
40+
| sort?: (a: any, b: any) => number
41+
| }
42+
|
43+
*/
44+
45+
/**
46+
* @param string|array $headers
47+
*
48+
* @return array
49+
*/
50+
51+
/**
52+
* Prepare the headers. The headers are very friendly to set, and here at the top is sample code
53+
*
54+
* @param array $headers
55+
*
56+
* @return array
57+
*/
58+
public function headers(array $headers) : array
59+
{
60+
foreach($headers as $header)
61+
{
62+
$arr = [
63+
'text' => $this->getText($header),
64+
'sortable' => $this->getSortable($header),
65+
'value' => $this->getValue($header),
66+
'align' => $this->getAlignment($header),
67+
];
68+
69+
isset($header['filterable']) ? $arr = array_merge($arr, ['filterable' => $this->getBoolean($header, 'filterable')]) : null;
70+
isset($header['sortable']) ? $arr = array_merge($arr, ['sortable' => $this->getBoolean($header, 'sortable')]) : null;
71+
isset($header['groupable']) ? $arr = array_merge($arr, ['groupable' => $this->getBoolean($header, 'groupable')]) : null;
72+
isset($header['divider']) ? $arr = array_merge($arr, ['divider' => $this->getBoolean($header, 'divider')]) : null;
73+
74+
$this->headers[] = $arr;
75+
}
76+
77+
return $this->headers;
78+
}
79+
80+
/**
81+
* get the text for the datatable. This is the display
82+
*
83+
* @param string|array $header
84+
*
85+
* @return string
86+
*/
87+
private function getText($header)
88+
{
89+
$value = $header;
90+
91+
if(is_array($header) and isset($header['text'])) {
92+
$value = $header['text'];
93+
}
94+
95+
return is_array($value) ? ucwords($value[1]) : ucwords($value);
96+
}
97+
98+
/**
99+
* get the value. This value is used in searching the vuetify datatable when no ajax search is required
100+
*
101+
* @param string|array $header
102+
*
103+
* @return string
104+
*/
105+
private function getValue($header)
106+
{
107+
$value = $header;
108+
109+
if(is_array($header) and isset($header['value'])) {
110+
$value = $header['value'];
111+
}
112+
113+
return is_array($value) ? Str::snake(strtolower(collect($value)->first())) : Str::snake(strtolower($value));
114+
}
115+
116+
/**
117+
* get the boolean value.
118+
*
119+
* @param string|array $header
120+
*
121+
* @return bool
122+
*/
123+
private function getBoolean($header, $entity)
124+
{
125+
$bool = $header;
126+
127+
if(is_array($header) and isset($header[$entity])) {
128+
$bool = $header[$entity];
129+
}
130+
131+
return is_array($bool) ? (bool)(strtolower(collect($bool)->first())) : (bool)(strtolower($bool));
132+
}
133+
134+
/**
135+
* get the sortable attribute
136+
*
137+
* @param string|array $header
138+
*
139+
* @return bool|mixed
140+
*/
141+
private function getSortable($header)
142+
{
143+
$value = true;
144+
145+
if(is_array($header) and isset($header['sortable'])) {
146+
147+
$value = $header['sortable'];
148+
149+
} else if(! is_array($header) and str_contains($header, 'action')) {
150+
// check if string is action
151+
$value = false;
152+
}
153+
154+
return $value;
155+
}
156+
157+
/**
158+
* Get allignment attr
159+
*
160+
* @param string|array $header
161+
*
162+
* @return mixed|string
163+
*/
164+
private function getAlignment($header)
165+
{
166+
$value = 'left';
167+
168+
if(is_array($header) and isset($header['align'])) {
169+
$value = $header['align'];
170+
}
171+
172+
return $value;
173+
}
174+
175+
/**
176+
* function to get the value for a certain index.
177+
*
178+
* @param string|array $header
179+
* @param int $index
180+
*
181+
* @return mixed
182+
*/
183+
private function getValueFromIndex($header, $index = 0)
184+
{
185+
return isset(array_keys($header)[$index]) ? $header[array_keys($header)[$index]] : $header[array_keys($header)[0]];
186+
}
187+
}

0 commit comments

Comments
 (0)