Skip to content

Commit 502016d

Browse files
committed
Add CRUD image and validation
1 parent a05994d commit 502016d

File tree

11 files changed

+918
-38
lines changed

11 files changed

+918
-38
lines changed
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
<?php
2+
3+
namespace App\Http\Controllers;
4+
5+
use Exception;
6+
use App\Models\Gallery;
7+
use Illuminate\Http\Request;
8+
use Illuminate\Http\JsonResponse;
9+
use Illuminate\Support\Facades\Storage;
10+
use Illuminate\Support\Facades\Validator;
11+
12+
class GalleryController extends Controller
13+
{
14+
/**
15+
* Display a listing of the resource.
16+
*/
17+
public function index(Request $request)
18+
{
19+
try
20+
{
21+
$perPage = $request->get('showing', 10);
22+
$search = $request->get('search', '');
23+
24+
$data = Gallery::where(function($query) use ($search) {
25+
$query->where('name_gallery', 'LIKE', "%{$search}%");
26+
$query->orWhere('description_gallery', 'LIKE', "%{$search}%");
27+
})->latest()->paginate($perPage);
28+
29+
return response()->json([
30+
'data' => $data,
31+
'success' => true,
32+
], JsonResponse::HTTP_OK);
33+
}
34+
catch (Exception $e)
35+
{
36+
return response()->json([
37+
'data' => [],
38+
'success' => false,
39+
'message' => $e->getMessage()
40+
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
41+
}
42+
}
43+
44+
/**
45+
* Store a newly created resource in storage.
46+
*/
47+
public function store(Request $request)
48+
{
49+
$validatedData = Validator::make($request->all(), [
50+
'name_gallery' => 'required',
51+
'description_gallery' => '',
52+
'image' => 'image|mimes:jpg,jpeg,png|max:3072'
53+
]);
54+
55+
try
56+
{
57+
if ($validatedData->fails()){
58+
return response()->json(['success' => false, 'message' => $validatedData->errors()], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
59+
}
60+
61+
if ($request->hasFile('image')) {
62+
$image = $request->file('image');
63+
$filename = time() . '_' . $image->getClientOriginalName();
64+
$image->storeAs('public/images', $filename);
65+
}
66+
67+
$data = Gallery::create([
68+
'name_gallery' => $request->input('name_gallery'),
69+
'description_gallery' => $request->input('description_gallery'),
70+
'image' => $filename
71+
]);
72+
73+
return response()->json([
74+
'data' => $data,
75+
'success' => true,
76+
'message' => 'Data created successfully'
77+
], JsonResponse::HTTP_CREATED);
78+
}
79+
catch (Exception $e)
80+
{
81+
return response()->json([
82+
'data' => [],
83+
'success' => false,
84+
'message' => $e->getMessage()
85+
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
86+
}
87+
}
88+
89+
/**
90+
* Display the specified resource.
91+
*/
92+
public function show($id)
93+
{
94+
try
95+
{
96+
$data = Gallery::findOrFail($id);
97+
98+
return response()->json([
99+
'data' => $data,
100+
'success' => true,
101+
], JsonResponse::HTTP_OK);
102+
}
103+
catch (Exception $e)
104+
{
105+
return response()->json([
106+
'data' => [],
107+
'success' => false,
108+
'message' => $e->getMessage()
109+
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
110+
}
111+
}
112+
113+
/**
114+
* Show the form for editing the specified resource.
115+
*/
116+
public function edit($id)
117+
{
118+
try
119+
{
120+
$data = Gallery::findOrFail($id);
121+
122+
return response()->json([
123+
'data' => $data,
124+
'success' => true,
125+
], JsonResponse::HTTP_OK);
126+
}
127+
catch (Exception $e)
128+
{
129+
return response()->json([
130+
'data' => [],
131+
'success' => false,
132+
'message' => $e->getMessage()
133+
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
134+
}
135+
}
136+
137+
/**
138+
* Update the specified resource in storage.
139+
*/
140+
public function update(Request $request, $id)
141+
{
142+
try
143+
{
144+
$data = Gallery::findOrFail($id);
145+
$filename = $data->image;
146+
147+
if ($request->hasFile('image')) {
148+
$validatedData = Validator::make($request->all(), [
149+
'name_gallery' => 'required',
150+
'image' => 'image|mimes:jpg,jpeg,png|max:3072'
151+
]);
152+
153+
if ($validatedData->fails()){
154+
return response()->json(['success' => false, 'message' => $validatedData->errors()], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
155+
}
156+
157+
Storage::delete('public/images/' . $filename);
158+
159+
$image = $request->file('image');
160+
$filename = time() . '_' . $image->getClientOriginalName();
161+
$image->storeAs('public/images', $filename);
162+
}
163+
164+
$data->update([
165+
'name_gallery' => $request->input('name_gallery'),
166+
'description_gallery' => $request->input('description_gallery'),
167+
'image' => $filename
168+
]);
169+
170+
return response()->json([
171+
'data' => $data,
172+
'success' => true,
173+
'message' => 'Data updated successfully'
174+
], JsonResponse::HTTP_OK);
175+
}
176+
catch (Exception $e)
177+
{
178+
return response()->json([
179+
'data' => [],
180+
'success' => false,
181+
'message' => $e->getMessage()
182+
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
183+
}
184+
}
185+
186+
/**
187+
* Remove the specified resource from storage.
188+
*/
189+
public function destroy($id)
190+
{
191+
try
192+
{
193+
$data = Gallery::findOrFail($id);
194+
195+
if ($data->image) {
196+
Storage::delete('public/images/' . $data->image);
197+
}
198+
199+
$data->delete();
200+
201+
return response()->json([
202+
'data' => $data,
203+
'success' => true,
204+
'message' => 'Data deleted successfully'
205+
], JsonResponse::HTTP_OK);
206+
}
207+
catch (Exception $e)
208+
{
209+
return response()->json([
210+
'data' => [],
211+
'success' => false,
212+
'message' => $e->getMessage()
213+
], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
214+
}
215+
}
216+
}

backend/app/Http/Controllers/ProductController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ public function index(Request $request)
4545
public function store(Request $request)
4646
{
4747
$validatedData = $request->validate([
48-
'name' => 'required|max:5',
48+
'name' => 'required',
49+
'description' => '',
4950
'price' => 'numeric'
5051
]);
5152

backend/app/Models/Gallery.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace App\Models;
4+
5+
use Illuminate\Database\Eloquent\Factories\HasFactory;
6+
use Illuminate\Database\Eloquent\Model;
7+
8+
class Gallery extends Model
9+
{
10+
use HasFactory;
11+
12+
protected $guarded = [];
13+
}
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::create('galleries', function (Blueprint $table) {
15+
$table->id();
16+
$table->text('name_gallery');
17+
$table->text('description_gallery');
18+
$table->text('image');
19+
$table->timestamps();
20+
});
21+
}
22+
23+
/**
24+
* Reverse the migrations.
25+
*/
26+
public function down(): void
27+
{
28+
Schema::dropIfExists('galleries');
29+
}
30+
};

backend/routes/api.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
<?php
22

3+
use App\Http\Controllers\GalleryController;
34
use Illuminate\Http\Request;
45
use Illuminate\Support\Facades\Route;
56
use App\Http\Controllers\ProductController;
@@ -26,6 +27,7 @@
2627

2728
Route::group(['middleware' => ['auth:api', 'role:admin']], function () {
2829
Route::resource('/products', ProductController::class);
30+
Route::resource('/gallery', GalleryController::class);
2931
});
3032

3133
Route::post('/logout', App\Http\Controllers\Api\LogoutController::class)->name('logout');

frontend/src/components/Footer.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default function Footer() {
88
By
99
<a href="https://github.com/fhmiibrhimdev"> Fahmi Ibrahim</a>
1010
</div>
11-
<div className="footer-right">0.1.4</div>
11+
<div className="footer-right">0.1.5</div>
1212
</footer>
1313
);
1414
}

frontend/src/components/Navigation.jsx

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ export default function Navigation() {
127127
className={`nav-item dropdown ${
128128
location.pathname === "/general-feature" ||
129129
location.pathname === "/advanced-feature" ||
130-
location.pathname === "/products"
130+
location.pathname === "/products" ||
131+
location.pathname === "/gallery"
131132
? "active"
132133
: ""
133134
}`}
@@ -172,17 +173,31 @@ export default function Navigation() {
172173
</NavLink>
173174
</li>
174175
{user.role === "admin" && (
175-
<li
176-
className={`nav-item ${
177-
location.pathname === "/products"
178-
? "active"
179-
: ""
180-
}`}
181-
>
182-
<NavLink href="/products">
183-
Products
184-
</NavLink>
185-
</li>
176+
<>
177+
<li
178+
className={`nav-item ${
179+
location.pathname ===
180+
"/products"
181+
? "active"
182+
: ""
183+
}`}
184+
>
185+
<NavLink href="/products">
186+
Products
187+
</NavLink>
188+
</li>
189+
<li
190+
className={`nav-item ${
191+
location.pathname === "/gallery"
192+
? "active"
193+
: ""
194+
}`}
195+
>
196+
<NavLink href="/gallery">
197+
Gallery
198+
</NavLink>
199+
</li>
200+
</>
186201
)}
187202
</ul>
188203
</li>

frontend/src/components/Router.jsx

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@ import { Route, Routes } from "react-router-dom";
33
import Dashboard from "../pages/Dashboard";
44
import AdvancedFeature from "../pages/AdvancedFeature";
55
import GeneralFeature from "../pages/GeneralFeature";
6-
import Product from "../pages/products/Product";
6+
import Product from "../pages/Products/Product";
77
import Login from "../pages/Auth/Login";
88
import Register from "../pages/Auth/Register";
99
import AuthLayout from "../pages/Layout/AuthLayout";
1010
import MainLayout from "../pages/Layout/MainLayout";
1111
import Error403 from "../pages/Error/403";
1212
import Error404 from "../pages/Error/404";
13+
import Gallery from "../pages/Gallery/Gallery";
1314

1415
export default function Router() {
1516
return (
@@ -69,6 +70,15 @@ export default function Router() {
6970
</MainLayout>
7071
}
7172
/>
73+
<Route
74+
exact
75+
path="/gallery"
76+
element={
77+
<MainLayout>
78+
<Gallery />
79+
</MainLayout>
80+
}
81+
/>
7282
<Route path="*" element={<Error404 />} />
7383
</Routes>
7484
);

frontend/src/index.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@
7878
}
7979

8080
.card {
81-
@apply tw-rounded-none tw-shadow-md tw-shadow-gray-200 lg:tw-rounded-lg;
81+
@apply tw-rounded-none tw-shadow-md tw-shadow-gray-300 lg:tw-rounded-lg;
8282
}
8383

8484
.section-body {

0 commit comments

Comments
 (0)