Code Monkey home page Code Monkey logo

upgle_front's Introduction

์žฌ๋Šฅ ๊ณต์œ  ํ”Œ๋žซํผ Upgle

์ž์‹ ์ด ์ž˜ํ•˜๋Š” ๋ถ„์•ผ๋ฅผ ํ™”์ƒ ์ฑ„ํŒ…์„ ์ด์šฉํ•˜์—ฌ ๋ฐฐ์šฐ๊ณ  ์‹ถ์€ ์‚ฌ๋žŒ๋“ค๊ณผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ธํ„ฐ๋ž™์…˜ ํ•˜๋ฉฐ ๋ฌด๋ฃŒ๋กœ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค.

Upgle ์€ ์›น ์‚ฌ์ดํŠธ ํ™˜๊ฒฝ์—์„œ ์ž์‹ ์ด ์ž˜ํ•˜๋Š” ๋ถ„์•ผ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๊ณต์œ ์ž์™€ ๋ฐฐ์šฐ๊ณ  ์‹ถ์€ ๋ถ„์•ผ๋ฅผ ๋ฐฐ์šฐ๋Š” ์‚ฌ๋žŒ๋“ค์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ธํ„ฐ๋ ‰์…˜ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋„์™€์ฃผ๋Š” ์‚ฌ์ดํŠธ์ž…๋‹ˆ๋‹ค.

๋น„์Šทํ•œ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•  ์ˆ˜ ์žˆ๋Š” ์ฑ„๋„์— ๊ฐ€์ž…ํ•ด์„œ ์‹ค์‹œ๊ฐ„ ์ฑ„ํŒ…, ํ™”์ƒ, ์Œ์„ฑ ๋“ฑ์œผ๋กœ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค๊ณผ ์†Œํ†ตํ•˜๋ฉด์„œ ์ž์‹ ์˜ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜๊ฑฐ๋‚˜, ํ‚ค์›Œ๋‚˜๊ฐ€์„ธ์š”!

โญ๏ธ ํ•ต์‹ฌ ๊ธฐ๋Šฅ

๐ŸŒˆ ์žฌ๋Šฅ๊ณต์œ ์ž์™€ ํ•™์Šต์ž๊ฐ€ ๋งŒ๋‚˜๊ธฐ ์œ„ํ•œ ์ฑ„๋„ ๊ธฐ๋Šฅ

์žฌ๋Šฅ ๊ณต์œ ์ž์™€ ์žฌ๋Šฅ ์ฐธ์—ฌ์ž๊ฐ€ ์‰ฝ๊ฒŒ ๋งŒ๋‚  ์ˆ˜ ์žˆ๋Š” ์ฑ„๋„์„ ๋งŒ๋“ค์–ด๋ณด์„ธ์š”!
๋ˆ„๊ตฌ๋‚˜ ์ฑ„๋„์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ  ๋ˆ„๊ตฌ๋‚˜ ์ฑ„๋„์— ๊ฐ€์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฑ„๋„์„ ํ†ตํ•ด ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ ์ž์‹ ๋งŒ์˜ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•ด์ฃผ์„ธ์š”!๐Ÿ˜Š

๐Ÿ‘ฅ ํšจ์œจ์ ์ธ ์žฌ๋Šฅ ๊ณต์œ ๋ฅผ ์œ„ํ•œ ์ฑ„ํŒ… ๋ฐ ํ™”์ƒ๋ฐฉ ๊ธฐ๋Šฅ

์žฌ๋Šฅ ๊ณต์œ ์ž๊ฐ€ ํŽธํ•˜๊ฒŒ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜๊ธฐ ์œ„ํ•ด ์ฑ„ํŒ… ๋ฐ ํ™”์ƒ๋ฐฉ์„ ๋งŒ๋“ค์–ด์ฃผ์„ธ์š”!
์ €ํฌ ์„œ๋น„์Šค์—์„œ ์ฑ„ํŒ…๋ฐฉ๊ณผ ํ™”์ƒ๋ฐฉ์„ ๋งŒ๋“ค์–ด์„œ ์ข€๋” ํšจ์œจ์ ์œผ๋กœ ์žฌ๋Šฅ์„ ๊ณต์œ ํ•˜์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.๐Ÿ‘‹๐Ÿป

๐Ÿ“ ์žฌ๋Šฅ ๊ณต์œ ๊ฐ€ ๋๋‚˜๊ณ  ๊ธฐ๋กํ•˜๋Š” ์•„์นด์ด๋น™ ๊ธฐ๋Šฅ

์žฌ๋Šฅ ๊ณต์œ ๊ฐ€ ๋๋‚˜๊ณ  ์œ ์ตํ•œ ๋‚ด์šฉ์„ ๊ธฐ๋กํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด?
์žฌ๋Šฅ ๊ณต์œ ์ž๊ฐ€ ์ฑ„ํŒ…๋ฐฉ์—์„œ ๋Œ€ํ™”ํ•œ ์œ ์ตํ•œ ๋‚ด์šฉ๋“ค์„ ์ง์ ‘ ์—๋””ํ„ฐ๋ฅผ ํ†ตํ•ด ์•„์นด์ด๋น™์œผ๋กœ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ฑ„๋„ ๊ฐ€์ž…์ž๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์—๊ฒŒ๋„ ์œ ์ตํ•œ ๋‚ด์šฉ์„ ๊ณต์œ ํ•ด์ฃผ์„ธ์š”!

์„œ๋น„์Šค ๊ฒฐ๊ณผ๋ฌผ

์„œ๋น„์Šค ์ฃผ์†Œ : https://upgle.hisfolio.com

๐Ÿ’ก Front-End ๊ธฐ์ˆ  ์Šคํƒ (Technique Used)

react
React.js
redux
Redux
material-ui
material-ui
emotion
emotion.js
react-helmet
react helmet

๐Ÿ–ฅ ์ปดํ“จํ„ฐ ๊ตฌ์„ฑ / ํ•„์ˆ˜ ์กฐ๊ฑด ์•ˆ๋‚ด (Prerequisites)

  • ECMAScript 6 ์ง€์› ๋ธŒ๋ผ์šฐ์ € ์‚ฌ์šฉ
  • ๊ถŒ์žฅ: Google Chrome ๋ฒ„์ ผ 77 ์ด์ƒ
  • IEํ™˜๊ฒฝ์—์„œ ์ž‘๋™์ด ์•ˆ๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ์šฉ๊ฐ€๋Šฅ ๋ธŒ๋ผ์šฐ์ €

Chrome Firefox Edge Opera Safari
56+ โœ” 32+ โœ” 16+ โœ” 42+ โœ” 8+ โœ”

๐ŸŒŸ Contribute

์ €ํฌ ์„œ๋น„์Šค๋Š” ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์˜ Contribute ๋ฅผ ์›ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ๐Ÿ‘‹๐Ÿป ์•„๋ž˜๋Š” ์„ค์น˜ ๋ฐ Contribute ๊ฐ€์ด๋“œ์ž…๋‹ˆ๋‹ค.

installation

์›ํ™œํ•œ ์‹คํ–‰์„ ์œ„ํ•ด์„œ๋Š” node LTS ์ด์ƒ์˜ ๋ฒ„์ „์„, ์ €ํฌ ์„œ๋น„์Šค์— Contribute ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” node v16.8.0์„ ์ค€๋น„ํ•ด์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค

  1. ์—…๊ธ€ ์›๊ฒฉ ์ €์žฅ์†Œ๋ฅผ ํด๋ก ํ•ฉ๋‹ˆ๋‹ค.
$ git clone https://github.com/Jandy-SeoulTech/Jandy_Web_Front.git
  1. ์ƒ์„ฑ๋œ ๋กœ์ปฌ ์ €์žฅ์†Œ๋กœ ์ด๋™ ํ›„ ๋ชจ๋“ˆ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
$ cd Jandy_Web_Front
$ npm install
  1. ์œ„ ์ž‘์—…์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค๋ฉด ์‹คํ–‰์„ ํ•ด์ฃผ์„ธ์š”!
$ npm run start

Contribute

๊ฐœ๋ฐœํ•˜์‹œ๊ธฐ ์ „ prettier๊ฐ€ ์—๋””ํ„ฐ์— ์„ค์ •์ด ์ž˜ ๋ผ์žˆ๋Š”์ง€ ํ™•์ธํ•ด์ฃผ์„ธ์š”!

๊ธฐ์—ฌ ๊ฐ€์ด๋“œ ๋ผ์ธ์„ ๋”ฐ๋ผ์„œ ํ•ด์ฃผ์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๊ฐ€์ด๋“œ๋ผ์ธ

๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ ํŒ€ ์ •๋ณด(Team Information)

Front-End Developer Back-End Developer Product Manager Product Designer
๊น€์„ฑํƒœ
๊น€์„ฑํƒœ

ํ™ฉ์ธ์„œ
ํ™ฉ์ธ์„œ
์กฐ์ธํ˜
์กฐ์ธํ˜
ํ™์„ฑ์›…
ํ™์„ฑ์›…
์ตœ๋ฏผ์ค€
์ตœ๋ฏผ์ค€
๊น€์—ฐ์ˆ˜
๊น€์—ฐ์ˆ˜

upgle_front's People

Contributors

sjsjsj1246 avatar md2eoseo avatar istiopaxx avatar

Stargazers

KyungJi Kim avatar Jo In Hyeok avatar Ungs avatar

Watchers

 avatar

Forkers

kc2585 istiopaxx

upgle_front's Issues

Post ๋ชจ๋“ˆ ๋ถ„๋ฆฌ ์ œ์•ˆ

