[Project] Pre-onboarding: Sir.Loin

nibooยท2022๋…„ 4์›” 19์ผ
0

Project

๋ชฉ๋ก ๋ณด๊ธฐ
7/7

๐Ÿƒ๐Ÿปโ€โ™€๏ธ ํ”„๋กœ์ ํŠธ ๊ธฐ๊ฐ„ ๋ฐ ์ธ์›

๐Ÿ“† 2022๋…„ 1์›” 27์ผ ~ 1์›” 29์ผ / Front-end 4๋ช…

๐Ÿ‘€ Repository

๋ฐฐํฌ์ฃผ์†Œ
๊นƒํ—™์ฃผ์†Œ

๐Ÿ• ๊ธฐ์ˆ  ์Šคํ…

Front-end

  • React
  • Styled-components

Common

  • Git
  • Slack

โœ๏ธ ๊ณผ์ œ ๊ฐœ์š”

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

๐Ÿ’ป ๊ณผ์ œ ๊ตฌํ˜„ ๋ชฉ๋ก

๋…ธ์ถœ ๋ฐ ํŒ๋งค๊ธฐ๊ฐ„ ์„ค์ •

  • Material-UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ™œ์šฉํ•˜์—ฌ ๋‹ฌ๋ ฅ ๋ฐ ์‹œ๊ฐ„ ์ง€์ • ์ปดํฌ๋„ŒํŠธ.
  • ์„ค์ •ํ•œ ๊ธฐ๊ฐ„์ด ๋งŒ๋ฃŒ๋˜์—ˆ์„ ๊ฒฝ์šฐ, ์ž๋™์œผ๋กœ state ๋ณ€๊ฒฝ๋˜๋Š” ๊ธฐ๋Šฅ.
  • ์„ค์ •ํ•œ ๊ธฐ๊ฐ„๋‚ด ๋‚ ์งœ ์„ ํƒ ๋น„ํ™œ์„ฑํ™” ๊ธฐ๋Šฅ.
  • ํ•œ ๋ฒ„ํŠผ์ด ํ™œ์„ฑํ™”๋˜๋ฉด ๋‹ค๋ฅธ ๋ฒ„ํŠผ์ด ๋น„ํ™œ์„ฑํ™”๋˜๋Š” ๊ธฐ๋Šฅ.

์ƒํ’ˆ ๊ธฐ๋ณธ ์ •๋ณด(๋ณธ์ธ ๋‹ด๋‹น)

  • ์ฒดํฌ๋ฐ•์Šค ์„ ํƒ ๋ฐ ํ•ด์ œ๋ฅผ ํ†ตํ•ด ์ƒํ’ˆ์— ์นดํ…Œ๊ณ ๋ฆฌ ์ง€์ • ๋ฐ ํ•ด์ œ ๊ธฐ๋Šฅ.
  • ์ธ๋„ค์ผ ์ด๋ฏธ์ง€ ํ•˜๋‚˜์˜ ์ด๋ฏธ์ง€๋งŒ ์—…๋กœ๋“œ ๊ฐ€๋Šฅ.
  • ์ƒํ’ˆ๋ช… ์„ ํƒ์‹œ ํ•ด๋‹น ์ƒํ’ˆ์ฝ”๋“œ ํ™”๋ฉด ์ถœ๋ ฅ.

์ƒํ’ˆ ์˜ต์…˜

  • ์ถ”๊ฐ€ ๋ฐ ์‚ญ์ œ ๋ฒ„ํŠผ ๋ˆŒ๋ €์„ ๋•Œ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ์ถ”๊ฐ€๋กœ ์ƒ์„ฑ ๋ฐ ์‚ญ์ œ๋˜๋Š” ๊ธฐ๋Šฅ.

