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

[NEXTLEVEL 클린코드 리액트 호준] 장바구니 미션 Step1 #7

Open
wants to merge 20 commits into
base: ganeodolu
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
22 changes: 12 additions & 10 deletions client/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import React from 'react';
import { QueryClientProvider, QueryClient } from 'react-query';
import { Routes, Route } from "react-router-dom";
import ProductList from './pages/ProductList';
import Cart from './pages/Cart';
import OrderList from './pages/OrderList';
import ProductListPage from './pages/ProductListPage';
import CartListPage from './pages/CartListPage';
import OrderListPage from "./pages/OrderListPage";
// import Home from './pages/Home';
import GNB from './components/GNB';
import { ReactQueryDevtools } from "react-query/devtools";

const queryClient = new QueryClient();

const App = () => {
return (
<QueryClientProvider client={queryClient}>
<GNB />
<Routes className="App">
{/* <Route path="/" element={<Home />} /> */}
<Route path="/" element={<ProductList />} />
<Route path="/carts" element={<Cart />} />
<Route path="/orders" element={<OrderList />} />
</Routes>
<GNB />
<Routes className="App">
{/* <Route path="/" element={<Home />} /> */}
<Route path="/" element={<ProductListPage />} />
<Route path="/carts" element={<CartListPage />} />
<Route path="/orders" element={<OrderListPage />} />
</Routes>
<ReactQueryDevtools />
</QueryClientProvider>
);
}
Expand Down
109 changes: 109 additions & 0 deletions client/src/components/product/ProductList.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
import React from "react";
import styled from "styled-components";
import CartSvg from '../../assets/svgs/cart.svg';

const ProductListBlock = styled.div`
.product-container {
display: flex;
justify-content: center;

flex-wrap: wrap;
gap: 20px;
padding: 50px 240px;

display: grid;
gap: 20px 20px;
grid-template-columns: repeat(4, 1fr);
}

@media screen and (max-width: 768px) {
.product-container {
grid-template-columns: repeat(3, 1fr);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반응형을 grid로 구현하셨네요. 저도 grid로 구현했는데,
처음에 배민상회 페이지에서 개발자도구로 봤을 때
상품을 4개씩 끊어서 받아와서 구현했더라고요. 그래서 저도 처음엔 그렇게 받아오는 방법을 고민했었는데, 너무 복잡하고
grid가 훨씬 간편해서 grid로 그냥 구현하긴 했는데,
다른 방식 생각해보신 것 있으신가요?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

말씀하신 것처럼 열, 행으로 구현은 grid가 제일 편한 것 같습니다. 다른 방식이라면 flex-wrap으로도 구현이 되지 않을까 생각해봅니당. 그리고 조사하신 배민방식은 페이지처럼 한페이지에 4개씩 백엔드에서 제공하는 것일까요??

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

배민페이지 방식에 확실히는 모르겠습니다. 6개씩 한 줄로 나오는 방식이긴 한데 반응형은 아니였습니다.
그래서 그냥 프론트에서도 받은 전체 상품을 6개씩 나눠도 할 수는 있을 것 같다고 생각했습니다.

}
}

@media screen and (max-width: 480px) {
.product-container {
grid-template-columns: repeat(2, 1fr);
}
}

.product-info {
display: flex;
flex-direction: column;
}

.product-info__name {
font-size: 12px;
}

.product-info__price {
}

.product-detail-container {
display: flex;
flex-direction: column;
align-items: center;

margin-top: 50px;
}

.product-detail-info {
width: 100%;
}

.product-detail-info__name {
font-size: 24px;
}

.product-detail-info__price {
font-size: 24px;
}

.product-detail-button {
width: 100%;
padding: 24px;
background: #73675c;
font-size: 24px;
color: white;
}
`;

const ProductItem = ({ product: { id, name, price, imageUrl } }) => {
return (
<div data-id={id}>
<img src={imageUrl} alt={name} />
<div className="flex justify-between p-5">
<div className="product-info">
<span className="product-info__name">{name}</span>
<span className="product-info__price">{price.toLocaleString()}원</span>
</div>
<img src={CartSvg} alt="장바구니" />
</div>
</div>
);
};

const ProductList = ({ isError, isLoading, data, error }) => {
if (isLoading) {
return <span>Loading...</span>;
}

if (isError) {
return <span>Error: {error.message}</span>;
}

return (
<ProductListBlock>
<div>
<section className="product-container">
{data.map((product, idx) => {
return <ProductItem key={idx} product={product} />;
})}
</section>
</div>
</ProductListBlock>
);
};

export default ProductList;
15 changes: 15 additions & 0 deletions client/src/containers/product/ProductListContainer.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react'
import ProductList from '../../components/product/ProductList';
import apiHandler from '../../lib/api/main';
import { useQuery } from 'react-query';