ํ˜„์žฌ ์ฑ„๋„ ๊ณต์œ  ์š”์ฒญ์ด Post์ด๊ณ  Channel ๋ชจ๋“ˆ ์•ˆ์— Post๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ๋Ÿฐ๋ฐ ์ฑ„๋„์ด ๋„ˆ๋ฌด ๋น„๋Œ€ํ•ด์ง€๊ณ  post๋˜ํ•œ ๊ด€๋ จ ๋กœ์ง์ด ๋งŽ์„ ๊ฒƒ ๊ฐ™๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“ˆ์„ ๋ถ„๋ฆฌํ•˜๋Š”๊ฒƒ์ด ๋งž๋Š”๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.(chat์ฒ˜๋Ÿผ)

channel -> channel, post

์žฌ๋Šฅ๊ณต์œ ์š”์ฒญ/์•„์นด์ด๋ธŒ MD ์—๋””ํ„ฐ ๊ตฌํ˜„

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ์ด๋ฏธ์ง€ ํ›… ๊ตฌํ˜„

    • ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ api๋ฅผ ์ด์šฉํ•ด ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ํ›„ url์„ ๋ฐ›์•„์™€ ๋ Œ๋”๋ง
  • ์งˆ๋ฌธ-๋‹ต์žฅ์Œ ์ปค์Šคํ…€๋ Œ๋”๋Ÿฌ ๊ตฌํ˜„

    • ์งˆ๋ฌธ ๋‹ต์žฅ์Œ์„ ์—๋””ํ„ฐ ๋‚ด์—์„œ ์ปค์Šคํ…€ ๋ Œ๋”๋Ÿฌ๋กœ ๊ตฌํ˜„ํ•˜๊ณ , ํ•ด๋‹น ํƒœ๊ทธ๋ฅผ ์Šคํƒ€์ผ์„ ์ž…ํ˜€์ค๋‹ˆ๋‹ค.
  • ๊ฐ ๊ฒŒ์‹œ๋ฌผ์€ ์„œ๋ฒ„์—์„œ ์ŠคํŠธ๋ง ํ˜•ํƒœ์˜ ๊ฒŒ์‹œ๋ฌผ ๋ณธ๋ฌธ์„ ๋ฐ›์•„์™€ ๋ Œ๋”๋งํ•˜๊ฒŒ ๋˜๋Š”๋ฐ, ๊ทธ๊ฒƒ๋„ ์—๋””ํ„ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ํฌํ•จ๋œ ๋ทฐ์–ด๋ฅผ ํ†ตํ•ด ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

Boilerplate ์ž‘์„ฑ

  • redux, redux-saga
  • react-router
  • react-helmet
  • material-ui
  • emotion.js
  • axios

์ž„์‹œ์„œ๋ฒ„ json server

ํšŒ์›๊ฐ€์ž… ๊ตฌํ˜„

์ฃผ์š” ๊ธฐ๋Šฅ

  • ๋‹‰๋„ค์ž… ์ž…๋ ฅ
    • ๋‹‰๋„ค์ž„ ํ˜•์‹ ๊ฒ€์‚ฌ
  • ์ด๋ฉ”์ผ ์ž…๋ ฅ
    • ์ด๋ฉ”์ผ ํ˜•์‹ ๊ฒ€์‚ฌ(์ •๊ทœํ‘œํ˜„์‹)
  • ์ด๋ฉ”์ผ ์ธ์ฆ
    • ์ด๋ฉ”์ผ ์ธ์ฆ์ฝ”๋“œ ๋ณด๋‚ด๊ธฐ ๋ฒ„ํŠผ
    • ์ธ์ฆ์ฝ”๋“œ ์ž…๋ ฅ
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ ํ˜•์‹ ๊ฒ€์‚ฌ(์ •๊ทœํ‘œํ˜„์‹, 8์ž ์ด์ƒ์˜ ์˜๋ฌธ ์ˆซ์ž ์กฐํ•ฉ)
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ํ™•์ธ ์ž…๋ ฅ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ๊ณผ ๊ฐ™์€์ง€ ํ™•์ธ
  • ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ์ด๋™ ๋ฒ„ํŠผ
  • ์†Œ์…œ ๊ณ„์ • ๊ฐ€์ž… ๋ฒ„ํŠผ

โœ”์™€์ด์–ด ํ”„๋ ˆ์ž„ ํ™•์ • ์ „ ๊นŒ์ง€ View ์ˆ˜์ • ์—ฌ์ง€ ์žˆ์Œ

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ์—์„œ ์ฑ„ํŒ…๋ฐฉ ๋งŒ๋“ค๊ธฐ ํ•  ์‹œ ๋ผ์šฐํ„ฐ ๊ผฌ์ž„

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ์—์„œ ์ฑ„ํŒ…๋ฐฉ ๋งŒ๋“ค๊ธฐ๋ฅผ ํด๋ฆญํ•ด ๋ชจ๋‹ฌ์—์„œ ๋ฐ”๋กœ ์—ด๊ธฐ๋ฅผ ๋ˆ„๋ฅด๋ฉด,

  1. ์ƒˆ์ฐฝ์œผ๋กœ ์—ด๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  2. ๋ผ์šฐํ„ฐ๊ฐ€ ๊ผฌ์—ฌ์„œ ์ œ๋Œ€๋กœ ๋ Œ๋”๋ง ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
    http://localhost:3000/channel/2/post/channel/2/chat

์ฑ„๋„ ์ฑ„ํŒ…๋ฐฉ ๋ฐฉ์žฅ์˜ ์ฑ„ํŒ…๋ฐฉ ๋๋‚ด๊ธฐ ๊ธฐ๋Šฅ ๋ถ€์žฌ

  1. ์ฑ„๋„ ์ฑ„ํŒ…๋ฐฉ์˜ ์ฃผ์ธ(๋ฐฉ์žฅ)์ผ๋•Œ ์ฑ„ํŒ…๋ฐฉ ๋‚˜๊ฐ€๊ธฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์ฑ„ํŒ…๋ฐฉ ๋๋‚ด๊ธฐ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  2. ์ฑ„ํŒ…๋ฐฉ ๋๋‚ด๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ํ•ด๋‹นํ•˜๋Š” ์„œ๋ฒ„ api๋ฅผ ํ˜ธ์ถœํ•˜๊ณ  ์ฑ„ํŒ…๋ฐฉ์ด ํญํŒŒ๋˜์–ด ๋ชจ๋“  ์ฐธ์—ฌ์ž๊ฐ€ ๋‚˜๊ฐ€๊ฒŒ ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
    ์บก์ฒ˜

์ฝ”๋“œ๋ฅผ ๋ณด๋‹ˆ ๊ธฐ๋Šฅ์ด ๋ถ€์žฌํ•œ๊ฒƒ์œผ๋กœ ๋ณด์ด๋Š”๋ฐ, ์ถ”๊ฐ€ํ•ด์ฃผ์„ธ์š”~~!

Feat: ์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ํŽ˜์ด์ง€ ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ ์šฉ

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ํŽ˜์ด์ง€์— ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ ์šฉ

์„ธ๋ถ€์‚ฌํ•ญ

  • ์ด์ „ api์— ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ์ ์šฉ๋˜์ง€ ์•Š์•„ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ์—†์Šต๋‹ˆ๋‹ค.
  • ์ฑ„๋„ ์žฌ๋Šฅ๊ณต์œ ์š”์ฒญ ํŽ˜์ด์ง€ ์ฒ˜๋Ÿผ ํŽ˜์ด์ง€๋„ค์ด์…˜์ด ์ ์šฉ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • GET /api/Archive/channel/:channelId?page=1&pageSize=3 <- api ์š”์ฒญ ์˜ˆ์‹œ

์ถ”๊ฐ€์‚ฌํ•ญ

์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ๋ฐ์ดํ„ฐ ์—ฐ๋™

์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ๋ฐ์ดํ„ฐ ์—ฐ๋™

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ์ฑ„๋„ ํ™ˆ ํŽ˜์ด์ง€ ๋ชจ์•„๋ณด๊ธฐ ์ปดํฌ๋„ŒํŠธ ์—ฐ๋™
  • ์ฑ„๋„ ํ™ˆ ๋ชจ์•„๋ณด๊ธฐ ๋ฒ„ํŠผ -> ์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ๋ฆฌ์ŠคํŠธ ํŽ˜์ด์ง€ ์ด๋™
  • ์ฑ„๋„ ํ”„๋กœํ•„ ํŽ˜์ด์ง€ ๋ชจ์•„๋ณด๊ธฐ ์ปดํฌ๋„ŒํŠธ ๋ฐ์ดํ„ฐ ์—ฐ๋™
  • ์ฑ„๋„ ํ”„๋กœํ•„ ํŽ˜์ด์ง€๋Š” ์ฑ„๋„ ์ฐธ์—ฌ์ž๋ฉด ๋ชจ๋‘ ๋ณด์—ฌ์ฃผ๊ณ  ์ฑ„๋„ ๋ฏธ์ฐธ์—ฌ์ž๋Š” public๋งŒ ๋ณด์—ฌ์ฃผ๋„๋ก api ์„ค๊ณ„๊ฐ€ ๋˜์žˆ์œผ๋ฏ€๋กœ ๊ทธ๋Œ€๋กœ ํ•ด์ฃผ์„ธ์š”.

๋‹‰๋„ค์ž„ ๋“ฑ๋ก ํ›„ ๊ฒฐ์ • ๋ฒ„ํŠผ์„ ๋ˆŒ๋Ÿฌ๋„ ๋ฐ˜์‘ ์—†์Œ

์บก์ฒ˜

develop ๋ธŒ๋žœ์น˜ ๊ธฐ์ค€์ž…๋‹ˆ๋‹ค.

