done crud employee

pull/1/head
Aji Kamaludin 3 years ago
parent 1d8cc39b1f
commit c8df4033a5
No known key found for this signature in database
GPG Key ID: 670E1F26AD5A8099

@ -0,0 +1,21 @@
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use App\Models\Employee;
class EmployeeQueryController extends Controller
{
public function __invoke(Request $request)
{
if ($request->q != null) {
$query = Employee::where('name', 'like', '%'.$request->q.'%')->orWhere('whatsapp', 'like', '%'.$request->q.'%')->orderBy('id');
} else {
$query = Employee::orderBy('id');
}
return $query->paginate(10);
}
}

@ -0,0 +1,103 @@
<?php
namespace App\Http\Controllers;
use App\Models\Employee;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class EmployeeController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $request)
{
if ($request->q != null) {
$query = Employee::where('name', 'like', '%'.$request->q.'%')->orWhere('whatsapp', 'like', '%'.$request->q.'%')->orderBy('id');
} else {
$query = Employee::orderBy('id');
}
return inertia('Employees', [
'employees' => $query->paginate(10),
]);
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
$request->validate([
'name' => 'required|string',
'whatsapp' => 'nullable|string',
'photo' => 'nullable|image'
]);
$employee = Employee::make($request->only(['name', 'whatsapp']));
$photo = $request->file('photo');
if ($photo != null) {
$photo->store('public');
$employee->photo = $photo->hashName();
}
$employee->save();
return redirect()->route('employees.index');
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Employee $employee)
{
$request->validate([
'name' => 'required|string',
'whatsapp' => 'nullable|string',
'photo' => 'nullable|image'
]);
$employee->fill($request->only(['name', 'whatsapp']));
$photo = $request->file('photo');
if ($photo != null) {
if ($employee->photo != null) {
Storage::delete('public/'.$employee->photo);
$employee->photo = null;
}
$photo->store('public');
$employee->photo = $photo->hashName();
}
$employee->save();
return redirect()->route('employees.index');
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy(Employee $employee)
{
if ($employee->photo != null) {
Storage::delete('public/'.$employee->photo);
}
$employee->delete();
return redirect()->route('employees.index');
}
}

@ -3,6 +3,7 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Support\Facades\Storage;
use Illuminate\Database\Eloquent\Model;
class Employee extends Model
@ -15,4 +16,14 @@ class Employee extends Model
'whatsapp',
'basic_salary',
];
protected $appends = ['photo_url'];
public function getPhotoUrlAttribute()
{
if ($this->photo != null) {
return asset(Storage::url($this->photo));
}
return null;
}
}

