diff --git a/app/Http/Controllers/GeneralController.php b/app/Http/Controllers/GeneralController.php index e017971..9cb1a4b 100644 --- a/app/Http/Controllers/GeneralController.php +++ b/app/Http/Controllers/GeneralController.php @@ -14,6 +14,6 @@ class GeneralController extends Controller public function jabatan() { - return Inertia::render('Jabatan'); + return Inertia::render('Jabatan/Index'); } } diff --git a/package-lock.json b/package-lock.json index 7451424..e7f69e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,8 @@ "packages": { "": { "dependencies": { - "firebase": "^9.9.1" + "firebase": "^9.9.1", + "react-toastify": "^9.0.7" }, "devDependencies": { "@headlessui/react": "^1.4.2", @@ -1547,6 +1548,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==", + "engines": { + "node": ">=6" + } + }, "node_modules/color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -2443,8 +2452,7 @@ "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/jsesc": { "version": "2.5.2", @@ -2539,7 +2547,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -2699,7 +2706,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -2989,7 +2995,6 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -3002,7 +3007,6 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -3021,6 +3025,18 @@ "node": ">=0.10.0" } }, + "node_modules/react-toastify": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.7.tgz", + "integrity": "sha512-UG5P/2F/fYdbK+v3XRWHM6xfMkWeLM+k2swKvwU8oO9DXx31GkeoH7Z6slBTkavZ0VjoQ+n/YD6xOBqEwN7HRg==", + "dependencies": { + "clsx": "^1.1.1" + }, + "peerDependencies": { + "react": ">=16", + "react-dom": ">=16" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -3152,7 +3168,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -4787,6 +4802,11 @@ "wrap-ansi": "^7.0.0" } }, + "clsx": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.2.1.tgz", + "integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==" + }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -5365,8 +5385,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "jsesc": { "version": "2.5.2", @@ -5440,7 +5459,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -5552,8 +5570,7 @@ "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" }, "object-hash": { "version": "3.0.0", @@ -5730,7 +5747,6 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -5740,7 +5756,6 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -5753,6 +5768,14 @@ "integrity": "sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==", "dev": true }, + "react-toastify": { + "version": "9.0.7", + "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-9.0.7.tgz", + "integrity": "sha512-UG5P/2F/fYdbK+v3XRWHM6xfMkWeLM+k2swKvwU8oO9DXx31GkeoH7Z6slBTkavZ0VjoQ+n/YD6xOBqEwN7HRg==", + "requires": { + "clsx": "^1.1.1" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -5842,7 +5865,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.20.2.tgz", "integrity": "sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" diff --git a/package.json b/package.json index 2382d6c..1b90daa 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "vite": "^3.0.0" }, "dependencies": { - "firebase": "^9.9.1" + "firebase": "^9.9.1", + "react-toastify": "^9.0.7" } } diff --git a/resources/js/Components/Button.jsx b/resources/js/Components/Button.jsx index 7675e99..16f411b 100644 --- a/resources/js/Components/Button.jsx +++ b/resources/js/Components/Button.jsx @@ -1,8 +1,9 @@ import React from 'react'; -export default function Button({ type = 'submit', className = '', processing, children }) { +export default function Button({ type = 'submit', className = '', processing, children, onClick }) { return ( + + +
+ {children} +
+ + + + ) +} \ No newline at end of file diff --git a/resources/js/Hooks/index.jsx b/resources/js/Hooks/index.jsx new file mode 100644 index 0000000..d52cc6a --- /dev/null +++ b/resources/js/Hooks/index.jsx @@ -0,0 +1,31 @@ +import { useState, useEffect } from 'react' + +export function useDebounce(value, delay) { + const [debouncedValue, setDebouncedValue] = useState(value) + useEffect(() => { + const handler = setTimeout(() => { + setDebouncedValue(value) + }, delay) + return () => { + clearTimeout(handler) + } + }, [value, delay]) + return debouncedValue +} + +export function useModalState(state = false) { + const [isOpen, setIsOpen] = useState(state) + const toggle = () => { + setIsOpen(!isOpen) + } + + const [data, setData] = useState(null) + + return { + isOpen, + toggle, + setIsOpen, + data, + setData, + } +} \ No newline at end of file diff --git a/resources/js/Layouts/Authenticated.jsx b/resources/js/Layouts/Authenticated.jsx index 7222b76..c717e03 100644 --- a/resources/js/Layouts/Authenticated.jsx +++ b/resources/js/Layouts/Authenticated.jsx @@ -1,4 +1,6 @@ import React, { useState } from 'react'; +import 'react-toastify/dist/ReactToastify.css' +import { ToastContainer } from 'react-toastify' import Dropdown from '@/Components/Dropdown'; import ResponsiveNavLink from '@/Components/ResponsiveNavLink'; import { Link } from '@inertiajs/inertia-react'; @@ -6,7 +8,6 @@ import { Link } from '@inertiajs/inertia-react'; export default function Authenticated({ auth, children }) { const [showingNavigationDropdown, setShowingNavigationDropdown] = useState(false); - return (
+ ); } diff --git a/resources/js/Layouts/Guest.jsx b/resources/js/Layouts/Guest.jsx index 5675737..a8472f8 100644 --- a/resources/js/Layouts/Guest.jsx +++ b/resources/js/Layouts/Guest.jsx @@ -7,7 +7,7 @@ export default function Guest({ children }) {
- Payroll App + Koro Koro Family Karaoke
diff --git a/resources/js/Pages/Dashboard.jsx b/resources/js/Pages/Dashboard.jsx index af589a0..ca898e2 100644 --- a/resources/js/Pages/Dashboard.jsx +++ b/resources/js/Pages/Dashboard.jsx @@ -13,7 +13,7 @@ export default function Dashboard(props) {
-
You're logged in!
+
Hai, {props.auth.user.name}
diff --git a/resources/js/Pages/Jabatan.jsx b/resources/js/Pages/Jabatan.jsx deleted file mode 100644 index 2b545a5..0000000 --- a/resources/js/Pages/Jabatan.jsx +++ /dev/null @@ -1,89 +0,0 @@ -import React from 'react'; -import Authenticated from '@/Layouts/Authenticated'; -import { Head } from '@inertiajs/inertia-react'; -import Button from '@/Components/Button'; - -export default function Jabatan(props) { - return ( - - - -
-
-
-
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- Product name - - Color - - Category - - Price -
- Apple MacBook Pro 17" - - Sliver - - Laptop - - $2999 -
- Microsoft Surface Pro - - White - - Laptop PC - - $1999 -
- Magic Mouse 2 - - Black - - Accessories - - $99 -
-
-
-
-
-
-
- ); -} diff --git a/resources/js/Pages/Jabatan/FormModal.jsx b/resources/js/Pages/Jabatan/FormModal.jsx new file mode 100644 index 0000000..e274372 --- /dev/null +++ b/resources/js/Pages/Jabatan/FormModal.jsx @@ -0,0 +1,91 @@ +import React, { useEffect, useState } from 'react' +import { toast } from 'react-toastify' +import { Modal } from '@/Components/Modal' +import { useForm } from '@inertiajs/inertia-react' +import Button from '@/Components/Button' +import Input from '@/Components/Input' +import { create, update } from '@/Services/Jabatan' + +export default function FormModal({ modalState, refresh }) { + const [loading, setLoading] = useState(false) + const { data, setData, reset } = useForm({ + nama: '', + tunjangan: 0 + }) + + useEffect(() => { + if (modalState.isOpen === false) { + reset() + modalState.setData(null) + } + if (modalState.data !== null) { + setData(modalState.data.data) + } + }, [modalState]) + + const onHandleChange = (event) => { + setData( + event.target.name, + event.target.type === 'checkbox' + ? event.target.checked + : event.target.value + ) + } + + const submit = (e) => { + e.preventDefault() + setLoading(true) + if (modalState.data !== null) { + update(data, modalState.data.id) + .finally(() => { + reset() + toast.success("berhasil update") + setLoading(false) + modalState.toggle() + refresh() + }) + } else { + create(data) + .then((id) => console.log(id)) + .finally(() => { + reset() + toast.success("berhasil simpan") + setLoading(false) + modalState.toggle() + refresh() + }) + } + } + + return ( + +
Jabatan
+ + + +
+ ) +} \ No newline at end of file diff --git a/resources/js/Pages/Jabatan/Index.jsx b/resources/js/Pages/Jabatan/Index.jsx new file mode 100644 index 0000000..72e9bc0 --- /dev/null +++ b/resources/js/Pages/Jabatan/Index.jsx @@ -0,0 +1,95 @@ +import React, { useEffect, useState } from 'react'; +import Authenticated from '@/Layouts/Authenticated'; +import { Head } from '@inertiajs/inertia-react'; +import { useModalState } from '@/Hooks' +import Button from '@/Components/Button'; +import FormModal from './FormModal'; +import { getAll, deleteById } from '@/Services/Jabatan'; +import { toast } from 'react-toastify'; + +export default function Jabatan(props) { + const formModal = useModalState(false) + const [items, setItems] = useState([]) + + const hanldeDeleteClick = (item) => { + const con = confirm("delete item?") + if (con) { + deleteById(item.id) + .then(() => toast.success('berhasil hapus')) + .finally(() => fetchData()) + } + } + + const handleEditClick = (item) => { + formModal.setData(item) + formModal.toggle() + } + + const fetchData = () => { + getAll() + .then(items => setItems(items)) + } + + useEffect(() => { + fetchData() + }, []) + + return ( + + + +
+
+
+
+ +
+ + + + + + + + + + + {items.map(item => ( + + + + + + + ))} + +
+ ID + + Nama + + Tunjangan +
+ {item.id} + + {item.data.nama} + + Rp. {item.data.tunjangan} + +
+ + +
+
+
+
+
+
+
+ +
+ ); +} diff --git a/resources/js/Services/Jabatan.js b/resources/js/Services/Jabatan.js index ee6e4c5..114adb2 100644 --- a/resources/js/Services/Jabatan.js +++ b/resources/js/Services/Jabatan.js @@ -1,19 +1,41 @@ import db from "@/firebase"; -import { collection, getDocs, doc, setDoc } from "firebase/firestore"; +import { collection, getDocs, doc, addDoc, deleteDoc, updateDoc } from "firebase/firestore"; -async function getAllJabatan() { - const collect = collection(db, 'jabatan') +const COLLECTION = "jabatan" + +async function getAll() { + const collect = collection(db, COLLECTION) const data = await getDocs(collect) - const lists = data.docs.map(doc => doc.data()) + const lists = data.docs.map(doc => { + return { + data: doc.data(), + id: doc.id + } + }) return lists } -async function createJabatan(payload) { - const docRef = await setDoc(doc(db, "jabatan"), payload); +async function create(payload) { + const docRef = await addDoc(collection(db, COLLECTION), payload) return docRef.id } +async function update(payload, id){ + const docRef = doc(db, COLLECTION, id) + const result = await updateDoc(docRef, payload); + return result +} + +async function deleteById(id) { + console.log(id) + const docRef = doc(db, COLLECTION, id) + const result = await deleteDoc(docRef); + return result +} + export { - getAllJabatan, - createJabatan + getAll, + create, + update, + deleteById } \ No newline at end of file