๋‹‰๋„ค์ž„ ์ฒดํฌ ๋กœ์ง์€ ์ž˜ ์ž‘๋™ํ•˜๋Š”๋ฐ ๊ฒฐ์ • ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด api ์š”์ฒญ์€ ์ •์ƒ์ ์œผ๋กœ ๊ฐ€๊ณ , ๋‹‰๋„ค์ž„๋„ ๋“ฑ๋ก ๋จ. ๊ทผ๋ฐ ๋‹ค์Œ ํŽ˜์ด์ง€๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š์Œ.
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/0a181211dd1f570a7ac8ac44ec7ef4649247e254/src/containers/profile/SetNicknameContainer.jsx#L29-L31
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/0a181211dd1f570a7ac8ac44ec7ef4649247e254/src/modules/auth.js#L20
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/0a181211dd1f570a7ac8ac44ec7ef4649247e254/src/modules/auth.js#L67-L73

https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/0a181211dd1f570a7ac8ac44ec7ef4649247e254/src/containers/profile/SetNicknameContainer.jsx#L39-L45
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/0a181211dd1f570a7ac8ac44ec7ef4649247e254/src/modules/user.js#L17
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/0a181211dd1f570a7ac8ac44ec7ef4649247e254/src/modules/user.js#L29-L32

ํžˆ์Šคํ† ๋ฆฌ ์ด๋™์ด ์•ˆ๋จนํžˆ๋Š”๊ฒƒ๊ฐ™์Šต๋‹ˆ๋‹ค.

์•„์นด์ด๋น™ ์ƒ์„ฑ ํŽ˜์ด์ง€ ๊ฐœ๋ฐœ

๊ฐœ๋ฐœ์‚ฌํ•ญ

์•„์นด์ด๋น™ ํŽ˜์ด์ง€ ๋ทฐ ์ž‘์„ฑ

  • ์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ๊ณผ ์—๋””ํ„ฐ ๋ถ€๋ถ„์€ ๋™์ผ
  • ํƒœ๊ทธ ์ž…๋ ฅ์ฐฝ
  • ๊ณต๊ฐœ ๋ฒ”์œ„ ์„ค์ • ์ฐฝ

์•„์นด์ด๋น™ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์—ฐ๋™ ๋ฐ ๋กœ์ง ์ž‘์„ฑ

  • ๋ชจ์•„๋ณด๊ธฐ ํŽ˜์ด์ง€์—์„œ ๊ธ€์“ฐ๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด ๋ชจ๋‹ฌ ๋ Œ๋”๋ง
  • ๋ชจ๋‹ฌ์—์„œ ์ฑ„ํŒ…๋ฐฉ ์•„์นด์ด๋ธŒ๋ฅผ ์„ ํƒํ•˜๋ฉด ๋ณธ์ธ์ด ๋ฐฉ์žฅ์ด๋ฉด์„œ ์ข…๋ฃŒ๋œ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก ๋œธ
    • GET /api/Room/list
  • ์ฑ„ํŒ…๋ฐฉ ์„ ํƒํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ๊ฐ€๋ฉด ์ฑ„ํŒ… ์งˆ๋ฌธ-๋‹ต์žฅ์Œ์ด ๋ Œ๋”๋ง๋˜๋ฉฐ, ํ•ด๋‹น ๋ชฉ๋ก์—์„œ ์„ ํƒํ•˜๊ณ  ๋‹ค์Œ์œผ๋กœ ๊ฐ
    • GET /api/Chat/room/:roomId/answer
  • ์—๋””ํ„ฐ ํŽ˜์ด์ง€๋กœ ์ „ํ™˜๋˜๊ณ  ๋ฏธ๋ฆฌ์„ ํƒํ•œ ์งˆ๋ฌธ ๋‹ต์žฅ์Œ ๋ Œ๋”๋ง ( ์ผ๋ฐ˜ ๊ธ€์ด๋ฉด ์งˆ๋ฌธ๋‹ต์žฅ์Œ์ด ์—†์Œ)
  • ์„ ํƒํ•œ ์ฑ„ํŒ…์ด ํ•˜๋‹จ์— ๋ณด์ด๋ฉฐ ์ดํ›„ writing ๊ธฐ๋Šฅ๊ณผ ์—ฐ๋™
  • ํƒœ๊ทธ ์ž‘์„ฑ
  • ๊ณต๊ฐœ๋ฒ”์œ„ ์„ค์ •
  • ๋งˆ์ด์ฑ„๋„ ํŽ˜์ด์ง€์—์„œ ๋‚ด๊ฐ€ ์˜คํ”ˆํ•œ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก ์ค‘ ์ข…๋ฃŒ๋˜์—ˆ์ง€๋งŒ ์•„์นด์ด๋ธŒ ๋˜์ง€์•Š์€ ์ฑ„ํŒ…๋ฐฉ์— ๋Œ€ํ•ด ๊ธฐ๋กํ•˜๊ธฐ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅผ ์‹œ ์งˆ๋ฌธ-๋‹ต์žฅ์Œ ๋ชจ๋‹ฌ์ด ๋œจ๊ณ , ์งˆ๋ฌธ๋‹ต์žฅ์Œ์„ ์„ ํƒํ•ด ์•„์นด์ด๋ธŒ ์ž‘์„ฑํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ๋กœ์ง์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœํ•„ ์กฐํšŒ ๊ตฌํ˜„

๋กœ๊ทธ์ธ ์—ฌ๋ถ€์— ๋”ฐ๋ผ ๋‚ด ํ”„๋กœํ•„, ๋‹ค๋ฅธ ์œ ์ € ํ”„๋กœํ•„ ๋””์ž์ธ ๋‹ค๋ฅด๊ฒŒ ๊ตฌํ˜„

Custom Component ์ž‘์„ฑ

์™€์ด์–ดํ”„๋ ˆ์ž„์˜ ๋””์ž์ธ์„ ๊ธฐ๋ฐ˜์œผ๋กœ material-ui์˜ ๊ธฐ๋ณธ ์ปดํฌ๋„ŒํŠธ๋“ค์„ ์ปค์Šคํ…€ํ•˜์—ฌ ์ž‘์„ฑํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.
์ด์—๋”ฐ๋ผ ๊ธฐ์กด์— ์“ฐ๋˜ material-ui ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ๋กœ ๋‹ค์‹œ importํ•ด์•ผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด material ui์˜ props๋Š” ๊ทธ๋Œ€๋กœ ์ „๋‹ฌ๋˜๊ณ  sx={{}}๋กœ ์ž‘์„ฑํ•œ ์ปค์Šคํ…€ ์Šคํƒ€์ผ์€ ์Šคํƒ€์ผ์ด ์ค‘๋ณต๋  ๊ฒฝ์šฐ ์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ์˜ ์Šคํƒ€์ผ์ด ์šฐ์„ ์ ์šฉ ๋ฉ๋‹ˆ๋‹ค.

์ปค์Šคํ…€ ์ปดํฌ๋„ŒํŠธ

import { Button as MuiButton, styled } from '@material-ui/core';

const Button = styled(MuiButton)((props) => ({
  background: 'gray',
  '&:hover': {
    background: 'black',
  },
}));

export default Button;

๋žœ๋”๋ง

<Button
  variant="outlined"
  size="small"
  sx={{
    background: 'pink',
  }}
>
  Signin
</Button>

๊ธฐ๋ณธ
image
ํ˜ธ๋ฒ„ ์‹œ์—
image
๋žœ๋”๋งํ•œ ๋ถ€๋ถ„์—์„œ background: 'pink'๋Š” ์ ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ props๋Š” ์ž˜ ์ ์šฉ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ž‘์—… ๋ชฉ๋ก

  • Button : ๋ฐฐ๊ฒฝ ๊ฒ€์€์ƒ‰
  • TextField

Feat: ์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ์ฑ„ํŒ…๋ฐฉ ๋ฐ”๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ ๊ตฌํ˜„

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๊ฐœ๋ณ„ ๊ฒŒ์‹œ๊ธ€ ํŽ˜์ด์ง€์—์„œ Open์ƒํƒœ์˜ ๊ฒŒ์‹œ๊ธ€์— ๋Œ€ํ•ด ์ฑ„ํŒ…๋ฐฉ ๋ฐ”๋กœ๊ฐ€๊ธฐ๋ฅผ ํด๋ฆญํ•˜๋ฉด ์ฑ„ํŒ…๋ฐฉ ์ฐฝ์ด ๋– ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„ธ๋ถ€์‚ฌํ•ญ

์žฌ๋Šฅ๊ณต์œ ์š”์ฒญ์—์„œ ์ฑ„ํŒ…๋ฐฉ ๋„์šฐ๊ธฐ

  • ์ด์ „์—๋Š” GET /api/Post/:postId api์—์„œ open๋œ ์ƒํƒœ์ธ ๊ฒฝ์šฐ ์—ฐ๊ฒฐ๋œ ์ฑ„ํŒ…๋ฐฉ์˜ ์ •๋ณด๋ฅผ ์ฃผ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๊ฐ€๋Šฅํ–ˆ์ง€๋งŒ, Jandy-SeoulTech/Jandy_Web_Back#87 ์—์„œ ํ•ด๊ฒฐํ•˜์˜€์Šต๋‹ˆ๋‹ค.
  • ์ด์ œ ์š”์ฒญ ์‹œ์— ์˜ค๋Š” ์‘๋‹ต์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.
{
    "status": 200,
    "success": true,
    "message": "ํฌ์ŠคํŠธ ์ •๋ณด ์–ป๊ธฐ ์„ฑ๊ณต",
    "data": {
        "id": 1,
        "title": "์ฑ„ํŒ…๋ฐฉ ์ƒ์„ฑ ํ…Œ์ŠคํŠธ",
        "status": "Open",
        "content": "ใ…ใ„ดใ…‡ใ…ใ„ดใ…‡",
        "authorId": 3,
        "channelId": 1,
        "reservedAt": null,
        "createdAt": "2021-10-06T20:37:52.889Z",
        "updatedAt": null,
        "author": {
            "id": 3,
            "email": "[email protected]",
            "nickname": "saasdasd",
            "profile": {
                "id": 2,
                "department": "",
                "introduce": "",
                "createdAt": "2021-10-06T20:37:17.243Z",
                "updatedAt": null,
                "userId": 3,
                "profileImage": null
            }
        },
        "attention": [],
        "images": [],
        "channelRoom": {
            "id": 2,
            "status": "Open",
            "name": "๋ฐ”๋กœ์—ฐ๋”ใ…",
            "userId": 4,
            "channelId": 1,
            "reservedAt": null,
            "createdAt": "2021-10-06T20:45:27.678Z",
            "updatedAt": null,
            "postId": 1
        }
    }
}

