feature bookmark - boostcampwm-2022/web33-Mildo GitHub Wiki

โœ‚๏ธ ๋ถ„๋ฐฐ๋œ ์ด์Šˆ

  • ๋ถ๋งˆํฌ ์ถ”๊ฐ€/์‚ญ์ œ(#48)
  • ์‚ฌ์ด๋“œ ๋ฐ” - ๋ถ๋งˆํฌ ๋ฆฌ์ŠคํŠธ(์ตœ๋Œ€ 5๊ฐœ) ์ถœ๋ ฅ(#40)

๐Ÿšฉ ๊ตฌํ˜„ ๋ชฉํ‘œ

๋ถ๋งˆํฌ api๋ฅผ ๋งŒ๋“ค๊ณ  ์ƒ์„ธ ์ •๋ณด ๋ชจ๋‹ฌ ๋ฐ ์‚ฌ์ด๋“œ๋ฐ”์— UI ์ ์šฉ

๐Ÿ€ ์„ธ๋ถ€ ๋ชฉํ‘œ

  • MongoDB user ์Šคํ‚ค๋งˆ์— ๋ถ๋งˆํฌ(๋ฐฐ์—ด) ์ถ”๊ฐ€
  • ๋ถ๋งˆํฌ api ๊ตฌํ˜„
  • ์ƒ์„ธ์ •๋ณด ์ฐฝ์—์„œ ๋ถ๋งˆํฌ ์ถ”๊ฐ€, ์‚ญ์ œ ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • ์‚ฌ์ด๋“œ๋ฐ”์—์„œ ๋ถ๋งˆํฌ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ, ์‚ญ์ œ ๊ธฐ๋Šฅ ๊ตฌํ˜„

๐Ÿ–ฅ๏ธ ๊ตฌํ˜„ ๋‚ด์šฉ

  • MongoDB User ์Šคํ‚ค๋งˆ ๋ณ€๊ฒฝ

    • bookmarks(๋ฐฐ์—ด)์™€ nickname(๋ฌธ์ž์—ด) ์ถ”๊ฐ€
    • nickname์˜ ๊ฒฝ์šฐ passport์—์„œ user ์ •๋ณด ์ƒ์„ฑํ•  ๋•Œ ๋„ฃ์–ด์คŒ
    • profile์ด ๋„ค์ด๋ฒ„ Oauth์—์„œ ๋ฐ›์€ ์‚ฌ์šฉ์ž ์ •๋ณด
    // server/src/apis/passport/naverStrategy.ts
    const newUser = await User.create({
    	snsId: profile.id,
    	provider: 'naver',
    	email: profile.email,
    	nickname: profile.nickname
    });
    
  • ๋กœ๊ทธ์ธ User ์ •๋ณด๋Š” ๋กœ๊ทธ์ธ๊ณผ ๋™์‹œ์— client์—์„œ ๊ณ„์† ๊ฐ€์ง€๊ณ  ์žˆ์Œ

    • ์ด์ „์— isLoggedIn๋กœ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ๊ด€๋ฆฌ ํ–ˆ์Œ
    • ์ „์—ญ ์ƒํƒœ userInfo๋กœ client์—์„œ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๊ณ„์† ๊ฐ€์ง€๊ณ  ์žˆ์Œ
    // client/src/pages/MainPage/MainPage.tsx
    useEffect(() => {
        // ๋กœ๊ทธ์ธ ์—ฌ๋ถ€ ํ™•์ธํ•˜๊ธฐ -> '๋กœ๊ทธ์•„์›ƒ' ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์‹œ ์žฌ์‚ฌ์šฉ ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜์—ฌ ์ปค์Šคํ…€ ํ›…์œผ๋กœ ๋นผ์•ผํ•จ
        const checkLoggedInFunction = async () => {
          const logInStatus = await apis.getWhetherUserLoggedIn();
    
          if (logInStatus.ok === true) {
            setIsLoggedIn(true);
            setUserInfo(logInStatus.data);
            setIsLoginModalOpen(false);
            return;
          }
          setIsLoggedIn(false);
          setUserInfo(null);
        };
    
        checkLoggedInFunction();
      }, []);
    
  • bookmark ๊ด€๋ จ api๋Š” ์šฐ์„  /api/auth ์•„๋ž˜์— ์„ค์ •

    • areaName๊ณผ userId๋ฅผ ๋ฐ›์•„ ์œ ์ €๋ณ„๋กœ ๋ถ๋งˆํฌ ๋“ฑ๋ก, ์‚ญ์ œ ์ˆ˜ํ–‰
    • client์—์„œ ์œ ์ € ์ •๋ณด ๋“ค๊ณ  ์žˆ์–ด๋„ server์—์„œ authMiddleware.authorizationUser ๋ฏธ๋“ค์›จ์–ด ํ†ต๊ณผํ•ด์•ผ ํ•ด๋‹น ๊ธฐ๋Šฅ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•จ
    • ๋ถ๋งˆํฌ 5๊ฐœ ์ดˆ๊ณผ ๋ง‰๋Š” ๊ธฐ๋Šฅ์€ client์—์„œ ์„ค์ •
  • ์ƒ์„ธ ์ •๋ณด ๋ชจ๋‹ฌ์—์„œ ๋ถ๋งˆํฌ ์‚ญ์ œ, ์ถ”๊ฐ€

    • client์—์„œ ์œ ์ €์˜ ๋ถ๋งˆํฌ ๊ด€๋ จ ๋‚ด์šฉ์€ ์ „๋ถ€ userInfo์— ๋ฐฐ์—ด๋กœ ๋“ค์–ด ์žˆ์–ด์„œ, ํ•ด๋‹น ๋ฐฐ์—ด์„ ์ˆ˜์ •ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๋ถ๋งˆํฌ ์‚ญ์ œ, ์ถ”๊ฐ€ ๊ตฌํ˜„
    // client/src/components/InfoDetailModal/InfoDetail.tsx
    const onClickBookmark = async () => {
        if (!firstLevelInfo || !userInfo) {
          alert('๋ถ๋งˆํฌ๋Š” ๋กœ๊ทธ์ธ ํ›„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.');
          return;
        }
        const [areaName] = firstLevelInfo;
        const { _id: userId, bookmarks } = userInfo;
    
        if (bookmarks.includes(areaName)) {
          await apis.deleteBookmark(areaName, userId);
          setUserInfo({
            ...userInfo,
            bookmarks: bookmarks.filter(bookmark => bookmark !== areaName)
          });
        } else {
          if (bookmarks.length >= 5) {
            alert('๋ถ๋งˆํฌ๋Š” ์ตœ๋Œ€ 5๊ฐœ๊นŒ์ง€ ๋“ฑ๋ก ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.');
            return;
          }
          await apis.addBookmark(areaName, userId);
          setUserInfo({
            ...userInfo,
            bookmarks: bookmarks.concat(areaName)
          });
        }
      };
    
  • ์‚ฌ์ด๋“œ ๋ฐ”์—์„œ ๊ฐ ์ง€์—ญ์˜ ํ˜ผ์žก๋„๋ฅผ ๊ฐ€์ ธ์˜ค๊ธฐ ์œ„ํ•ด areas๋ฅผ ์ง€์—ญ ์ƒํƒœ์—์„œ ์ „์—ญ ์ƒํƒœ๋กœ ๋ณ€๊ฒฝ

    • ์‚ฌ์ด๋“œ ๋ฐ”์—์„œ ์‚ญ์ œ ํด๋ฆญ ์‹œ ๋ถ๋งˆํฌ ์‚ญ์ œ, ์›๋ฆฌ๋Š” ์ƒ์„ธ ์ •๋ณด ๋ชจ๋‹ฌ๊ณผ ๋™์ผ
    • ์‚ฌ์ด๋“œ ๋ฐ”์—์„œ ์žฅ์†Œ๋ช… ํด๋ฆญ ์‹œ ์œ„์น˜ ์ด๋™ ์‹œํ‚ค๊ณ  ์‹ถ์€๋ฐ ๋…ผ์˜ ํ•ด๋ณด๊ธฐ

๐Ÿ“– ํ•™์Šต ๋‚ด์šฉ

  • MongoDB์—์„œ array type์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” interface์—๋Š” Types๋กœ ๊ฑธ์–ด์ค˜์•ผํ•˜๊ณ  ์Šคํ‚ค๋งˆ์—๋Š” [string]์œผ๋กœ ๊ฑธ์–ด์ฃผ๋ฉด ๋จ

  • mongoose์—์„œ array๊ฐ’ pushํ•˜๋Š” ๋ฐฉ๋ฒ•

    • ์‚ญ์ œํ•  ๊ฒฝ์šฐ์—๋Š” pull๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด ๋จ
    Nft.findOneAndUpdate(
    			{ tokenId : tokenId },		
    			{ $push: { bids:bid}},
    			(err, result) => {
    				console.log('autcion is normal, Do not Worry');
    				res.json({
    					success: true,
    					detail: 'success set highstbid',
    				});
    				if (err) console.log(err);
    			}
    		)
    

๐Ÿฉบ ์˜์‚ฌ๊ฒฐ์ •

  • ์‚ฌ์ด๋“œ ๋ฐ”์—์„œ ์žฅ์†Œ๋ช… ํด๋ฆญ ํ–ˆ์„ ๋•Œ ์ง€๋„ ์œ„์น˜ ๋ฐ”๊ฟ€์ง€?
    • ์ง€๊ธˆ ์ฃผ์„ ์ฒ˜๋ฆฌ ํ•ด๋†“์€ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•˜๋ฉด ์ค‘๊ฐ„์— ์œ„์น˜๊ฐ€ ํ•œ ๋ฒˆ ์ด๋™ํ•จ
    • naverMap์„ ๊ฐ€์ ธ์™€์•ผ๋Š”๋ฐ ์ด๊ฒƒ๋„ ์ „์—ญ์œผ๋กœ ์„ ์–ธํ•˜๋ฉด ๋„ˆ๋ฌด ๋ณต์žกํ•จ

โ“ ๊ถ๊ธˆํ•œ ์ 

  • setState์˜ ๋น„๋™๊ธฐ์„ฑ์— ๋Œ€ํ•ด ์ดํ•ดํ•  ํ•„์š”๊ฐ€ ์žˆ์Œ