데이터 초기화 화면 추가
This commit is contained in:
@@ -9,12 +9,11 @@ import {
|
|||||||
AdminView,
|
AdminView,
|
||||||
AuthSetting,
|
AuthSetting,
|
||||||
AuthSettingUpdate,
|
AuthSettingUpdate,
|
||||||
BusinessLogView,
|
CaliumRequest, DataInitView,
|
||||||
CaliumRequest,
|
|
||||||
LogView,
|
LogView,
|
||||||
} from './pages/UserManage';
|
} from './pages/UserManage';
|
||||||
import { EconomicIndex, UserIndex } from './pages/IndexManage';
|
import { EconomicIndex, UserIndex } from './pages/IndexManage';
|
||||||
import { LandInfoView, CryptView, GameLogView, UserView } from './pages/DataManage';
|
import { LandInfoView, CryptView, GameLogView, UserView, BusinessLogView, } from './pages/DataManage';
|
||||||
import {
|
import {
|
||||||
Board,
|
Board,
|
||||||
Event,
|
Event,
|
||||||
@@ -50,6 +49,7 @@ const RouteInfo = () => {
|
|||||||
<Route path="authsetting" element={<AuthSetting />} />
|
<Route path="authsetting" element={<AuthSetting />} />
|
||||||
<Route path="authsetting/:id" element={<AuthSettingUpdate />} />
|
<Route path="authsetting/:id" element={<AuthSettingUpdate />} />
|
||||||
<Route path="caliumrequest" element={<CaliumRequest />} />
|
<Route path="caliumrequest" element={<CaliumRequest />} />
|
||||||
|
<Route path="datainit" element={<DataInitView />} />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path="/indexmanage">
|
<Route path="/indexmanage">
|
||||||
<Route path="userindex" element={<UserIndex />} />
|
<Route path="userindex" element={<UserIndex />} />
|
||||||
|
|||||||
32
src/apis/Data.js
Normal file
32
src/apis/Data.js
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
//사용자 관리 - 데이터 api 연결
|
||||||
|
|
||||||
|
import { Axios } from '../utils';
|
||||||
|
|
||||||
|
|
||||||
|
export const InitData = async (token, params) => {
|
||||||
|
try {
|
||||||
|
const res = await Axios.post('/api/v1/data/init-data', params, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.data;
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof Error) {
|
||||||
|
throw new Error('InitData Error', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const InitHistoryList = async (token, params) => {
|
||||||
|
try {
|
||||||
|
const res = await Axios.post(`/api/v1/data/init-list`, params, {
|
||||||
|
headers: { Authorization: `Bearer ${token}` },
|
||||||
|
});
|
||||||
|
|
||||||
|
return res.data;
|
||||||
|
} catch (e) {
|
||||||
|
if (e instanceof Error) {
|
||||||
|
throw new Error('InitHistoryList Error', e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -16,6 +16,7 @@ import LandAuctionSearchBar from './searchBar/LandAuctionSearchBar'
|
|||||||
import MailListSearchBar from './searchBar/MailListSearchBar';
|
import MailListSearchBar from './searchBar/MailListSearchBar';
|
||||||
import LandInfoSearchBar from './searchBar/LandInfoSearchBar';
|
import LandInfoSearchBar from './searchBar/LandInfoSearchBar';
|
||||||
import BusinessLogSearchBar from './searchBar/BusinessLogSearchBar';
|
import BusinessLogSearchBar from './searchBar/BusinessLogSearchBar';
|
||||||
|
import DataInitSearchBar from './searchBar/DataInitSearchBar';
|
||||||
//etc
|
//etc
|
||||||
import ReportListSummary from './ReportListSummary';
|
import ReportListSummary from './ReportListSummary';
|
||||||
import WhiteListSearchBar from './WhiteListRegistBar';
|
import WhiteListSearchBar from './WhiteListRegistBar';
|
||||||
@@ -27,6 +28,7 @@ export {
|
|||||||
MailListSearchBar,
|
MailListSearchBar,
|
||||||
LandInfoSearchBar,
|
LandInfoSearchBar,
|
||||||
BusinessLogSearchBar,
|
BusinessLogSearchBar,
|
||||||
|
DataInitSearchBar,
|
||||||
ReportListAnswerModal,
|
ReportListAnswerModal,
|
||||||
ReportListDetailModal,
|
ReportListDetailModal,
|
||||||
ReportListSearchBar,
|
ReportListSearchBar,
|
||||||
|
|||||||
132
src/components/ServiceManage/searchBar/DataInitSearchBar.js
Normal file
132
src/components/ServiceManage/searchBar/DataInitSearchBar.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
import { BtnWrapper, InputLabel, TextInput } from '../../../styles/Components';
|
||||||
|
import Button from '../../common/button/Button';
|
||||||
|
import { SearchBarLayout, SearchPeriod } from '../../common/SearchBar';
|
||||||
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import { InitHistoryList } from '../../../apis/Data';
|
||||||
|
|
||||||
|
export const useDataInitSearch = (token, setAlertMsg) => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [searchParams, setSearchParams] = useState({
|
||||||
|
tran_id: '',
|
||||||
|
start_dt: (() => {
|
||||||
|
return new Date();
|
||||||
|
})(),
|
||||||
|
end_dt: (() => {
|
||||||
|
return new Date();
|
||||||
|
})(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const [data, setData] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const initialLoad = async () => {
|
||||||
|
await fetchData(searchParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
initialLoad();
|
||||||
|
}, [token]);
|
||||||
|
|
||||||
|
const fetchData = useCallback(async (params) => {
|
||||||
|
if (!token) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
const result = await InitHistoryList(
|
||||||
|
token,
|
||||||
|
params
|
||||||
|
);
|
||||||
|
if(result.result === "ERROR_LOG_MEMORY_LIMIT"){
|
||||||
|
setAlertMsg(t('LOG_MEMORY_LIMIT_WARNING'))
|
||||||
|
}else if(result.result === "ERROR_MONGODB_QUERY"){
|
||||||
|
setAlertMsg(t('LOG_MONGGDB_QUERY_WARNING'))
|
||||||
|
}
|
||||||
|
setData(result.data);
|
||||||
|
return result.data;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error fetching auction data:', error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
}, [token]);
|
||||||
|
|
||||||
|
const updateSearchParams = useCallback((newParams) => {
|
||||||
|
setSearchParams(prev => ({
|
||||||
|
...prev,
|
||||||
|
...newParams
|
||||||
|
}));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleSearch = useCallback(async (newParams = {}) => {
|
||||||
|
const updatedParams = {
|
||||||
|
...searchParams,
|
||||||
|
...newParams,
|
||||||
|
};
|
||||||
|
updateSearchParams(updatedParams);
|
||||||
|
return await fetchData(updatedParams);
|
||||||
|
}, [searchParams, fetchData]);
|
||||||
|
|
||||||
|
const handleReset = useCallback(async () => {
|
||||||
|
const now = new Date();
|
||||||
|
const resetParams = {
|
||||||
|
tran_id: '',
|
||||||
|
start_dt: now,
|
||||||
|
end_dt: now,
|
||||||
|
};
|
||||||
|
setSearchParams(resetParams);
|
||||||
|
return await fetchData(resetParams);
|
||||||
|
}, [fetchData]);
|
||||||
|
|
||||||
|
return {
|
||||||
|
searchParams,
|
||||||
|
loading,
|
||||||
|
data,
|
||||||
|
handleSearch,
|
||||||
|
handleReset,
|
||||||
|
updateSearchParams
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const DataInitSearchBar = ({ searchParams, onSearch, onReset }) => {
|
||||||
|
const handleSubmit = event => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
onSearch(searchParams);
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchList = [
|
||||||
|
<>
|
||||||
|
<InputLabel>트랜잭션 ID</InputLabel>
|
||||||
|
<TextInput
|
||||||
|
type="text"
|
||||||
|
placeholder='트랜잭션 ID 입력'
|
||||||
|
value={searchParams.tran_id}
|
||||||
|
width="300px"
|
||||||
|
onChange={e => onSearch({ tran_id: e.target.value })}
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
<>
|
||||||
|
<InputLabel>일자</InputLabel>
|
||||||
|
<SearchPeriod
|
||||||
|
startDate={searchParams.start_dt}
|
||||||
|
handleStartDate={date => onSearch({ start_dt: date }, false)}
|
||||||
|
endDate={searchParams.end_dt}
|
||||||
|
handleEndDate={date => onSearch({ end_dt: date }, false)}
|
||||||
|
/>
|
||||||
|
</>,
|
||||||
|
<></>,<></>,<></>,
|
||||||
|
<>
|
||||||
|
<BtnWrapper $gap="8px">
|
||||||
|
<Button theme="reset" handleClick={onReset} type="button" />
|
||||||
|
<Button theme="search" text="검색" handleClick={handleSubmit} type="submit" />
|
||||||
|
</BtnWrapper>
|
||||||
|
</>,
|
||||||
|
];
|
||||||
|
|
||||||
|
return <SearchBarLayout firstColumnData={searchList} direction={'column'} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default DataInitSearchBar;
|
||||||
@@ -8,6 +8,7 @@ const resources = {
|
|||||||
DATE_KTC: '* UTC+9 한국시간 기준으로 설정 (UTC+0 자동 반영처리)',
|
DATE_KTC: '* UTC+9 한국시간 기준으로 설정 (UTC+0 자동 반영처리)',
|
||||||
NOT_ITEM: '존재하지 않는 아이템코드입니다.',
|
NOT_ITEM: '존재하지 않는 아이템코드입니다.',
|
||||||
REGIST_COMPLTE: "등록이 완료되었습니다.",
|
REGIST_COMPLTE: "등록이 완료되었습니다.",
|
||||||
|
INIT_COMPLTE: "초기화 등록이 완료되었습니다.\n순차적으로 처리됩니다.",
|
||||||
REGIST_FAIL: '등록에 실패하였습니다. 잠시 후 다시 한번 진행해 주세요.',
|
REGIST_FAIL: '등록에 실패하였습니다. 잠시 후 다시 한번 진행해 주세요.',
|
||||||
UPDATE_FAIL: '수정에 실패하였습니다. 잠시 후 다시 한번 진행해 주세요.',
|
UPDATE_FAIL: '수정에 실패하였습니다. 잠시 후 다시 한번 진행해 주세요.',
|
||||||
STOP_FAIL: '중단에 실패하였습니다. 잠시 후 다시 한번 진행해 주세요.',
|
STOP_FAIL: '중단에 실패하였습니다. 잠시 후 다시 한번 진행해 주세요.',
|
||||||
@@ -40,6 +41,7 @@ const resources = {
|
|||||||
//db
|
//db
|
||||||
LOG_MEMORY_LIMIT_WARNING: '데이터가 너무 많아 조회할 수 없습니다.\n조회조건 조정 후 다시 조회해주세요.',
|
LOG_MEMORY_LIMIT_WARNING: '데이터가 너무 많아 조회할 수 없습니다.\n조회조건 조정 후 다시 조회해주세요.',
|
||||||
LOG_MONGGDB_QUERY_WARNING: '조회 중 오류가 발생하였습니다. 잠시 후 다시 한번 진행해 주세요.\n오류가 지속될 경우, 담당자에게 문의해주세요.',
|
LOG_MONGGDB_QUERY_WARNING: '조회 중 오류가 발생하였습니다. 잠시 후 다시 한번 진행해 주세요.\n오류가 지속될 경우, 담당자에게 문의해주세요.',
|
||||||
|
DATA_INIT_CONFIRM: '대상 {{data}}\n데이터를 초기화 하시겠습니까?\n초기화시 되돌릴 수 없습니다.',
|
||||||
//랜드
|
//랜드
|
||||||
LAND_OWNED_CHANGES_WARNING: "해당 랜드는 소유권 변경이 불가능합니다.",
|
LAND_OWNED_CHANGES_WARNING: "해당 랜드는 소유권 변경이 불가능합니다.",
|
||||||
LAND_OWNED_CHANGES_REGIST_CONFIRM: "랜드 소유권 변경을 등록하시겠습니까?",
|
LAND_OWNED_CHANGES_REGIST_CONFIRM: "랜드 소유권 변경을 등록하시겠습니까?",
|
||||||
|
|||||||
257
src/pages/UserManage/DataInitView.js
Normal file
257
src/pages/UserManage/DataInitView.js
Normal file
@@ -0,0 +1,257 @@
|
|||||||
|
import React, { useState, Fragment, useMemo } from 'react';
|
||||||
|
import Button from '../../components/common/button/Button';
|
||||||
|
import Loading from '../../components/common/Loading';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Title,
|
||||||
|
SelectInput,
|
||||||
|
TableStyle,
|
||||||
|
TableWrapper,
|
||||||
|
TableActionButton,
|
||||||
|
TableDetailRow,
|
||||||
|
TableDetailContainer,
|
||||||
|
TableDetailFlex,
|
||||||
|
TableDetailColumn,
|
||||||
|
DetailTableInfo,
|
||||||
|
} from '../../styles/Components';
|
||||||
|
|
||||||
|
import { modalTypes } from '../../assets/data';
|
||||||
|
|
||||||
|
import { useTranslation } from 'react-i18next';
|
||||||
|
import {
|
||||||
|
FormLabel,
|
||||||
|
FormRowGroup, MessageWrapper,
|
||||||
|
} from '../../styles/ModuleComponents';
|
||||||
|
import { authType } from '../../assets/data';
|
||||||
|
import { useModal, withAuth } from '../../utils/hook';
|
||||||
|
import { DynamicModal, TopButton } from '../../components/common';
|
||||||
|
import { opInitDataType, opSuccessType } from '../../assets/data/options';
|
||||||
|
import { InitData } from '../../apis/Data';
|
||||||
|
import DataInitSearchBar, { useDataInitSearch } from '../../components/ServiceManage/searchBar/DataInitSearchBar';
|
||||||
|
|
||||||
|
const DataInitView = () => {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
const token = sessionStorage.getItem('token');
|
||||||
|
|
||||||
|
const [loading, setLoading] = useState(false); // 로딩 창
|
||||||
|
const {
|
||||||
|
modalState,
|
||||||
|
handleModalView,
|
||||||
|
handleModalClose
|
||||||
|
} = useModal({
|
||||||
|
cancel: 'hidden',
|
||||||
|
registConfirm: 'hidden',
|
||||||
|
registComplete: 'hidden'
|
||||||
|
});
|
||||||
|
|
||||||
|
const [alertMsg, setAlertMsg] = useState('');
|
||||||
|
|
||||||
|
const [resultData, setResultData] = useState(initData); //데이터 정보
|
||||||
|
const [expandedRows, setExpandedRows] = useState({});
|
||||||
|
|
||||||
|
const {
|
||||||
|
searchParams,
|
||||||
|
loading: dataLoading,
|
||||||
|
data: dataList,
|
||||||
|
handleSearch,
|
||||||
|
handleReset,
|
||||||
|
updateSearchParams
|
||||||
|
} = useDataInitSearch(token, 500, setAlertMsg);
|
||||||
|
|
||||||
|
const toggleRowExpand = (index) => {
|
||||||
|
setExpandedRows(prev => ({
|
||||||
|
...prev,
|
||||||
|
[index]: !prev[index]
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
const tableHeaders = useMemo(() => {
|
||||||
|
return [
|
||||||
|
{ id: 'logTime', label: '일시', width: '100px' },
|
||||||
|
{ id: 'key', label: '키', width: '150px' },
|
||||||
|
{ id: 'dataType', label: '초기화대상', width: '80px' },
|
||||||
|
{ id: 'tranId', label: '트랜잭션ID', width: '150px' },
|
||||||
|
{ id: 'success', label: '성공여부', width: '60px' },
|
||||||
|
{ id: 'message', label: '작업메시지', width: '300px' },
|
||||||
|
{ id: 'details', label: '상세정보', width: '100px' },
|
||||||
|
// { id: 'recovery', label: '복구', width: '100px' }
|
||||||
|
];
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const renderDetailData = (data) => {
|
||||||
|
if (!data || typeof data !== 'object') return <></>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DetailTableInfo>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colSpan="2">정보</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{Object.entries(data).map(([key, value]) => (
|
||||||
|
<tr key={`${key}`}>
|
||||||
|
<td>{key}</td>
|
||||||
|
<td>
|
||||||
|
{typeof value === 'object' && value !== null
|
||||||
|
? JSON.stringify(value)
|
||||||
|
: String(value)
|
||||||
|
}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</DetailTableInfo>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (type, param = null) => {
|
||||||
|
switch (type) {
|
||||||
|
case "submit":
|
||||||
|
handleModalView('registConfirm');
|
||||||
|
break;
|
||||||
|
case "registConfirm":
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
await InitData(token, resultData).then(data => {
|
||||||
|
setLoading(false);
|
||||||
|
handleModalClose('registConfirm');
|
||||||
|
if(data.result === "SUCCESS") {
|
||||||
|
handleModalView('registComplete');
|
||||||
|
}else{
|
||||||
|
setAlertMsg(t('REGIST_FAIL'));
|
||||||
|
}
|
||||||
|
}).catch(reason => {
|
||||||
|
setLoading(false);
|
||||||
|
handleModalClose('registConfirm');
|
||||||
|
setAlertMsg(t('API_FAIL'));
|
||||||
|
});
|
||||||
|
|
||||||
|
break;
|
||||||
|
case "registComplete":
|
||||||
|
dataReset();
|
||||||
|
handleModalClose('registComplete');
|
||||||
|
break;
|
||||||
|
case "warning":
|
||||||
|
setAlertMsg('');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dataReset = () => {
|
||||||
|
setResultData(initData);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Title>데이터 초기화</Title>
|
||||||
|
<MessageWrapper>
|
||||||
|
<FormRowGroup>
|
||||||
|
<FormLabel>초기화 대상</FormLabel>
|
||||||
|
<SelectInput value={resultData?.init_data_type} onChange={e => setResultData({ ...resultData, init_data_type: e.target.value })} width="150px">
|
||||||
|
{opInitDataType.map((data, index) => (
|
||||||
|
<option key={index} value={data.value}>
|
||||||
|
{data.name}
|
||||||
|
</option>
|
||||||
|
))}
|
||||||
|
</SelectInput>
|
||||||
|
<Button
|
||||||
|
text="초기화"
|
||||||
|
theme={'primary'}
|
||||||
|
type="submit"
|
||||||
|
size="large"
|
||||||
|
width="100px"
|
||||||
|
handleClick={() => handleSubmit('submit')}
|
||||||
|
/>
|
||||||
|
</FormRowGroup>
|
||||||
|
</MessageWrapper>
|
||||||
|
<MessageWrapper>
|
||||||
|
<DataInitSearchBar
|
||||||
|
searchParams={searchParams}
|
||||||
|
onSearch={(newParams, executeSearch = true) => {
|
||||||
|
if (executeSearch) {
|
||||||
|
handleSearch(newParams);
|
||||||
|
} else {
|
||||||
|
updateSearchParams(newParams);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onReset={handleReset}
|
||||||
|
/>
|
||||||
|
</MessageWrapper>
|
||||||
|
<TableWrapper>
|
||||||
|
<TableStyle>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
{tableHeaders.map(header => (
|
||||||
|
<th key={header.id} width={header.width}>{header.label}</th>
|
||||||
|
))}
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{dataList?.init_list?.map((item, index) => (
|
||||||
|
<Fragment key={index}>
|
||||||
|
<tr>
|
||||||
|
<td>{item.timestamp}</td>
|
||||||
|
<td>{item.key}</td>
|
||||||
|
<td>{opInitDataType.find(type => type.value === item.initDataType)?.name}</td>
|
||||||
|
<td>{item.tranId}</td>
|
||||||
|
<td>{opSuccessType.find(type => type.value === item.success)?.name}</td>
|
||||||
|
<td>{item.message}</td>
|
||||||
|
<td>
|
||||||
|
<TableActionButton onClick={() => toggleRowExpand(index)}>
|
||||||
|
{expandedRows[index] ? '접기' : '상세보기'}
|
||||||
|
</TableActionButton>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{expandedRows[index] && (
|
||||||
|
<TableDetailRow>
|
||||||
|
<td colSpan={tableHeaders.length}>
|
||||||
|
<TableDetailContainer>
|
||||||
|
<TableDetailFlex>
|
||||||
|
<TableDetailColumn>
|
||||||
|
{renderDetailData(item.data)}
|
||||||
|
</TableDetailColumn>
|
||||||
|
</TableDetailFlex>
|
||||||
|
</TableDetailContainer>
|
||||||
|
</td>
|
||||||
|
</TableDetailRow>
|
||||||
|
)}
|
||||||
|
</Fragment>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</TableStyle>
|
||||||
|
</TableWrapper>
|
||||||
|
|
||||||
|
{/* 확인 모달 */}
|
||||||
|
<DynamicModal
|
||||||
|
modalType={modalTypes.confirmOkCancel}
|
||||||
|
view={modalState.registConfirmModal}
|
||||||
|
modalText={t('DATA_INIT_CONFIRM',{data:opInitDataType.find(type => type.value === resultData.init_data_type).name})}
|
||||||
|
handleSubmit={() => handleSubmit('registConfirm')}
|
||||||
|
handleCancel={() => handleModalClose('registConfirm')}
|
||||||
|
/>
|
||||||
|
{/* 완료 모달 */}
|
||||||
|
<DynamicModal
|
||||||
|
modalType={modalTypes.completed}
|
||||||
|
view={modalState.registCompleteModal}
|
||||||
|
modalText={t('INIT_COMPLTE')}
|
||||||
|
handleSubmit={() => handleSubmit('registComplete')}
|
||||||
|
/>
|
||||||
|
{/* 경고 모달 */}
|
||||||
|
<DynamicModal
|
||||||
|
modalType={modalTypes.completed}
|
||||||
|
view={alertMsg ? 'view' : 'hidden'}
|
||||||
|
modalText={alertMsg}
|
||||||
|
handleSubmit={() => setAlertMsg('')}
|
||||||
|
/>
|
||||||
|
{loading && <Loading/>}
|
||||||
|
<TopButton />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default withAuth(authType.levelMaster)(DataInitView);
|
||||||
|
|
||||||
|
const initData = {
|
||||||
|
init_data_type: 'None'
|
||||||
|
}
|
||||||
@@ -3,4 +3,4 @@ export { default as LogView } from './LogView';
|
|||||||
export { default as AuthSetting } from './AuthSetting';
|
export { default as AuthSetting } from './AuthSetting';
|
||||||
export { default as AuthSettingUpdate } from './AuthSettingUpdate';
|
export { default as AuthSettingUpdate } from './AuthSettingUpdate';
|
||||||
export { default as CaliumRequest} from './CaliumRequest';
|
export { default as CaliumRequest} from './CaliumRequest';
|
||||||
export { default as BusinessLogView} from './BusinessLogView';
|
export { default as DataInitView} from './DataInitView';
|
||||||
@@ -78,6 +78,17 @@ export const SelectInput = styled.select`
|
|||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const FormCenteredContainer = styled.div`
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
width: calc(100vw - 400px);
|
||||||
|
height: calc(100vh - 500px); /* 상단 영역 높이에 따라 조정 (헤더+필터 영역) */
|
||||||
|
padding: 20px;
|
||||||
|
overflow: auto;
|
||||||
|
min-height: 100px;
|
||||||
|
`;
|
||||||
|
|
||||||
export const Textarea = styled.textarea`
|
export const Textarea = styled.textarea`
|
||||||
&:focus {
|
&:focus {
|
||||||
border: 1px solid #2c2c2c;
|
border: 1px solid #2c2c2c;
|
||||||
@@ -548,4 +559,63 @@ export const DetailMessage = styled(Link)`
|
|||||||
export const PopupMessage = styled(Link)`
|
export const PopupMessage = styled(Link)`
|
||||||
color: #61a2d0;
|
color: #61a2d0;
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const TableDetailRow = styled.tr`
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const TableDetailContainer = styled.div`
|
||||||
|
padding: 15px;
|
||||||
|
background-color: #f8f9fa;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const TableDetailFlex = styled.div`
|
||||||
|
display: flex;
|
||||||
|
gap: 20px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const TableDetailColumn = styled.div`
|
||||||
|
flex: 1 1 48%;
|
||||||
|
min-width: 300px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const DetailTableInfo = styled.table`
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
padding: 8px;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
th {
|
||||||
|
background-color: #f1f1f1;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const TableActionButton = styled.button`
|
||||||
|
cursor: pointer;
|
||||||
|
background: #4a89dc;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
border-radius: 3px;
|
||||||
|
padding: 2px 5px;
|
||||||
|
font-size: 13px;
|
||||||
|
min-width: max-content;
|
||||||
|
width: 80px;
|
||||||
|
height: 24px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #3a70bc;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
Reference in New Issue
Block a user