@ -2833,6 +2833,11 @@ html {
margin-top: calc(0.5rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(0.5rem * var(--tw-space-y-reverse));
}
.space-y-4 > :not([hidden]) ~ :not([hidden]) {
--tw-space-y-reverse: 0;
margin-top: calc(1rem * calc(1 - var(--tw-space-y-reverse)));
margin-bottom: calc(1rem * var(--tw-space-y-reverse));
}
.overflow-hidden {
overflow: hidden;
}

389
public/js/app.js vendored

@ -4143,6 +4143,203 @@ function Guest(_ref) {
/***/ }),
/***/ "./resources/js/Modals/FormEmployeeModal.js":
/*!**************************************************!*\
!*** ./resources/js/Modals/FormEmployeeModal.js ***!
\**************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => (/* binding */ FormEmployeeModal)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
/* harmony import */ var _inertiajs_inertia_react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @inertiajs/inertia-react */ "./node_modules/@inertiajs/inertia-react/dist/index.js");
/* harmony import */ var react_toastify__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! react-toastify */ "./node_modules/react-toastify/dist/react-toastify.esm.js");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react/jsx-runtime */ "./node_modules/react/jsx-runtime.js");
function FormEmployeeModal(props) {
var isOpen = props.isOpen,
_props$toggle = props.toggle,
toggle = _props$toggle === void 0 ? function () {} : _props$toggle,
_props$employee = props.employee,
employee = _props$employee === void 0 ? null : _props$employee;
var _useForm = (0,_inertiajs_inertia_react__WEBPACK_IMPORTED_MODULE_1__.useForm)({
name: '',
whatsapp: '',
photo: null,
img_alt: null
}),
data = _useForm.data,
setData = _useForm.setData,
post = _useForm.post,
processing = _useForm.processing,
errors = _useForm.errors,
clearErrors = _useForm.clearErrors;
var inputPhoto = (0,react__WEBPACK_IMPORTED_MODULE_0__.useRef)();
var handleOnChange = function handleOnChange(event) {
setData(event.target.name, event.target.value);
};
var handleReset = function handleReset() {
setData({
name: '',
whatsapp: '',
photo: null,
img_alt: null
});
clearErrors();
};
var handleCancel = function handleCancel() {
handleReset();
toggle();
};
var handleSubmit = function handleSubmit() {
if (employee !== null) {
post(route('employees.update', employee), {
forceFormData: true,
onSuccess: function onSuccess() {
return Promise.all([handleReset(), toggle(), react_toastify__WEBPACK_IMPORTED_MODULE_2__.toast.success('The Data has been changed')]);
}
});
return;
}
post(route('employees.store'), {
onSuccess: function onSuccess() {
return Promise.all([handleReset(), toggle(), react_toastify__WEBPACK_IMPORTED_MODULE_2__.toast.success('The Data has been saved')]);
}
});
};
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
setData({
name: employee !== null && employee !== void 0 && employee.name ? employee.name : '',
whatsapp: employee !== null && employee !== void 0 && employee.whatsapp ? employee.whatsapp : '',
img_alt: employee !== null && employee !== void 0 && employee.photo_url ? employee.photo_url : null
});
}, [employee]);
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "modal",
style: isOpen ? {
opacity: 1,
pointerEvents: 'auto',
visibility: 'visible'
} : {},
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "modal-box",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("h1", {
className: "font-bold text-2xl pb-8",
children: "Barang"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "form-control",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("label", {
className: "label",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("span", {
className: "label-text",
children: "Nama"
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("input", {
type: "text",
placeholder: "nama",
className: "input input-bordered ".concat(errors.name && 'input-error'),
name: "name",
value: data.name,
onChange: handleOnChange
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("label", {
className: "label",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("span", {
className: "label-text-alt",
children: errors.name
})
})]
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "form-control",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("label", {
className: "label",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("span", {
className: "label-text",
children: "Whatsapp"
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("input", {
type: "text",
placeholder: "whatsapp",
className: "input input-bordered ".concat(errors.whatsapp && 'input-error'),
name: "whatsapp",
value: data.whatsapp,
onChange: handleOnChange
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("label", {
className: "label",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("span", {
className: "label-text-alt",
children: errors.whatsapp
})
})]
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "form-control",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("label", {
className: "label",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("span", {
className: "label-text",
children: "Foto"
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "input input-bordered ".concat(errors.photo && 'input-error'),
onClick: function onClick() {
console.log(inputPhoto.current.click());
},
children: data.photo ? data.photo.name : ''
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("input", {
ref: inputPhoto,
type: "file",
className: "hidden",
name: "photo",
onChange: function onChange(e) {
return setData('photo', e.target.files[0]);
},
accept: "image/png, image/jpeg, image/jpg"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("label", {
className: "label",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("span", {
className: "label-text-alt",
children: errors.photo
})
})]
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "form-control",
children: data.img_alt !== null && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("img", {
src: data.img_alt
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "modal-action",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
onClick: handleSubmit,
className: "btn btn-primary",
disabled: processing,
children: "Simpan"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
onClick: handleCancel,
className: "btn btn-secondary",
disabled: processing,
children: "Batal"
})]
})]
})
});
}
/***/ }),
/***/ "./resources/js/Modals/FormProductModal.js":
/*!*************************************************!*\
!*** ./resources/js/Modals/FormProductModal.js ***!
@ -5200,19 +5397,19 @@ function Dashboard(props) {
className: "bg-white overflow-hidden shadow-sm rounded-lg w-full",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "py-4 px-4 font-bold text-xl",
children: ["Barang", /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "text-4xl",
children: product
})]
}), "Barang"]
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "bg-white overflow-hidden shadow-sm rounded-lg w-full",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)("div", {
className: "py-4 px-4 font-bold text-xl",
children: ["Karyawan", /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "text-4xl",
children: employee
})]
}), "Karyawan"]
})
})]
})
@ -5234,29 +5431,195 @@ __webpack_require__.r(__webpack_exports__);
/* harmony export */ "default": () => (/* binding */ Employees)
/* harmony export */ });
/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react/index.js");
/* harmony import */ var _Layouts_Authenticated__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/Layouts/Authenticated */ "./resources/js/Layouts/Authenticated.js");
/* harmony import */ var _inertiajs_inertia_react__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @inertiajs/inertia-react */ "./node_modules/@inertiajs/inertia-react/dist/index.js");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react/jsx-runtime */ "./node_modules/react/jsx-runtime.js");
/* harmony import */ var _inertiajs_inertia_react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @inertiajs/inertia-react */ "./node_modules/@inertiajs/inertia-react/dist/index.js");
/* harmony import */ var _inertiajs_inertia__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @inertiajs/inertia */ "./node_modules/@inertiajs/inertia/dist/index.js");
/* harmony import */ var react_use__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! react-use */ "./node_modules/react-use/esm/usePrevious.js");
/* harmony import */ var react_toastify__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! react-toastify */ "./node_modules/react-toastify/dist/react-toastify.esm.js");
/* harmony import */ var _Hooks__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/Hooks */ "./resources/js/Hooks/index.js");
/* harmony import */ var _Layouts_Authenticated__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/Layouts/Authenticated */ "./resources/js/Layouts/Authenticated.js");
/* harmony import */ var _Components_Pagination__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/Components/Pagination */ "./resources/js/Components/Pagination.js");
/* harmony import */ var _Components_ModalConfirm__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/Components/ModalConfirm */ "./resources/js/Components/ModalConfirm.js");
/* harmony import */ var _Modals_FormEmployeeModal__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/Modals/FormEmployeeModal */ "./resources/js/Modals/FormEmployeeModal.js");
/* harmony import */ var react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! react/jsx-runtime */ "./node_modules/react/jsx-runtime.js");
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function Employees(props) {
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsxs)(_Layouts_Authenticated__WEBPACK_IMPORTED_MODULE_1__["default"], {
var _props$employees = props.employees,
employees = _props$employees.data,
links = _props$employees.links;
var _useState = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(''),
_useState2 = _slicedToArray(_useState, 2),
search = _useState2[0],
setSearch = _useState2[1];
var preValue = (0,react_use__WEBPACK_IMPORTED_MODULE_10__["default"])(search);
var _useState3 = (0,react__WEBPACK_IMPORTED_MODULE_0__.useState)(null),
_useState4 = _slicedToArray(_useState3, 2),
employee = _useState4[0],
setEmployee = _useState4[1];
var formModal = (0,_Hooks__WEBPACK_IMPORTED_MODULE_4__.useModalState)(false);
var toggle = function toggle() {
var employee = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
setEmployee(employee);
formModal.toggle();
};
var confirmModal = (0,_Hooks__WEBPACK_IMPORTED_MODULE_4__.useModalState)(false);
var handleDelete = function handleDelete(employee) {
confirmModal.setData(employee);
confirmModal.toggle();
};
var onDelete = function onDelete() {
var employee = confirmModal.data;
if (employee != null) {
_inertiajs_inertia__WEBPACK_IMPORTED_MODULE_2__.Inertia["delete"](route('employees.destroy', employee), {
onSuccess: function onSuccess() {
return react_toastify__WEBPACK_IMPORTED_MODULE_3__.toast.success('The Data has been deleted');
}
});
}
};
(0,react__WEBPACK_IMPORTED_MODULE_0__.useEffect)(function () {
if (preValue) {
_inertiajs_inertia__WEBPACK_IMPORTED_MODULE_2__.Inertia.get(route(route().current()), {
q: search
}, {
replace: true,
preserveState: true
});
}
}, [search]);
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)(_Layouts_Authenticated__WEBPACK_IMPORTED_MODULE_5__["default"], {
auth: props.auth,
errors: props.errors,
header: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("h2", {
header: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("h2", {
className: "font-semibold text-xl text-gray-800 leading-tight",
children: "Keryawan"
}),
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)(_inertiajs_inertia_react__WEBPACK_IMPORTED_MODULE_2__.Head, {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)(_inertiajs_inertia_react__WEBPACK_IMPORTED_MODULE_1__.Head, {
title: "Employees"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "py-12",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_3__.jsx)("div", {
className: "flex flex-row w-full sm:px-6 lg:px-8 space-x-4"
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "flex flex-col w-full sm:px-6 lg:px-8 space-y-2",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "card bg-white w-full",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)("div", {
className: "card-body",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)("div", {
className: "flex w-full mb-4 justify-between",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "btn btn-neutral",
onClick: function onClick() {
return toggle();
},
children: "Tambah"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "form-control",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("input", {
type: "text",
className: "input input-bordered",
value: search,
onChange: function onChange(e) {
return setSearch(e.target.value);
},
placeholder: "Search"
})
})]
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "overflow-x-auto",
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)("table", {
className: "table w-full table-zebra",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("thead", {
children: /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)("tr", {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("th", {
children: "Id"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("th", {
children: "Nama"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("th", {
children: "Whatsapp"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("th", {
children: "Foto"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("th", {})]
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("tbody", {
children: employees === null || employees === void 0 ? void 0 : employees.map(function (employee) {
return /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)("tr", {
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("th", {
children: employee.id
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("td", {
children: employee.name
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("td", {
children: employee.whatsapp
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("td", {
children: employee.photo_url !== null && /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("img", {
width: "100px",
src: employee.photo_url
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsxs)("td", {
className: "text-right",
children: [/*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "btn btn-primary mx-1",
onClick: function onClick() {
return toggle(employee);
},
children: "Edit"
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)("div", {
className: "btn btn-secondary mx-1",
onClick: function onClick() {
return handleDelete(employee);
},
children: "Delete"
})]
})]
}, employee.id);
})
})]
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)(_Components_Pagination__WEBPACK_IMPORTED_MODULE_6__["default"], {
links: links
})]
})
})
})
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)(_Modals_FormEmployeeModal__WEBPACK_IMPORTED_MODULE_8__["default"], {
isOpen: formModal.isOpen,
toggle: toggle,
employee: employee
}), /*#__PURE__*/(0,react_jsx_runtime__WEBPACK_IMPORTED_MODULE_9__.jsx)(_Components_ModalConfirm__WEBPACK_IMPORTED_MODULE_7__["default"], {
isOpen: confirmModal.isOpen,
toggle: confirmModal.toggle,
onConfirm: onDelete
})]
});
}

@ -0,0 +1,169 @@
import React, { useEffect, useRef } from 'react'
import { useForm } from '@inertiajs/inertia-react'
import { toast } from 'react-toastify'
export default function FormEmployeeModal(props) {
const { isOpen, toggle = () => {}, employee = null } = props
const { data, setData, post, processing, errors, clearErrors } =
useForm({
name: '',
whatsapp: '',
photo: null,
img_alt: null,
})
const inputPhoto = useRef()
const handleOnChange = (event) => {
setData(event.target.name, event.target.value)
}
const handleReset = () => {
setData({
name: '',
whatsapp: '',
photo: null,
img_alt: null,
})
clearErrors()
}
const handleCancel = () => {
handleReset()
toggle()
}
const handleSubmit = () => {
if (employee !== null) {
post(route('employees.update', employee), {
forceFormData: true,
onSuccess: () =>
Promise.all([
handleReset(),
toggle(),
toast.success('The Data has been changed'),
]),
})
return
}
post(route('employees.store'), {
onSuccess: () =>
Promise.all([
handleReset(),
toggle(),
toast.success('The Data has been saved'),
]),
})
}
useEffect(() => {
setData({
name: employee?.name ? employee.name : '',
whatsapp: employee?.whatsapp ? employee.whatsapp : '',
img_alt: employee?.photo_url ? employee.photo_url : null,
})
}, [employee])
return (
<div
className="modal"
style={
isOpen
? {
opacity: 1,
pointerEvents: 'auto',
visibility: 'visible',
}
: {}
}
>
<div className="modal-box">
<h1 className="font-bold text-2xl pb-8">Barang</h1>
<div className="form-control">
<label className="label">
<span className="label-text">Nama</span>
</label>
<input
type="text"
placeholder="nama"
className={`input input-bordered ${
errors.name && 'input-error'
}`}
name="name"
value={data.name}
onChange={handleOnChange}
/>
<label className="label">
<span className="label-text-alt">{errors.name}</span>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Whatsapp</span>
</label>
<input
type="text"
placeholder="whatsapp"
className={`input input-bordered ${
errors.whatsapp && 'input-error'
}`}
name="whatsapp"
value={data.whatsapp}
onChange={handleOnChange}
/>
<label className="label">
<span className="label-text-alt">
{errors.whatsapp}
</span>
</label>
</div>
<div className="form-control">
<label className="label">
<span className="label-text">Foto</span>
</label>
<div
className={`input input-bordered ${
errors.photo && 'input-error'
}`}
onClick={() => {
console.log(inputPhoto.current.click())
}}
>
{data.photo ? data.photo.name : ''}
</div>
<input
ref={inputPhoto}
type="file"
className="hidden"
name="photo"
onChange={(e) => setData('photo', e.target.files[0])}
accept="image/png, image/jpeg, image/jpg"
/>
<label className="label">
<span className="label-text-alt">{errors.photo}</span>
</label>
</div>
<div className="form-control">
{data.img_alt !== null && <img src={data.img_alt} />}
</div>
<div className="modal-action">
<div
onClick={handleSubmit}
className="btn btn-primary"
disabled={processing}
>
Simpan
</div>
<div
onClick={handleCancel}
className="btn btn-secondary"
disabled={processing}
>
Batal
</div>
</div>
</div>
</div>
)
}

@ -20,14 +20,14 @@ export default function Dashboard(props) {
<div className="flex flex-row sm:px-6 lg:px-8 space-x-4">
<div className="bg-white overflow-hidden shadow-sm rounded-lg w-full">
<div className="py-4 px-4 font-bold text-xl">
Barang
<div className="text-4xl">{product}</div>
Barang
</div>
</div>
<div className="bg-white overflow-hidden shadow-sm rounded-lg w-full">
<div className="py-4 px-4 font-bold text-xl">
Karyawan
<div className="text-4xl">{employee}</div>
Karyawan
</div>
</div>
</div>

@ -1,24 +1,158 @@
import React from 'react'
import Authenticated from '@/Layouts/Authenticated'
import React, { useState, useEffect } from 'react'
import { Head } from '@inertiajs/inertia-react'
import { Inertia } from '@inertiajs/inertia'
import { usePrevious } from 'react-use'
import { toast } from 'react-toastify'
import { useModalState } from '@/Hooks'
import Authenticated from '@/Layouts/Authenticated'
import Pagination from '@/Components/Pagination'
import ModalConfirm from '@/Components/ModalConfirm'
import FormEmployeeModal from '@/Modals/FormEmployeeModal'
export default function Employees(props) {
return (
<Authenticated
auth={props.auth}
errors={props.errors}
header={
<h2 className="font-semibold text-xl text-gray-800 leading-tight">
Keryawan
</h2>
}
>
<Head title="Employees" />
<div className="py-12">
<div className="flex flex-row w-full sm:px-6 lg:px-8 space-x-4">
</div>
</div>
</Authenticated>
)
}
const { data: employees, links } = props.employees
const [search, setSearch] = useState('')
const preValue = usePrevious(search)
const [employee, setEmployee] = useState(null)
const formModal = useModalState(false)
const toggle = (employee = null) => {
setEmployee(employee)
formModal.toggle()
}
const confirmModal = useModalState(false)
const handleDelete = (employee) => {
confirmModal.setData(employee)
confirmModal.toggle()
}
const onDelete = () => {
const employee = confirmModal.data
if (employee != null) {
Inertia.delete(route('employees.destroy', employee), {
onSuccess: () => toast.success('The Data has been deleted'),
})
}
}
useEffect(() => {
if (preValue) {
Inertia.get(
route(route().current()),
{ q: search },
{
replace: true,
preserveState: true,
}
)
}
}, [search])
return (
<Authenticated
auth={props.auth}
errors={props.errors}
header={
<h2 className="font-semibold text-xl text-gray-800 leading-tight">
Keryawan
</h2>
}
>
<Head title="Employees" />
<div className="py-12">
<div className="flex flex-col w-full sm:px-6 lg:px-8 space-y-2">
<div className="card bg-white w-full">
<div className="card-body">
<div className="flex w-full mb-4 justify-between">
<div
className="btn btn-neutral"
onClick={() => toggle()}
>
Tambah
</div>
<div className="form-control">
<input
type="text"
className="input input-bordered"
value={search}
onChange={(e) =>
setSearch(e.target.value)
}
placeholder="Search"
/>
</div>
</div>
<div className="overflow-x-auto">
<table className="table w-full table-zebra">
<thead>
<tr>
<th>Id</th>
<th>Nama</th>
<th>Whatsapp</th>
<th>Foto</th>
<th></th>
</tr>
</thead>
<tbody>
{employees?.map((employee) => (
<tr key={employee.id}>
<th>{employee.id}</th>
<td>{employee.name}</td>
<td>{employee.whatsapp}</td>
<td>
{employee.photo_url !==
null && (
<img
width="100px"
src={
employee.photo_url
}
/>
)}
</td>
<td className="text-right">
<div
className="btn btn-primary mx-1"
onClick={() =>
toggle(employee)
}
>
Edit
</div>
<div
className="btn btn-secondary mx-1"
onClick={() =>
handleDelete(
employee
)
}
>
Delete
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<Pagination links={links} />
</div>
</div>
</div>
</div>
<FormEmployeeModal
isOpen={formModal.isOpen}
toggle={toggle}
employee={employee}
/>
<ModalConfirm
isOpen={confirmModal.isOpen}
toggle={confirmModal.toggle}
onConfirm={onDelete}
/>
</Authenticated>
)
}

@ -2,6 +2,7 @@
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\Api\EmployeeQueryController;
/*
|--------------------------------------------------------------------------
@ -13,6 +14,7 @@ use Illuminate\Support\Facades\Route;
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::get('employees', EmployeeQueryController::class)->name('api.employees.query');
Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
return $request->user();

@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Route;
use App\Http\Controllers\DashboardController;
use App\Http\Controllers\UserController;
use App\Http\Controllers\ProductController;
use App\Http\Controllers\EmployeeController;
/*
|--------------------------------------------------------------------------
@ -34,7 +35,11 @@ Route::middleware(['auth'])->group(function () {
Route::post('/products/{product}', [ProductController::class, 'update'])->name('products.update');
Route::delete('/products/{product}', [ProductController::class, 'destroy'])->name('products.destroy');
Route::get('/employees', fn () => inertia('Employees'))->name('employees.index');
Route::get('/employees', [EmployeeController::class, 'index'])->name('employees.index');
Route::post('/employees', [EmployeeController::class, 'store'])->name('employees.store');
Route::post('/employees/{employee}', [EmployeeController::class, 'update'])->name('employees.update');
Route::delete('/employees/{employee}', [EmployeeController::class, 'destroy'])->name('employees.destroy');
Route::get('/payrolls', fn () => inertia('Payrolls'))->name('payrolls.index');
Route::get('/report', fn () => inertia('Report'))->name('report');
});

Loading…
Cancel
Save