- 게시글 수정 페이지에서, 새로 수정할 값을 입력하고 다른 탭 갔다 돌아온 경우, 새로 수정한 값들이 없어지고 기존에 있던 데이터로 덮어씌워지는 이슈가 있었다. 의존성 배열에 값이 두 개가 들어가 있어서 한 값 때문에 실행되던 함수가 다른 값에 영향을 줘서 다른 페이지를 갔다 올 때마다 새로고침이 되던 거였다. 의존성 배열을 분리해 해결했다.
- 안내 팝업을 띄우고, 유저가 확인을 누르면 일시적으로 팝업이 닫히게, 유저가 다시 보지 않기를 누르면 localStorage를 사용해 팝업을 닫고 영원히 보여주지 않게끔 함
const [showPopup, setShowPopup] = useState(false);
const handleCloseForever = () => {
localStorage.setItem('hidePopupForever', 'true');
setShowPopup(false);
};
useEffect(()=>{
const hide = localStorage.getItem('hidePopupForever');
if (user && !hide) {
setShowPopup(true);
}
},[])
- MUI Datagrid를 사용하면서 data를 flat하게 만들어서, header에 맞춘 표 형태로 데이터를 보여줄 수 있게끔 하기
const flatRows = data?.participants?.map((item) => ({
id: item.id,
galleryName: item.gallery?.name ?? '',
manager: '', // manager 없음..
contact: item.gallery?.phone ?? '',
email: item.gallery?.email ?? '',
address: `${item.gallery?.address1 ?? ''} ${item.gallery?.address2 ?? ''}`,
}))
setRows(flatRows)
- pagination 하기
- MUI Datagrid 엑셀 다운로드가 가능하게끔 하기
const [rows, setRows] = useState([])
const columns = [
{ field: 'galleryName', headerName: t('artfair:galleryName'), width: '225', align: 'center', headerAlign: 'center'},
{ field: 'manager', headerName: t('artfair:galleryManager'), width: '100', align: 'center', headerAlign: 'center'},
{ field: 'contact', headerName: t('artfair:galleryContact'), width: '140', align: 'center', headerAlign: 'center'},
{ field: 'email', headerName: t('artfair:galleryEmail'), width: '190', align: 'center', headerAlign: 'center'},
{ field: 'address', headerName: t('artfair:galleryAddress'), width: '285', align: 'center', headerAlign: 'center'}
]
...
const excelDownloader = async () => {
const workbook = new ExcelJS.Workbook();
const worksheet = workbook.addWorksheet('Exhibitor List');
worksheet.columns = [
{ header: 'Exhibitor', key: 'galleryName', width: 30 },
{ header: 'Manager', key: 'manager', width: 15 },
{ header: 'Phone', key: 'contact', width: 20 },
{ header: 'E-mail', key: 'email', width: 30 },
{ header: 'Address', key: 'address', width: 40 },
];
rows.forEach((row) => {
worksheet.addRow({
galleryName: row.galleryName,
manager: row.manager,
contact: row.contact,
email: row.email,
address: row.address,
});
});
worksheet.getRow(1).font = { bold: true };
const buffer = await workbook.xlsx.writeBuffer();
const blob = new Blob([buffer], {
type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
});
saveAs(blob, 'Exhibitors_List_by_ArtSpoon.xlsx');
};
...
<DataGridPremium
loading={loading}
apiRef={apiRef}
rows={rows}
columns={columns}
sx={{
backgroundColor: 'white',
minHeight: 300,
}}
pagination
initialState={{
pagination: {
paginationModel: { pageSize: 15, page: 0 },
},
}}
slots={{
noRowsOverlay: () => (
<Box
sx={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100%',
}}
>
<div style={{display:"flex", justifyContent:"center", alignItems:"center", gap:"10px", fontSize:"16px", fontWeight:"500", fontFamily:"pretendard", color: "rgba(0, 0, 0, 0.87)"}}>
<Image src={'/images/noDataIcon.webp'} width={20} height={20} />
{t('artfair:noExhibitors')}
</div>
</Box>
),
}}
onCellClick={(e) => handleRouteToDetail(e.id)}
/>
import styles from 'components/plas-calendar.module.scss'
import dayjs from 'dayjs'
import { useState } from 'react'
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos';
const daysOfWeek = ['일', '월', '화', '수', '목', '금', '토']
export default function PlasCalendar() {
const [currentDate, setCurrentDate] = useState(dayjs())
const year = currentDate.year()
const month = currentDate.month()
const startOfMonth = dayjs().year(year).month(month).startOf('month')
const endOfMonth = dayjs().year(year).month(month).endOf('month')
const startDay = startOfMonth.day()
const totalDays = endOfMonth.date()
const today = dayjs()
const days = []
// 이전 달 날짜 추가
const prevMonthDate = currentDate.subtract(1, 'month')
const prevMonthDays = prevMonthDate.daysInMonth()
for (let i = startDay - 1; i >= 0; i--) {
days.push({
date: dayjs().year(prevMonthDate.year()).month(prevMonthDate.month()).date(prevMonthDays - i),
isOtherMonth: true
})
}
// 이번 달 날짜 추가
for (let i = 1; i <= totalDays; i++) {
days.push({
date: dayjs().year(year).month(month).date(i),
isOtherMonth: false
})
}
// 다음 달 날짜 추가 (총 42칸 맞춤)
const nextMonthDate = currentDate.add(1, 'month')
const remaining = 42 - days.length
for (let i = 1; i <= remaining; i++) {
days.push({
date: dayjs().year(nextMonthDate.year()).month(nextMonthDate.month()).date(i),
isOtherMonth: true
})
}
const prevMonth = () => setCurrentDate(currentDate.subtract(1, 'month'))
const nextMonth = () => setCurrentDate(currentDate.add(1, 'month'))
return (
<div className={styles.calendarRoot}>
<div className={styles.calendarContainer}>
<div className={styles.calendarHeader}>
<span>{year}년 {month + 1}월</span>
<div className={styles.calendarNav}>
<button onClick={prevMonth}><ArrowBackIosIcon/></button>
<button onClick={nextMonth}><ArrowForwardIosIcon/></button>
</div>
</div>
<div className={styles.calendarGrid}>
{daysOfWeek.map(day => (
<div key={day} className={styles.dayLabel}>{day}</div>
))}
{days.map(({ date, isOtherMonth }, idx) => {
const day = date.date()
const isToday = today.isSame(date, 'day')
const isTargetMonth = date.year() === 2025 && date.month() === 4
const isStart = isTargetMonth && day === 22
const isEnd = isTargetMonth && day === 25
const isBetween = isTargetMonth && (day === 23 || day === 24)
const textClass = isOtherMonth ? styles.otherMonth : ''
if (isStart) {
return (
<div key={idx} className={styles.rangeStartBox}>
<div className={styles.rangeCircle}>
<span className={textClass}>{day}</span>
</div>
</div>
)
}
if (isEnd) {
return (
<div key={idx} className={styles.rangeEndBox}>
<div className={styles.rangeCircle}>
<span className={textClass}>{day}</span>
</div>
</div>
)
}
if (isBetween) {
return (
<div key={idx} className={styles.rangeMiddleBox}>
<span className={textClass}>{day}</span>
</div>
)
}
return (
<div key={idx} className={`${styles.calendarDay} ${isToday ? styles.calendarToday : ''}`}>
<span className={textClass}>{day}</span>
</div>
)
})}
</div>
</div>
</div>
)
}
댓글