์ถ”๊ฐ€์‚ฌํ•ญ

Jandy-SeoulTech/Jandy_Web_Back#87
https://documenter.getpostman.com/view/14901542/Tzz7Pdio#603a01b6-91a2-44b3-9c3c-35f3bbda7f7e

ํ”„๋กœํ•„ ๋ชจ์•„๋ณด๊ธฐ ๋ฐ์ดํ„ฐ ์—ฐ๋™

ํ”„๋กœํ•„ ๋ชจ์•„๋ณด๊ธฐ ๋ฐ์ดํ„ฐ ์—ฐ๋™

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ํ”„๋กœํ•„ ๋ชจ์•„๋ณด๊ธฐ ๋ฒ„ํŠผ -> ๋ชจ์•„๋ณด๊ธฐ ๋ชจ๋‹ฌ(ํ”ผ๊ทธ๋งˆ ์ฐธ์กฐ)
  • ํ”„๋กœํ•„์„ ๋ณด๋Š” ์‚ฌ๋žŒ(์ฆ‰ api์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ์‚ฌ๋žŒ)์ด ์ž๊ธฐ ์ž์‹ ์ด๋ฉด ๋ชจ๋‘, ํƒ€์ธ์ด๋ฉด public๋งŒ ๊ฐ€์ ธ์˜ค๋„๋ก api์„ค๊ณ„๊ฐ€ ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Œ€๋กœ ์‚ฌ์šฉํ•ด์ฃผ์„ธ์š”.

Auth Module ๋ฒ„๊ทธ(๋‹‰๋„ค์ž„ ๋“ฑ๋ก)

redux-pender๋กœ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ํ•˜๋ฉด์„œ ๋‹ค์†Œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋“ฏ ํ•ฉ๋‹ˆ๋‹ค.
๋‹‰๋„ค์ž„ ๋“ฑ๋ก์„ ํ•  ๋•Œ ์ค‘๋ณต ์ฒดํฌ๋ฅผ ํ•˜๋Š”๋ฐ ์ค‘๋ณต์ฒดํฌ๊ฐ€ ์•ˆ๋˜๋Š” ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ์ƒํƒœ ์—…๋ฐ์ดํŠธ ๋กœ์ง์„ ์ž˜๋ชป ์ ์šฉํ•œ ๊ฒƒ ๊ฐ™์•„ ์ˆ˜์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.


์•Œ๊ณ ๋ณด๋‹ˆ ํ˜„์žฌ Peding ์ƒํƒœ์ธ PR์„ ๋ณ‘ํ•ฉํ•˜๋ฉด ํ•ด๊ฒฐ๋  ๋“ฏ ํ•ฉ๋‹ˆ๋‹ค.

์ฑ„ํŒ… ๋ชฉ๋ก ํŽ˜์ด์ง€

์ฑ„๋„ ๋„ค๋น„๊ฒŒ์ด์…˜ ๋ฐ”์—์„œ ์žฌ๋Šฅ ๊ณต์œ  ์ฑ„ํŒ…์„ ํด๋ฆญํ•˜๋ฉด ์žฌ๋Šฅ๊ณต์œ  ์ฑ„ํŒ… ๋ชฉ๋ก ํŽ˜์ด์ง€๋กœ ๋„˜์–ด๊ฐ€์ง€ ์•Š๊ณ  ์ฑ„๋„ ํ”„๋กœํ•„ ํŽ˜์ด์ง€๋กœ ๊ฐ‘๋‹ˆ๋‹ค.

์ฑ„๋„ ์ฑ„ํŒ…๋ฐฉ ๋ฆฌ๋ทฐ ๋ฏธ์ž‘์„ฑ ์ฑ„ํŒ…๋ฐฉ ๋ Œ๋”๋ง๋˜์ง€์•Š์Œ

์ฑ„๋„ ์ฑ„ํŒ…๋ฐฉ์—์„œ ๋ฆฌ๋ทฐ๋ฅผ ์ž‘์„ฑํ•˜์ง€ ์•Š์•˜์ง€๋งŒ ๋‚˜๊ฐ€์žˆ๋Š” ์ฑ„ํŒ…๋ฐฉ์— ๋Œ€ํ•ด ๋ฆฌ๋ทฐ ์ž‘์„ฑํ•˜๊ธฐ ๋ฒ„ํŠผ์ด ํ™œ์„ฑํ™” ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์บก์ฒ˜2

์œ„์˜ ์ฑ„ํŒ…๋ฐฉ์€ ํ˜„์žฌ ๋กœ๊ทธ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ์ฐธ์—ฌ์ž๋กœ ์ฐธ์—ฌํ•œ ์ฑ„ํŒ…๋ฐฉ์ด๊ณ , redux ์ƒํƒœ๋ฅผ ๋ณด๋ฉด inactive ์ƒํƒœ๋กœ ๋‚˜๊ฐ€์ ธ์žˆ๋Š” ์ƒํƒœ๋ผ๋Š” ๊ฒƒ์„ ์•Œ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ทธ ์ฑ„ํŒ…๋ฐฉ์€ Close ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ํ”ผ๊ทธ๋งˆ์—์„œ์ฒ˜๋Ÿผ ๋‚˜๊ฐ€์ ธ์žˆ๊ณ /๋ฆฌ๋ทฐ๊ฐ€ ์•ˆ๋˜์–ด์žˆ์œผ๋ฉด ๋ฆฌ๋ทฐ ์ž‘์„ฑ ๋ชจ๋‹ฌ์ด ๋– ์•ผํ•˜๋ฉฐ, ๋‚˜๊ฐ€์ ธ์žˆ๊ณ /๋ฆฌ๋ทฐ๊ฐ€ ๋˜์–ด์žˆ์œผ๋ฉด ๋ชฉ๋ก์— ์—†์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์—ฐ๋™

Main Development

๋ฐ์ดํ„ฐ ์—ฐ๋™

๊ฐ ํŽ˜์ด์ง€์—์„œ ์„œ๋ฒ„์ธก API ๊ณ ์ • ์‘๋‹ต ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž„์‹œ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒดํ•˜๋Š” ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ ์ •๋ฆฌ

์ด ์™ธ์— ๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ๋“ค์„ ์ด์Šˆ์— ์ž„์‹œ๋กœ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

์ž‘์—…์‚ฌํ•ญ

๋ฐ์ดํ„ฐ ์—ฐ๋™

์œ ์ € ํ”„๋กœํ•„

  • ๋ชจ์•„ ๋ณด๊ธฐ
  • ์˜คํ”ˆ ์ฑ„๋„
  • ์ฐธ์—ฌ ์ฑ„๋„

์ฑ„๋„ ํ”„๋กœํ•„

  • ๋ชจ์•„ ๋ณด๊ธฐ

์ฑ„๋„ ํ™ˆ

  • ๊ฒŒ์‹œํŒ
  • ์˜คํ”ˆ๋œ ์ฑ„ํŒ…๋ฐฉ
  • ๋ชจ์•„ ๋ณด๊ธฐ

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ

  • ๊ฒŒ์‹œ๋ฌผ

์ฑ„๋„ ํฌ์ŠคํŠธ

  • ์ผ์น˜ํ•˜๋Š” ํฌ์ŠคํŠธ ํ‘œ์‹œํ•˜๋„๋ก ๊ตฌํ˜„ ํ•„์š”

๊ตฌํ˜„๋˜์ง€ ์•Š์€ ๊ธฐ๋Šฅ ์ •๋ฆฌ

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์ฑ„ํŒ…

  • ํŽ˜์ด์ง€ ๊ตฌํ˜„ ํ•„์š”

์ฑ„๋„ ๋ชจ์•„ ๋ณด๊ธฐ

  • ํŽ˜์ด์ง€ ๊ตฌํ˜„ ํ•„์š”

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์—ฐ๋™

๋‚ด์šฉ

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ํŽ˜์ด์ง€์—์„œ ์„œ๋ฒ„์ธก API ๊ณ ์ • ์‘๋‹ต ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž„์‹œ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒดํ•˜๋Š” ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฒŒ์‹œ๋ฌผ

Feat: ์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ํŽ˜์ด์ง€, ๊ฐœ๋ณ„ ์•„์นด์ด๋ธŒ ์กฐํšŒ ํŽ˜์ด์ง€ ๊ตฌํ˜„

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ํŽ˜์ด์ง€ ๊ตฌํ˜„
  • ๋ชจ์•„๋ณด๊ธฐ ๊ฐœ๋ณ„ ๊ฒŒ์‹œ๊ธ€ ๋ทฐ ๊ตฌํ˜„
  • ๋ชจ์•„๋ณด๊ธฐ ๊ธ€์˜ ๋ณธ๋ฌธ(content, mdํ˜•์‹) ๋ทฐ ๊ตฌํ˜„

์„ธ๋ถ€์‚ฌํ•ญ