์ƒํ’ˆ ์†Œ๊ฐœ์ด๋ฏธ์ง€, ๊ตฌ๋งค์ž ์ถ”์ฒœ ์ด๋ฏธ์ง€

  • ์‚ฌ์šฉ์ž์—๊ฒŒ ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ ์˜์—ญ ์ œ๊ณต ๋ฐ ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€ ํŒŒ์ผ๋ช… ๋…ธ์ถœ ๊ธฐ๋Šฅ.
  • ์—…๋กœ๋“œ๋œ ์ด๋ฏธ์ง€ ์‚ญ์ œ ๋ฒ„ํŠผ์„ ํ†ตํ•ด ์—…๋กœ๋“œ ์ƒํƒœ์—์„œ ์‚ญ์ œ.

์ƒํ’ˆ ๋ฐฐ์†ก ์„ค์ •

  • ์ปค์Šคํ…€ ํ† ๊ธ€ ๋ฒ„ํŠผ

์ƒํ’ˆ ํ˜œ์ฑ… ํ—ˆ์šฉ ์„ค์ •, ๊ธฐํƒ€ ์„ค์ •

  • ์ปค์Šคํ…€ ํ† ๊ธ€ ๋ฒ„ํŠผ

๐Ÿ™‹๐Ÿปโ€โ™€๏ธ ๊ตฌํ˜„ ๋‚ด์šฉ

์นดํ…Œ๊ณ ๋ฆฌ ์ง€์ •

  • ์ฒดํฌ๋ฐ•์Šค ์„ ํƒ์„ ํ†ตํ•ด ํ•ด๋‹น ์ƒํ’ˆ์— ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Œ
  • '์ฒดํฌ๋ฐ•์Šค ์ง€์ • ํ•ด์ œ' ๋˜๋Š” ์นดํ…Œ๊ณ ๋ฆฌ X๋ฒ„ํŠผ์„ ํ†ตํ•ด ์นดํ…Œ๊ณ ๋ฆฌ ์ง€์ •์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Œ

์นดํ…Œ๊ณ ๋ฆฌ ๋ฆฌ์ŠคํŠธ์™€ ์ƒํ’ˆ๋ช… ์ƒ์ˆ˜๋ฐ์ดํ„ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

ํ•จ์ˆ˜ ์•ˆ์— ์žˆ์œผ๋ฉด ๋ฆฌ๋ Œ๋” ๋ ๋•Œ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ๊ฐ€ ๋ถˆ๋Ÿฌ์™€์ง€๋Š”๋ฐ, ์ƒ์ˆ˜๋ฐ์ดํ„ฐ๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š” ๋ฐ์ดํ„ฐ์ด๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ํ•˜๋ฉด์„œ ํ•จ์ˆ˜ ์•ˆ์— ์œ„์น˜์‹œํ‚ฌ ํ•„์š”๊ฐ€ ์—†๋‹ค.

const CATEGORY_LIST = [
  { id: 0, data: '๊ตฌ์ด์šฉ' },
  { id: 1, data: '์•ˆ์‹ฌ' },
  { id: 2, data: '๋“ฑ์‹ฌ' },
  { id: 3, data: '์ฑ„๋' },
  { id: 4, data: 'ํŠน์ˆ˜' },
  { id: 5, data: '์–‘๋…' },
  { id: 6, data: 'Bone' },
  { id: 7, data: '์„ ๋ฌผ์ œ์•ˆ' },
  { id: 8, data: '์ด๋ฒคํŠธ' },
  { id: 9, data: '์š”๋ฆฌ์šฉ' },
  { id: 10, data: '๋ฌด๋ฃŒ๋ฐฐ์†ก' },
  { id: 11, data: '์„ธํŠธ' },
];

์ฒดํฌ๋ฐ•์Šค, ์นดํ…Œ๊ณ ๋ฆฌ ์„ ํƒ ๋ฐ ํ•ด์ œ๋ฅผ ํ†ตํ•œ ์ƒํ’ˆ ๊ธฐ๋ณธ ์ •๋ณด ๋…ธ์ถœ

  • ์ž์„ธํ•œ ์„ค๋ช…์€ ์ฃผ์„์ฒ˜๋ฆฌ
