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
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
258a8fa
style: 스택 모달의 특정 컴포넌트에만 hover 시, 마우스 cursor가 pointer로 보이도록 style 변경
SungHyun627 Apr 21, 2024
992d68c
style: ChipMenu 컴포넌트 hover 시 style 추가
SungHyun627 Apr 21, 2024
79ff176
fix: 모집공고 모아보기 페이지에서 사용되지 않는 코드 제거
SungHyun627 Apr 21, 2024
13615c4
refactor: 갱신된 InputText 컴포넌트 반영
hyosin-Jang Apr 20, 2024
99c5480
refactor: 스택 모달의 검색 컴포넌트를 InputText로 수정
SungHyun627 Apr 21, 2024
1105bf0
feat: useDebounce Custom Hook 구현
SungHyun627 Apr 21, 2024
0aabcb4
feat: useDebounce Hook을 활용하여 스택 검색 기능 구현
SungHyun627 Apr 21, 2024
b611f11
style: 수정된 modal style 및 반응형 구현
SungHyun627 Apr 21, 2024
13ec583
refactor: 스택을 필터링하는 로직 분리
SungHyun627 Apr 21, 2024
5051cd7
feat: 기술 스택을 알파벳 순으로 정렬
SungHyun627 Apr 21, 2024
b823a2f
refactor: useOutsideClick hook으로 modal 외부클릭 시 닫히는 로직 분리
SungHyun627 Apr 23, 2024
6f9f277
feat: 임시저장 목록에서 클릭된 카드 key 스토어에 저장
hyosin-Jang Apr 20, 2024
778017f
feat: 임시저장 글 목록 로컬스토리지에서 획득
hyosin-Jang Apr 20, 2024
654a0de
feat: 임시저장 삭제 기능 구현
SungHyun627 Apr 23, 2024
e412cac
style: 마이페이지의 회원정보 section 변경된 스타일 반영
SungHyun627 Apr 23, 2024
60edc72
style: 마이페이지의 스터디 section의 변경된 스타일 반영
SungHyun627 Apr 23, 2024
4b13229
style: 임시저장 card section 수정된 디자인 반영
SungHyun627 Apr 23, 2024
556fcfe
style: 로그아웃 버튼 디자인 수정사항 반영
SungHyun627 Apr 24, 2024
384184a
Merge feat/search-stack into local dev branch
SungHyun627 Apr 25, 2024
1c64e85
feat: 초기 선택된 stack이 props로 전달된 StackModal storybook component 생성
SungHyun627 Apr 29, 2024
6da2e12
Merge branch 'dev' into feat/search-stack
SungHyun627 Apr 29, 2024
cc52244
fix: 임시 저장 카드 컴포넌트 수정사항 반영
SungHyun627 Apr 29, 2024
72a3d02
fix: dev branch와 conflict되는 코드 수정
SungHyun627 Apr 29, 2024
dc46376
fix: 폴더명 오타 및 import 경로 수정
SungHyun627 Apr 29, 2024
61ae403
feat: 컴포넌트 반응형 스타일 적용
SungHyun627 Apr 30, 2024
af1927d
feat: MyStudyCard 컴포넌트 반응형 스타일 적용
SungHyun627 Apr 30, 2024
61e860c
feat: MyStudyCard 컴포넌트가 지원한 스터디를 나타내는 경우, 다른 UI 적용
SungHyun627 Apr 30, 2024
d928b78
feat: 프로필 수정 아이콘 및 프로필 모달의 input 컴포넌트 너비 수정
SungHyun627 Apr 30, 2024
ffbbf14
fix: origin feat/search-stack와 local feat/search-stack 동기화
SungHyun627 Apr 30, 2024
6c7157f
feat: MyStudyCard storybook 컴포넌트 구현
SungHyun627 May 1, 2024
7b06aa4
chore: StudyThumbnail과 Setting icon storybook에 추가
SungHyun627 May 1, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions src/Assets/icons/setting.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions src/Assets/icons/studyThumbnail.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions src/Assets/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ export { default as Loading } from './icons/lodaing.svg?react';
export { default as Logout } from './icons/logout.svg?react';
export { default as Article } from './icons/article.svg?react';
export { default as Study } from './icons/study.svg?react';
export { default as StudyThumbnail } from './icons/studyThumbnail.svg?react';
export { default as Setting } from './icons/setting.svg?react';
SungHyun627 marked this conversation as resolved.
Show resolved Hide resolved

// Logo
export { default as BlankLogo } from './images/blank-logo.png';
Expand Down
4 changes: 4 additions & 0 deletions src/Components/Common/ChipMenu/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,13 @@ const ChipMenuContainer = styled.div<{ checked: boolean }>`
font-style: normal;
font-weight: 600;
line-height: 40px;
white-space: nowrap;

&:hover {
cursor: pointer;
border: 1px solid ${({ theme }) => theme.color.black1};
background: ${({ theme }) => theme.color.orange4};
color: ${({ theme }) => theme.color.white};
}
`;