const ProductListContainer = () => {
const { isLoading, isError, data, error } = useQuery(["products"], () => apiHandler.getProducts());
return (
<div>
<ProductList isLoading={isLoading} isError={isError} data={data} error={error} />
</div>
)
}

export default ProductListContainer
4 changes: 2 additions & 2 deletions client/src/lib/api/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ const apiHandler = {
getProduct: async ({ id }) => {
try {
const response = await API.get(`/products/${id}`)
return response
return response.data
} catch {
console.log(error);
}
},
getProducts: async () => {
try {
const response = await API.get(`/products/`)
return response
return response.data
} catch {
console.log(error);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'

const Cart = () => {
const CartListPage = () => {
return (
<div>

</div>
)
}

export default Cart
export default CartListPage
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import React from 'react'

const OrderList = () => {
const OrderListPage = () => {
return (
<div>

</div>
)
}

export default OrderList
export default OrderListPage
11 changes: 0 additions & 11 deletions client/src/pages/ProductList.jsx

This file was deleted.

12 changes: 12 additions & 0 deletions client/src/pages/ProductListPage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react'
import ProductListContainer from '../containers/product/ProductListContainer';

const ProductListPage = () => {
return (
<div>
<ProductListContainer />
</div>
);
}

export default ProductListPage
138 changes: 79 additions & 59 deletions client/src/styles/global.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,71 +2,24 @@ import { createGlobalStyle } from 'styled-components';

const GlobalStyle = createGlobalStyle`

/*** The new CSS Reset - version 1.4.4 (last updated 22.12.2021) ***/

/*
Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property
- The "symbol *" part is to solve Firefox SVG sprite bug
*/
*:where(:not(iframe, canvas, img, svg, video):not(svg *, symbol *)) {
all: unset;
display: revert;
}

/* Preferred box-sizing value */
*,
*::before,
*::after {
box-sizing: border-box;
body {
width: 1920px;
margin: 24px auto 0;
}

/* Remove list styles (bullets/numbers) */
ol,
ul,
menu {
list-style: none;
.divide-line {
width: 100%;
border: 2px solid black;
}

/* For images to not be able to exceed their container */
img {
max-width: 100%;
.divide-line-gray {
width: 100%;
border: 2px solid #aaaaaa;
}

/* removes spacing between cells in tables */
table {
border-collapse: collapse;
}

/* revert the 'white-space' property for textarea elements on Safari */
textarea {
white-space: revert;
}

/* fix the feature of 'hidden' attribute.
display:revert; revert to element instead of attribute */
:where([hidden]) {
display: none;
}

/* revert for bug in Chromium browsers
- fix for the content editable attribute will work properly. */
:where([contenteditable]) {
-moz-user-modify: read-write;
-webkit-user-modify: read-write;
overflow-wrap: break-word;
-webkit-line-break: after-white-space;
}

/* apply back the draggable feature - exist only in Chromium and Safari */
:where([draggable="true"]) {
-webkit-user-drag: element;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
.divide-line-thin {
width: 100%;
border: 1px solid #aaaaaa;
}


Expand Down Expand Up @@ -240,6 +193,73 @@ input[type="number"]::-webkit-inner-spin-button {
}


/*** The new CSS Reset - version 1.4.4 (last updated 22.12.2021) ***/

/*
Remove all the styles of the "User-Agent-Stylesheet", except for the 'display' property
- The "symbol *" part is to solve Firefox SVG sprite bug
*/
*:where(:not(iframe, canvas, img, svg, video):not(svg *, symbol *)) {
all: unset;
display: revert;
}

/* Preferred box-sizing value */
*,
*::before,
*::after {
box-sizing: border-box;
}

/* Remove list styles (bullets/numbers) */
ol,
ul,
menu {
list-style: none;
}

/* For images to not be able to exceed their container */
img {
max-width: 100%;
}

/* removes spacing between cells in tables */
table {
border-collapse: collapse;
}

/* revert the 'white-space' property for textarea elements on Safari */
textarea {
white-space: revert;
}

/* fix the feature of 'hidden' attribute.
display:revert; revert to element instead of attribute */
:where([hidden]) {
display: none;
}

/* revert for bug in Chromium browsers
- fix for the content editable attribute will work properly. */
:where([contenteditable]) {
-moz-user-modify: read-write;
-webkit-user-modify: read-write;
overflow-wrap: break-word;
-webkit-line-break: after-white-space;
}

/* apply back the draggable feature - exist only in Chromium and Safari */
:where([draggable="true"]) {
-webkit-user-drag: element;
}

input[type="number"]::-webkit-outer-spin-button,
input[type="number"]::-webkit-inner-spin-button {
-webkit-appearance: none;
-moz-appearance: none;
appearance: none;
}



`;
Expand Down
Loading