function ProdBasicInfo() {
  
  // ์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ๊ฐ’์„ ๋ฐ”๊ฟ”์ฃผ๋Š” state. ์ดˆ๊ธฐ๊ฐ’์€ ๋นˆ๋ฐฐ์—ด.
  const [checkedList, setCheckedList] = useState([]);
 
  // onChange์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด์„œ checked(Boolean)๊ฐ’, item(value)๊ฐ’์„ ๋ฐ›์•„์˜จ๋‹ค.
  const onCheckedElement = (checked, item) => {
    // check๋˜์—ˆ์„๋•Œ check๋œ value๊ฐ’์„ ๋นˆ๋ฐฐ์—ด์ธ checkedList์— ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์ค€๋‹ค
    if (checked) {
      setCheckedList([...checkedList, item]);
    } 
   /* filterํ•จ์ˆ˜๋Š” ๋ฐ˜ํ™˜๊ฐ’์ด true์ธ๊ฒƒ๋งŒ ๊ตฌ์„ฑ๋œ ์ƒˆ๋กœ์šด ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    ํด๋ฆญ๋œ๊ฐ’์ด item์ด๊ณ  item์ด el๋ž‘ ๋‹ค๋ฅธ ๊ฒฝ์šฐ๊ฐ€ true, ์ฆ‰ ํด๋ฆญ๋œ ์š”์†Œ๊ฐ€ ๋น ์ง„ ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ž„. */
    else if (!checked) {
      setCheckedList(checkedList.filter(el => el !== item));
    }
  };
  
  /*์ฒดํฌ๋ฐ•์Šค๊ฐ€ ์•„๋‹Œ ์นดํ…Œ๊ณ ๋ฆฌ ๋ฐฐ๋„ˆ์˜ x๋ฅผ ํด๋ฆญํ–ˆ์„ ๋•Œ ํ•ด์ œ๋˜๋Š” ๊ธฐ๋Šฅ.
  ์œ„์—์žˆ๋Š” ์ฒดํฌ๋ฐ•์Šค ํ•ด์ œํ•˜๋Š” ์›๋ฆฌ์™€ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•จ!*/
  const onRemove = item => {
    setCheckedList(checkedList.filter(el => el !== item));
  };
  
return (
      <S.CategoryContainer>
        <S.SubTitle>์นดํ…Œ๊ณ ๋ฆฌ *</S.SubTitle>
        <S.SelectContainer>
          <S.CheckBox>
  // ์ƒ์ˆ˜๋ฐ์ดํ„ฐ ์นดํ…Œ๊ณ ๋ฆฌ ๋ฆฌ์ŠคํŠธ์— ๋งต์„ ํ™œ์šฉํ•˜์—ฌ ๋ Œ๋”๋ง ํ•จ
            {CATEGORY_LIST.map(item => {
              return (
             /* ๊ณ ์œ  key๊ฐ’ ๋ถ€์—ฌ. 
             ๋ฐฐ์—ด์„ ๋ Œ๋”๋ง ํ–ˆ์„ ๋•Œ key๊ฐ’์„ ํ†ตํ•ด ๋ฐฐ์—ด์˜ ์–ด๋–ค ์›์†Œ์— ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ๋Š”์ง€๋ฅผ ์•Œ์•„๋‚ธ๋‹ค.*/
                <S.Label key={item.id}>
  /*์—ฌ๊ธฐ์„œ Check๋Š” Inputํƒœ๊ทธ. type์„ ์ฒดํฌ๋ฐ•์Šค๋กœ ์ง€์ •ํ•˜๊ณ  
  value๊ฐ’์€ CATEGORT_LIST์˜ data๊ฐ’์œผ๋กœ ์ง€์ •*/
                  <S.Check
                    type="checkbox"
                    value={item.data}
// onChange์ด๋ฒคํŠธ๋ฅผ ํ†ตํ•ด ๋ณ€ํ™”๋ฅผ ๊ฐ์ง€ํ•˜๊ณ  onCheckedElementํ•จ์ˆ˜์— check์—ฌ๋ถ€์™€ check๋œ value๊ฐ’์„ ์ „๋‹ฌํ•ด์ค€๋‹ค.
                    onChange={e => {
                      onCheckedElement(e.target.checked, e.target.value);
                    }}
                    // ์„ ํƒ๋œ ์ƒํƒœ๋ฅผ ๋งํ•˜๋Š” ๊ฒƒ. checkeList์— ์š”์†Œ๊ฐ€ ์žˆ์œผ๋ฉด true, ์—†์œผ๋ฉด false.
                    checked={checkedList.includes(item.data) ? true : false}
                  />
// ์ฒดํฌ๋ฐ•์Šค ๋ฆฌ์ŠคํŠธ์— ์ถœ๋ ฅ๋  data๊ฐ’.
                  <S.Type>{item.data}</S.Type>
                </S.Label>
              );
            })}
          </S.CheckBox>
          <S.SelectedBox>
            /* ์นดํ…Œ๊ณ ๋ฆฌ๋ž€
           checkedList์˜ ๊ธธ์ด๊ฐ€ 0์ด๋ผ๋ฉด ๋นˆ๋ฐฐ์—ด์ด๋ž€ ๋œป์œผ๋กœ ๊ธฐ๋ณธ๊ฐ’์ด '์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ง€์ •ํ•ด ์ฃผ์„ธ์š”' ๋ฌธ๊ตฌ๋ฅผ ์ถœ๋ ฅํ•œ๋‹ค.*/
            {checkedList.length === 0 && (
              <S.AlertMessage>์นดํ…Œ๊ณ ๋ฆฌ๋ฅผ ์ง€์ •ํ•ด ์ฃผ์„ธ์š”.</S.AlertMessage>
            )}
            // ์„ ํƒ๋œ ๊ฐ’๋“ค์„ ๊ด€๋ฆฌํ•˜๋Š” ๊ฒƒ์ด๋ฏ€๋กœ checkedList์— map์„ ํ™œ์šฉํ•œ๋‹ค.
            {checkedList.map(item => {
              return (
                <S.SelectedCategory key={item}>
                  <S.Selected>{item}</S.Selected>
                  <S.CancelChecked onClick={() => onRemove(item)}>
                    X
                  </S.CancelChecked>
                </S.SelectedCategory>
              );
            })}
          </S.SelectedBox>
        </S.SelectContainer>
      </S.CategoryContainer>
 );
}

