๐Ÿš€ Wanted Pre-Onboarding FE

โš™๏ธ ํ”„๋กœ์ ํŠธ ์‹คํ–‰ ๋ฐฉ๋ฒ•

1. git clone https://github.com/hjpark625/wanted-pre-onboarding-fe.git
2. cd wanted-pre-onboarding-fe
3. npm install
4. npm start

โŒจ๏ธ ์‚ฌ์šฉ ๊ธฐ์ˆ  ์Šคํƒ

react typescript styledComponents axios react-router-dom


๐ŸŽฅ ์‹œ์—ฐ์˜์ƒ

1๏ธโƒฃ ๋กœ๊ทธ์ธ ๋ฐ ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€

  1. ๋กœ๊ทธ์ธ ๋ฐ ํšŒ์›๊ฐ€์ž… ์˜์ƒ

    แ„…แ…ฉแ„€แ…ณแ„‹แ…ตแ†ซ แ„’แ…ฌแ„‹แ…ฏแ†ซแ„€แ…กแ„‹แ…ตแ†ธ(gif)

  2. ํ† ํฐ ์œ ๋ฌด์— ๋”ฐ๋ฅธ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œ์—ฐ์˜์ƒ

    แ„แ…ฉแ„แ…ณแ†ซ แ„…แ…ตแ„ƒแ…กแ„‹แ…ตแ„…แ…ฆแ†จแ„แ…ณ(gif)

2๏ธโƒฃ Todo ๋งŒ๋“ค๊ธฐ

  1. Todo CRUD ์‹œ์—ฐ์˜์ƒ

    Todo CRUD(gif)


๐Ÿ”ง ๊ตฌํ˜„ ๊ธฐ๋Šฅ

๊ตฌํ˜„ ํ•ด์•ผ ํ•  ํ•„์ˆ˜ ๊ธฐ๋Šฅ

  1. ๋กœ๊ทธ์ธ / ํšŒ์›๊ฐ€์ž…

    • '/' ๊ฒฝ๋กœ์— ๋กœ๊ทธ์ธ ๋ฐ ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ํŽ˜์ด์ง€ ์•ˆ์— ์ด๋ฉ”์ผ ์ž…๋ ฅ์ฐฝ, ๋น„๋ฐ€๋ฒˆํ˜ธ ์ž…๋ ฅ์ฐฝ, ์ œ์ถœ ๋ฒ„ํŠผ์ด ํฌํ•จ๋œ ํ˜•ํƒœ ๊ตฌ์„ฑ
    • ์ด๋ฉ”์ผ ๋ฐ ๋น„๋ฐ€๋ฒˆํ˜ธ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ ๊ธฐ๋Šฅ ๊ตฌํ˜„
      • ์ด๋ฉ”์ผ: @ํฌํ•จ
      • ๋น„๋ฐ€๋ฒˆํ˜ธ: 8์ž ์ด์ƒ
      • ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์œ„ ์กฐ๊ฑด์„ ๊ฐ–์ท„์„ ๋•Œ ํ™œ์„ฑํ™”
    • ๋กœ๊ทธ์ธ APIํ˜ธ์ถœ ํ›„ ์˜ฌ๋ฐ”๋ฅธ ์‘๋‹ต์„ ๋ฐ›์„ ๋•Œ /todo๊ฒฝ๋กœ๋กœ ์ด๋™
      • ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ JWT๋ฅผ ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ
    • ๋กœ๊ทธ์ธ ์—ฌ๋ถ€์— ๋”ฐ๋ฅธ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ๊ตฌํ˜„
      • ํ† ํฐ์ด ์žˆ์„ ๋•Œ /ํŽ˜์ด์ง€์— ์ ‘์†์‹œ /todo๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
      • ํ† ํฐ์ด ์—†์„ ๋•Œ /todoํŽ˜์ด์ง€์— ์ ‘์†์‹œ /๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ
  2. Todo List

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

