183 lines
5.9 KiB
JavaScript
183 lines
5.9 KiB
JavaScript
import React, { memo, useState, useEffect } from 'react';
|
|
import { Button, Col, Row, Input, ConfigProvider, Card, Tag, Table, Space } from 'antd';
|
|
import {
|
|
PlusOutlined,
|
|
EditOutlined,
|
|
DeleteOutlined,
|
|
SearchOutlined,
|
|
EyeOutlined,
|
|
SyncOutlined,
|
|
} from '@ant-design/icons';
|
|
import { NotifConfirmDialog } from '../../../../components/Global/ToastNotif';
|
|
import { useNavigate } from 'react-router-dom';
|
|
|
|
const ListShift = (props) => {
|
|
const [searchValue, setSearchValue] = useState('');
|
|
const navigate = useNavigate();
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem('token');
|
|
if (!token) {
|
|
navigate('/signin');
|
|
}
|
|
}, [navigate]);
|
|
|
|
const handleSearch = (value) => {
|
|
// This will be handled by the parent component if server-side search is needed
|
|
console.log('Search value:', value);
|
|
};
|
|
|
|
const handleSearchClear = () => {
|
|
setSearchValue('');
|
|
// This will be handled by the parent component if server-side search is needed
|
|
};
|
|
|
|
const showPreviewModal = (record) => {
|
|
props.setSelectedData(record);
|
|
props.setActionMode('preview');
|
|
};
|
|
|
|
const showEditModal = (record) => {
|
|
props.setSelectedData(record);
|
|
props.setActionMode('edit');
|
|
};
|
|
|
|
const showAddModal = () => {
|
|
props.setSelectedData(null);
|
|
props.setActionMode('add');
|
|
};
|
|
|
|
const showDeleteDialog = (record) => {
|
|
NotifConfirmDialog({
|
|
icon: 'question',
|
|
title: 'Konfirmasi',
|
|
message: `Apakah anda yakin ingin menghapus data shift "${record.nama_shift}"?`,
|
|
onConfirm: () => props.onDelete(record.id),
|
|
});
|
|
};
|
|
|
|
const columns = [
|
|
{
|
|
title: 'No',
|
|
key: 'no',
|
|
width: '5%',
|
|
align: 'center',
|
|
render: (_, __, index) => index + 1,
|
|
},
|
|
{
|
|
title: 'Nama Shift',
|
|
dataIndex: 'nama_shift',
|
|
key: 'nama_shift',
|
|
},
|
|
{
|
|
title: 'Jam Shift',
|
|
dataIndex: 'jam_shift',
|
|
key: 'jam_shift',
|
|
},
|
|
{
|
|
title: 'Status',
|
|
dataIndex: 'status',
|
|
key: 'status',
|
|
align: 'center',
|
|
render: (status) => (
|
|
<Tag color={status ? 'green' : 'red'}>
|
|
{status ? 'Active' : 'Inactive'}
|
|
</Tag>
|
|
),
|
|
},
|
|
{
|
|
title: 'Aksi',
|
|
key: 'action',
|
|
align: 'center',
|
|
width: '15%',
|
|
render: (_, record) => (
|
|
<Space>
|
|
<Button
|
|
icon={<EyeOutlined />}
|
|
onClick={() => showPreviewModal(record)}
|
|
style={{
|
|
color: '#1890ff',
|
|
borderColor: '#1890ff',
|
|
}}
|
|
/>
|
|
<Button
|
|
icon={<EditOutlined />}
|
|
onClick={() => showEditModal(record)}
|
|
style={{
|
|
color: '#faad14',
|
|
borderColor: '#faad14',
|
|
}}
|
|
/>
|
|
<Button
|
|
danger
|
|
icon={<DeleteOutlined />}
|
|
onClick={() => showDeleteDialog(record)}
|
|
style={{
|
|
borderColor: '#ff4d4f',
|
|
}}
|
|
/>
|
|
</Space>
|
|
),
|
|
},
|
|
];
|
|
|
|
const filteredData = props.shiftData.filter(item =>
|
|
item.nama_shift.toLowerCase().includes(searchValue.toLowerCase())
|
|
);
|
|
|
|
return (
|
|
<Card>
|
|
<Row justify="space-between" align="middle" gutter={[16, 16]}>
|
|
<Col xs={24} sm={12} md={10} lg={8}>
|
|
<Input.Search
|
|
placeholder="Cari nama shift..."
|
|
value={searchValue}
|
|
onChange={(e) => setSearchValue(e.target.value)}
|
|
onSearch={handleSearch}
|
|
allowClear={{
|
|
clearIcon: <span onClick={handleSearchClear}>x</span>,
|
|
}}
|
|
enterButton={<Button type="primary" icon={<SearchOutlined />} style={{ backgroundColor: '#23A55A', borderColor: '#23A55A' }}>Cari</Button>}
|
|
size="large"
|
|
/>
|
|
</Col>
|
|
<Col>
|
|
<ConfigProvider
|
|
theme={{
|
|
token: { colorBgContainer: '#E9F6EF' },
|
|
components: {
|
|
Button: {
|
|
defaultBg: 'white',
|
|
defaultColor: '#23A55A',
|
|
defaultBorderColor: '#23A55A',
|
|
defaultHoverColor: '#23A55A',
|
|
defaultHoverBorderColor: '#23A55A',
|
|
},
|
|
},
|
|
}}
|
|
>
|
|
<Button
|
|
icon={<PlusOutlined />}
|
|
onClick={showAddModal}
|
|
size="large"
|
|
>
|
|
Tambah Shift
|
|
</Button>
|
|
</ConfigProvider>
|
|
</Col>
|
|
</Row>
|
|
<Row style={{ marginTop: 16 }}>
|
|
<Col span={24}>
|
|
<Table
|
|
columns={columns}
|
|
dataSource={filteredData}
|
|
loading={props.loading}
|
|
rowKey="id"
|
|
/>
|
|
</Col>
|
|
</Row>
|
|
</Card>
|
|
);
|
|
};
|
|
|
|
export default memo(ListShift); |