-
Notifications
You must be signed in to change notification settings - Fork 79
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #736 from Bersk3r/Next.js-이종욱-sprint12
[이종욱] Sprint12
- Loading branch information
Showing
23 changed files
with
785 additions
and
78 deletions.
There are no files selected for viewing
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,25 @@ | ||
import axios from "./axios"; | ||
|
||
interface GetProductsQueries { | ||
page?: number; | ||
pageSize?: number; | ||
orderBy?: "recent" | "favorite"; | ||
keyword?: string; | ||
} | ||
|
||
export const getProducts = async ({ | ||
page = 1, | ||
pageSize = 3, | ||
orderBy = "recent", | ||
keyword, | ||
}: GetProductsQueries) => { | ||
try { | ||
const response = await axios.get("/products", { | ||
params: { page, pageSize, orderBy, keyword }, | ||
}); | ||
return response.data; | ||
} catch (error) { | ||
console.error(`Failed to fetch Data: ${error}`); | ||
throw error; | ||
} | ||
}; |
This file was deleted.
Oops, something went wrong.
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 "/styles/index.scss"; | ||
|
||
.title { | ||
display: flex; | ||
align-items: center; | ||
justify-content: space-between; | ||
gap: 10px; | ||
padding-block: 24px 12px; | ||
|
||
.content { | ||
@include font-base(get_color(black), 700, 20px, 28px); | ||
max-width: 600px; | ||
flex-grow: 3; | ||
} | ||
|
||
.search { | ||
height: 42px; | ||
display: flex; | ||
align-items: center; | ||
gap: 3px; | ||
background-color: get_color(gray_100); | ||
border-radius: 12px; | ||
padding-block: 9px; | ||
padding-inline: 20px 16px; | ||
|
||
.search_image { | ||
width: 16px; | ||
height: 16px; | ||
background-size: 16px; | ||
background-repeat: no-repeat; | ||
background-image: url("../../src/assets/images/icons/ic_search.svg"); | ||
} | ||
|
||
.search_input { | ||
@include font-base(get_color(black), 400, 16px, 24px); | ||
background-color: get_color(gray_100); | ||
border: none; | ||
} | ||
} | ||
|
||
.add_item { | ||
@include font-base(get_color(white), 600, 16px, 19.09px); | ||
text-align: center; | ||
width: 133px; | ||
height: 42px; | ||
border-radius: 8px; | ||
padding: 12px 10px; | ||
background-color: get_color(blue_primary); | ||
text-decoration: none; | ||
flex-shrink: 0; | ||
} | ||
.select_box_area { | ||
position: relative; | ||
max-width: 64px; | ||
background-color: get_color(white); | ||
padding: 3px; | ||
border-radius: 3px; | ||
right: 0; | ||
} | ||
} | ||
|
||
@media screen and (min-width: 768px) and (max-width: 1199px) { | ||
.search { | ||
width: 242px; | ||
} | ||
} | ||
|
||
@media screen and (min-width: 375px) and (max-width: 767px) { | ||
.title { | ||
display: grid; | ||
grid-template: repeat(2, auto) / 300px auto; | ||
|
||
.content { | ||
width: fit-content; | ||
grid-column: 1 / span 1; | ||
grid-row: 1 / span 1; | ||
} | ||
|
||
.search { | ||
grid-column: 1 / span 1; | ||
grid-row: 2 / span 1; | ||
} | ||
.add_item { | ||
grid-column: 2 / span 1; | ||
grid-row: 1 / span 1; | ||
} | ||
} | ||
|
||
.select_box_area { | ||
grid-column: 2 / span 1; | ||
grid-row: 2 / span 1; | ||
} | ||
} |
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,139 @@ | ||
import { useEffect, useState } from "react"; | ||
import { sortItemsByOrder } from "../../lib/sort"; | ||
import { AllProducts } from "./Products"; | ||
import styles from "./AllItems.module.scss"; | ||
import SelectMenu from "./SelectMenu"; | ||
import Link from "next/link"; | ||
import { ProductSortOption } from "../../types/productTypes"; | ||
import useWindowSize from "../../src/hooks/useWindowSize"; | ||
import { FieldValues, SubmitHandler, useForm } from "react-hook-form"; | ||
import { getProducts } from "../../api/getProduct"; | ||
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; | ||
|
||
function AllItems() { | ||
const [order, setOrder] = useState<ProductSortOption>("recent"); | ||
const queryClient = useQueryClient(); | ||
const windowWidth = useWindowSize(); | ||
const { register, watch, handleSubmit, setValue, getValues } = useForm(); | ||
const [pageSize, setPageSize] = useState<number>(10); | ||
const [keyword, setKeyword] = useState<string>(""); | ||
|
||
const { | ||
data: itemsData, | ||
isPending, | ||
isError, | ||
} = useQuery({ | ||
queryKey: ["allitems"], | ||
queryFn: () => getProducts({ pageSize, orderBy: order }), | ||
retry: 0, | ||
}); | ||
|
||
const items = itemsData?.list ?? []; | ||
|
||
const addKeywordMutation = useMutation({ | ||
mutationFn: (keyword: string) => | ||
getProducts({ pageSize, orderBy: order, keyword }), | ||
onSuccess: () => { | ||
queryClient.invalidateQueries({ | ||
queryKey: ["allitems"], | ||
}); | ||
}, | ||
}); | ||
|
||
const addOrderMutation = useMutation({ | ||
mutationFn: (order: ProductSortOption) => | ||
getProducts({ pageSize, orderBy: order, keyword }), | ||
onSuccess: () => { | ||
queryClient.invalidateQueries({ | ||
queryKey: ["allitems"], | ||
}); | ||
}, | ||
}); | ||
|
||
const handleKeyword = (keyword: string) => { | ||
addKeywordMutation.mutate(keyword); | ||
}; | ||
|
||
const handleOrder = (order: ProductSortOption) => { | ||
addKeywordMutation.mutate(order); | ||
setOrder(order); | ||
}; | ||
|
||
const sortedItems = sortItemsByOrder(items, order); | ||
|
||
const onSubmit: SubmitHandler<FieldValues> = async (data) => { | ||
if (data.keyword) { | ||
setKeyword(data.keyword); | ||
} | ||
handleKeyword(keyword); | ||
}; | ||
|
||
useEffect(() => { | ||
if (windowWidth < 768) { | ||
setPageSize(4); | ||
} else if (windowWidth < 1199) { | ||
setPageSize(6); | ||
} else { | ||
setPageSize(10); | ||
} | ||
}, [windowWidth]); | ||
|
||
// useEffect(() => { | ||
// async ({ | ||
// pageSize, | ||
// order, | ||
// keyword, | ||
// }: { | ||
// pageSize: number; | ||
// order: ProductSortOption; | ||
// keyword: string; | ||
// }) => { | ||
// let result = await getProducts({ pageSize, orderBy: order, keyword }); | ||
// const { list } = result; | ||
// setAllItems(list); | ||
// }; | ||
// // eslint-disable-next-line react-hooks/exhaustive-deps | ||
// }, [pageSize, order, keyword]); | ||
|
||
return ( | ||
<> | ||
<div className={styles.container}> | ||
<div className={styles.title}> | ||
<h2 className={styles.content}> | ||
{windowWidth < 1199 ? "판매 중인 상품" : "전체 상품"} | ||
</h2> | ||
<div className={styles.search}> | ||
<span className={styles.search_image} /> | ||
<form onSubmit={handleSubmit(onSubmit)}> | ||
<input | ||
{...register("keyword")} | ||
type="search" | ||
placeholder="검색할 상품을 입력해주세요" | ||
className={styles.search_input} | ||
/> | ||
</form> | ||
</div> | ||
<Link href="/additem" className={styles.add_item}> | ||
상품 등록하기 | ||
</Link> | ||
<span className={styles.select_box_area}> | ||
<SelectMenu order={order} setOrder={handleOrder} /> | ||
</span> | ||
</div> | ||
<div> | ||
<AllProducts items={sortedItems} counts={pageSize} /> | ||
</div> | ||
{/* {isError && <span>{loadingError.message}</span>} */} | ||
</div> | ||
{/* <Paging | ||
itemsCount={1} | ||
totalPageCount={totalPage} | ||
displayCount={pageSize} | ||
order={order} | ||
onClick={handleLoad} | ||
/> */} | ||
</> | ||
); | ||
} | ||
|
||
export default AllItems; |
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,10 @@ | ||
@import "/styles/index.scss"; | ||
|
||
.container { | ||
.title { | ||
padding-block: 24px 12px; | ||
.content { | ||
@include font-base(get_color(gray_800), 700, 20px, 28px); | ||
} | ||
} | ||
} |
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,49 @@ | ||
import { useEffect, useState } from "react"; | ||
import { BestProducts } from "./Products"; | ||
import { sortItemsByOrder } from "../../lib/sort"; | ||
import styles from "./BestItems.module.scss"; | ||
import useWindowSize from "../../src/hooks/useWindowSize"; | ||
import { useQuery, useQueryClient } from "@tanstack/react-query"; | ||
import { getProducts } from "../../api/getProduct"; | ||
|
||
function BestItems() { | ||
const windowWidth = useWindowSize(); | ||
const [pageSize, setPageSize] = useState(4); | ||
|
||
const { | ||
data: itemsData, | ||
isPending, | ||
isError, | ||
} = useQuery({ | ||
queryKey: ["bestitems"], | ||
queryFn: () => getProducts({ pageSize, orderBy: "favorite" }), | ||
retry: 0, | ||
}); | ||
|
||
// const items = itemsData?.results ?? []; | ||
const items = itemsData?.list ?? []; | ||
|
||
const sortedItems = sortItemsByOrder(items, "favorite"); | ||
|
||
useEffect(() => { | ||
if (windowWidth < 768) { | ||
setPageSize(1); | ||
} else if (windowWidth < 1199) { | ||
setPageSize(2); | ||
} else { | ||
setPageSize(4); | ||
} | ||
}, [windowWidth]); | ||
|
||
return ( | ||
<div className={styles.container}> | ||
<div className={styles.title}> | ||
<h2 className={styles.content}>베스트 상품</h2> | ||
</div> | ||
<BestProducts items={sortedItems} counts={pageSize} /> | ||
{/* {loadingError?.message && <span>{loadingError.message}</span>} */} | ||
</div> | ||
); | ||
} | ||
|
||
export default BestItems; |
Oops, something went wrong.