Expand Down
21 changes: 15 additions & 6 deletions src/Components/Common/InfoField/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ export interface InfoFieldProps {
title: string;
content: string | number;
width?: string;
titleWidth?: string;
titleWidth?: number;
contentWidth?: string;
flexDirection?: string;
gap?: string;
gap?: number;
disabled?: boolean;
fontSize?: number;
}

export const InfoField = ({
Expand All @@ -18,6 +19,7 @@ export const InfoField = ({
contentWidth,
title,
content,
fontSize,
flexDirection,
gap,
disabled = false,
Expand All @@ -30,6 +32,7 @@ export const InfoField = ({
flexDirection={flexDirection}
gap={gap}
disabled={disabled}
fontSize={fontSize}
>
<div className="field__title">{title}</div>
<div className="field__content">{content}</div>
Expand All @@ -39,20 +42,21 @@ export const InfoField = ({

const InfoFieldWrapper = styled.div<{
width?: string;
titleWidth?: string;
titleWidth?: number;
contentWidth?: string;
flexDirection?: string;
gap?: string;
gap?: number;
disabled?: boolean;
fontSize?: number;
}>`
display: flex;
flex-direction: ${(props) => props.flexDirection || 'row'};
width: ${(props) => props.width};
text-align: start;
gap: ${(props) => (props.flexDirection ? '4px' : '24px')};
font-size: ${(props) => props.theme.font.medium};
font-size: ${(props) => (props.fontSize ? props.fontSize : props.theme.font.medium)};
font-weight: 500;
line-height: 40px;
line-height: 24px;

.field {
&__title {
Expand All @@ -62,10 +66,15 @@ const InfoFieldWrapper = styled.div<{
${media.tablet} {
width: auto;
}

${media.mobile} {
width: ${({ titleWidth }) => `${titleWidth}px` || 'auto'};
}
}

&__content {
color: ${({ theme, disabled }) => (disabled ? 'rgba(0, 0, 0, 0.25)' : theme.color.black2)};
overflow-x: hidden;
}
}
`;
65 changes: 57 additions & 8 deletions src/Components/Common/InputText/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,39 @@
import React, { ForwardedRef } from 'react';
import { ComponentProps, ForwardedRef, ReactNode, forwardRef } from 'react';
import styled from 'styled-components';

interface InputTextProps extends React.InputHTMLAttributes<HTMLInputElement> {
placeholder?: string;
inputType?: 'text' | 'email' | 'password' | 'member';
defaultValue?: string;
currentLength?: number;
maxLength?: number;
icon?: ReactNode;
}

const InputText = React.forwardRef(
({ placeholder, inputType, onChange, ...props }: InputTextProps, ref: ForwardedRef<HTMLInputElement>) => {
return <InputWrapper placeholder={placeholder} ref={ref} type={inputType} onChange={onChange} {...props} />;
const InputText = forwardRef<HTMLInputElement, ComponentProps<'input'> & InputTextProps>(
(
{ name, placeholder, defaultValue, inputType, onChange, maxLength, currentLength, icon, ...props }: InputTextProps,
ref: ForwardedRef<HTMLInputElement>,
) => {
return (
<Box>
<InputWrapper
placeholder={placeholder}
defaultValue={defaultValue}
name={name}
ref={ref}
type={inputType ?? 'text'}
onChange={onChange}
autoComplete="off"
{...props}
/>
{maxLength && (
<LengthIndicator>
{currentLength} / {maxLength}
</LengthIndicator>
)}
{icon && <IconWrapper>{icon}</IconWrapper>}
</Box>
);
},
);

Expand All @@ -17,18 +42,42 @@ const InputWrapper = styled.input`
padding: 10px 16px;
border: 1px solid ${({ theme }) => theme.color.black1};
border-radius: ${({ theme }) => theme.borderRadius.small};
font-size: ${({ theme }) => theme.font.medium};
font-size: ${({ theme }) => theme.font.small};
line-height: 1.5;
color: ${({ theme }) => theme.color.black};

::placeholder {
color: ${({ theme }) => theme.color.black2};
font-family: 'Pretendard400';
font-size: ${({ theme }) => theme.font.medium};
font-size: ${({ theme }) => theme.font.small};
font-style: normal;
font-weight: 400;
line-height: 28px;
}
`;

const Box = styled.div`
position: relative;
display: flex;
`;

const IconWrapper = styled.div`
display: flex;
position: absolute;
top: 10px;
right: 16px;
&:hover {
cursor: pointer;
}
`;
const LengthIndicator = styled.div`
position: absolute;
top: 10px;
right: 16px;
color: #00000073;
font-family: Pretendard400;
font-weight: 400;
font-size: 14px;
line-height: 20px;
`;

export default InputText;
5 changes: 3 additions & 2 deletions src/Components/Common/StudyToken/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ const StudyToken = ({ status }: StudyTokenProps) => {

const StudyTokenWrapper = styled.span<{ status: ApplyStatus | MemberStatus | StudyStatus }>`
display: flex;
padding: 4px 12px;
padding: 0px 12px;
justify-content: center;
align-items: center;
white-space: nowrap;

color: ${({ status, theme }) =>
status === 'PARTICIPATED'
Expand All @@ -45,7 +46,7 @@ const StudyTokenWrapper = styled.span<{ status: ApplyStatus | MemberStatus | Stu
font-family: 'Pretendard500';
font-style: normal;
font-weight: 500;
line-height: 30px;
line-height: 32px;
`;

export default StudyToken;
9 changes: 4 additions & 5 deletions src/Components/Common/TechStack/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const TechStack = ({ name, imageUrl, selected = false, onClick }: TechSta

const TechStackWrapper = styled.div<{ selected: boolean; imageUrl?: string }>`
display: inline-flex;
padding: 8px 12px 8px 8px;
padding: 8px;
justify-content: center;
align-items: center;
gap: 12px;
Expand All @@ -44,14 +44,13 @@ const TechStackWrapper = styled.div<{ selected: boolean; imageUrl?: string }>`
}

.stack__name {
width: 108px;
width: 84px;
color: ${({ theme, selected }) => (selected ? theme.color.purple1 : theme.color.black3)};
font-family: Pretendard600;
font-family: 'Pretendard600';
font-size: ${({ theme }) => theme.font.xsmall};
font-style: normal;
font-weight: 600;
line-height: 32px;
white-space: nowrap;
line-height: 16px;
}

&:hover {
Expand Down
7 changes: 2 additions & 5 deletions src/Components/DropdownFilter/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useOutSideClick } from '@/Hooks/useOutsideClick';
import { Up, Down } from '@/Assets';
import { useFilterOptionsStore } from '@/store/filter';
import { media } from '@/Styles/theme';
import StackModal from '../Modal/StackModal';
import { StackModal } from '../Modal/StackModal';

export interface DropdownFilterProps {
filterName: string;
Expand Down Expand Up @@ -94,10 +94,6 @@ const DropdownFilterWrapper = styled.ul`
text-overflow: ellipsis;
}

&:hover {
cursor: pointer;
}

${media.custom(800)} {
width: 90px;
}
Expand All @@ -123,6 +119,7 @@ const DropdownSelectWrapper = styled.div<{ checked?: boolean }>`
svg > path {
fill: ${(props) => props.theme.color.white};
}
cursor: pointer;
}
svg > path {
fill: ${({ theme, checked }) => (checked ? theme.color.orange2 : theme.color.black3)};
Expand Down
2 changes: 1 addition & 1 deletion src/Components/Footer/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const FooterWrapper = styled.footer`
background-color: ${({ theme }) => theme.color.gray1};

${media.custom(800)} {
width: 400px;
width: 100%;
margin: 20px auto 0 auto;
}
`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { Meta, StoryObj } from '@storybook/react';
import EditProfileModal from '.';
import { EditProfileModal } from '.';
import { fn } from '@storybook/test';

const meta = {
Expand Down
8 changes: 5 additions & 3 deletions src/Components/Modal/EditProfileModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface EdiptProfileModalProps {
handleEdit: React.Dispatch<SetStateAction<'NOT START' | 'EDIT' | 'END'>>;
}

const EditProfileModal = ({ userNickname, handleEdit }: EdiptProfileModalProps) => {
export const EditProfileModal = ({ userNickname, handleEdit }: EdiptProfileModalProps) => {
const { closeModal } = useModalStore();
const queryClient = useQueryClient();
const submitSuccessHandler = () => {
Expand Down Expand Up @@ -157,6 +157,10 @@ const FormWrapper = styled.div`
.input__section {
display: flex;
gap: 8px;

& > div {
width: 100%;
}
}

.error__message {
Expand All @@ -183,5 +187,3 @@ const ModalBtnsWrapper = styled.div`
width: 100%;
}
`;

export default EditProfileModal;
28 changes: 28 additions & 0 deletions src/Components/Modal/StackModal/StackModal.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Meta, StoryObj } from '@storybook/react';
import { StackModal } from '.';

const meta = {
component: StackModal,
args: {
handleModal: () => {},
initialSelectedStacks: [
{
id: 93,
name: 'ReactJS',
imageUrl: '/static/stack/images/reactjs.png',
},
{
id: 96,
name: 'React Query',
imageUrl: '/static/stack/images/react_query.png',
},
],
handleSelectedStacks: () => {},
},
} satisfies Meta<typeof StackModal>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Primary: Story = {};
Loading