crud santri be

This commit is contained in:
alealien666 2025-02-07 22:52:43 +07:00
parent 347b5ff28e
commit cdf4e7abac
11 changed files with 243 additions and 111 deletions

View File

@ -5,56 +5,148 @@
use App\Models\Santri;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\File;
class SantriController extends Controller
{
/**
* Display a listing of the resource.
*/
public function index()
{
$santri = Santri::all();
return Inertia::render('list-admin/santri/IndexSantri', compact('santri'));
return Inertia::render('list-admin/santri/IndexSantri', [
'santri' => $santri,
'fields' => [
'nama' => 'text',
'alamat' => 'text',
'status_santri' => 'select',
'role_santri' => 'select',
'jk' => 'select',
'tanggal_lahir' => 'date',
'foto' => 'file'
],
'options' => [
'status_santri' => ['boyong' => 'Boyong', 'aktif' => 'Aktif'],
'role_santri' => ['santri' => 'Santri', 'pengurus' => 'Pengurus'],
'jk' => ['laki laki' => 'Laki-Laki', 'perempuan' => 'Perempuan'],
],
]);
}
public function create() {}
/**
* Store a newly created resource in storage.
*/
public function store(Request $request)
{
//
$request->validate([
'nama' => 'required',
'alamat' => 'required',
'status_santri' => 'required',
'role_santri' => 'required',
'jk' => 'required',
'tanggal_lahir' => 'required|date',
'foto' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
], [
'nama.required' => 'wajib mengisi nama santri',
'alamat.required' => 'wajib mengisi alamat santri',
'status_santri.required' => 'wajib mengisi status santri',
'role.required' => 'wajib mengisi role santri',
'gender.required' => 'wajib mengisi gender',
'ttl.required' => 'wajib mengisi tanggal lahir santri',
'ttl.date' => 'tanggal lahir harus dalam format tanggal yang benar',
]);
$fotoPath = null;
if ($request->hasFile('foto')) {
$foto = $request->file('foto');
$fotoName = time() . '_' . $foto->getClientOriginalName();
$foto->move(public_path('fotoSantri'), $fotoName);
$fotoPath = 'fotoSantri/' . $fotoName;
}
try {
$santri = Santri::create([
'nama' => $request->nama,
'alamat' => $request->alamat,
'status_santri' => $request->status_santri,
'role_santri' => $request->role_santri,
'jk' => $request->jk,
'tanggal_lahir' => $request->tanggal_lahir,
'foto' => $fotoPath
]);
// dd($santri);
return redirect()->back()->with('success', 'Data berhasil ditambahkan');
} catch (\Throwable $th) {
// dd($th->getMessage());
return redirect()->back()->with('error', 'Data gagal ditambahkan : ' . $th->getMessage());
}
}
/**
* Display the specified resource.
*/
public function show(Santri $santri)
public function update(Request $request, Santri $santri, $id)
{
//
$request->validate(
[
'nama' => 'required',
'alamat' => 'required',
'status_santri' => 'required',
'role_santri' => 'required',
'jk' => 'required',
'tanggal_lahir' => 'required',
'foto' => 'nullable|image|mimes:jpeg,png,jpg,gif,svg|max:2048'
],
[
'nama.required' => 'nama santri wajib di isi',
'alamat.required' => 'alamat santri wajib di isi',
'status_santri.required' => 'wajib memilih status santri',
'role_santri.required' => 'wajib memilih role santri',
'jk.required' => 'wajib memilih jenis kelamin santri',
'tanggal_lahir.required' => 'wajib mengisi tanggal lahir santri'
]
);
$fotoPath = null;
if ($request->has('foto')) {
$foto = $request->file('foto');
$fotoName = time() . '_' . $foto->getClientOriginalName();
$foto->move(public_path('fotoSantri/'), $fotoName);
$fotoPath = 'fotoSantri/' . $fotoName;
}
$santri = Santri::findOrFail($id);
try {
if ($request->file('foto') == '') {
$santri->nama = $request->nama;
$santri->alamat = $request->alamat;
$santri->status_santri = $request->status_santri;
$santri->role_santri = $request->role_santri;
$santri->jk = $request->jk;
$santri->tanggal_lahir = $request->tanggal_lahir;
} else {
File::delete('fotoSantri/' . basename($santri->foto));
$santri->foto = $fotoPath;
$santri->nama = $request->nama;
$santri->alamat = $request->alamat;
$santri->status_santri = $request->status_santri;
$santri->role_santri = $request->role_santri;
$santri->jk = $request->jk;
$santri->tanggal_lahir = $request->tanggal_lahir;
}
return redirect()->back()->with('success', 'Data Berhasil Di Ubah');
} catch (\Throwable $th) {
return redirect()->back()->with('error', 'Gagal' . $th->getMessage());
}
}
/**
* Show the form for editing the specified resource.
*/
public function edit(Santri $santri)
public function destroy(Santri $santri, $id)
{
//
}
$santri = Santri::findOrFail($id);
/**
* Update the specified resource in storage.
*/
public function update(Request $request, Santri $santri)
{
//
}
/**
* Remove the specified resource from storage.
*/
public function destroy(Santri $santri)
{
//
$santri->delete();
File::delete('fotoSantri/' . basename($santri->foto));
return redirect()->back()->with('success', 'data berhasil di hapus');
}
}

