Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 스택 검색 기능 구현 #168

Merged
merged 31 commits into from
May 1, 2024
Merged

feat: 스택 검색 기능 구현 #168

merged 31 commits into from
May 1, 2024

Conversation

SungHyun627
Copy link
Collaborator

@SungHyun627 SungHyun627 commented Apr 21, 2024

Closes #158

💡 다음 이슈를 해결했어요.

  • 스택 검색 기능 구현
  • 수정된 모달 컴포넌트 디자인을 반영하여, 반응형 구현
  • MyStudyCard 컴포넌트 리팩토링 및 반응형 구현

💡 이슈를 처리하면서 추가된 코드가 있어요.

🛠 스택 검색 기능 구현

✔︎ useDebounce hook을 사용한 검색기능 구현

추후에 검색을 통한 스택 api 호출이 이뤄질 것을 고려하여, useDebounce 커스텀 훅을 통해 검색기능을 구현하였습니다.

📓 useDebounce Hook

//hooks/useDebounce.ts
import { useEffect, useState } from 'react';

const DEFAULT_DELAY = 500;

const useDebounce = <T>(value: T, delay: number = DEFAULT_DELAY) => {
  const [debouncedValue, setDebounceValue] = useState(value);

  useEffect(() => {
    const timer: NodeJS.Timeout = setTimeout(() => {
      setDebounceValue(value);
    }, delay);
    return () => {
      clearTimeout(timer);
    };
  }, [value, delay]);

  return debouncedValue;
};

export default useDebounce;

📓 StackModal에 적용

//src/Components/Modal/StackModal

export const StackModal = ({ handleModal, initialSelectedStacks, handleSelectedStacks }: StackModalProps) => {
   ...
  const [keyword, setKeyword] = useState<string>('');
  const deBouncedKeyword = useDebounce(keyword);
  .....
  const filteredStacks = getFilteredStacks(stacksSortedByCategory, selectedCategory, deBouncedKeyword);

  return (
    <StackModalWrapper ref={stackModalRef}>
      <ModalContentWrapper>
         .....
        <SearchInputWrapper>
          <InputText placeholder="기술 스택" icon={<Search />} onChange={(e) => setKeyword(e.target.value)} />
        </SearchInputWrapper>
      ....
  );
};

✔︎ 선택된 스택을 계산하는 로직 분리(getFilteredStacks)

return 내부에 있던 선택된 스택을 계산하는 로직을 컴포넌트 밖으로 분리하였습니다. 또한 카테고리 및 검색어로 필터링 된 스택을
이름 순으로 정렬하여 반환해도록 구현하였습니다.

const getFilteredStacks = (
  stacksByCategory: { id: number; name: StackCategory; stacks: Stack[] }[],
  selectedCategory: StackCategory,
  deBouncedKeyword: string,
) => {
  let filteredStacks: Stack[] = [];
  stacksByCategory
    ?.filter(
      (stacksByCategory: { id: number; name: StackCategory; stacks: Stack[] }) =>
        selectedCategory === null || STACK_CATEGORY[selectedCategory] === stacksByCategory.id,
    )
    .map((stacksByCategory: { id: number; name: StackCategory; stacks: Stack[] }) => {
      filteredStacks = [
        ...filteredStacks,
        ...stacksByCategory.stacks.filter(
          (stack: Stack) =>
            deBouncedKeyword.length === 0 || stack.name.toLowerCase().includes(deBouncedKeyword.toLowerCase()),
        ),
      ];
    });
  filteredStacks.sort((a, b) => (a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1));
  return filteredStacks;
};

✔︎ 반응형 stack Modal 구현

피그마 디자인 + TechStack 컴포넌트의 너비를 고려하여 Stack Modal을 반응형으로 구현하였습니다.

🎬 Stack Modal 반응형

✔︎ MyStudyCard 컴포넌트 리팩토링 및 반응형 구현

마이페이지에서 사용하는 MyStudyCard 컴포넌트에서 참여/진행 완료된 스터디와 지원한 스터디의 디자인 수정사항을 반영하기 위해, 리팩토링하는 과정을 진행하였습니다. 이 때 해당 컴포넌트의 props로 전달 되는 status를 통해 지원한 스터디를 나타내는 컴포넌트인지
계산한 후, 그에 맞는 Styling 작업을 진행하였습니다.

