Skip to content

Commit

Permalink
Merge pull request #204 from ODOICHON/feat/#202
Browse files Browse the repository at this point in the history
Feat/#202 ๋งˆ์ดํŽ˜์ด์ง€ "์ž„์‹œ์ €์žฅํ•œ ๊ฒŒ์‹œ๊ธ€" ํŽ˜์ด์ง€ ๊ตฌํ˜„
  • Loading branch information
sangminlee98 authored Nov 28, 2023
2 parents d8242e6 + 6426cb6 commit 2672a0d
Show file tree
Hide file tree
Showing 14 changed files with 277 additions and 41 deletions.
5 changes: 3 additions & 2 deletions src/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const MyPageHome = lazy(() => import('@/pages/Mypage/home'));
const MyselfPage = lazy(() => import('@/pages/Mypage/trade/myself'));
const MyWritePage = lazy(() => import('@/pages/Mypage/community/write'));
const MyPageTradeScrap = lazy(() => import('@/pages/Mypage/trade/scrap'));
const MyPageSaves = lazy(() => import('@/pages/Mypage/trade/saves'));
const IntroducePage = lazy(() => import('@/pages/Introduce'));
const IntroWritePage = lazy(() => import('@/pages/Introduce/Write'));
const IntroBoardPage = lazy(() => import('@/pages/Introduce/Board'));
Expand Down Expand Up @@ -46,8 +47,8 @@ export const routes: RouteObject[] = [
element: <MyselfPage />,
},
{
path: 'trade/save',
element: <div>save</div>,
path: 'trade/saves',
element: <MyPageSaves />,
},
{
path: 'trade/scrap',
Expand Down
10 changes: 10 additions & 0 deletions src/assets/common/paperclip.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
27 changes: 19 additions & 8 deletions src/components/Community/Quill/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,16 @@ export default function CommunityQuill({ queryParam }: CommunityQuillProps) {
const [title, setTitle] = useState(boardData ? boardData.title : '');
const [contents, setContents] = useState('');
const [category, setCategory] = useState(boardData ? boardData.category : '');
const [isProcessing, setIsProcessing] = useState(false);

const prefixCategory =
queryParam === 'free_board' ? 'DEFAULT' : 'ADVERTISEMENT';
const categoryList =
queryParam === 'free_board' ? freeCategory : advertiseCategory;

const queryClient = useQueryClient();

const { mutate } = useMutation(
const { mutate, isLoading: isUpdateLoading } = useMutation(
(BoardForm: BoardFormType) =>
restFetcher({
method: 'PUT',
Expand Down Expand Up @@ -69,6 +71,7 @@ export default function CommunityQuill({ queryParam }: CommunityQuillProps) {
};

const onPost = async () => {
setIsProcessing(true);
const imageUrls = [...getImageUrls(contents)];
if (!checkBeforePost(title, contents, category)) return;

Expand All @@ -80,11 +83,19 @@ export default function CommunityQuill({ queryParam }: CommunityQuillProps) {
prefixCategory,
fixed: false,
};
const response = await PostBoardAPI(BoardForm);
if (response?.code === 'SUCCESS') {
alert('๊ฒŒ์‹œ๊ธ€์ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค๐Ÿ˜„');
queryClient.refetchQueries([QueryKeys.COMMUNITY_BOARD]);
navigate(`/community/${queryParam}`);
try {
const response = await PostBoardAPI(BoardForm);
if (response?.code === 'SUCCESS') {
alert('๊ฒŒ์‹œ๊ธ€์ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค๐Ÿ˜„');
queryClient.refetchQueries([QueryKeys.COMMUNITY_BOARD]);
navigate(`/community/${queryParam}`);
} else {
throw new Error(response?.message);
}
} catch (error) {
console.error(error);
} finally {
setIsProcessing(false);
}
};

Expand Down Expand Up @@ -163,11 +174,11 @@ export default function CommunityQuill({ queryParam }: CommunityQuillProps) {
</section>
<section>
{boardData ? (
<button type="button" onClick={onUpdate}>
<button type="button" onClick={onUpdate} disabled={isUpdateLoading}>
์ˆ˜์ •ํ•˜๊ธฐ
</button>
) : (
<button type="button" onClick={onPost}>
<button type="button" onClick={onPost} disabled={isProcessing}>
๋“ฑ๋กํ•˜๊ธฐ
</button>
)}
Expand Down
26 changes: 18 additions & 8 deletions src/components/Introduce/Quill/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,11 @@ export default function IntroduceQuill() {
const [thumbnailTitle, setThumbnailTitle] = useState(
boardData ? boardData.imageUrls[0].split('/')[3] : '',
);
const [isProcessing, setIsProcessing] = useState(false);

const queryClient = useQueryClient();

const { mutate } = useMutation(
const { mutate, isLoading: isUpdateLoading } = useMutation(
(BoardForm: BoardFormType) =>
restFetcher({
method: 'PUT',
Expand Down Expand Up @@ -88,6 +89,7 @@ export default function IntroduceQuill() {
};

const onPost = async () => {
setIsProcessing(true);
const imageUrls = [thumbnail, ...getImageUrls(contents)];
if (!checkBeforePost(title, contents, category, imageUrls)) return;

Expand All @@ -99,11 +101,19 @@ export default function IntroduceQuill() {
prefixCategory: 'INTRO',
fixed: false,
};
const response = await PostBoardAPI(BoardForm);
if (response?.code === 'SUCCESS') {
alert('๊ฒŒ์‹œ๊ธ€์ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
queryClient.refetchQueries([QueryKeys.INTRO_BOARD]);
navigate('/introduce');
try {
const response = await PostBoardAPI(BoardForm);
if (response?.code === 'SUCCESS') {
alert('๊ฒŒ์‹œ๊ธ€์ด ์ž‘์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
queryClient.refetchQueries([QueryKeys.INTRO_BOARD]);
navigate('/introduce');
} else {
throw new Error(response?.message);
}
} catch (error) {
console.error(error);
} finally {
setIsProcessing(false);
}
};

Expand Down Expand Up @@ -196,11 +206,11 @@ export default function IntroduceQuill() {
</span>
</section>
{boardData ? (
<button type="button" onClick={onUpdate}>
<button type="button" onClick={onUpdate} disabled={isUpdateLoading}>
์ˆ˜์ •ํ•˜๊ธฐ
</button>
) : (
<button type="button" onClick={onPost}>
<button type="button" onClick={onPost} disabled={isProcessing}>
๋“ฑ๋กํ•˜๊ธฐ
</button>
)}
Expand Down
6 changes: 5 additions & 1 deletion src/components/Login/AfterLogin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ function DesktopMenu({
navigate,
}: DesktopMenuProps) {
const dropdownRef = useRef<HTMLDivElement>(null);
const handleMyPageClick = () => {
navigate('/mypage');
setIsClicked(false);
};
useEffect(() => {
const handleCloseModal = (e: Event | React.MouseEvent) => {
if (
Expand Down Expand Up @@ -74,7 +78,7 @@ function DesktopMenu({
<li
role="presentation"
className={styles.dropdownMenu}
onClick={() => navigate('/mypage')}
onClick={handleMyPageClick}
>
<img className={styles.image} src={homeImage} alt="home" />
<p>๋งˆ์ดํŽ˜์ด์ง€</p>
Expand Down
2 changes: 1 addition & 1 deletion src/components/MyPage/MyPageNavbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ const navList: NavListType[] = [
},
{
title: '์ž„์‹œ์ €์žฅ',
path: '/mypage/trade/save',
path: '/mypage/trade/saves',
},
{
title: '์Šคํฌ๋žฉ',
Expand Down
49 changes: 49 additions & 0 deletions src/components/MyPage/MySaveCard/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { useNavigate } from 'react-router-dom';
import { useQuery } from '@tanstack/react-query';
import dayjs from 'dayjs';
import clipImage from '@/assets/common/paperclip.svg';
import { QueryKeys, restFetcher } from '@/queryClient';
import { TradeBoardDetailType, TradeBoardType } from '@/types/Board/tradeType';
import { ApiResponseWithDataType } from '@/types/apiResponseType';
import styles from './styles.module.scss';

type MySaveCardProps = {
saveData: TradeBoardType;
};

export default function MySaveCard({ saveData }: MySaveCardProps) {
const navigate = useNavigate();

const { data: detailData } = useQuery<
ApiResponseWithDataType<TradeBoardDetailType>
>(
[QueryKeys.TRADE_BOARD, saveData.houseId],
() =>
restFetcher({
method: 'GET',
path: `/houses/user-scrap/${saveData.houseId}`,
}),
{
staleTime: 0,
},
);
const handleEditButtonClick = (data: TradeBoardDetailType | undefined) => {
if (!data) return;
navigate(`/trade/write`, {
state: { data: { ...data, tmpYn: true } },
});
};
return (
<li
role="presentation"
className={styles.wrapper}
onClick={() => handleEditButtonClick(detailData?.data)}
>
<h1 className={styles.title}>
{saveData.title}
<img src={clipImage} alt="ํด๋ฆฝ์ด๋ฏธ์ง€" />
</h1>
<p>{dayjs(saveData.createdAt).format('YYYY.MM.DD')}</p>
</li>
);
}
23 changes: 23 additions & 0 deletions src/components/MyPage/MySaveCard/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.wrapper {
display: flex;
flex-direction: column;
justify-content: space-between;
width: 100%;
height: 9.375rem;
padding: 2.25rem 2rem;
background-color: white;
cursor: pointer;
&:hover {
background-color: rgba(0, 0, 0, 0.03);
}
}
.title {
display: flex;
align-items: center;
gap: 0.25rem;
font-size: 1.375rem;
font-weight: 700;
& > img {
width: 1.25rem;
}
}
70 changes: 52 additions & 18 deletions src/components/Trade/Quill/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useRef } from 'react';
import { useRef, useState } from 'react';
import ReactQuill from 'react-quill';
import { useLocation, useNavigate } from 'react-router-dom';
import { useMutation, useQueryClient } from '@tanstack/react-query';
Expand Down Expand Up @@ -32,8 +32,10 @@ export default function TradeQuill({
// ์ด๋ฏธ์ง€๋ฅผ ์—…๋กœ๋“œ ํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜
const modules = useQuillModules(QuillRef);

const [isProcessing, setIsProcessing] = useState(false);

const queryClient = useQueryClient();
const { mutate } = useMutation(
const { mutate, isLoading: isUpdateLoading } = useMutation(
(tradeBoardForm: TradeBoardForm) =>
restFetcher({
method: 'PUT',
Expand All @@ -44,9 +46,8 @@ export default function TradeQuill({
}),
{
onSuccess: () => {
alert('๊ฒŒ์‹œ๊ธ€์„ ์ˆ˜์ •ํ•˜์˜€์Šต๋‹ˆ๋‹ค.');
queryClient.refetchQueries([QueryKeys.TRADE_BOARD]);
navigate(`/trade`);
queryClient.refetchQueries([QueryKeys.MY_SAVES]);
},
onError: () => {
alert('๊ฒŒ์‹œ๊ธ€ ์ˆ˜์ •์„ ์‹คํŒจํ–ˆ์Šต๋‹ˆ๋‹ค.');
Expand All @@ -55,6 +56,7 @@ export default function TradeQuill({
);

const onPost = async ({ isTempSave }: { isTempSave: boolean }) => {
setIsProcessing(true);
const imageUrls = [thumbnail, ...getImageUrls(form.code)];

const extractedYear = form.createdDate.match(/\d{4}/);
Expand All @@ -77,16 +79,20 @@ export default function TradeQuill({
await PostHouseAPI(newForm);
if (isTempSave) {
alert('๊ฒŒ์‹œ๊ธ€์ด ์ž„์‹œ์ €์žฅ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
queryClient.refetchQueries([QueryKeys.MY_SAVES]);
} else {
alert('๊ฒŒ์‹œ๊ธ€์ด ๋“ฑ๋ก๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
queryClient.refetchQueries([QueryKeys.TRADE_BOARD]);
navigate(`/trade`);
}
} catch (error) {
console.error(error);
} finally {
setIsProcessing(false);
}
};

const onUpdate = async () => {
const onUpdate = async ({ isTempSave }: { isTempSave: boolean }) => {
const imageUrls = [thumbnail, ...getImageUrls(form.code)];
const extractedYear = form.createdDate.match(/\d{4}/);
const createdDate = extractedYear ? extractedYear[0] : '2002';
Expand All @@ -97,13 +103,29 @@ export default function TradeQuill({
size: form.size.replace(/m2/g, ''),
createdDate,
imageUrls,
tmpYn: isTempSave,
};

if (!checkBeforeTradePost(user!, newForm)) return;

mutate(newForm);
if (!isTempSave) {
if (!checkBeforeTradePost(user!, newForm)) return;
}
try {
mutate(newForm);
if (isTempSave) {
alert('๊ฒŒ์‹œ๊ธ€์ด ์ž„์‹œ์ €์žฅ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.');
} else {
alert(`๊ฒŒ์‹œ๊ธ€์ด ์ˆ˜์ •๋˜์—ˆ์Šต๋‹ˆ๋‹ค.`);
navigate(`/trade`);
}
} catch (error) {
console.error(error);
}
};

const isPosting = Boolean(!state); // ์ฒ˜์Œ ๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ์ƒํƒœ
const isUpdating = Boolean(state && !state.data.tmpYn); // ๋“ฑ๋ก๋œ ๊ธ€์„ ์ˆ˜์ •ํ•˜๋Š” ์ƒํƒœ
const isSaving = Boolean(state && state.data.tmpYn); // ์ž„์‹œ์ €์žฅ๋œ ๊ธ€์„ ์ž‘์„ฑํ•˜๋Š” ์ƒํƒœ

return (
<div className={styles.container}>
<section className={styles.sectionWrapper}>
Expand Down Expand Up @@ -135,18 +157,30 @@ export default function TradeQuill({
</span>
</section>
<section>
<button type="button" onClick={() => onPost({ isTempSave: true })}>
์ž„์‹œ์ €์žฅ
</button>
{state ? (
<button type="button" onClick={onUpdate}>
์ˆ˜์ •ํ•˜๊ธฐ
</button>
) : (
<button type="button" onClick={() => onPost({ isTempSave: false })}>
๋“ฑ๋กํ•˜๊ธฐ
{(isPosting || isSaving) && (
<button
type="button"
onClick={() =>
isPosting
? onPost({ isTempSave: true })
: onUpdate({ isTempSave: true })
}
disabled={isProcessing || isUpdateLoading}
>
์ž„์‹œ์ €์žฅ
</button>
)}
<button
type="button"
onClick={() =>
isPosting
? onPost({ isTempSave: false })
: onUpdate({ isTempSave: false })
}
disabled={isProcessing || isUpdateLoading}
>
{isUpdating ? '์ˆ˜์ •ํ•˜๊ธฐ' : '๋“ฑ๋กํ•˜๊ธฐ'}
</button>
</section>
</div>
);
Expand Down
Loading

0 comments on commit 2672a0d

Please sign in to comment.