View File

@ -10,6 +10,7 @@ class Santri extends Model
use HasFactory;
protected $guarded = ['id'];
protected $table = 'santris';
public function user()
{

44
package-lock.json generated
View File

@ -4,9 +4,12 @@
"requires": true,
"packages": {
"": {
"dependencies": {
"@inertiajs/inertia": "^0.11.1"
},
"devDependencies": {
"@headlessui/react": "^1.4.2",
"@inertiajs/react": "^1.0.0",
"@inertiajs/react": "^1.3.0",
"@tailwindcss/forms": "^0.5.3",
"@vitejs/plugin-react": "^4.2.0",
"autoprefixer": "^10.4.12",
@ -680,6 +683,24 @@
"qs": "^6.9.0"
}
},
"node_modules/@inertiajs/inertia": {
"version": "0.11.1",
"resolved": "https://registry.npmjs.org/@inertiajs/inertia/-/inertia-0.11.1.tgz",
"integrity": "sha512-btmV53c54oW4Z9XF0YyTdIUnM7ue0ONy3/KJOz6J1C5CYIwimiKfDMpz8ZbGJuxS+SPdOlNsqj2ZhlHslpJRZg==",
"dependencies": {
"axios": "^0.21.1",
"deepmerge": "^4.0.0",
"qs": "^6.9.0"
}
},
"node_modules/@inertiajs/inertia/node_modules/axios": {
"version": "0.21.4",
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.4.tgz",
"integrity": "sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg==",
"dependencies": {
"follow-redirects": "^1.14.0"
}
},
"node_modules/@inertiajs/react": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@inertiajs/react/-/react-1.3.0.tgz",
@ -1080,7 +1101,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz",
"integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"function-bind": "^1.1.2"
@ -1093,7 +1113,6 @@
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
"integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"get-intrinsic": "^1.2.6"
@ -1306,7 +1325,6 @@
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
"dev": true,
"engines": {
"node": ">=0.10.0"
}
@ -1336,7 +1354,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
"integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-errors": "^1.3.0",
@ -1368,7 +1385,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
"integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
@ -1377,7 +1393,6 @@
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
@ -1386,7 +1401,6 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
"integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0"
},
@ -1499,7 +1513,6 @@
"version": "1.15.9",
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
"integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
"dev": true,
"funding": [
{
"type": "individual",
@ -1576,7 +1589,6 @@
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
@ -1594,7 +1606,6 @@
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz",
"integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==",
"dev": true,
"dependencies": {
"call-bind-apply-helpers": "^1.0.1",
"es-define-property": "^1.0.1",
@ -1618,7 +1629,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
"integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
"dev": true,
"dependencies": {
"dunder-proto": "^1.0.1",
"es-object-atoms": "^1.0.0"
@ -1672,7 +1682,6 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
"integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
@ -1684,7 +1693,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
"integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
@ -1696,7 +1704,6 @@
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.2"
},
@ -1896,7 +1903,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
"integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
"dev": true,
"engines": {
"node": ">= 0.4"
}
@ -2064,7 +2070,6 @@
"version": "1.13.3",
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
"dev": true,
"engines": {
"node": ">= 0.4"
},
@ -2304,7 +2309,6 @@
"version": "6.14.0",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
"integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
"dev": true,
"dependencies": {
"side-channel": "^1.1.0"
},
@ -2502,7 +2506,6 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
"integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3",
@ -2521,7 +2524,6 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
"integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
"dev": true,
"dependencies": {
"es-errors": "^1.3.0",
"object-inspect": "^1.13.3"
@ -2537,7 +2539,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
"integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",
@ -2555,7 +2556,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
"integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
"dev": true,
"dependencies": {
"call-bound": "^1.0.2",
"es-errors": "^1.3.0",

View File

@ -6,7 +6,7 @@
},
"devDependencies": {
"@headlessui/react": "^1.4.2",
"@inertiajs/react": "^1.0.0",
"@inertiajs/react": "^1.3.0",
"@tailwindcss/forms": "^0.5.3",
"@vitejs/plugin-react": "^4.2.0",
"autoprefixer": "^10.4.12",
@ -18,5 +18,8 @@
"react-dom": "^18.2.0",
"tailwindcss": "^3.2.1",
"vite": "^4.0.0"
},
"dependencies": {
"@inertiajs/inertia": "^0.11.1"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 181 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 160 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 KiB

View File

@ -1,61 +1,97 @@
import React, { useState } from "react"
import { Inertia } from "@inertiajs/inertia"
import { Inertia } from "@inertiajs/inertia";
import React, { useState } from "react";
const ModalInput = () => {
const [status, setStatus] = useState('')
const [role, setRole] = useState('')
const [gender, setGender] = useState('')
const ModalInput = ({ fields, tableName, options }) => {
const [formData, setFormData] = useState({});
const [errors, setErrors] = useState({});
const handleSubmit = () => {
const data = {
nama, alamat, status, role, jk, ttl
const handleChange = (e) => {
if (e.target.type === "file") {
setFormData({ ...formData, [e.target.name]: e.target.files[0] });
} else {
setFormData({ ...formData, [e.target.name]: e.target.value });
}
};
Inertia.post('/addSantri', data)
const handleSubmit = (e) => {
e.preventDefault()
console.log("tableName:", tableName); // Debugging
const formDataObj = new FormData()
Object.keys(formData).forEach((key) => {
formDataObj.append(key, formData[key])
})
Inertia.post(`/add${tableName}`, formDataObj, {
forceFormData: true,
onError: (errors) => setErrors(errors),
onSuccess: () => {
document.getElementById('my_modal_7').checked = false
setFormData({})
setErrors({})
}
})
}
return (
<div>
<label htmlFor="my_modal_7" className="btn">open modal</label>
<form action="" method="post" encType="multipart/form-data">
<input type="checkbox" id="my_modal_7" className="modal-toggle" />
<div className="modal" role="dialog">
<div className="modal-box">
<h2 className="font-bold text-lg text-center mb-5">Add Santri</h2>
<label className="input input-bordered input-secondary flex items-center gap-2 mb-2">
Name
<input type="text" name="nama" className="grow border-none focus:ring-0 " placeholder="Daisy" />
</label>
<label className="input input-bordered input-secondary flex items-center gap-2 mb-2">
Alamat
<input type="text" name="alamat" className="grow border-none focus:ring-0 " placeholder="Daisy" />
</label>
<select value={status} onChange={(e) => setStatus(e.target.value)} className="select select-bordered w-full select-secondary mb-2" name="status">
<option disabled value="">Pilih Status</option>
<option value={"boyong"}>Boyong</option>
<option value={"aktif"}>Aktif</option>
</select>
<select value={role} onChange={(e) => setRole(e.target.value)} className="select select-bordered w-full select-secondary mb-2" name="role">
<option disabled value={""}>Pilih Role Santri</option>
<option value={"laki laki"}>Santri</option>
<option value={"perempuan"}>Pengurus</option>
</select>
<select value={gender} onChange={(e) => setGender(e.target.value)} className="select select-bordered w-full select-secondary mb-2" name="gender">
<option disabled value={""}>Pilih Gender</option>
<option value={"laki laki"}>Laki Laki</option>
<option value={"perempuan"}>Perempuan</option>
</select>
<label className="input input-bordered input-secondary flex items-center gap-2 mb-2">
Tanggal Lahir
<input type="date" name="ttl" className="grow border-none focus:ring-0 " placeholder="Daisy" />
</label>
<button typeof="submit" onClick={() => handleSubmit()} className="btn btn-secondary">Add Santri</button>
</div>
<label className="modal-backdrop" htmlFor="my_modal_7">Close</label>
</div>
</form>
</div>
)
}
<label htmlFor="my_modal_7" className="btn">Open Modal</label>
<input type="checkbox" id="my_modal_7" className="modal-toggle" />
<div className="modal" role="dialog">
<div className="modal-box">
<h2 className="font-bold text-lg text-center mb-5">Tambah Data</h2>
<form onSubmit={handleSubmit} encType="multipart/form-data">
{Object.keys(fields).map((field) => (
<div key={field} className="mb-2">
<label className="input input-bordered input-secondary flex items-center gap-2">
{field.replace("_", " ")}
{fields[field] === "select" ? (
<select
name={field}
value={formData[field] || ""}
onChange={handleChange}
className="select select-bordered w-full select-secondary"
>
<option disabled value="">Pilih {field.replace("_", " ")}</option>
{options[field] && Object.entries(options[field]).map(([key, value]) => (
<option key={key} value={key}>{value}</option>
))}
</select>
) : fields[field] === "file" ? (
<input
type="file"
name={field}
onChange={handleChange}
className="file-input file-input-bordered w-full file-input-secondary"
/>
) : (
<input
type={fields[field]}
name={field}
onChange={(e) =>
setFormData({
...formData,
[field]: e.target.type === "file" ? e.target.files[0] : e.target.value
})
}
className="grow border-none focus:ring-0"
placeholder={`Masukkan ${field.replace("_", " ")}`}
/>
export default ModalInput
)}
</label>
{errors[field] && <p className="text-red-500 text-sm">{errors[field]}</p>}
</div>
))}
<button type="submit" className="btn btn-secondary">Tambah Data</button>
</form>
</div>
<label className="modal-backdrop" htmlFor="my_modal_7">Close</label>
</div>
</div>
);
};
export default ModalInput;

View File

@ -2,12 +2,12 @@ import React from 'react'
import { Head } from '@inertiajs/react'
import ModalInput from '@/Components/ModalInput'
export default function IndexSantri({ santri }) {
export default function IndexSantri({ santri, fields, options, santris }) {
return (
<div className="text-red-900">
<Head title="Daftar Santri" />
<h1>Daftar Santri</h1>
<ModalInput />
<ModalInput fields={fields} options={options} tableName="santris" />
{santri ? santri.map((item, i) => {
return (
<div key={i}>

View File

@ -27,7 +27,7 @@
});
Route::get('/data-santri', [SantriController::class, 'index'])->name('indexSantri');
Route::post('/addSantri', [SantriController::class, 'store'])->name('storeSantri');
Route::post('/addsantris', [SantriController::class, 'store'])->name('storeSantri');
Route::get('/dashboard', function () {
return Inertia::render('Dashboard');