diff --git a/src/apis/admin.ts b/src/apis/admin.ts index f768098..8508d49 100644 --- a/src/apis/admin.ts +++ b/src/apis/admin.ts @@ -41,11 +41,12 @@ const patchReport = async (reportId: number, patchReportRequest: PatchReportRequ }; // badwords -const getBadWords = async (setBadWords: React.Dispatch>) => { +const getBadWords = async () => { try { const res = await client.get('/api/bad-words'); - setBadWords(res.data.data); + if (!res) throw new Error('금칙어 조회 도중 에러가 발생했습니다.'); console.log(res); + return res; } catch (error) { console.error(error); } @@ -63,14 +64,34 @@ const postBadWords = async (badWordsRequest: BadWords) => { }; // 내 상상대로 만든 필터링 단어 취소 버튼 -const patchBadWords = async (badWordId: number) => { +const patchBadWordsUsed = async (badWordId: string) => { try { const res = await client.patch(`/api/bad-words/${badWordId}/status`, { isUsed: false }); if (!res) throw new Error('검열 단어 삭제 도중 에러가 발생했습니다.'); console.log(res); + return res; + } catch (error) { + console.error(error); + } +}; + +const patchBadWords = async (badWordId: string, word: string) => { + try { + const res = await client.patch(`/api/bad-words/${badWordId}`, { word: word }); + if (!res) throw new Error('검열 단어 삭제 도중 에러가 발생했습니다.'); + console.log(res); + return res; } catch (error) { console.error(error); } }; -export { postReports, getReports, patchReport, getBadWords, postBadWords, patchBadWords }; +export { + postReports, + getReports, + patchReport, + getBadWords, + postBadWords, + patchBadWordsUsed, + patchBadWords, +}; diff --git a/src/apis/write.ts b/src/apis/write.ts index 2a93094..012478f 100644 --- a/src/apis/write.ts +++ b/src/apis/write.ts @@ -7,7 +7,9 @@ const postLetter = async (data: LetterRequest) => { if (!res) throw new Error('편지 전송과정에서 오류가 발생했습니다.'); return res; } catch (error) { + const errorWithStatus = error as unknown as { status: number }; console.error(error); + return errorWithStatus; } }; @@ -42,4 +44,17 @@ const postTemporarySave = async (data: TemporaryRequest) => { } }; -export { postLetter, postFirstReply, getPrevLetter, postTemporarySave }; +const postTemporaryLetter = async (data: TemporaryRequest) => { + console.log('Temporary request', data); + try { + const res = await client.post('/api/letters', data); + if (!res) throw new Error('편지 전송과정에서 오류가 발생했습니다.'); + return res; + } catch (error) { + const errorWithStatus = error as unknown as { status: number }; + console.error(error); + return errorWithStatus; + } +}; + +export { postLetter, postFirstReply, getPrevLetter, postTemporarySave, postTemporaryLetter }; diff --git a/src/assets/icons/index.ts b/src/assets/icons/index.ts index 42da171..1f952b5 100644 --- a/src/assets/icons/index.ts +++ b/src/assets/icons/index.ts @@ -25,6 +25,8 @@ import SnowIcon from './snow.svg?react'; import StampIcon from './stamp.svg?react'; import ThermostatIcon from './thermostat.svg?react'; import WarmIcon from './warm.svg?react'; +import ToggleOff from './toggle-off.svg?react'; +import ToggleOn from './toggle-on.svg?react'; export { AddIcon, @@ -54,4 +56,6 @@ export { DeleteIcon, CancelIcon, PencilIcon, + ToggleOff, + ToggleOn, }; diff --git a/src/assets/icons/toggle-off.svg b/src/assets/icons/toggle-off.svg new file mode 100644 index 0000000..e75f80e --- /dev/null +++ b/src/assets/icons/toggle-off.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/icons/toggle-on.svg b/src/assets/icons/toggle-on.svg new file mode 100644 index 0000000..e896baa --- /dev/null +++ b/src/assets/icons/toggle-on.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/components/ToastItem.tsx b/src/components/ToastItem.tsx index e9499c2..4d4e506 100644 --- a/src/components/ToastItem.tsx +++ b/src/components/ToastItem.tsx @@ -21,7 +21,7 @@ export default function ToastItem({ toastObj, index }: { toastObj: ToastObj; ind const TOAST_POSITION = { Top: 'top-20', - Bottom: 'bottom-5', + Bottom: 'bottom-20', }; const animation = `toast-blink ${toastObj.time}s ease-in-out forwards`; diff --git a/src/pages/Admin/Filtering.tsx b/src/pages/Admin/Filtering.tsx index 38ec96e..8f59b21 100644 --- a/src/pages/Admin/Filtering.tsx +++ b/src/pages/Admin/Filtering.tsx @@ -1,19 +1,29 @@ import { useEffect, useState } from 'react'; -import { getBadWords } from '@/apis/admin'; +import { getBadWords, patchBadWordsUsed } from '@/apis/admin'; import { AddIcon, AlarmIcon, CancelIcon } from '@/assets/icons'; import AddInputButton from './components/AddInputButton'; import AdminPageTitle from './components/AdminPageTitle'; import WrapperFrame from './components/WrapperFrame'; import WrapperTitle from './components/WrapperTitle'; +import FilterTextItem from './components/FilterTextItem'; export default function FilteringManage() { - const [badWords, setBadWords] = useState([]); + const [badWords, setBadWords] = useState([]); const [addInputShow, setAddInputShow] = useState(false); + const handleGetBadWords = async () => { + const res = await getBadWords(); + if (res?.status === 200) { + setBadWords(res.data.data); + } else { + console.log('검열 조회 오류 발생'); + } + }; + useEffect(() => { - getBadWords(setBadWords); + handleGetBadWords(); }, []); return ( <> @@ -21,23 +31,13 @@ export default function FilteringManage() {
- {badWords.map((badWord, idx) => { - return ( - - {badWord.word} - - - ); + {badWords.map((badWord) => { + return ; })} {addInputShow ? ( ) : ( - + 추가하기 + + + + + + ); +} diff --git a/src/pages/Admin/components/PatchInput.tsx b/src/pages/Admin/components/PatchInput.tsx new file mode 100644 index 0000000..f48cd9c --- /dev/null +++ b/src/pages/Admin/components/PatchInput.tsx @@ -0,0 +1,75 @@ +import { useEffect, useRef, useState } from 'react'; + +import { patchBadWords } from '@/apis/admin'; +import { AddIcon } from '@/assets/icons'; + +export default function PatchInput({ + badWordId, + setPatchInputShow, + setBadWords, +}: { + badWordId: string; + setPatchInputShow: React.Dispatch>; + setBadWords: React.Dispatch>; +}) { + const [inputText, setInputText] = useState({ word: '' }); + const inputRef = useRef(null); + + const handleInputWidth = (event: React.FormEvent) => { + const target = event.target as HTMLInputElement; + target.style.width = '50px'; + target.style.width = `${target.scrollWidth}px`; + }; + + const handlePatchBadWords = async () => { + if (inputText.word === '') return setPatchInputShow(false); + const res = await patchBadWords(badWordId, inputText.word); + if (res?.status === 200) { + setBadWords((cur) => + cur.map((e) => { + if (e.id === badWordId) { + return { ...e, word: inputText.word }; + } + return e; + }), + ); + console.log('일단 수정했음 api 새로 업데이트되면 바인딩'); + setPatchInputShow(false); + } + }; + + useEffect(() => { + const inputElement = inputRef.current; + if (inputElement) { + inputElement.focus(); + } + }, []); + + return ( + <> + { + handleInputWidth(e); + }} + onChange={(e) => { + setInputText(() => ({ word: e.target.value })); + }} + onKeyDown={(e) => { + if (e.key === 'Enter') { + handlePatchBadWords(); + } + }} + /> + + + ); +} diff --git a/src/pages/Admin/components/ReportListItem.tsx b/src/pages/Admin/components/ReportListItem.tsx index fec8aab..51877d2 100644 --- a/src/pages/Admin/components/ReportListItem.tsx +++ b/src/pages/Admin/components/ReportListItem.tsx @@ -64,14 +64,17 @@ export default function ReportListItem({ {`${formattedDate} ${formattedTime}`} {reasonList[report.reasonType]}
- + {report.status === 'PENDING' && ( + + )} + {modalOpen && } ); diff --git a/src/pages/Notifications/components/SendingModal.tsx b/src/pages/Notifications/components/SendingModal.tsx index 341532d..70ff870 100644 --- a/src/pages/Notifications/components/SendingModal.tsx +++ b/src/pages/Notifications/components/SendingModal.tsx @@ -1,6 +1,7 @@ import LetterWrapper from '@/components/LetterWrapper'; import ModalOverlay from '@/components/ModalOverlay'; import { useNavigate } from 'react-router'; +import SendOutlinedIcon from '@mui/icons-material/SendOutlined'; export default function SendingModal({ isOpenSendingModal, @@ -21,7 +22,13 @@ export default function SendingModal({

편지 도착

편지는 작성된 시점으로 1시간 이후에 도착합니다. - 남은시간은 홈 화면의 편지 도착 시간 버튼을 눌러 확인 가능합니다. +
+
+ 남은시간은 홈 화면의 편지 도착 시간 버튼 + +
+ 을 눌러 확인 가능합니다. +
+
+ + + + ); +} diff --git a/src/pages/Notifications/index.tsx b/src/pages/Notifications/index.tsx index 92b459d..445e31e 100644 --- a/src/pages/Notifications/index.tsx +++ b/src/pages/Notifications/index.tsx @@ -8,6 +8,7 @@ import NotificationItem from './components/NotificationItem'; import WarningModal from './components/WarningModal'; import SendingModal from './components/SendingModal'; import useNotificationStore from '@/stores/notificationStore'; +import ShareModal from './components/ShareModal'; const NotificationsPage = () => { const navigate = useNavigate(); @@ -19,6 +20,7 @@ const NotificationsPage = () => { const [isOpenWarningModal, setIsOpenWarningModal] = useState(false); const [isOpenSendingModal, setIsOpenSendingModal] = useState(false); + const [isOpenShareModal, setIsOpenShareModal] = useState(false); const [reportContent, setReportContent] = useState(''); @@ -35,7 +37,7 @@ const NotificationsPage = () => { if (typeof content === 'string') setReportContent(content); } if (alarmType === 'SHARE') { - navigate(`/board/letter/${content}`, { state: { isShareLetterPreview: true } }); + setIsOpenShareModal(true); } if (alarmType === 'POSTED') { navigate(`/board/letter/${content}`); @@ -99,6 +101,7 @@ const NotificationsPage = () => { isOpenSendingModal={isOpenSendingModal} setIsOpenSendingModal={setIsOpenSendingModal} /> +
알림