diff --git a/src/components/projects/main/ProjectList.tsx b/src/components/projects/main/ProjectList.tsx
index b4e6968de..a5b2b11dd 100644
--- a/src/components/projects/main/ProjectList.tsx
+++ b/src/components/projects/main/ProjectList.tsx
@@ -4,46 +4,44 @@ import { ImpressionArea } from '@toss/impression-area';
import { uniqBy as _uniqBy } from 'lodash-es';
import Link from 'next/link';
-import Responsive from '@/components/common/Responsive';
import Text from '@/components/common/Text';
import useEventLogger from '@/components/eventLogger/hooks/useEventLogger';
import ProjectCard from '@/components/projects/main/ProjectCard';
import useGetProjectListQuery from '@/components/projects/upload/hooks/useGetProjectListQuery';
import { playgroundLink } from '@/constants/links';
import IconPen from '@/public/icons/icon-pen.svg';
-import IconPlusWhite from '@/public/icons/icon-plus-black.svg';
import { MOBILE_MEDIA_QUERY } from '@/styles/mediaQuery';
import { textStyles } from '@/styles/typography';
+import ProjectSearch from '@/components/projects/main/ProjectSearch';
+import { StringParam, useQueryParam, withDefault } from 'use-query-params';
+import { useDebounce } from '@toss/react';
+import { fonts } from '@sopt-makers/fonts';
+import { useState } from 'react';
const ProjectList = () => {
+ const [query, setQuery] = useQueryParam('name', withDefault(StringParam, undefined));
+ const [value, setValue] = useState(query);
+ const debouncedChangeName = useDebounce(setQuery, 300);
const { data, isLoading, fetchNextPage } = useGetProjectListQuery({
limit: 20,
+ name: query,
});
const { logClickEvent } = useEventLogger();
return (
-
-
- ✨ 솝트에서 진행된 프로젝트 둘러보기
-
-
-
- logClickEvent('projectUpload', {
- referral: 'projectPage',
- })
- }
- >
-
- 내 프로젝트 올리기
-
-
-
+ {
+ setValue(value);
+ debouncedChangeName(value);
+ }}
+ placeholder='프로젝트 검색'
+ />
+
- {data?.pages && {data.pages[0].totalCount}개의 프로젝트}
+ {data?.pages && 전체 {data.pages[0].totalCount}개}
logClickEvent('projectUpload', {
@@ -66,6 +64,10 @@ const ProjectList = () => {
)}
+
+
+ 프로젝트 올리기
+
);
};
@@ -92,21 +94,6 @@ const StyledContent = styled.div`
}
`;
-const Title = styled(Text)`
- ${textStyles.SUIT_32_B};
-
- @media ${MOBILE_MEDIA_QUERY} {
- margin: 0 6px;
- ${textStyles.SUIT_20_B};
- }
-`;
-
-const TopWrapper = styled.div`
- display: flex;
- align-items: center;
- justify-content: space-between;
-`;
-
const ProjectMobileUploadButton = styled(Link)`
display: none;
@media ${MOBILE_MEDIA_QUERY} {
@@ -118,23 +105,43 @@ const ProjectMobileUploadButton = styled(Link)`
const ProjectUploadButton = styled(Link)`
display: flex;
- gap: 12px;
+ position: fixed;
+ right: 60px;
+ bottom: 80px;
+ gap: 8px;
align-items: center;
- border-radius: 10px;
+ border-radius: 18px;
background-color: ${colors.gray10};
- padding: 18px 24px 18px 20px;
+ padding: 14px 30px 14px 27px;
color: ${colors.gray950};
+ ${fonts.TITLE_20_SB};
&:hover {
background-color: ${colors.gray50};
}
+
+ @media ${MOBILE_MEDIA_QUERY} {
+ right: 16px;
+ bottom: 16px;
+ padding: 12px;
+ ${fonts.LABEL_16_SB}
+ }
`;
+const PlusIcon = () => (
+
+);
+
const LengthWrapper = styled.div`
display: flex;
align-items: center;
justify-content: space-between;
- margin-top: 48px;
+ margin-top: 20px;
@media ${MOBILE_MEDIA_QUERY} {
margin: 30px 6px 0;
@@ -142,10 +149,10 @@ const LengthWrapper = styled.div`
`;
const StyledLength = styled(Text)`
- ${textStyles.SUIT_18_M};
+ ${fonts.BODY_16_M};
@media ${MOBILE_MEDIA_QUERY} {
- ${textStyles.SUIT_16_M};
+ ${fonts.BODY_14_M};
}
`;
diff --git a/src/components/projects/main/ProjectSearch.tsx b/src/components/projects/main/ProjectSearch.tsx
new file mode 100644
index 000000000..dc12d0a33
--- /dev/null
+++ b/src/components/projects/main/ProjectSearch.tsx
@@ -0,0 +1,70 @@
+import { MOBILE_MEDIA_QUERY } from '@/styles/mediaQuery';
+
+import styled from '@emotion/styled';
+import { colors } from '@sopt-makers/colors';
+import { fonts } from '@sopt-makers/fonts';
+import { Flex, width100 } from '@toss/emotion-utils';
+
+interface ProjectSearchProps {
+ defaultValue?: string;
+ value?: string;
+ onValueChange?: (value: string) => void;
+ placeholder?: string;
+}
+
+const ProjectSearch = ({ value, defaultValue, onValueChange, placeholder }: ProjectSearchProps) => {
+ return (
+
+ onValueChange?.(e.target.value)}
+ />
+
+
+ );
+};
+
+export default ProjectSearch;
+
+const Container = styled(Flex)`
+ gap: 8px;
+ border-radius: 8px;
+ background-color: ${colors.gray800};
+ padding: 16px 14px;
+
+ ${width100}
+
+ @media ${MOBILE_MEDIA_QUERY} {
+ border-radius: 6px;
+ padding: 9px 18px;
+ ${fonts.BODY_14_M};
+ }
+`;
+
+const Input = styled.input`
+ color: ${colors.gray200};
+ ${width100};
+ ${fonts.BODY_16_M};
+
+ ::placeholder {
+ ${colors.gray200};
+ }
+`;
+
+const Icon = () => (
+
+);