์ฑ„๋„ ๋ชจ์•„๋ณด๊ธฐ ํŽ˜์ด์ง€ ๊ตฌํ˜„

  • ์ฑ„๋„ ์•„์นด์ด๋ธŒ ๋ชฉ๋ก ์กฐํšŒ

๊ฐœ๋ณ„ ์•„์นด์ด๋ธŒ ์กฐํšŒ ํŽ˜์ด์ง€ ๊ตฌํ˜„

  • ๊ธ€ ์ œ๋ชฉ, ์ƒํƒœ, ๋ชจ๋‹ฌ ๋“ฑ
  • ๊ธ€ ์•„๋ž˜ ๋ฒ„ํŠผ ๋ฉ”๋‰ด(๊ณต๊ฐ, ์š”์ฒญ๊ธ€ ๋ฐ”๋กœ๊ฐ€๊ธฐ ๋“ฑ)
  • ๋Œ“๊ธ€ ์ฐฝ

๋ชจ์•„๋ณด๊ธฐ ๊ธ€์˜ ๋ณธ๋ฌธ(content, mdํ˜•์‹) ๋ทฐ ๊ตฌํ˜„

  • ๋ชจ์•„๋ณด๊ธฐ ๊ธ€์˜ ๋ณธ๋ฌธ(content, mdํ˜•์‹)๋ฅผ ๋ณด์—ฌ์ฃผ๋Š” ๋ถ€๋ถ„์€ tui.viewer๋กœ ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. editorConfig.js ํŒŒ์ผ์˜ editorCSS๊ฐ€ ํ•ด๋‹น ๋ทฐ์–ด์™€ ์—๋””ํ„ฐ ๋ชจ๋‘์˜ css๋ฅผ dom์—์„œ ํƒœ๊ทธ๋ฅผ ๋”ฐ์™€์„œ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ•˜๋Š” ์‹์œผ๋กœ ์Šคํƒ€์ผ๋ง ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์ด ๋‚œํ•ดํ•˜๋‹ค๋ฉด ๋ทฐ์–ด ๋ถ€๋ถ„ ์ œ์™ธํ•˜๊ณ  ๋ทฐ ๊ตฌํ˜„ํ•ด์ฃผ์„ธ์š”.

์ถ”๊ฐ€์‚ฌํ•ญ

  • comments api ์ˆ˜์ •์œผ๋กœ ์ธํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ ์ „๋‹ฌ ๋ฐฉ์‹ ์ˆ˜์ •

ํฌ์ŠคํŒ…/์•„์นด์ด๋น™ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์—ฐ๋™/๊ธฐ๋Šฅ ์—ฐ๊ฒฐ

ํฌ์ŠคํŒ…/์•„์นด์ด๋น™ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์—ฐ๋™

  1. API ๊ฐœ๋ฐœ ์™„๋ฃŒ ์‹œ ์ง„ํ–‰
  2. ๋ฐ์ดํ„ฐ ์ „๋‹ฌ ํ˜•์‹ ๋…ผ์˜ ํ•„์š”

ํฌ์ŠคํŒ…/์•„์นด์ด๋น™ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๊ธฐ๋Šฅ ์—ฐ๊ฒฐ

  1. ๊ฐ ์ปดํฌ๋„ŒํŠธ ํด๋ฆญ ์‹œ ํŽ˜์ด์ง€ ์ด๋™ ๊ธฐ๋Šฅ
  2. ๊ธ€ ์ž‘์„ฑ ๋ฒ„ํŠผ
  3. ๋”๋ณด๊ธฐ ๋ฒ„ํŠผ => ํด๋ฆญํ•˜๋ฉด ๊ฒŒ์‹œ๋ฌผ์„ ๋” ์š”์ฒญํ•˜์—ฌ ๋ Œ๋”๋งํ•จ(ํŽ˜์ด์ง€๋„ค์ด์…˜)

์ฑ„๋„ ํ™ˆ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์—ฐ๋™

๋‚ด์šฉ

์ฑ„๋„ ํ™ˆ ํŽ˜์ด์ง€์—์„œ ์„œ๋ฒ„์ธก API ๊ณ ์ • ์‘๋‹ต ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž„์‹œ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒดํ•˜๋Š” ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฒŒ์‹œํŒ
  • ์˜คํ”ˆ๋œ ์ฑ„ํŒ…๋ฐฉ

ํšŒ์›๊ฐ€์ž… ์‹œ ์ด๋ฉ”์ผ ์ฝ”๋“œ ์ธ์ฆ ๋ถˆ๊ฐ€ ๋ฒ„๊ทธ

ํšŒ์›๊ฐ€์ž… ์ด๋ฉ”์ผ ์ธ์ฆ ๋ถˆ๊ฐ€ ๋ฒ„๊ทธ

์บก์ฒ˜

์›์ธ ์ฝ”๋“œ:

๋น„๊ตฌ์กฐํ™” ํ• ๋‹น ์‹œ code ์™€ auth์˜ ๋„ค์ด๋ฐ์ด ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ž…๋‹ˆ๋‹ค.
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/512e4a669d9645e6ea7fd75febcfabcc6dc865b7/src/containers/auth/SignupContainer.jsx#L39-L41
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/512e4a669d9645e6ea7fd75febcfabcc6dc865b7/src/modules/auth.js#L23-L26
https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/512e4a669d9645e6ea7fd75febcfabcc6dc865b7/src/lib/api/auth.js#L28-L31

API ํ†ต์‹  ์ฝ”๋“œ ๋‹จ์ˆœํ™”

๊ธฐ์กด API ํ†ต์‹  ์ฝ”๋“œ๊ฐ€ ์“ธ๋ฐ์—†์ด ๋งŽ์€ ์ฝ”๋“œ๋ฅผ ์š”๊ตฌํ•˜์—ฌ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‹จ์ˆœํ™”์‹œํ‚ค๋ ค ํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ์กด ์ฝ”๋“œ

import axios from 'axios';

export const signin = async ({ email, password }) => {
  const response = await axios({
    url: '/api/Auth/login',
    method: 'POST',
    data: { email, password },
  });
  return response.data;
};

export const signup = async ({ email, password, nickname }) => {
  const response = await axios({
    url: '/api/Auth/signup',
    method: 'POST',
    data: { email, password, nickname },
  });
  return response.data;
};

export const checkNickname = async ({ nickname }) => {
  const response = await axios({
    url: '/api/Auth/nicknamecheck',
    method: 'POST',
    data: { nickname },
  });
  return response.data;
};

export const checkEmail = async ({ email }) => {
  const response = await axios({
    url: '/api/Auth/emailcheck',
    method: 'POST',
    data: { email },
  });
  return response.data;
};

export const sendVerificationCode = async ({ email }) => {
  const response = await axios({
    url: '/api/Auth/emailauth',
    method: 'POST',
    data: { email },
  });
  return response.data;
};

export const checkVerificationCode = async ({ email, auth }) => {
  const response = await axios({
    url: '/api/Auth/authcheck',
    method: 'POST',
    data: { email, auth },
  });
  return response.data;
};

export const logout = async () => {
  const response = await axios({
    url: '/api/Auth/logout',
    method: 'GET',
  });
  return response.data;
};

export const check = async () => {
  const response = await axios({
    url: '/api/Auth',
    method: 'GET',
  });
  return response.data;
};

export const kakaoOauth = async (token) => {
  const response = await axios({
    method: 'post',
    url: '/api/OAuth/kakao',
    data: { token },
  });
  return response.data;
};

export const googleOauth = async (token) => {
  const response = await axios({
    method: 'post',
    url: '/api/OAuth/google',
    data: { token },
  });
  return response.data;
};

export const naverOauth = async (token) => {
  const response = await axios({
    method: 'post',
    url: '/api/OAuth/naver',
    data: { token },
  });
  return response.data;
};

export const setNickname = async ({ nickname }) => {
  const response = await axios({
    method: 'post',
    url: '/api/Oauth/nickname',
    data: { nickname },
  });
  return { ...response.data, nickname };
};

์ˆ˜์ • ์ฝ”๋“œ

import axios from 'axios';

export const signin = async ({ email, password }) => {
  const response = await axios.post('/api/Auth/login', { email, password });
  return response.data;
};

export const signup = async ({ email, password, nickname }) => {
  const response = await axios.post('/api/Auth/signup', { email, password, nickname });
  return response.data;
};

export const checkNickname = async ({ nickname }) => {
  const response = await axios.post('/api/Auth/nicknamecheck', { nickname });
  return response.data;
};

export const checkEmail = async ({ email }) => {
  const response = await axios.post('/api/Auth/emailcheck', { email });
  return response.data;
};

export const sendVerificationCode = async ({ email }) => {
  const response = await axios.post('/api/Auth/emailauth', { email });
  return response.data;
};

export const checkVerificationCode = async ({ email, auth }) => {
  const response = await axios.post('/api/Auth/authcheck', { email, auth });
  return response.data;
};

export const logout = async () => {
  const response = await axios.get('/api/Auth/logout');
  return response.data;
};

export const check = async () => {
  const response = await axios.get('/api/Auth');
  return response.data;
};

export const kakaoOauth = async (token) => {
  const response = await axios.post('/api/OAuth/kakao', { token });
  return response.data;
};

export const googleOauth = async (token) => {
  const response = await axios.post('/api/OAuth/google', { token });
  return response.data;
};

export const naverOauth = async (token) => {
  const response = await axios.post('/api/OAuth/naver', { token });
  return response.data;
};

export const setNickname = async ({ nickname }) => {
  const response = await axios.post('/api/Oauth/nickname', { nickname });
  return response.data;
};

์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ์ž‘์„ฑ์‹œ ๋ผ์šฐํ„ฐ ๊ฒน์นจ

https://github.com/Jandy-SeoulTech/Jandy_Web_Front/blob/512e4a669d9645e6ea7fd75febcfabcc6dc865b7/src/routers/ChannelRouter.jsx#L23-L30

