178 lines
4.2 KiB
JavaScript
178 lines
4.2 KiB
JavaScript
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
import { useRecoilValue } from 'recoil';
|
|
import { AuthModal } from '../components/common';
|
|
import { authList } from '../store/authList';
|
|
import { INITIAL_CURRENT_PAGE, INITIAL_PAGE_SIZE } from '../assets/data/adminConstants';
|
|
import { PageSkeleton } from '../components/Skeleton/PageSkeleton';
|
|
|
|
export const useDateTimeState = (initialDate = '') => {
|
|
const [date, setDate] = useState(initialDate);
|
|
const [hour, setHour] = useState('00');
|
|
const [minute, setMinute] = useState('00');
|
|
|
|
const setDateTime = (newDate, newHour = hour, newMinute = minute) => {
|
|
const dateObj = newDate ? new Date(newDate) : new Date();
|
|
const result = new Date(
|
|
dateObj.getFullYear(),
|
|
dateObj.getMonth(),
|
|
dateObj.getDate(),
|
|
newHour,
|
|
newMinute
|
|
);
|
|
setDate(result);
|
|
setHour(newHour);
|
|
setMinute(newMinute);
|
|
return result;
|
|
};
|
|
|
|
return [date, hour, minute, setDateTime, setHour, setMinute];
|
|
};
|
|
|
|
export const useModal = (initialModals = {}) => {
|
|
const [modalState, setModalState] = useState(
|
|
Object.keys(initialModals).reduce((acc, key) => ({
|
|
...acc,
|
|
[`${key}Modal`]: initialModals[key] || 'hidden'
|
|
}), {})
|
|
);
|
|
|
|
const handleModalView = (type) => {
|
|
setModalState((prevState) => ({
|
|
...prevState,
|
|
[`${type}Modal`]: 'view'
|
|
}));
|
|
};
|
|
|
|
const handleModalClose = (type) => {
|
|
setModalState((prevState) => ({
|
|
...prevState,
|
|
[`${type}Modal`]: 'hidden'
|
|
}));
|
|
};
|
|
|
|
return {
|
|
modalState,
|
|
handleModalView,
|
|
handleModalClose
|
|
};
|
|
};
|
|
|
|
export const withAuth = (requiredAuth) => (WrappedComponent) => {
|
|
return function WithAuthComponent(props) {
|
|
const userInfo = useRecoilValue(authList);
|
|
|
|
if (!userInfo || !userInfo.auth_list) {
|
|
return (
|
|
<PageSkeleton />
|
|
);
|
|
}
|
|
|
|
const hasRequiredAuth = userInfo.auth_list &&
|
|
userInfo.auth_list.some(auth => auth.id === requiredAuth);
|
|
|
|
if (!hasRequiredAuth) {
|
|
return <AuthModal />;
|
|
}
|
|
|
|
return <WrappedComponent {...props} />;
|
|
// return <PageSkeleton />
|
|
};
|
|
};
|
|
|
|
export const useTable = (tableData = [], options = {mode: 'multi'}) => {
|
|
const [selectedRows, setSelectedRows] = useState([]);
|
|
const tableDataRef = useRef(tableData);
|
|
|
|
// tableData가 변경될 때 선택된 행 초기화
|
|
useEffect(() => {
|
|
const hasDataChanged =
|
|
tableData.length !== tableDataRef.current.length ||
|
|
tableData.some((item, index) =>
|
|
tableDataRef.current[index]?.id !== item.id
|
|
);
|
|
|
|
if (hasDataChanged) {
|
|
setSelectedRows([]);
|
|
tableDataRef.current = tableData;
|
|
}
|
|
}, [tableData]);
|
|
|
|
// 단일 행 선택/해제
|
|
const handleSelectRow = useCallback((e, rowData) => {
|
|
const checked = e.target.checked;
|
|
setSelectedRows(prev => {
|
|
if (checked) {
|
|
if (options.mode === 'single') {
|
|
return [rowData];
|
|
}
|
|
return [...prev, rowData];
|
|
} else {
|
|
return prev.filter(row => row.id !== rowData.id);
|
|
}
|
|
});
|
|
}, []);
|
|
|
|
// 전체 선택/해제
|
|
const handleSelectAll = useCallback(() => {
|
|
if (options.mode === 'single') return;
|
|
|
|
setSelectedRows(prev =>
|
|
prev.length === tableData.length ? [] : [...tableData]
|
|
);
|
|
}, [tableData]);
|
|
|
|
// 특정 행이 선택되었는지 확인
|
|
const isRowSelected = useCallback((rowId) => {
|
|
return selectedRows.some(row => row.id === rowId);
|
|
}, [selectedRows]);
|
|
|
|
// 전체 선택 여부 확인
|
|
const isAllSelected = tableData.length > 0 && selectedRows.length === tableData.length;
|
|
|
|
// 선택된 행 삭제
|
|
const removeSelectedRows = useCallback(() => {
|
|
setSelectedRows([]);
|
|
}, []);
|
|
|
|
return {
|
|
selectedRows,
|
|
handleSelectRow,
|
|
handleSelectAll,
|
|
isRowSelected,
|
|
isAllSelected,
|
|
removeSelectedRows
|
|
};
|
|
};
|
|
|
|
export const useDataFetch = (fetchFunction, dependencies = [], initialState = null) => {
|
|
const [data, setData] = useState(initialState);
|
|
const [loading, setLoading] = useState(false);
|
|
const [error, setError] = useState(null);
|
|
|
|
const fetchData = async (...params) => {
|
|
try {
|
|
setLoading(true);
|
|
setError(null);
|
|
const result = await fetchFunction(...params);
|
|
setData(result);
|
|
return result;
|
|
} catch (err) {
|
|
setError(err);
|
|
throw err;
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
useEffect(() => {
|
|
fetchData();
|
|
}, dependencies);
|
|
|
|
return {
|
|
data,
|
|
loading,
|
|
error,
|
|
refetch: fetchData,
|
|
setData
|
|
};
|
|
}; |