์ƒํ’ˆ๋ช… ์„ ํƒ ์‹œ ํ•ด๋‹น ์ƒํ’ˆ ์ฝ”๋“œ ํ™”๋ฉด์— ์ถœ๋ ฅ

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์ƒํ’ˆ ๋ฆฌ์ŠคํŠธ๋Š” ์ƒ์ˆ˜๋ฐ์ดํ„ฐ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ

const PRODUCT_DATA = [
  { id: null, value: '์ƒํ’ˆ์„ ์„ ํƒํ•˜์„ธ์š”.' },
  { id: '0001', value: '์•Œ๊ผฌ๋ฆฌ 300g' },
  { id: '0002', value: '๋ฏธ๋‹ˆ์ƒคํ†  150g' },
  { id: '0003', value: '์•ˆ์‹ฌ์ถ”๋ฆฌ 150g' },
  { id: '0004', value: '์•ˆ์‹ฌ์Šฌ๋ผ์ด์Šค 150g' },
  { id: '0005', value: '๋ฆฝ์•„์ด' },
  { id: '0006', value: '๋กœ์Šค ๋“ฑ์‹ฌ 200g' },
  { id: '0007', value: '๊ฝƒ๋“ฑ์‹ฌ 200g' },
  { id: '0008', value: '์ฑ„๋ ๋“ฑ์‹ฌ 200g' },
];

๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด์—์„œ ์„ ํƒ๋˜๋Š” ์ƒํ’ˆ์˜ ์ƒํ’ˆ์ฝ”๋“œ ๊ฐ€์ ธ์˜ค๊ธฐ & ์ถœ๋ ฅ

  • ์œ„์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ filterํ•จ์ˆ˜๋ฅผ ์จ์„œ ๋ฐ์ดํ„ฐ์— ์ ‘๊ทผํ•œ๋‹ค(์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ฃผ์„์œผ๋กœ ์ž‘์„ฑ)
function ProdBasicInfo() {
  
  // ์ƒํ’ˆ๋ช…, ์ƒํ’ˆ์ฝ”๋“œ ์ถœ๋ ฅ์„ ์œ„ํ•œ state
  const [selectedDropValue, setSelectedDropValue] =
    useState('์ƒํ’ˆ์„ ์„ ํƒํ•˜์„ธ์š”.');

const handleDropProduct = e => {
  // e.target.value. ๊ตฌ์กฐ๋ถ„ํ•ด๋กœ e.target์—์„œ ํƒ€๊ฒŸํŒ… ๋œ ์š”์†Œ์˜ value๋ฅผ ๊ฐ€์ ธ์˜ด. ์ฆ‰, ์„ ํƒ๋œ ์š”์†Œ!
    const { value } = e.target;
  // PRODUCT_DATA๋Š” id(์ƒํ’ˆ์ฝ”๋“œ)์™€ value(์ƒํ’ˆ๋ช…)๋กœ ๊ตฌ์„ฑ๋œ ๊ฐ์ฒด๋“ค๋กœ ๊ตฌ์„ฑ๋œ ๋ฐฐ์—ด. filterํ•จ์ˆ˜๋ฅผ ์จ์„œ ์„ ํƒ๋œ ์ƒํ’ˆ๋ช…๊ณผ PRODUCT_DATA ์— ์žˆ๋Š” ์ƒํ’ˆ๋ช…์ด ์ผ์น˜ํ•˜๋Š” ๋ฐฐ์—ด์„ ๋ฐ˜ํ™˜. ์ธ๋ฑ์Šค 0๊ณผ id๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฐฐ์—ด ์•ˆ์— ์žˆ๋Š” ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜์—ฌ id๊ฐ’์„ ์ถ”์ถœํ•œ๋‹ค. id๊ฐ’์ด ์ƒํ’ˆ์ฝ”๋“œ. ์ด id๊ฐ’์„ selectedDropValue์— ์—…๋ฐ์ดํŠธ.
    setSelectedDropValue(PRODUCT_DATA.filter(el => PRODUCT_DATA.filter(el => el.value === value)[0].id));
  };

return (
<S.ProductNameContainer>
        <S.SubTitle>์ƒํ’ˆ๋ช… *</S.SubTitle>
        <S.ProductBar>
  // selectํƒœ๊ทธ์™€ optionํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋“œ๋กญ๋‹ค์šด ๋ฉ”๋‰ด๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
          <S.ProductSearch onChange={handleDropProduct}>
            {PRODUCT_DATA.map(el => {
              return (
                <option key={el.id}>
                  {el.value}
                </option>
              );
            })}
          </S.ProductSearch>
        </S.ProductBar>
        <S.ProductCode>
          <S.Code>์ƒํ’ˆ ์ฝ”๋“œ</S.Code>
// ์ƒํ’ˆ์ฝ”๋“œ ์ถœ๋ ฅ
          <S.ShowingCode>{selectedDropValue}</S.ShowingCode>
        </S.ProductCode>
      </S.ProductNameContainer>
 );
}
profile
ํˆฌ๋ช…์ธ๊ฐ„

0๊ฐœ์˜ ๋Œ“๊ธ€