๋ผ์šฐํ„ฐ๊ฐ€ edit์ด๋ž€ ๋ฌธ์ž์—ด์„ ํฌ์ŠคํŠธid๋กœ ์ธ์‹ํ•ด์„œ exact๋ฅผ ๋ถ™ํ˜€๋„ ๋‘๊ฐœ ๋‹ค ๋ Œ๋”๋งํ•จ.
์ˆ˜์ • ํ˜น์€ ์‹ ๊ทœ ์ž‘์„ฑ ๋ชจ๋‘ writing์œผ๋กœ ํ†ต์ผํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ #71 ์—์„œ ํ•ด๊ฒฐํ•˜๊ฒ ์Œ.

ํฌ์ŠคํŒ…/์•„์นด์ด๋น™ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ทฐ ๊ตฌํ˜„

ํฌ์ŠคํŒ…/์•„์นด์ด๋น™ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๋ทฐ ๊ตฌํ˜„

  1. ์ฑ„๋„ / ์‚ฌ์šฉ์ž๋ณ„ ๊ตฌ๋ถ„
  2. ์ „์ฒด์ ์ธ ๋ทฐ ๋ ˆ์ด์•„์›ƒ์€ ์ฑ„๋„ ์žฌ๋Šฅ๊ณต์œ ์š”์ฒญ ๊ฒŒ์‹œ๋ฌผ / ๊ฒŒ์‹œ๊ธ€ ๋ ˆ์ด์•„์›ƒ์„ ๋”ฐ๋ผ๊ฐ€๋„๋ก ๋””์ž์ธ ์š”์ฒญ
  3. ๊ฐœ๋ฐœ ์‹œ ๋‹ค๋ฅธ ๋ทฐ ํŽ˜์ด์ง€์™€ ๊ฒน์น˜๋Š” ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์žˆ์„ ๊ฒฝ์šฐ ์บก์Šํ™” ๊ถŒ์žฅ

Login ๊ตฌํ˜„

์ฃผ์š” ๊ธฐ๋Šฅ

  • ์ด๋ฉ”์ผ ์ž…๋ ฅ
    • ์ด๋ฉ”์ผ ํ˜•์‹ ๊ฒ€์‚ฌ(์ •๊ทœํ‘œํ˜„์‹)
  • ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ
    • ๋น„๋ฐ€๋ฒˆํ˜ธ ํ˜•์‹ ๊ฒ€์‚ฌ(์ •๊ทœํ‘œํ˜„์‹, 8์ž ์ด์ƒ์˜ ์˜๋ฌธ ์ˆซ์ž ์กฐํ•ฉ)
  • ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€ ์ด๋™ ๋ฒ„ํŠผ

โœ”์™€์ด์–ด ํ”„๋ ˆ์ž„ ํ™•์ • ์ „ ๊นŒ์ง€ View ์ˆ˜์ • ์—ฌ์ง€ ์žˆ์Œ

Refactor: ํ”„๋กœํ•„ ์—…๋กœ๋“œ ๊ด€๋ จ ์ปดํฌ๋„ŒํŠธ, ๊ตฌ์กฐ ๋‹จ์ˆœํ™”

ํ…์ŠคํŠธ ํ•„๋“œ๋Š” ์—ฌ๋Ÿฌ ์ปดํฌ๋„ŒํŠธ์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
๊ทธ์ค‘์—์„œ๋„ ํŠนํžˆ ํ”„๋กœํ•„ ์—…๋กœ๋“œ, ์ฑ„๋„ ๋งŒ๋“ค๊ธฐ, ์ฑ„๋„ ์ˆ˜์ •ํ•˜๊ธฐ ํ”„๋กœํ•„ ์ˆ˜์ •ํ•˜๊ธฐ ๋“ฑ์—์„œ ์žฌ๋Šฅ ์ž…๋ ฅ, ์ž๊ธฐ์†Œ๊ฐœ, ์†Œ์†์ด ์žฌ์‚ฌ์šฉ๋˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
์ด์—๋”ฐ๋ผ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ์žฌ์‚ฌ์šฉํ•ฉ์œผ๋กœ์จ ์ƒํƒœ๊ด€๋ฆฌ ์ค‘๋ณต๋กœ์ง์„ ์ค„์—ฌ์ฃผ๊ณ  ๋ทฐ์˜ ์ฝ”๋“œ๋ฅผ ๋‹จ์ˆœํ™”์‹œํ‚ค๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์ด์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์ปดํฌ๋„ŒํŠธ, ํƒœ๊ทธ๋ฐ•์Šค ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ถ„๋ฆฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๊ฐ ๊ธ€ ๊ณต๊ฐ ๋ฒ„ํŠผ ๊ตฌํ˜„

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ์—์„œ ๊ณต๊ฐ ๋ฒ„ํŠผ์˜ ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„์•ˆ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค.

  1. api์—์„œ attention์„ ์“ฐ๋ฉด ๋  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.
  2. ๊ณต๊ฐ ์ƒํƒœ๋ฉด ๋‹ค์‹œ ํ•œ๋ฒˆ ๋ˆ„๋ฅผ๋•Œ noattention api ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋น„๊ณต๊ฐ ์ƒํƒœ๋กœ ๊ฐ€๋ฉด ๋ฉ๋‹ˆ๋‹ค.

๋‹‰๋„ค์ž„ ์ž…๋ ฅ ๊ทœ์น™

์ˆ˜์ • ๊ธฐ๋Šฅ

  • ๋‹‰๋„ค์ž„ ์ž…๋ ฅ ๊ทœ์น™์„ '10์ž ์ด๋‚ด'๋กœ ๋ช…์‹œ
  • ๋‹‰๋„ค์ž„ ์ž…๋ ฅ ๊ฐ’์„ ๊ฒ€์ฆํ•˜๋Š” ์ •๊ทœํ‘œํ˜„์‹ ์ˆ˜์ •

Redux-saga -> Redux-pender ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜

Redux-saga๋Š” ํ”„๋กœ์ ํŠธ ๊ทœ๋ชจ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์ž‘์„ฑํ•ด์•ผ ํ•˜๋Š” ์ฝ”๋“œ์˜ ์–‘์ด ๋งŽ๊ณ  ๊ทธ ๋™์ž‘์›๋ฆฌ๊ฐ€ ๊ทผ๋ณธ์ ์œผ๋กœ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ Redux-pender๋ฅผ ์ด์šฉํ•ด ์ „์—ญ ์ƒํƒœ๊ด€๋ฆฌ๋ฅผ ํ•˜๋ ค ํ•ฉ๋‹ˆ๋‹ค.

redux-saga ์˜ˆ์‹œ

import { createAction, handleActions } from 'redux-actions';
import createRequestSaga, {
  createRequestActionTypes,
} from '../lib/util/createRequestSaga';
import * as chatAPI from '../lib/api/chat';
import { call, put, takeLatest, throttle } from 'redux-saga/effects';

const INITIALIZE = 'chat/INITIALIZE';
const [
  GET_CHANNEL_MESSAGES,
  GET_CHANNEL_MESSAGES_SUCCESS,
  GET_CHANNEL_MESSAGES_FAILURE,
] = createRequestActionTypes('chat/GET_CHANNEL_MESSAGES');
const [
  SEND_CHANNEL_MESSAGE,
  SEND_CHANNEL_MESSAGE_SUCCESS,
  SEND_CHANNEL_MESSAGE_FAILURE,
] = createRequestActionTypes('chat/SEND_CHANNEL_MESSAGE');
const CONCAT_CHANNEL_MESSAGES = 'chat/CONCAT_CHANNEL_MESSAGES';
const [
  GET_ROOM_MESSAGES,
  GET_ROOM_MESSAGES_SUCCESS,
  GET_ROOM_MESSAGES_FAILURE,
] = createRequestActionTypes('chat/GET_ROOM_MESSAGES');
const [
  SEND_ROOM_MESSAGE,
  SEND_ROOM_MESSAGE_SUCCESS,
  SEND_ROOM_MESSAGE_FAILURE,
] = createRequestActionTypes('chat/SEND_ROOM_MESSAGE');
const [
  REPLY_ROOM_MESSAGE,
  REPLY_ROOM_MESSAGE_SUCCESS,
  REPLY_ROOM_MESSAGE_FAILURE,
] = createRequestActionTypes('chat/REPLY_ROOM_MESSAGE');
const CONCAT_ROOM_MESSAGES = 'chat/CONCAT_ROOM_MESSAGES';

export const initialize = createAction(INITIALIZE);
export const getChannelMessages = createAction(
  GET_CHANNEL_MESSAGES,
  ({ channelId, lastId }) => ({ channelId, lastId }),
);
export const sendChannelMessage = createAction(
  SEND_CHANNEL_MESSAGE,
  ({ channelId, content }) => ({ channelId, content }),
);
export const concatChannelMessages = createAction(
  CONCAT_CHANNEL_MESSAGES,
  (message) => message,
);
export const getRoomMessages = createAction(
  GET_ROOM_MESSAGES,
  ({ roomId, lastId }) => ({ roomId, lastId }),
);
export const sendRoomMessage = createAction(
  SEND_ROOM_MESSAGE,
  ({ roomId, content }) => ({ roomId, content }),
);
export const replyRoomMessage = createAction(
  REPLY_ROOM_MESSAGE,
  ({ roomId, answeredId, content }) => ({ roomId, answeredId, content }),
);
export const concatRoomMessages = createAction(
  CONCAT_ROOM_MESSAGES,
  (message) => message,
);

