Skip to content

Commit

Permalink
Merge branch 'develop' into feat/#172-change-password-api
Browse files Browse the repository at this point in the history
  • Loading branch information
jonique98 committed Jun 9, 2024
2 parents 499586f + b204dc1 commit 3b3e606
Show file tree
Hide file tree
Showing 24 changed files with 481 additions and 396 deletions.
34 changes: 34 additions & 0 deletions src/components/RealTimeKeyword/RealTimeKeyword.constant.ts
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 src/components/RealTimeKeyword/RealTimeKeyword.style.ts
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;
93 changes: 93 additions & 0 deletions src/components/RealTimeKeyword/RealTimeKeyword.tsx
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>
);
};
4 changes: 2 additions & 2 deletions src/drawer/apis/getBookMarked.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { soomsilClient } from '@/apis';

import { RankingRequestParams } from '../types/RankingRequestParams.type';
import { ProductRequestParams } from '../types/ProductRequestParams.type';
import { ProductResponses } from '../types/product.type';

export const getBookmarked = async ({ responseType, page }: RankingRequestParams) => {
export const getBookmarked = async ({ responseType, page }: ProductRequestParams) => {
const response = await soomsilClient.get<ProductResponses>('/v2/drawer/my-bookmarked', {
params: {
responseType,
Expand Down
4 changes: 2 additions & 2 deletions src/drawer/apis/getMyProduct.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { soomsilClient } from '@/apis';

import { RankingRequestParams } from '../types/RankingRequestParams.type';
import { ProductRequestParams } from '../types/ProductRequestParams.type';
import { ProductResponses } from '../types/product.type';

export const getMyProduct = async ({ responseType, page }: RankingRequestParams) => {
export const getMyProduct = async ({ responseType, page }: ProductRequestParams) => {
const response = await soomsilClient.get<ProductResponses>('/v2/drawer/my-registered', {
params: {
responseType,
Expand Down
4 changes: 2 additions & 2 deletions src/drawer/apis/getNewRelease.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { soomsilClient } from '@/apis';

import { RankingRequestParams } from '../types/RankingRequestParams.type';
import { ProductRequestParams } from '../types/ProductRequestParams.type';
import { ProductResponses } from '../types/product.type';

export const getNewRelease = async ({ responseType, category, page }: RankingRequestParams) => {
export const getNewRelease = async ({ responseType, category, page }: ProductRequestParams) => {
const response = await soomsilClient.get<ProductResponses>('/v2/drawer/new-release', {
params: {
responseType,
Expand Down
4 changes: 2 additions & 2 deletions src/drawer/apis/getRanking.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { soomsilClient } from '@/apis';

import { RankingRequestParams } from '../types/RankingRequestParams.type';
import { ProductRequestParams } from '../types/ProductRequestParams.type';
import { ProductResponses } from '../types/product.type';

export const getRanking = async ({ responseType, category, page }: RankingRequestParams) => {
export const getRanking = async ({ responseType, category, page }: ProductRequestParams) => {
const response = await soomsilClient.get<ProductResponses>('/v2/drawer/rank', {
params: {
responseType,
Expand Down
1 change: 1 addition & 0 deletions src/drawer/constants/page.constant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const PRODUCTS_PER_PAGE = 21;
30 changes: 22 additions & 8 deletions src/drawer/hooks/useGetBookMarked.ts
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,
});
};
30 changes: 22 additions & 8 deletions src/drawer/hooks/useGetMyRegistered.ts
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,
});
};
Loading

0 comments on commit 3b3e606

Please sign in to comment.