From 4a9b6c9d014e43387b08af3fa10ba4b4651017e4 Mon Sep 17 00:00:00 2001 From: Iqbal Rizqi Kurniawan Date: Fri, 17 Oct 2025 15:49:49 +0700 Subject: [PATCH] feat: enhance jadwal shift management with improved component structure and dummy data handling --- src/pages/jadwalShift/IndexJadwalShift.jsx | 106 ++--- .../component/DetailJadwalShift.jsx | 247 +++++------ .../jadwalShift/component/ListJadwalShift.jsx | 386 +++++++++++------- 3 files changed, 400 insertions(+), 339 deletions(-) diff --git a/src/pages/jadwalShift/IndexJadwalShift.jsx b/src/pages/jadwalShift/IndexJadwalShift.jsx index 0a9f7ea..95895a2 100644 --- a/src/pages/jadwalShift/IndexJadwalShift.jsx +++ b/src/pages/jadwalShift/IndexJadwalShift.jsx @@ -1,62 +1,74 @@ -import { useState, useEffect } from 'react'; +import React, { memo, useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; import ListJadwalShift from './component/ListJadwalShift'; import DetailJadwalShift from './component/DetailJadwalShift'; -import { getAllJadwalShift, deleteJadwalShift } from '../../api/jadwal-shift'; +import { useBreadcrumb } from '../../layout/LayoutBreadcrumb'; +import { Typography } from 'antd'; + +const { Text } = Typography; + +const IndexJadwalShift = memo(function IndexJadwalShift() { + const navigate = useNavigate(); + const { setBreadcrumbItems } = useBreadcrumb(); -const IndexJadwalShift = () => { const [actionMode, setActionMode] = useState('list'); const [selectedData, setSelectedData] = useState(null); - const [jadwalShiftData, setJadwalShiftData] = useState([]); - const [loading, setLoading] = useState(false); + const [readOnly, setReadOnly] = useState(false); + const [showModal, setShowModal] = useState(false); - const fetchData = async () => { - setLoading(true); - try { - const response = await getAllJadwalShift(new URLSearchParams()); - if (response.data) { - setJadwalShiftData(response.data.data); - } - } catch (error) { - console.error("Error fetching jadwal shift data:", error); + const setMode = (param) => { + setShowModal(true); + switch (param) { + case 'add': + setReadOnly(false); + break; + + case 'edit': + setReadOnly(false); + break; + + case 'preview': + setReadOnly(true); + break; + + default: + setShowModal(false); + break; } - setLoading(false); + setActionMode(param); }; useEffect(() => { - fetchData(); + const token = localStorage.getItem('token'); + if (token) { + setBreadcrumbItems([ + { title: • Jadwal }, + { title: Jadwal Shift } + ]); + } else { + navigate('/signin'); + } }, []); - const handleDelete = async (id) => { - try { - await deleteJadwalShift(id); - fetchData(); - } catch (error) { - console.error("Error deleting jadwal shift:", error); - } - }; - return ( - <> - {actionMode === 'list' && ( - - )} - {(actionMode === 'add' || actionMode === 'edit') && ( - - )} - + + + + ); -}; +}); -export default IndexJadwalShift; +export default IndexJadwalShift; \ No newline at end of file diff --git a/src/pages/jadwalShift/component/DetailJadwalShift.jsx b/src/pages/jadwalShift/component/DetailJadwalShift.jsx index 697e6c5..4f77120 100644 --- a/src/pages/jadwalShift/component/DetailJadwalShift.jsx +++ b/src/pages/jadwalShift/component/DetailJadwalShift.jsx @@ -1,51 +1,32 @@ -import { useEffect, useState } from 'react'; -import { Modal, Select, Divider, Typography, Button, ConfigProvider } from 'antd'; -import { NotifAlert, NotifOk } from '../../../components/Global/ToastNotif'; -import { createJadwalShift, updateJadwalShift } from '../../../api/jadwal-shift'; -import { getAllShift } from '../../../api/master-shift'; -import { getAllUser } from '../../../api/user'; +import React, { useEffect, useState } from 'react'; +import { + Modal, + Input, + Typography, + Button, + ConfigProvider, + Row, + Col +} from 'antd'; +import { NotifOk } from '../../../components/Global/ToastNotif'; const { Text } = Typography; -const { Option } = Select; const DetailJadwalShift = (props) => { const [confirmLoading, setConfirmLoading] = useState(false); - const [shifts, setShifts] = useState([]); - const [users, setUsers] = useState([]); const defaultData = { id: '', - id_shift: null, - id_user: null, + nama_shift: '', + jam_masuk: '', + jam_pulang: '', + username: '', + nama_employee: '', + whatsapp: '' }; const [FormData, setFormData] = useState(defaultData); - const fetchShifts = async () => { - try { - const response = await getAllShift(new URLSearchParams()); - setShifts(response?.data?.data || []); - } catch (error) { - console.error("Failed to fetch shifts:", error); - setShifts([]); - } - }; - - const fetchUsers = async () => { - try { - const response = await getAllUser(new URLSearchParams("limit=1000")); // Fetch all users - setUsers(response?.data?.data || []); - } catch (error) { - console.error("Failed to fetch users:", error); - setUsers([]); - } - }; - - useEffect(() => { - fetchShifts(); - fetchUsers(); - }, []); - const handleCancel = () => { props.setSelectedData(null); props.setActionMode('list'); @@ -53,70 +34,16 @@ const DetailJadwalShift = (props) => { const handleSave = async () => { setConfirmLoading(true); - - if (!FormData.id_shift) { - NotifOk({ - icon: 'warning', - title: 'Peringatan', - message: 'Kolom Shift Tidak Boleh Kosong', - }); + // This is a dummy save function for slicing purposes + setTimeout(() => { setConfirmLoading(false); - return; - } - - if (!FormData.id_user) { NotifOk({ - icon: 'warning', - title: 'Peringatan', - message: 'Kolom User Tidak Boleh Kosong', + icon: 'success', + title: 'Berhasil', + message: 'Data dummy berhasil disimpan.', }); - setConfirmLoading(false); - return; - } - - const payload = { - id_shift: FormData.id_shift, - id_user: FormData.id_user, - }; - - try { - const response = FormData.id - ? await updateJadwalShift(FormData.id, payload) - : await createJadwalShift(payload); - - if (response && (response.statusCode === 200 || response.statusCode === 201)) { - NotifOk({ - icon: 'success', - title: 'Berhasil', - message: `Data Jadwal Shift berhasil ${FormData.id ? 'diubah' : 'ditambahkan'}.`, - }); - - props.setActionMode('list'); - props.fetchData(); - } else { - NotifAlert({ - icon: 'error', - title: 'Gagal', - message: response?.message || 'Terjadi kesalahan saat menyimpan data.', - }); - } - } catch (error) { - console.error('Save Jadwal Shift Error:', error); - NotifAlert({ - icon: 'error', - title: 'Error', - message: error.message || 'Terjadi kesalahan pada server. Coba lagi nanti.', - }); - } - - setConfirmLoading(false); - }; - - const handleSelectChange = (name, value) => { - setFormData({ - ...FormData, - [name]: value, - }); + props.setActionMode('list'); + }, 1000); }; useEffect(() => { @@ -125,93 +52,119 @@ const DetailJadwalShift = (props) => { } else { setFormData(defaultData); } - }, [props.actionMode, props.selectedData]); + }, [props.showModal, props.selectedData]); + + // Dummy handler for slicing + const handleInputChange = (e) => { + const { name, value } = e.target; + setFormData({ ...FormData, [name]: value }); + }; return ( + - + - + {!props.readOnly && ( + + )} - , + , ]} > {FormData && (
-
- Shift - * - -
-
- User - * - -
+ + + Nama Karyawan + + + + Username + + + + Nama Shift + + + + Whatsapp + + + + Jam Masuk + + + + Jam Pulang + + +
)}
diff --git a/src/pages/jadwalShift/component/ListJadwalShift.jsx b/src/pages/jadwalShift/component/ListJadwalShift.jsx index 3bfdacd..23f5dae 100644 --- a/src/pages/jadwalShift/component/ListJadwalShift.jsx +++ b/src/pages/jadwalShift/component/ListJadwalShift.jsx @@ -1,186 +1,282 @@ import React, { memo, useState, useEffect } from 'react'; -import { Button, Col, Row, Input, ConfigProvider, Card, Table, Space } from 'antd'; +import { Space, Tag, ConfigProvider, Button, Row, Col, Card, Input } from 'antd'; import { PlusOutlined, EditOutlined, DeleteOutlined, - SearchOutlined, EyeOutlined, + SearchOutlined, } from '@ant-design/icons'; -import { NotifConfirmDialog } from '../../../components/Global/ToastNotif'; +import { NotifAlert, NotifConfirmDialog } from '../../../components/Global/ToastNotif'; import { useNavigate } from 'react-router-dom'; +import TableList from '../../../components/Global/TableList'; -const ListJadwalShift = (props) => { +// --- DUMMY DATA (Initial State) --- // +const initialDummyData = [ + { + id: 1, + nama_shift: 'Shift Pagi', + jam_masuk: '07:00', + jam_pulang: '15:00', + username: 'd.sanjaya', + nama_employee: 'Dede Sanjaya', + whatsapp: '081234567890' + }, + { + id: 2, + nama_shift: 'Shift Siang', + jam_masuk: '15:00', + jam_pulang: '23:00', + username: 'a.wijaya', + nama_employee: 'Andi Wijaya', + whatsapp: '081234567891' + }, + { + id: 3, + nama_shift: 'Shift Malam', + jam_masuk: '23:00', + jam_pulang: '07:00', + username: 'b.cahya', + nama_employee: 'Budi Cahya', + whatsapp: '081234567892' + }, +]; + +const columns = (showPreviewModal, showEditModal, showDeleteDialog) => [ + { + title: 'Nama Karyawan', + dataIndex: 'nama_employee', + key: 'nama_employee', + }, + { + title: 'Username', + dataIndex: 'username', + key: 'username', + }, + { + title: 'Nama Shift', + dataIndex: 'nama_shift', + key: 'nama_shift', + }, + { + title: 'Jam Masuk', + dataIndex: 'jam_masuk', + key: 'jam_masuk', + }, + { + title: 'Jam Pulang', + dataIndex: 'jam_pulang', + key: 'jam_pulang', + }, + { + title: 'Whatsapp', + dataIndex: 'whatsapp', + key: 'whatsapp', + }, + { + title: 'Aksi', + key: 'aksi', + align: 'center', + render: (_, record) => ( + + } - size="large" - /> - - - - - - - - - - - - - + + + + + + + { + const value = e.target.value; + setSearchValue(value); + if (value === '') { + handleSearchClear(); + } + }} + onSearch={handleSearch} + allowClear={{ + clearIcon: , + }} + enterButton={ + + } + size="large" + /> + + + + + + + + + + + + + + + + ); -}; +}); -export default ListJadwalShift; +export default ListJadwalShift; \ No newline at end of file