export function* getChannelMessagesSaga(action) {
  try {
    const response = yield call(chatAPI.getChannelMessages, action.payload);
    if (response.data.length > 0) {
      yield put({
        type: GET_CHANNEL_MESSAGES_SUCCESS,
        payload: response.data,
        meta: response,
      });
    }
  } catch (e) {
    yield put({
      type: GET_CHANNEL_MESSAGES_FAILURE,
      payload: e,
      error: true,
    });
  }
}

const sendChannelMessageSaga = createRequestSaga(
  SEND_CHANNEL_MESSAGE,
  chatAPI.sendChannelMessage,
);

export function* getRoomMessagesSaga(action) {
  try {
    const response = yield call(chatAPI.getRoomMessages, action.payload);
    if (response.data.length > 0) {
      yield put({
        type: GET_ROOM_MESSAGES_SUCCESS,
        payload: response.data,
        meta: response,
      });
    }
  } catch (e) {
    yield put({
      type: GET_ROOM_MESSAGES_FAILURE,
      payload: e,
      error: true,
    });
  }
}

const sendRoomMessageSaga = createRequestSaga(
  SEND_ROOM_MESSAGE,
  chatAPI.sendRoomMessage,
);
const sendReplyMessageSaga = createRequestSaga(
  REPLY_ROOM_MESSAGE,
  chatAPI.replyRoomMessage,
);

export function* chatSaga() {
  yield throttle(5000, GET_CHANNEL_MESSAGES, getChannelMessagesSaga);
  yield takeLatest(SEND_CHANNEL_MESSAGE, sendChannelMessageSaga);
  yield throttle(5000, GET_ROOM_MESSAGES, getRoomMessagesSaga);
  yield takeLatest(SEND_ROOM_MESSAGE, sendRoomMessageSaga);
  yield takeLatest(REPLY_ROOM_MESSAGE, sendReplyMessageSaga);
}

const initialState = {
  messages: [],
  lastId: null,
  error: null,
  success: null,
};

const chat = handleActions(
  {
    [GET_CHANNEL_MESSAGES_SUCCESS]: (state, { payload }) => ({
      ...state,
      messages: state.messages.concat(payload),
      lastId: payload[payload.length - 1].id,
    }),
    [GET_CHANNEL_MESSAGES_FAILURE]: (state, { payload: error }) => ({
      ...state,
      error,
    }),
    [CONCAT_CHANNEL_MESSAGES]: (state, { payload: message }) => ({
      ...state,
      messages: [message, ...state.messages],
    }),
    [GET_ROOM_MESSAGES_SUCCESS]: (state, { payload }) => ({
      ...state,
      messages: state.messages.concat(payload),
      lastId: payload[payload.length - 1].id,
    }),
    [GET_ROOM_MESSAGES_FAILURE]: (state, { payload: error }) => ({
      ...state,
      error,
    }),
    [CONCAT_ROOM_MESSAGES]: (state, { payload: message }) => ({
      ...state,
      messages: [message, ...state.messages],
    }),
    [SEND_CHANNEL_MESSAGE]: (state) => ({
      ...state,
      success: null,
    }),
    [SEND_CHANNEL_MESSAGE_SUCCESS]: (state) => ({
      ...state,
      success: true,
    }),
    [SEND_ROOM_MESSAGE]: (state) => ({
      ...state,
      success: null,
    }),
    [SEND_ROOM_MESSAGE_SUCCESS]: (state) => ({
      ...state,
      success: true,
    }),
    [REPLY_ROOM_MESSAGE]: (state) => ({
      ...state,
      success: null,
    }),
    [REPLY_ROOM_MESSAGE_SUCCESS]: (state) => ({
      ...state,
      success: true,
    }),
    [INITIALIZE]: () => initialState,
  },
  initialState,
);

export default chat;

redux-pender ์˜ˆ์‹œ

import { createAction, handleActions } from 'redux-actions';
import { Map, List, fromJS } from 'immutable';
import { pender } from 'redux-pender';
import * as WebAPI from 'lib/web-api';

// ์•ก์…˜ ํƒ€์ž…
const CREATE_MEMO = 'memo/CREATE_MEMO';
const GET_INITIAL_MEMO = 'memo/GET_INITIAL_MEMO';
const GET_RECENT_MEMO = 'memo/GET_RECENT_MEMO';
const UPDATE_MEMO = 'memo/UPDATE_MEMO';
const DELETE_MEMO = 'memo/DELETE_MEMO';
const GET_PREVIOUS_MEMO = 'memo/GET_PREVIOUS_MEMO';

// ์•ก์…˜ ์ƒ์„ฑ์ž
export const createMemo = createAction(CREATE_MEMO, WebAPI.createMemo) // { title, body }
export const getInitialMemo = createAction(GET_INITIAL_MEMO, WebAPI.getInitialMemo);
export const getRecentMemo = createAction(GET_RECENT_MEMO, WebAPI.getRecentMemo) // cursor
export const updateMemo = createAction(UPDATE_MEMO, WebAPI.updateMemo, payload => payload); // { id, memo: {title,body} }
export const deleteMemo = createAction(DELETE_MEMO, WebAPI.deleteMemo, payload => payload); // id
export const getPreviousMemo = createAction(GET_PREVIOUS_MEMO, WebAPI.getPreviousMemo); // endCursor

const initialState = Map({
    data: List()
});

export default handleActions({
    // ์ดˆ๊ธฐ ๋ฉ”๋ชจ ๋กœ๋”ฉ
    ...pender({
        type: GET_INITIAL_MEMO,
        onSuccess: (state, action) => state.set('data', fromJS(action.payload.data))
    }),
    // ์‹ ๊ทœ ๋ฉ”๋ชจ ๋กœ๋”ฉ
    ...pender({
        type: GET_RECENT_MEMO,
        onSuccess: (state, action) => {
            // ๋ฐ์ดํ„ฐ ๋ฆฌ์ŠคํŠธ์˜ ์•ž๋ถ€๋ถ„์— ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ™์—ฌ์ค€๋‹ค
            const data = state.get('data');
            return state.set('data', fromJS(action.payload.data).concat(data))
        }
    }),
    ...pender({
        type: UPDATE_MEMO,
        onSuccess: (state, action) => {
            const { id, memo: { title, body } } = action.meta;
            const index = state.get('data').findIndex(memo => memo.get('id') === id);
            return state.updateIn(['data', index], (memo) => memo.merge({
                title,
                body
            }))
        }
    }),
    // ๋ฉ”๋ชจ ์‚ญ์ œ
    ...pender({
        type: DELETE_MEMO,
        onSuccess: (state, action) => {
            const id = action.meta;
            const index = state.get('data').findIndex(memo => memo.get('id') === id);
            return state.deleteIn(['data', index]);
        }
    }),
    ...pender({
        type: GET_PREVIOUS_MEMO,
        onSuccess: (state, action) => {
            // ๋ฐ์ดํ„ฐ ๋ฆฌ์ŠคํŠธ์˜ ๋’ท๋ถ€๋ถ„์— ์ƒˆ ๋ฐ์ดํ„ฐ๋ฅผ ๋ถ™์—ฌ์ค€๋‹ค
            const data = state.get('data');
            return state.set('data', data.concat(fromJS(action.payload.data)))
        }
    })
}, initialState);

pender๋ฅผ ์ด์šฉํ•ธ ๋ชจ๋“ˆ์˜ ์ฝ”๋“œ๋ฅผ ์ž์„ธํžˆ ๋ณด๋ฉด, ์•ก์…˜ํƒ€์ž…์„ ๊ฐ„๋‹จํžˆ ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ๊ณ , sagaํ•จ์ˆ˜์™€ ์•ก์…˜ ์ƒ์„ฑํ•จ์ˆ˜๋ฅผ ๋ณต์žกํ•˜๊ฒŒ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค.
๊ทธ๋ฆฌ๊ณ  ๋ฆฌ๋“€์„œ์—์„œ ํƒ€์ž…๋ณ„๋กœ ์ƒํƒœ ์—…๋ฐ์ดํŠธ๋ฅผ ๊ด€๋ฆฌํ•ด์ค„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์•ก์…˜์ด ๋งŽ์•„์ €๋„ ๋ฆฌ๋“€์„œ๊ฐ€ ๋ณด๊ธฐ ํŽธํ•ด์ง‘๋‹ˆ๋‹ค.

OAuth ๋กœ๊ทธ์ธ ๊ตฌํ˜„

๊ธฐ๋Šฅ : ์†Œ์…œ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ, ๋ฒ„ํŠผ ํด๋ฆญ ์‹œ OAuh ์ง„ํ–‰

  • Kakao OAuth
  • Google OAuth
  • Naver OAuth

๊ณผ์ • :

  1. ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๊ธฐ๊ด€์—์„œ Access token์„ ๋ฐ›์•„์˜ด
  2. Access Token์„ ๋ฐฑ์— ์ „๋‹ฌํ•จ
  3. ๋ฐฑ์—์„œ ์ธ์ฆ ๋กœ์ง ์ฒ˜๋ฆฌ

์ฑ„๋„ ํ™ˆ ํŽ˜์ด์ง€ ์ฝ˜ํ…์ธ  ์—†๋Š” ๊ฒฝ์šฐ ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ

๋‚ด์šฉ

์ฑ„๋„ ํ™ˆ ํŽ˜์ด์ง€ ๋‚ด์— ์ฝ˜ํ…์ธ ๊ฐ€ ์—†๋Š” ํŒŒํŠธ์— ์ฝ˜ํ…์ธ ๊ฐ€ ์—†๋‹ค๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ํ‘œ์‹œํ•œ๋‹ค.

  • ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ
  • ์˜คํ”ˆ๋œ ์ฑ„ํŒ…๋ฐฉ