//src/Components/MyStudyCard
export const MyStudyCard = ({
  ...
}: MyStudyCardProps) => {
  ...
  const isApplyStatus = status === 'UNCHECKED' || status === 'REFUSED' || status === 'ACCEPTED';

  return (
    <MyStudyCardWrapper
      onClick={() => {
        navigate(`/studies/${id}${isApplyStatus ? '/recruitment' : ''}`);
      }}
      isApplyStatus={isApplyStatus}
    >
      {!isApplyStatus && <StudyThumbnail width="244px" height="100%" />}

      <StudyInfoWrapper status={status} hasRecruitment={hasRecruitment} isOwner={isOwner} isApplyStatus={isApplyStatus}>
          .....
        <MyStudyCardButtonsWrapper isApplyStatus={isApplyStatus}>
               ......
        </MyStudyCardButtonsWrapper>
      </StudyInfoWrapper>
    </MyStudyCardWrapper>
  );
};

🎬 참여/완료중인 스터디를 나타내는 MyStudyCard 컴포넌트, 반응형

image

image

🎬 지원중인 스터디를 나타내는 MyStudyCard 컴포넌트, 반응형

image

image

💡 필요한 후속작업이 있어요.

  • 추가 기능이 마이페이지에 도입이 되면 수정될 디자인 부분이 많을 것 같아서, 우선적으로 MyStudyCard 컴포넌트의 반응형만 잡았습니다.추후 구현할 기능 구현과 함께 반응형 작업 마무리하겠습니다.

💡 다음 자료를 참고하면 좋아요.

✅ 셀프 체크리스트

  • 브랜치 전략에 맞는 브랜치에 PR을 올리고 있습니다. (master/main이 아닙니다.)
  • 커밋 메세지를 컨벤션에 맞추었습니다.
  • 변경 후 코드는 컴파일러/브라우저 warning/error 가 발생시키지 않습니다.
  • 변경 후 코드는 기존의 테스트를 통과합니다.
  • 테스트 추가가 필요한지 검토해보았고, 필요한 경우 테스트를 추가했습니다.
  • docs 수정이 필요한지 검토해보았고, 필요한 경우 docs를 수정했습니다.

@SungHyun627 SungHyun627 marked this pull request as ready for review April 24, 2024 09:56
@SungHyun627 SungHyun627 marked this pull request as draft April 24, 2024 12:41
@SungHyun627 SungHyun627 marked this pull request as ready for review April 29, 2024 21:51
@abiriadev
Copy link
Member

abiriadev commented Apr 30, 2024

@SungHyun627
image

폼 페이지들에서 스택 모달이 흰색 배경하고 살짝 구분이 어려운 문제가 있다고 느꼈는데

  1. box-shadow
  2. border
  3. backdrop

등을 추가해서 모달을 구분시켜보는 건 어떻게 생각하시나요?

@SungHyun627
Copy link
Collaborator Author

SungHyun627 commented Apr 30, 2024

@SungHyun627 image

폼 페이지들에서 스택 모달이 흰색 배경하고 살짝 구분이 어려운 문제가 있다고 느꼈는데

  1. box-shadow
  2. border
  3. backdrop

등을 추가해서 모달을 구분시켜보는 건 어떻게 생각하시나요?

@abiriadev

동의합니다. 사실 backdrop이 가장 깔끔할 것 같기는 한데, 코드 수정이 많이 필요할 것 같아서, shadow로 처리하면 좋을 것 같습니다. 이 부분은 포키님과도 이야기가 필요할 듯 하네요. 현재 border는 border: 1px solid ${({ theme }) => theme.color.black1}; 다음과 같이 설정되어 있는데, 색이 연해서 잘 티가 안나는 것 같습니다ㅠㅠ

✔︎ box-shadow 적용 안시켰을 때

image

✔︎ box-shadow: 0px 0px 10px 0px ${(props) => props.theme.color.black1} 적용 시

image

@abiriadev
Copy link
Member

이 부분은 포키님과도 이야기가 필요할 듯 하네요.

오늘 회의 때에도 잠시 시간 나시면 이것 관련해서 얘기해 보셔도 좋을 것 같습니다!

src/Assets/index.tsx Show resolved Hide resolved
Copy link
Member

@abiriadev abiriadev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

수고하셨습니다! 👍

@SungHyun627 SungHyun627 merged commit 5c2c0c6 into dev May 1, 2024
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

스택 모달에서 원하는 스택을 검색하는 기능
3 participants