1๏ธโƒฃ ๋กœ๊ทธ์ธ / ํšŒ์›๊ฐ€์ž…

  1. ํšŒ์›๊ฐ€์ž… ํŽ˜์ด์ง€

    • ํšŒ์›๊ฐ€์ž… ์‹œ ์ด๋ฉ”์ผ๊ณผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ž…๋ ฅํ•  ๋•Œ ๊ฒฝ๊ณ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜์—ฌ ์œ ์ €๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ๋„
      • ์กฐ๊ฑด์ด ๋ถˆ์ผ์น˜ ํ•  ๊ฒฝ์šฐ ์ œ์ถœ ๋ฒ„ํŠผ์ด ๋น„ํ™œ์„ฑํ™”
        • ๋ฒ„ํŠผ์— disabled์†์„ฑ ๋ถ€์—ฌ
        • cursor: not-allowed์™€ ๋ฒ„ํŠผ ๋ฐฐ๊ฒฝ์ƒ‰์„ ํšŒ์ƒ‰์œผ๋กœ ์„ธํŒ…
    • / ๋‹จ์ผ๊ฒฝ๋กœ ๋‚ด์— type์„ ์„ค์ •ํ•˜์—ฌ ํšŒ์›๊ฐ€์ž… ๋ฒ„ํŠผ๊ณผ ๋กœ๊ทธ์ธ ๋ฒ„ํŠผ์„ ๋ˆŒ๋ €์„ ๋•Œ ์กฐ๊ฑด๋ถ€ ๋ Œ๋”๋ง์„ ํ†ตํ•ด ๋ชฉ์ ์— ๋งž๋Š” ํŽ˜์ด์ง€ ๋ Œ๋”๋ง
  2. ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€

    • ํšŒ์›๊ฐ€์ž…๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๊ฒฝ๊ณ ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•ด ์œ ์ €๊ฐ€ ์˜ฌ๋ฐ”๋ฅธ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ๋„๋ก ์œ ๋„
      • ์กฐ๊ฑด๋ถˆ์ผ์น˜ ์‹œ ํšŒ์›๊ฐ€์ž…๊ณผ ๋™์ผํ•œ ์†์„ฑ ์ ์šฉ
    • ๋กœ๊ทธ์ธ ์„ฑ๊ณต ์‹œ /todoํŽ˜์ด์ง€๋กœ ์ด๋™

2๏ธโƒฃ ํ† ํฐ ์œ ๋ฌด์— ๋”ฐ๋ฅธ ํŽ˜์ด์ง€ ๋ฆฌ๋‹ค์ด๋ ‰ํŒ…

  1. ๋ Œ๋”๋ง์ด ๋˜๋Š” ํŽ˜์ด์ง€์ƒ์— ๋กœ์ปฌ์Šคํ† ๋ฆฌ์ง€์— ์ €์žฅ๋œ ํ† ํฐ์˜ ์œ ๋ฌด๋ฅผ ํŒ๋‹จํ•ด / ํ˜น์€ /todo๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŒ… ๊ตฌํ˜„

    // ํ† ํฐ์ด ์žˆ์„ ๋•Œ ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€ ์ ‘์† ์‹œ(main.tsx)
    const token = localStorage.getItem('access_token');
    
    const checkToken = () => {
      token && navigate('/todo');
    };
    
    useEffect(() => {
      checkToken();
    }, []);
    
    // ํ† ํฐ์ด ์—†์„ ๋•Œ todo ํŽ˜์ด์ง€ ์ ‘์† ์‹œ(todo.tsx)
    const token = localStorage.getItem('access_token');
    
    const checkToken = () => {
      !token && navigate('/');
    };
    
    useEffect(() => {
      checkToken();
    }, []);

