-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into feat/#172-change-password-api
- Loading branch information
Showing
24 changed files
with
481 additions
and
396 deletions.
There are no files selected for viewing
34 changes: 34 additions & 0 deletions
34
src/components/RealTimeKeyword/RealTimeKeyword.constant.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { RealTimeKeywordStyleProps } from '@/components/RealTimeKeyword/RealTimeKeyword.style.ts'; | ||
|
||
export type VariantType = 'home' | 'search'; | ||
|
||
export const variantStyles: { [key in VariantType]: RealTimeKeywordStyleProps } = { | ||
home: { | ||
$containerPadding: '1rem', | ||
$containerWidth: '32.5rem', | ||
$containerHeight: 'auto', | ||
$titleContainerPadding: '0.3125rem 0.5rem', | ||
$titleContainerMarginBottom: '0.5rem', | ||
$updateDateTypo: 'caption2', | ||
$columnCount: 2, | ||
$keywordWidth: '7.375rem', | ||
$imageWidth: '10.3125rem', | ||
$imageHeight: '6.875rem', | ||
$imageTop: '-1.125rem', | ||
$imageRight: '0.9375rem', | ||
}, | ||
search: { | ||
$containerPadding: '1.25rem', | ||
$containerWidth: '25rem', | ||
$containerHeight: '38.7rem', | ||
$titleContainerPadding: '0.5rem', | ||
$titleContainerMarginBottom: '0.75rem', | ||
$updateDateTypo: 'body3', | ||
$columnCount: 1, | ||
$keywordWidth: 'auto', | ||
$imageWidth: '12.6875rem', | ||
$imageHeight: '8.5rem', | ||
$imageTop: '-3.125rem', | ||
$imageRight: '0', | ||
}, | ||
}; |
121 changes: 121 additions & 0 deletions
121
src/components/RealTimeKeyword/RealTimeKeyword.style.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import { Typo } from '@yourssu/design-system-react'; | ||
import styled from 'styled-components'; | ||
|
||
interface StyledContainerProps { | ||
$containerPadding: string; | ||
$containerWidth: string; | ||
$containerHeight: string; | ||
} | ||
|
||
export const StyledContainer = styled.div<StyledContainerProps>` | ||
position: relative; | ||
padding: ${({ $containerPadding }) => $containerPadding}; | ||
width: ${({ $containerWidth }) => $containerWidth}; | ||
height: ${({ $containerHeight }) => $containerHeight}; | ||
border-radius: 0.75rem; | ||
border: 1px solid ${({ theme }) => theme.color.borderNormal}; | ||
background: ${({ theme }) => theme.color.bgNormal}; | ||
`; | ||
|
||
interface StyledTitleContainerProps { | ||
$titleContainerPadding: string; | ||
$titleContainerMarginBottom: string; | ||
} | ||
|
||
export const StyledTitleContainer = styled.div<StyledTitleContainerProps>` | ||
padding: ${({ $titleContainerPadding }) => $titleContainerPadding}; | ||
margin-bottom: ${({ $titleContainerMarginBottom }) => $titleContainerMarginBottom}; | ||
`; | ||
|
||
export const StyledTitle = styled.div` | ||
margin-bottom: 0.5rem; | ||
white-space: pre-wrap; | ||
color: ${({ theme }) => theme.color.textPrimary}; | ||
${({ theme }) => theme.typo.subtitle3}; | ||
`; | ||
|
||
interface StyledUpdateDateProps { | ||
$updateDateTypo: Typo; | ||
} | ||
|
||
export const StyledUpdateDate = styled.div<StyledUpdateDateProps>` | ||
color: ${({ theme }) => theme.color.textTertiary}; | ||
${({ theme, $updateDateTypo }) => theme.typo[$updateDateTypo]}; | ||
`; | ||
|
||
interface StyledListProps { | ||
$columnCount: number; | ||
} | ||
|
||
export const StyledList = styled.div<StyledListProps>` | ||
display: grid; | ||
grid-template-rows: ${({ $columnCount }) => `repeat(${10 / $columnCount}, 1fr)`}; | ||
grid-template-columns: ${({ $columnCount }) => `repeat(${$columnCount}, 1fr)`}; | ||
grid-auto-flow: column; | ||
grid-column-gap: 0.5rem; | ||
`; | ||
|
||
export const StyledListItem = styled.li` | ||
display: flex; | ||
padding: 0.625rem 0.75rem; | ||
justify-content: space-between; | ||
align-items: center; | ||
align-self: stretch; | ||
background: ${({ theme }) => theme.color.bgNormal}; | ||
&:hover { | ||
background: ${({ theme }) => theme.color.bgRecomment}; | ||
} | ||
`; | ||
|
||
export const StyledListItemText = styled.span` | ||
display: flex; | ||
align-items: center; | ||
gap: 8px; | ||
`; | ||
|
||
interface StyledRankProps { | ||
$rank: number; | ||
} | ||
|
||
export const StyledListItemRanking = styled.span<StyledRankProps>` | ||
color: ${({ $rank, theme }) => ($rank < 4 ? '#423FCC' : theme.color.textTertiary)}; | ||
${({ theme }) => theme.typo.subtitle4}; | ||
width: 1.5rem; | ||
`; | ||
|
||
interface StyledListItemKeywordProps { | ||
$keywordWidth: string; | ||
} | ||
|
||
export const StyledListItemKeyword = styled.p<StyledListItemKeywordProps>` | ||
width: ${({ $keywordWidth }) => $keywordWidth}; | ||
color: ${({ theme }) => theme.color.textPrimary}; | ||
${({ theme }) => theme.typo.body1}; | ||
white-space: nowrap; | ||
overflow: hidden; | ||
text-overflow: ellipsis; | ||
`; | ||
|
||
interface StyledImageProps { | ||
$imageWidth: string; | ||
$imageHeight: string; | ||
$imageTop: string; | ||
$imageRight: string; | ||
} | ||
|
||
export const StyledImage = styled.img<StyledImageProps>` | ||
width: ${({ $imageWidth }) => $imageWidth}; | ||
height: ${({ $imageHeight }) => $imageHeight}; | ||
position: absolute; | ||
right: ${({ $imageRight }) => $imageRight}; | ||
top: ${({ $imageTop }) => $imageTop}; | ||
`; | ||
|
||
export type RealTimeKeywordStyleProps = StyledContainerProps & | ||
StyledTitleContainerProps & | ||
StyledUpdateDateProps & | ||
StyledListProps & | ||
StyledListItemKeywordProps & | ||
StyledImageProps; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
import { Suspense } from 'react'; | ||
|
||
import { IcSearchLine } from '@yourssu/design-system-react'; | ||
import { Link } from 'react-router-dom'; | ||
|
||
import RealTimeKeywordImage from '@/assets/realTimeKeyword.webp'; | ||
import { | ||
variantStyles, | ||
VariantType, | ||
} from '@/components/RealTimeKeyword/RealTimeKeyword.constant.ts'; | ||
import { | ||
StyledContainer, | ||
StyledTitleContainer, | ||
StyledImage, | ||
StyledTitle, | ||
StyledUpdateDate, | ||
StyledList, | ||
StyledListItemRanking, | ||
StyledListItemKeyword, | ||
StyledListItem, | ||
StyledListItemText, | ||
} from '@/components/RealTimeKeyword/RealTimeKeyword.style.ts'; | ||
import { useGetRealTimeKeyword } from '@/search/hooks/useGetRealTimeKeyword.ts'; | ||
import { formatDateTime } from '@/utils/formatDateTime.ts'; | ||
|
||
interface RealTimeKeywordProps { | ||
variant: VariantType; | ||
} | ||
|
||
export const RealTimeKeyword = ({ variant }: RealTimeKeywordProps) => { | ||
const { data } = useGetRealTimeKeyword(); | ||
const { | ||
$containerPadding, | ||
$containerWidth, | ||
$containerHeight, | ||
$titleContainerPadding, | ||
$titleContainerMarginBottom, | ||
$updateDateTypo, | ||
$columnCount, | ||
$keywordWidth, | ||
$imageWidth, | ||
$imageHeight, | ||
$imageTop, | ||
$imageRight, | ||
} = variantStyles[variant]; | ||
|
||
return ( | ||
<StyledContainer | ||
$containerPadding={$containerPadding} | ||
$containerWidth={$containerWidth} | ||
$containerHeight={$containerHeight} | ||
> | ||
<Suspense | ||
fallback={ | ||
<StyledUpdateDate $updateDateTypo={$updateDateTypo}>연결 중입니다.</StyledUpdateDate> | ||
} | ||
> | ||
<StyledTitleContainer | ||
$titleContainerPadding={$titleContainerPadding} | ||
$titleContainerMarginBottom={$titleContainerMarginBottom} | ||
> | ||
<StyledTitle>{'숨쉬듯이\n검색한 키워드'}</StyledTitle> | ||
<StyledUpdateDate | ||
$updateDateTypo={$updateDateTypo} | ||
>{`${formatDateTime(data.basedTime)} 기준`}</StyledUpdateDate> | ||
</StyledTitleContainer> | ||
<StyledImage | ||
$imageHeight={$imageHeight} | ||
$imageWidth={$imageWidth} | ||
$imageRight={$imageRight} | ||
$imageTop={$imageTop} | ||
src={RealTimeKeywordImage} | ||
alt="뿌슝이" | ||
/> | ||
<StyledList $columnCount={$columnCount}> | ||
{data.queries.map((value, index) => ( | ||
<Link key={value.query} to={`/search?query=${value.query}`}> | ||
<StyledListItem> | ||
<StyledListItemText> | ||
<StyledListItemRanking $rank={index + 1}>{index + 1}</StyledListItemRanking> | ||
<StyledListItemKeyword $keywordWidth={$keywordWidth}> | ||
{value.query} | ||
</StyledListItemKeyword> | ||
</StyledListItemText> | ||
<IcSearchLine color="#423FCC" width="1.25rem" height="1.25rem" /> | ||
</StyledListItem> | ||
</Link> | ||
))} | ||
</StyledList> | ||
</Suspense> | ||
</StyledContainer> | ||
); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export const PRODUCTS_PER_PAGE = 21; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,29 @@ | ||
import { useSuspenseQuery } from '@tanstack/react-query'; | ||
import { InfiniteData, useSuspenseInfiniteQuery } from '@tanstack/react-query'; | ||
|
||
import { getBookmarked } from '../apis/getBookMarked'; | ||
import { RankingRequestParams } from '../types/RankingRequestParams.type'; | ||
import { PRODUCTS_PER_PAGE } from '../constants/page.constant'; | ||
import { ProductRequestParams } from '../types/ProductRequestParams.type'; | ||
import { ProductResponses, ProductResult } from '../types/product.type'; | ||
|
||
export const useGetBookmarked = ({ responseType, page }: RankingRequestParams) => { | ||
return useSuspenseQuery({ | ||
queryKey: ['bookmarked', { responseType, page }], | ||
queryFn: () => { | ||
return getBookmarked({ responseType, page }); | ||
type ProductRequestParamsWithoutPage = Omit<ProductRequestParams, 'page'>; | ||
|
||
export const useGetBookmarked = ({ responseType }: ProductRequestParamsWithoutPage) => { | ||
return useSuspenseInfiniteQuery< | ||
ProductResponses[], | ||
Error, | ||
InfiniteData<ProductResult[], number>, | ||
string[], | ||
number | ||
>({ | ||
queryKey: ['bookmarked', responseType], | ||
queryFn: ({ pageParam }) => | ||
getBookmarked({ responseType, page: pageParam }).then((data) => data.productList) as Promise< | ||
ProductResponses[] | ||
>, | ||
initialPageParam: 0, | ||
getNextPageParam: (lastPage, allPages) => { | ||
return lastPage.length === PRODUCTS_PER_PAGE ? allPages.length : undefined; | ||
}, | ||
retry: false, | ||
select: (data) => data.productList, | ||
}); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,15 +1,29 @@ | ||
import { useSuspenseQuery } from '@tanstack/react-query'; | ||
import { InfiniteData, useSuspenseInfiniteQuery } from '@tanstack/react-query'; | ||
|
||
import { getMyProduct } from '../apis/getMyProduct'; | ||
import { RankingRequestParams } from '../types/RankingRequestParams.type'; | ||
import { PRODUCTS_PER_PAGE } from '../constants/page.constant'; | ||
import { ProductRequestParams } from '../types/ProductRequestParams.type'; | ||
import { ProductResponses, ProductResult } from '../types/product.type'; | ||
|
||
export const useGetMyRegistered = ({ responseType, page }: RankingRequestParams) => { | ||
return useSuspenseQuery({ | ||
queryKey: ['myRegistered', { responseType, page }], | ||
queryFn: () => { | ||
return getMyProduct({ responseType, page }); | ||
type ProductRequestParamsWithoutPage = Omit<ProductRequestParams, 'page'>; | ||
|
||
export const useGetMyRegistered = ({ responseType }: ProductRequestParamsWithoutPage) => { | ||
return useSuspenseInfiniteQuery< | ||
ProductResponses[], | ||
Error, | ||
InfiniteData<ProductResult[], number>, | ||
string[], | ||
number | ||
>({ | ||
queryKey: ['myRegistered', responseType], | ||
queryFn: ({ pageParam }) => | ||
getMyProduct({ responseType, page: pageParam }).then((data) => data.productList) as Promise< | ||
ProductResponses[] | ||
>, | ||
initialPageParam: 0, | ||
getNextPageParam: (lastPage, allPages) => { | ||
return lastPage.length === PRODUCTS_PER_PAGE ? allPages.length : undefined; | ||
}, | ||
retry: false, | ||
select: (data) => data.productList, | ||
}); | ||
}; |
Oops, something went wrong.