diff --git a/src/components/NotificationProvider.tsx b/src/components/NotificationProvider.tsx index 632c6fb..b2a694f 100644 --- a/src/components/NotificationProvider.tsx +++ b/src/components/NotificationProvider.tsx @@ -32,14 +32,9 @@ export const NotificationProvider = () => { autoHideDuration={autoHideDuration} onClose={handleClose} anchorOrigin={{ vertical: 'top', horizontal: 'right' }} - sx={{}} + sx={{ marginTop: '40px' }} > - + {message} diff --git a/src/pages/ManagePage/StepSlope/components/ImgsModal.tsx b/src/pages/ManagePage/StepSlope/components/ImgsModal.tsx index bc1ba37..74125ff 100644 --- a/src/pages/ManagePage/StepSlope/components/ImgsModal.tsx +++ b/src/pages/ManagePage/StepSlope/components/ImgsModal.tsx @@ -710,13 +710,14 @@ const DeleteImageButton = styled.button` color: white; border: none; border-radius: 50%; - width: 20px; - height: 20px; + width: 30px; + height: 30px; cursor: pointer; - font-size: 14px; + font-size: 20px; display: flex; align-items: center; justify-content: center; + padding-bottom: 3px; &:hover { background: rgba(0, 0, 0, 0.9); diff --git a/src/pages/ManagePage/StepSlope/components/regionData.tsx b/src/pages/ManagePage/StepSlope/components/regionData.tsx index 09b609c..b7d4340 100644 --- a/src/pages/ManagePage/StepSlope/components/regionData.tsx +++ b/src/pages/ManagePage/StepSlope/components/regionData.tsx @@ -16,15 +16,16 @@ export const CityOptions: CityOptionType[] = [ { value: '광주광역시', label: '광주광역시' }, { value: '대전광역시', label: '대전광역시' }, { value: '울산광역시', label: '울산광역시' }, + { value: '세종특별자치시', label: '세종특별자치시' }, { value: '경기도', label: '경기도' }, - { value: '강원도', label: '강원도' }, + { value: '강원특별자치도', label: '강원특별자치도' }, { value: '충청북도', label: '충청북도' }, { value: '충청남도', label: '충청남도' }, - { value: '전라북도', label: '전라북도' }, + { value: '전북특별자치도', label: '전북특별자치도' }, { value: '전라남도', label: '전라남도' }, { value: '경상북도', label: '경상북도' }, { value: '경상남도', label: '경상남도' }, - { value: '제주도', label: '제주도' }, + { value: '제주특별자치도', label: '제주특별자치도' }, ]; export const CountyOptions: CountyOptionsType = { @@ -61,6 +62,7 @@ export const CountyOptions: CountyOptionsType = { '모두', '강서구', '금정구', + '기장군', '남구', '동구', '동래구', @@ -74,156 +76,170 @@ export const CountyOptions: CountyOptionsType = { '영도구', '중구', '해운대구', - '기장군', ], 대구광역시: [ '모두', + '군위군', '남구', '달서구', + '달성군', '동구', '북구', '서구', '수성구', '중구', - '달성군', ], 인천광역시: [ '모두', + '강화군', '계양구', - '남구', '남동구', '동구', + '미추홀구', '부평구', '서구', '연수구', - '중구', - '강화군', '옹진군', + '중구', ], 광주광역시: ['모두', '광산구', '남구', '동구', '북구', '서구'], 대전광역시: ['모두', '대덕구', '동구', '서구', '유성구', '중구'], - 울산광역시: ['모두', '남구', '동구', '북구', '중구', '울주군'], + 울산광역시: ['모두', '남구', '동구', '북구', '울주군', '중구'], + 세종특별자치시: ['모두'], 경기도: [ '모두', - '고양시', + '가평군', + '고양시 덕양구', + '고양시 일산동구', + '고양시 일산서구', '과천시', '광명시', + '광주시', '구리시', '군포시', + '김포시', '남양주시', '동두천시', '부천시', - '성남시', - '수원시', + '성남시 분당구', + '성남시 수정구', + '성남시 중원구', + '수원시 권선구', + '수원시 영통구', + '수원시 장안구', + '수원시 팔달구', '시흥시', - '안산시', - '안양시', + '안산시 단원구', + '안산시 상록구', + '안성시', + '안양시 동안구', + '안양시 만안구', + '양주시', + '양평군', + '여주시', + '연천군', '오산시', + '용인시 기흥구', + '용인시 수지구', + '용인시 처인구', '의왕시', '의정부시', + '이천시', + '파주시', '평택시', '하남시', - '가평군', - '광주시', - '김포시', - '안성시', - '양주군', - '양평군', - '여주군', - '연천군', - '용인시', - '이천군', - '파주시', - '포천시', '화성시', ], - 강원도: [ + 강원특별자치도: [ '모두', '강릉시', + '고성군', '동해시', '삼척시', '속초시', - '원주시', - '춘천시', - '태백시', - '고성군', '양구군', '양양군', '영월군', + '원주시', '인제군', '정선군', '철원군', + '춘천시', + '태백시', '평창군', '홍천군', '화천군', - '황성군', + '횡성군', ], 충청북도: [ '모두', - '제천시', - '청주시', - '충주시', '괴산군', '단양군', '보은군', '영동군', '옥천군', '음성군', + '제천시', + '증평군', '진천군', - '청원군', + '청주시 상당구', + '청주시 서원구', + '청주시 청원구', + '청주시 흥덕구', + '충주시', ], 충청남도: [ '모두', + '계룡시', '공주시', - '보령시', - '서산시', - '아산시', - '천안시', '금산군', - '논산군', - '당진군', + '논산시', + '당진시', + '보령시', '부여군', + '서산시', '서천군', - '연기군', + '아산시', '예산군', + '천안시 동남구', + '천안시 서북구', '청양군', '태안군', '홍성군', ], - 전라북도: [ + 전북특별자치도: [ '모두', + '고창군', '군산시', '김제시', '남원시', - '익산시', - '전주시', - '정읍시', - '고창군', '무주군', '부안군', '순창군', '완주군', + '익산시', '임실군', '장수군', + '전주시 덕진구', + '전주시 완산구', + '정읍시', '진안군', ], 전라남도: [ '모두', - '광양시', - '나주시', - '목포시', - '순천시', - '여수시', - '여천시', '강진군', '고흥군', '곡성군', + '광양시', '구례군', + '나주시', '담양군', + '목포시', '무안군', '보성군', + '순천시', '신안군', - '여천군', + '여수시', '영광군', '영암군', '완도군', @@ -238,20 +254,18 @@ export const CountyOptions: CountyOptionsType = { '모두', '경산시', '경주시', + '고령군', '구미시', '김천시', '문경시', - '상주시', - '안동시', - '영주시', - '영천시', - '포항시', - '고령군', - '군위군', '봉화군', + '상주시', '성주군', + '안동시', '영덕군', '영양군', + '영주시', + '영천시', '예천군', '울릉군', '울진군', @@ -259,30 +273,33 @@ export const CountyOptions: CountyOptionsType = { '청도군', '청송군', '칠곡군', + '포항시 남구', + '포항시 북구', ], 경상남도: [ '모두', '거제시', - '김해시', - '마산시', - '밀양시', - '사천시', - '울산시', - '진주시', - '진해시', - '창원시', - '통영시', '거창군', '고성군', + '김해시', '남해군', + '밀양시', + '사천시', '산청군', '양산시', '의령군', + '진주시', '창녕군', + '창원시 마산합포구', + '창원시 마산회원구', + '창원시 성산구', + '창원시 의창구', + '창원시 진해구', + '통영시', '하동군', '함안군', '함양군', '합천군', ], - 제주도: ['모두', '서귀포시', '제주시', '남제주군', '북제주군'], + 제주특별자치도: ['모두', '서귀포시', '제주시'], }; diff --git a/src/pages/ManagePage/StepSlope/pages/SteepSlopeAdd.tsx b/src/pages/ManagePage/StepSlope/pages/SteepSlopeAdd.tsx index b4f7c5a..aaf60c4 100644 --- a/src/pages/ManagePage/StepSlope/pages/SteepSlopeAdd.tsx +++ b/src/pages/ManagePage/StepSlope/pages/SteepSlopeAdd.tsx @@ -1,307 +1,3 @@ -// import React, { useState, useRef, DragEvent, ChangeEvent } from 'react'; -// import styled from 'styled-components'; -// import Title from '../../components/Title'; -// import { slopeManageAPI } from '../../../../apis/slopeManage'; -// import CloudUploadRoundedIcon from '@mui/icons-material/CloudUploadRounded'; -// import { useNotificationStore } from '../../../../hooks/notificationStore'; -// import AddSlope from '../components/AddSlopeContainer'; -// import { FileInputContainerProps } from '../../interface'; - -// const SteepSlopeAdd: React.FC = () => { -// const [isDragActive, setIsDragActive] = useState(false); -// const [uploadedFile, setUploadedFile] = useState(null); -// const [fileName, setFileName] = useState(''); -// const [isUploading, setIsUploading] = useState(false); -// const fileInputRef = useRef(null); -// //전역 알림 -// const showNotification = useNotificationStore( -// (state) => state.showNotification -// ); -// // 드래그 시작 핸들러 -// const handleDragStart = (event: DragEvent): void => { -// event.preventDefault(); -// setIsDragActive(true); -// }; - -// // 드래그 종료 핸들러 -// const handleDragEnd = (event: DragEvent): void => { -// event.preventDefault(); -// setIsDragActive(false); -// }; - -// // 파일 드롭 핸들러 -// const handleDrop = (event: DragEvent): void => { -// event.preventDefault(); -// setIsDragActive(false); - -// const files = event.dataTransfer.files; -// if (files && files.length > 0) { -// handleFile(files[0]); -// } -// }; - -// // 파일 선택 핸들러 -// const handleFileSelect = (event: ChangeEvent): void => { -// const files = event.target.files; -// if (files && files.length > 0) { -// handleFile(files[0]); -// } -// }; - -// // 파일 처리 함수 -// const handleFile = (file: File): void => { -// setUploadedFile(file); -// setFileName(file.name); -// console.log('선택된 파일:', file); -// }; - -// // 파일 입력창 클릭 -// const handleContainerClick = (): void => { -// if (fileInputRef.current) { -// fileInputRef.current.click(); -// } -// }; - -// // 업로드 취소 -// const handleCancelUpload = (e: React.MouseEvent): void => { -// e.stopPropagation(); // 이벤트 버블링 방지 -// setUploadedFile(null); -// setFileName(''); -// if (fileInputRef.current) { -// fileInputRef.current.value = ''; -// } -// }; - -// // 파일 업로드 실행 -// const handleUpload = async ( -// e: React.MouseEvent -// ): Promise => { -// e.stopPropagation(); // 이벤트 버블링 방지 -// if (!uploadedFile) return; - -// setIsUploading(true); - -// try { -// console.log('파일 업로드 시작:', uploadedFile); -// const formData = new FormData(); -// formData.append('file', uploadedFile); -// const data = await slopeManageAPI.uploadExcelSlope(formData); -// showNotification(`${data.message}\n${data.count}건 추가되었습니다.`, { -// severity: 'success', -// }); -// // 업로드 성공 후 상태 초기화 -// setUploadedFile(null); -// setFileName(''); -// if (fileInputRef.current) { -// fileInputRef.current.value = ''; -// } -// } catch (error) { -// showNotification('파일 업로드 오류', { -// severity: 'error', -// }); -// console.error('파일 업로드 오류:', error); -// } finally { -// setIsUploading(false); -// } -// }; - -// const [isOpen, setIsOpen] = useState(false); - -// return ( -// <> -// setIsOpen(false)} /> -// -// -// -// setIsOpen(!isOpen)}> -// 직접 추가 -// -// -// -// ) => { -// event.preventDefault(); -// setIsDragActive(true); -// }} -// onDragLeave={handleDragEnd} -// onDrop={handleDrop} -// > -// - -// {uploadedFile ? ( -// -// {fileName} -// {(uploadedFile.size / 1024).toFixed(2)} KB -// -// -// {isUploading ? '업로드 중...' : '업로드'} -// -// 취소 -// -// -// ) : ( -// -// -// -//

클릭 혹은 파일을 이곳에 드롭하세요.

-//
-//
-// )} -//
-//
-//
-// -// ); -// }; - -// export default SteepSlopeAdd; - -// const Container = styled.div` -// width: 100%; -// height: 100%; -// display: flex; -// flex-direction: column; -// gap: 30px; -// padding-top: 20px; -// `; - -// const HeaderContainer = styled.div` -// width: 100%; -// height: 8%; -// display: flex; -// align-items: center; -// justify-content: space-between; -// padding: 0 20px; -// margin-bottom: 16px; -// `; -// const InputContainerWrapper = styled.div` -// padding: 0 20px; -// `; -// const FileInputContainer = styled.div` -// width: 100%; -// display: flex; -// flex-direction: column; -// min-height: 250px; -// height: 250px; -// border-radius: 15px; -// border: 3px dashed -// ${({ theme, $isDragActive, $hasFile }) => -// $isDragActive -// ? '#24478f' -// : $hasFile -// ? theme.colors.grey[300] -// : theme.colors.grey[200]}; -// justify-content: center; -// align-items: center; -// transition: all 0.3s ease; -// background-color: ${({ $isDragActive }) => -// $isDragActive ? 'rgba(51, 102, 255, 0.05)' : 'transparent'}; -// `; - -// // 파일이 없을 때 표시되는 영역 -// const UploadArea = styled.div` -// display: flex; -// flex-direction: column; -// justify-content: center; -// align-items: center; -// width: 100%; -// height: 100%; -// cursor: pointer; -// &:hover { -// background-color: rgba(0, 0, 0, 0.02); -// } -// `; - -// const UploadText = styled.div` -// margin-top: 15px; -// color: ${({ theme }) => theme.colors.grey[600]}; -// `; - -// const FileInfo = styled.div` -// display: flex; -// flex-direction: column; -// align-items: center; -// justify-content: center; -// width: 100%; -// height: 100%; -// `; - -// const FileName = styled.p` -// font-size: 16px; -// font-weight: 500; -// margin-bottom: 8px; -// `; - -// const FileSize = styled.p` -// font-size: 14px; -// color: ${({ theme }) => theme.colors.grey[600]}; -// margin-bottom: 15px; -// `; - -// const ButtonContainer = styled.div` -// display: flex; -// gap: 10px; -// `; - -// const UploadButton = styled.button` -// padding: 8px 16px; -// background-color: ${({ theme }) => theme.colors.primary}; -// color: white; -// border: none; -// border-radius: 4px; -// cursor: pointer; -// transition: all 0.2s ease; - -// &:hover { -// background-color: ${({ theme }) => theme.colors.primary}DD; -// } - -// &:disabled { -// background-color: ${({ theme }) => theme.colors.grey[400]}; -// cursor: not-allowed; -// } -// `; - -// const CancelButton = styled.button` -// padding: 8px 16px; -// background-color: transparent; -// border: 1px solid ${({ theme }) => theme.colors.grey[300]}; -// border-radius: 4px; -// cursor: pointer; -// transition: all 0.2s ease; - -// &:hover { -// background-color: ${({ theme }) => theme.colors.grey[100]}; -// } -// `; - -// const Button = styled.button` -// padding: 8px 16px; -// border-radius: 6px; -// font-weight: 500; -// cursor: pointer; -// transition: all 0.2s ease; -// `; - -// const SubmitButton = styled(Button)` -// background: #24478f; -// color: white; -// border: none; - -// &:hover { -// opacity: 0.9; -// } -// `; import React, { useState, useRef, DragEvent, ChangeEvent } from 'react'; import styled from 'styled-components'; import Title from '../../components/Title'; diff --git a/src/pages/ManagePage/components/Pagination.tsx b/src/pages/ManagePage/User/components/Pagination.tsx similarity index 67% rename from src/pages/ManagePage/components/Pagination.tsx rename to src/pages/ManagePage/User/components/Pagination.tsx index fd05df9..f24e071 100644 --- a/src/pages/ManagePage/components/Pagination.tsx +++ b/src/pages/ManagePage/User/components/Pagination.tsx @@ -1,6 +1,6 @@ import styled from 'styled-components'; import { FC } from 'react'; -import { PaginationProps } from '../interface'; +import { PaginationProps } from '../../interface'; const Pagination: FC = ({ currentPage, @@ -13,7 +13,36 @@ const Pagination: FC = ({ onNextPage, onLastPage, onPageSizeChange, + onPageChange, // 새로 추가된 prop }) => { + // 페이지 번호 범위를 계산하는 함수 + const getPageNumbers = () => { + const maxVisiblePages = 5; // 표시할 최대 페이지 수 + const pages: number[] = []; + + if (pageCount <= maxVisiblePages) { + // 전체 페이지가 5개 이하면 모든 페이지 표시 + for (let i = 0; i < pageCount; i++) { + pages.push(i); + } + } else { + // 현재 페이지를 중심으로 5개 페이지 표시 + const start = Math.max( + 0, + Math.min(currentPage - 2, pageCount - maxVisiblePages) + ); + const end = Math.min(pageCount, start + maxVisiblePages); + + for (let i = start; i < end; i++) { + pages.push(i); + } + } + + return pages; + }; + + const pageNumbers = getPageNumbers(); + return ( @@ -23,7 +52,18 @@ const Pagination: FC = ({ {'<'} - {currentPage + 1} + + {/* 페이지 번호들을 나열 */} + {pageNumbers.map((pageIndex) => ( + onPageChange && onPageChange(pageIndex)} + > + {pageIndex + 1} + + ))} + {'>'} @@ -63,6 +103,7 @@ const PageButton = styled.button<{ $active?: boolean }>` padding: 6px 12px; border-radius: 6px; font-size: ${({ theme }) => theme.fonts.sizes.ms}; + cursor: pointer; background: ${(props) => (props.$active ? '#3b82f6' : 'transparent')}; color: ${(props) => (props.$active ? 'white' : 'inherit')}; @@ -71,6 +112,11 @@ const PageButton = styled.button<{ $active?: boolean }>` &:hover:not(:disabled) { background: ${(props) => (props.$active ? '#2563eb' : '#f9fafb')}; } + + &:disabled { + opacity: 0.5; + cursor: not-allowed; + } `; const PaginationContainer = styled.div` @@ -88,6 +134,7 @@ const PaginationButton = styled.button<{ disabled?: boolean }>` border: 1px solid #e5e7eb; border-radius: 6px; font-size: ${({ theme }) => theme.fonts.sizes.ms}; + cursor: pointer; &:hover:not(:disabled) { background-color: #f9fafb; diff --git a/src/pages/ManagePage/User/pages/UserLookUp.tsx b/src/pages/ManagePage/User/pages/UserLookUp.tsx index 3a8a7be..88030f1 100644 --- a/src/pages/ManagePage/User/pages/UserLookUp.tsx +++ b/src/pages/ManagePage/User/pages/UserLookUp.tsx @@ -16,7 +16,7 @@ import { rankItem } from '@tanstack/match-sorter-utils'; import Title from '../../components/Title'; import { DebouncedInputProps } from '../../interface'; -import Pagination from '../../components/Pagination'; +import Pagination from '../components/Pagination'; import SearchRoundedIcon from '@mui/icons-material/SearchRounded'; import DoneRoundedIcon from '@mui/icons-material/DoneRounded'; @@ -266,6 +266,7 @@ const UserLookUp = () => { onNextPage={() => table.nextPage()} onLastPage={() => table.lastPage()} onPageSizeChange={(size) => table.setPageSize(size)} + onPageChange={(page) => table.setPageIndex(page)} /> {isLoading && Loading...} diff --git a/src/pages/ManagePage/User/pages/UserModi.tsx b/src/pages/ManagePage/User/pages/UserModi.tsx index d3a4219..91d9305 100644 --- a/src/pages/ManagePage/User/pages/UserModi.tsx +++ b/src/pages/ManagePage/User/pages/UserModi.tsx @@ -16,7 +16,7 @@ import { FilterFn, getFilteredRowModel } from '@tanstack/react-table'; import { rankItem } from '@tanstack/match-sorter-utils'; import Title from '../../components/Title'; import { DebouncedInputProps } from '../../interface'; -import Pagination from '../../components/Pagination'; +import Pagination from '../components/Pagination'; import EditModal from '../components/UserEditModal'; import SearchRoundedIcon from '@mui/icons-material/SearchRounded'; @@ -278,6 +278,7 @@ const UserModi = () => { onNextPage={() => table.nextPage()} onLastPage={() => table.lastPage()} onPageSizeChange={(size) => table.setPageSize(size)} + onPageChange={(page) => table.setPageIndex(page)} /> {isLoading && Loading...} diff --git a/src/pages/ManagePage/interface.ts b/src/pages/ManagePage/interface.ts index db666ad..e6b1014 100644 --- a/src/pages/ManagePage/interface.ts +++ b/src/pages/ManagePage/interface.ts @@ -36,6 +36,7 @@ export interface PaginationProps { onNextPage: () => void; onLastPage: () => void; onPageSizeChange: (size: number) => void; + onPageChange: (page: number) => void; } //급경사지 테이블 관련 props타입