3๏ธโƒฃ TODO CRUD

  1. Create(TodoInsert.tsx)

    • setTodoValue๋ฅผ ํ™œ์šฉํ•ด inputํƒœ๊ทธ์˜ ์ž…๋ ฅ๊ฐ’์„ ์ €์žฅ
    • ์ €์žฅํ•œ ์ž…๋ ฅ๊ฐ’์„ onSubmit ํ•จ์ˆ˜์— POST๋กœ API์š”์ฒญ๋ฌธ ์ž‘์„ฑ
      • async / await์„ ํ†ตํ•ด post์š”์ฒญ์ด ์™„๋ฃŒ๋˜๋ฉด ์ „์†ก์ด ์™„๋ฃŒ๋˜๋ฉด ์ƒˆ๋กญ๊ฒŒ ์ถ”๊ฐ€๋œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์‹œ GET์š”์ฒญ์œผ๋กœ ๋ฐ›์•„์˜ค๊ธฐ
    • GET์š”์ฒญ์œผ๋กœ ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ ํ†ตํ•ด ๋‹ค์‹œ ๋ Œ๋”๋ง ํ•˜๊ฒŒ๋” ๊ธฐ๋Šฅ ๊ตฌํ˜„
  2. Read(Todo.tsx & TodoList.tsx + TodoListItem.tsx)

    • Todo.tsx์— ์„œ๋ฒ„ ์š”์ฒญ ์‹œ ๋“ค์–ด์˜ค๋Š” todo ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ state ์„ค์ •
      • ํŽ˜์ด์ง€๊ฐ€ ๋‚˜ํƒ€๋‚  ๋•Œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์™€์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์— useEffect๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์ตœ์ดˆ ๋ Œ๋”๋ง ๋  ๋•Œ GET์š”์ฒญ์œผ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„ setTodo์— ์ €์žฅ
    • ์ €์žฅ๋œ todo๋ฐ์ดํ„ฐ๋ฅผ TodoList.tsx์— props๋กœ ์ „๋‹ฌ
      • ์ „๋‹ฌ๋ฐ›์€ ๋ฐ์ดํ„ฐ๋ฅผ map์„ ํ†ตํ•˜์—ฌ ๋ Œ๋”๋ง
    • TodoListItem.tsx์— ์ตœ์ข…์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๋“ค์„ ์ „๋‹ฌํ•˜์—ฌ ๋ Œ๋”๋ง
  3. Update(TodoListItem.tsx)

    • ์ˆ˜์ •๋ฒ„ํŠผ์„ ๊ฐ ๋ Œ๋”๋ง ๋˜๋Š” ๋ฐ์ดํ„ฐ ์šฐ์ธก์— ์ œ์ž‘ํ•˜์—ฌ ์ˆ˜์ •๋ฒ„ํŠผ ํด๋ฆญ์‹œ input์ฐฝ์ด ๋‚˜์˜ค๊ฒŒ๋” ๊ตฌํ˜„
      • ์ˆ˜์ •ํ•˜๋Š” ์‚ฌํ•ญ์ž„์„ ์•Œ๊ฒŒ ํ•˜๊ธฐ์œ„ํ•ด ์ˆ˜์ •๋ฒ„ํŠผ ํด๋ฆญ ์‹œ ํšŒ์ƒ‰์œผ๋กœ ๋ฐ”๋€Œ๊ณ  input์ฐฝ์˜ ๊ธ€์ž๊ฐ€ ํšŒ์ƒ‰์œผ๋กœ ๋ณ€๊ฒฝ
      • ์ˆ˜์ •์™„๋ฃŒ ์‹œ(enter๋ฅผ ์ณค์„ ๋•Œ) ๋ฐ”๋กœ PUT์š”์ฒญ์„ ๋ณด๋ƒ„
        • PUT์š”์ฒญ ์™„๋ฃŒ์‹œ Create๋•Œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ”๋€Œ๋Š” ๋ฐ์ดํ„ฐ๋ฅผ GET์š”์ฒญ์œผ๋กœ ๋ฐ›์•„์„œ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ฐ”๋€๋ฐ์ดํ„ฐ๋ฅผ ๋ Œ๋”๋ง
  4. Delete(TodoListItem.tsx)

    • ์‚ญ์ œ๋ฒ„ํŠผ๋„ ์ˆ˜์ •๋ฒ„ํŠผ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ๋ Œ๋”๋ง๋˜๋Š” ๋ฆฌ์ŠคํŠธ ์šฐ์ธก์— ๋ Œ๋”๋ง
    • ์‚ญ์ œ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ url์— ํ•ด๋‹น ์•„์ดํ…œ์˜ id๋ฅผ params์— ๋‹ด์•„ DELETE API์š”์ฒญ
      • ์š”์ฒญ ์„ฑ๊ณต ์‹œ ํ•ด๋‹น ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋˜๋ฉด ์‚ญ์ œ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๋ฐ์ดํ„ฐ๋ฅผ GET์š”์ฒญ์œผ๋กœ ๋ฐ›์•„์™€ ๋ Œ๋”๋ง ์‹ค์‹œ