ํ—ค๋” ๋””์ž์ธ ์ˆ˜์ •

  • ๋กœ๊ณ  ์œ„์น˜ ์ˆ˜์ •
  • Navigation ์œ„์น˜ ์ˆ˜์ •
  • ๊ฒ€์ƒ‰ ํ•„๋“œ ์‚ฌ์ด์ฆˆ ์กฐ์ •
  • ์•Œ๋ฆผ ๋ฒ„ํŠผ -> ์•Œ๋ฆผ ํŽ˜์ด์ง€๋กœ ์ด๋™
  • ํ”„๋กœํ•„ ๋ฒ„ํŠผ์œผ๋กœ ๋ฉ”๋‰ด popper๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ
  • ๋กœ๊ทธ์ธ, ๋น„๋กœ๊ทธ์ธ ์ƒํƒœ ๊ตฌ๋ถ„
  • ์ „์ฒด์ ์ธ ํ—ค๋” ๋””์ž์ธ ์ˆ˜์ •

Feat: ์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๋ชฉ๋ก ํŽ˜์ด์ง€ ๊ธฐ๋Šฅ ๋ณ€๊ฒฝ

๊ฐœ๋ฐœ์‚ฌํ•ญ

  • ์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๋ชฉ๋ก ํŽ˜์ด์ง€์— post status์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ๋ณด์—ฌ์ง€๋Š” ๋กœ์ง ์ถ”๊ฐ€
  • ์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๋ชฉ๋ก ํŽ˜์ด์ง€์— ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ถ”๊ฐ€

์„ธ๋ถ€์‚ฌํ•ญ

post status์— ๋”ฐ๋ผ ๋ฌถ์–ด๋ณด๊ธฐ

  • ํ”ผ๊ทธ๋งˆ ๋””์ž์ธ ์™€ํ”„ ๋ณด์‹œ๋ฉด ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๋ชฉ๋ก ํŽ˜์ด์ง€์—์„œ ์ „์ฒด, ์ฑ„ํŒ… ์˜คํ”ˆ, ์ฑ„ํŒ… ์˜ˆ์•ฝ, ์ฑ„ํŒ… ๋Œ€๊ธฐ, ํ•ด๊ฒฐ ์™„๋ฃŒ ์ด๋ ‡๊ฒŒ 5๊ฐ€์ง€ ์ƒํƒœ๋กœ ๋ฌถ์–ด์„œ ๋ณผ ์ˆ˜ ์žˆ๊ฒŒ ๋ฐ”๋€Œ์—ˆ์Šต๋‹ˆ๋‹ค.
  • GET /api/Post/channel/:channelId?type=&page=&pageSize= ์ฟผ๋ฆฌ ์ค‘ type์— ์ƒํƒœ๋ฅผ ๋„ฃ์œผ๋ฉด ๋˜๊ณ , ๊ฐ’์€ enum[All, Open, Reservation, Close, Archived] ์ž…๋‹ˆ๋‹ค.
  • ์ „์ฒด ํƒญ์—์„œ๋Š” ๊ณต์ง€๊ฐ€ ๋งจ์œ„๋กœ ์˜ฌ๋ผ์˜ค๊ณ , ๊ทธ์™ธ ๋‚˜๋จธ์ง€ ๊ธ€๋“ค์ด ์‹œ๊ฐ„ ์ˆœ์œผ๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค. (์„œ๋ฒ„์—์„œ ์ฃผ๋Š” ๋ฐ์ดํ„ฐ๋„ ํ•ด๋‹น ์ˆœ์„œ๋กœ ์ •๋ ฌ๋˜์–ด์žˆ๋Š” ๋ฆฌ์ŠคํŠธ์ž„)
  • ์ „์ฒด๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ํƒญ์—์„œ๋Š” ํ•ด๋‹นํ•˜๋Š” status์˜ ๊ธ€๋“ค์ด ์‹œ๊ฐ„์ˆœ์œผ๋กœ ์ •๋ ฌ๋ฉ๋‹ˆ๋‹ค.(์„œ๋ฒ„์—์„œ ์ฃผ๋Š”๋ฐ์ดํ„ฐ๋„ ์ •๋ ฌ๋จ)

ํŽ˜์ด์ง€๋„ค์ด์…˜ ์ถ”๊ฐ€

  • GET /api/Post/channel/:channelId?type=&page=&pageSize= ์—์„œ page๋Š” ํ˜„์žฌ ๋ณผ ํŽ˜์ด์ง€, pageSize๋Š” ๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ๋ณด๋Š” ๊ฐฏ์ˆ˜์ž…๋‹ˆ๋‹ค.
  • type=All ์ธ ๊ฒฝ์šฐ pageSize์— Notice ์ƒํƒœ์˜ ๊ธ€(๊ณต์ง€) ๊ฐฏ์ˆ˜๋Š” ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ณต์ง€์ธ ๊ธ€์˜ ๊ฐฏ์ˆ˜๊ฐ€ 3๊ฐœ๊ณ  pageSize = 10์ด๋ฉด, ํ•œ ์š”์ฒญ์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๊ธ€ ๊ฐฏ์ˆ˜๋Š” ์ด 13๊ฐœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

์ถ”๊ฐ€์‚ฌํ•ญ

Jandy-SeoulTech/Jandy_Web_Back#87
https://documenter.getpostman.com/view/14901542/Tzz7Pdio#603a01b6-91a2-44b3-9c3c-35f3bbda7f7e

์ฑ„๋„ ์žฌ๋Šฅ๊ณต์œ ์š”์ฒญ ๊ฒŒ์‹œ๋ฌผ<->์ฑ„ํŒ…๋ฐฉ ์—ฐ๋™

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๊ฒŒ์‹œ๋ฌผ์€ ์ƒํƒœ์— ๋”ฐ๋ผ

  1. ์•ˆ์—ด๋ฆผ ์ƒํƒœ : ์ฑ„ํŒ…๋ฐฉ ๋งŒ๋“ค๊ธฐ ๋ฒ„ํŠผ -> ์ฑ„ํŒ…๋ฐฉ ๋งŒ๋“ค๊ธฐ ๋ชจ๋‹ฌ ๋„์šด ํ›„ ์ฑ„ํŒ…๋ฐฉ ๋งŒ๋“ค๊ธฐ
  2. ์—ด๋ฆผ ์˜ˆ์•ฝ ์ƒํƒœ
  3. ์—ด๋ฆผ ์ƒํƒœ : ์ฑ„ํŒ…๋ฐฉ ๋ฐ”๋กœ๊ฐ€๊ธฐ ๋ฒ„ํŠผ -> ํ•ด๋‹นํ•˜๋Š” ์ฑ„ํŒ…๋ฐฉ ์ฐฝ ๋„์›€

์ด ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
๊ฒŒ์‹œ๋ฌผ๊ณผ ์ฑ„ํŒ…๋ฐฉ ๊ฐ„ ์—ฐ๋™์ด ์•ˆ๋˜์–ด์žˆ์œผ๋ฏ€๋กœ ๊ฐœ๋ฐœ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ ๋Œ“๊ธ€ ๊ธฐ๋Šฅ

์ฑ„๋„ ์žฌ๋Šฅ ๊ณต์œ  ์š”์ฒญ์—์„œ ๋Œ“๊ธ€ ์ž‘์„ฑ ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.

  1. ๋Œ“๊ธ€์€ ๋กœ๊ทธ์ธ/์ฑ„๋„๋ฉค๋ฒ„๋งŒ ๋‹ฌ ์ˆ˜ ์žˆ์Œ
  2. ๋Œ“๊ธ€์€ ์ž‘์„ฑ์ž๋งŒ ์ˆ˜์ •, ์‚ญ์ œ ๊ฐ€๋Šฅ

์œ ์ € ํ”„๋กœํ•„ ํŽ˜์ด์ง€ ๋ฐ์ดํ„ฐ ์—ฐ๋™

๋‚ด์šฉ

์œ ์ € ํ”„๋กœํ•„ ํŽ˜์ด์ง€์—์„œ ์„œ๋ฒ„์ธก API ๊ณ ์ • ์‘๋‹ต ๋˜๋Š” ํด๋ผ์ด์–ธํŠธ์—์„œ ์ž„์‹œ๋กœ ๊ตฌํ˜„ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ ๋ฐ์ดํ„ฐ๋กœ ๊ต์ฒดํ•˜๋Š” ์ž‘์—…์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ์˜คํ”ˆ ์ฑ„๋„
  • ์ฐธ์—ฌ ์ฑ„๋„

Request: ๋ธŒ๋žœ์น˜ ์ •๋ฆฌ

๋จธ์ง€๋œ ๋ธŒ๋žœ์น˜ ์ •๋ฆฌ ํ•„์š”ํ•จ.
์ถ”๊ฐ€๋กœ, ์ปค๋ฐ‹๊ธฐ๋ก ๊ผฌ์—ฌ์žˆ์œผ๋ฏ€๋กœ deploy ๋ธŒ๋žœ์น˜๋ž‘ main ๋ธŒ๋žœ์น˜๋ž‘ ๋จธ์ง€ํ•„์š”.

์žฌ๋Šฅ ์ฐพ๊ธฐ(๊ฒ€์ƒ‰) ๊ตฌํ˜„

๊ฐœ๋ฐœ ๊ธฐ๋Šฅ

  • ๊ฒ€์ƒ‰ ํŽ˜์ด์ง€ ๋ทฐ ์ž‘์„ฑ
  • ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ์ฑ„๋„ ๊ฒ€์ƒ‰
    • ์œ ์ € ๊ฒ€์ƒ‰
    • ๊ธ€(์•„์นด์ด๋ธŒ) ๊ฒ€์ƒ‰
  • ์นดํ…Œ๊ณ ๋ฆฌ ํ•„ํ„ฐ๋ง ๊ฒ€์ƒ‰ ๊ตฌํ˜„
  • ํŽ˜์ด์ง€๋„ค์ด์…˜ ๊ตฌํ˜„

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.