[TIL/React] 2023/10/09
Detail page layout ๐ขProductDetailPageBackgroundStyle์ ์ํด ์ ์ฒด์ ์ธ ๋ฐฐ๊ฒฝ์์ด ์ ์ฉ๋๊ณ ์๋ค. AllContentWrapper๋ ์ฒซ ๋ฒ์งธ ์ฌ์ง์์ ๋ ธ๋์ border๋ก ํ์๋๋ ์์ญ์ด๋ค. ํด๋น wrapper๋ width๊ฐ 90
Detail page layout ๐ข



ProductDetailPageBackgroundStyle์ ์ํด ์ ์ฒด์ ์ธ ๋ฐฐ๊ฒฝ์์ด ์ ์ฉ๋๊ณ ์๋ค. AllContentWrapper๋ ์ฒซ ๋ฒ์งธ ์ฌ์ง์์ ๋ ธ๋์ border๋ก ํ์๋๋ ์์ญ์ด๋ค. ํด๋น wrapper๋ width๊ฐ 900px ์ดํ๊ฐ ๋๋ฉด flex ๋ฐฉํฅ์ column์ผ๋ก ๋ณ๊ฒฝํ๋ ํน๋ณํ ์ญํ ์ ์ํํ๋ค.

AllContentWrapper๋ ์ฌ์ค์ ImgWrapper์ InfoWrapper๋ฅผ ๊ฐ์ธ๊ณ ์๋ค๊ณ ๋ด๋ ๋ฌด๋ฐฉํ๋ค. 'flex:1'์ด ๊ณตํต์ ์ผ๋ก ์์ฑ๋์ด ์๋ ์ ์ ํ์ธํ ์ ์๋ค. ์ฝ๊ฒ ๋งํ์๋ฉด AllContentWrapper ์์ญ์ ๋ฐ๋ฐ์ผ๋ก ๋๋๊ฒ ๋ค๋ ์๋ฏธ์ด๋ค. align-items๋ฅผ flex-start๋ก ์ง์ ํ์ฌ ํ๋ฉด ์๋จ์ ์์นํ๋๋ก ์ค์ ํ๋ค.

๊ฐ์ข info, ์ต์ ๊ทธ๋ฆฌ๊ณ ์๋์ ํฉ์น ์์ญ์ด ProductDetailPageInfoDataWrapper์ด๋ค. ํ๋ง๋๋ก InfoWrapper๋ฅผ InfoDataWrapper์ ButtonWrapper๋ก ๊ตฌ์ฑ๋๋ค๊ณ ํ ์ ์๋ค. 'flex:1.5'์ 'flex:2'๋ฅผ ํตํด 1.5 ๋ 2์ ๋น์จ๋ก InfoWrapper ๋ด๋ถ์ ์์ญ์ ์ฐจ์งํ๊ณ ์๋ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.

๋ง์ง๋ง์ผ๋ก ProductDetailPageInfoDataWrapper๋ div์ OptionWrapper ๊ทธ๋ฆฌ๊ณ AmountWrapper๋ก ๊ตฌ์ฑ๋๋ค. InfoDataWrapper๋ฅผ ๊ธฐ์ค์ผ๋ก ์ ์ ํ flex๋ฅผ ๋๋ ๊ฐ๊ณ ์๋ค.

detail page์์ ์ฌ์ฉํ๋ ์นด์ดํฐ์ ๋๋กญ๋ค์ด์, component -> Detail ํด๋๋ก ๋ถ๋ฆฌํ๋ค. ๋ฐ์ดํฐ๊ฐ ์ฐ๊ฒฐ๋ ์ํ๋ ์๋๋ค. ์ด ๋ถ๋ถ์ด ์์ธ ํ์ด์ง์์ ์ฅ๋ฐ๊ตฌ๋ ํ์ด์ง๋ก ๋์ด๊ฐ๋ ๋ณ๊ณก์ ์ด๋ค.
Counter.js
import React, { useState } from "react";
import styled from "styled-components";
const CounterContainer = styled.div`
display: flex;
align-items: center;
`;
const Button = styled.button`
padding: 10px 20px;
font-size: 1.5em;
`;
const Display = styled.div`
padding: 10px;
font-size: 1.5em;
margin: 0 20px;
`;
const Counter = () => {
const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount((prevCount) => prevCount + 1);
};
const handleDecrement = () => {
if (count > 0) {
setCount((prevCount) => prevCount - 1);
}
};
return (
<CounterContainer>
<Button onClick={handleDecrement}>-</Button>
<Display>{count}</Display>
<Button onClick={handleIncrement}>+</Button>
</CounterContainer>
);
};
export default Counter;
Dropdown.js
import React, { useState } from "react";
import styled from "styled-components";
const DropdownButton = styled.div`
padding: 10px;
width: 100%;
border: 2px solid black;
cursor: pointer;
background-color: #f0f0f0;
color: black;
`;
const DropdownList = styled.div`
display: ${({ isOpen }) => (isOpen ? "block" : "none")};
`;
const DropdownItem = styled.div`
padding: 10px;
width: 200px;
border: 2px solid black;
cursor: pointer;
&:hover {
background-color: #f0f0f0;
}
`;
const Dropdown = () => {
const [isOpen, setIsOpen] = useState(false);
const [selectedOption, setSelectedOption] = useState(null);
const options = ["Option 1", "Option 2", "Option 3"];
const handleOptionClick = (option) => {
setSelectedOption(option);
setIsOpen(false);
};
return (
<>
<DropdownButton onClick={() => setIsOpen(!isOpen)}>
{selectedOption || "Select an option"}
</DropdownButton>
<DropdownList isOpen={isOpen}>
{options.map((option) => (
<DropdownItem key={option} onClick={() => handleOptionClick(option)}>
{option}
</DropdownItem>
))}
</DropdownList>
</>
);
};
export default Dropdown;
ํ์ฌ ๐ข

๊ตฌ๋ฆฌ๋ค. ํ์ง๋ง ์ฒ์๋ณด๋จ ๊ด์ฐฎ์์ก๋ค. ๋ด์ผ ๋ ์์ ํ๊ธฐ๋ก
More to read
ํ๋ก ํธ์๋์ ๋ฐฑ์๋ ์ฌ์ด
HTTP ์ํ ์ฝ๋๋ ํ๋ก ํธ์๋์์ ๋ฐฑ์๋๋ก ๋ณด๋๋ ์์ฒญ์ ์ํ ๊ฒฐ๊ณผ๋ฅผ ์๋ฏธํ๋ ์ผ์ข ์ ์ฝ์์ด๋ฉฐ, API๋ฅผ ๊ตฌ์ฑํ๋ ํต์ฌ ์์ ์ค ํ๋์ ๋๋ค. ์ํ ์ฝ๋์ ๊ด๋ จํ์ฌ, ๋ฐฑ์๋๋ ์ ๋ชจ๋ฅด๋ ํ๋ก ํธ์๋์ ์ฌํ ์ฌ์ ์ด ์์ต๋๋ค.์๋๋ ์์ฒญ์ด ์คํจํ์์๋, ๋ฐฑ์๋์์ ์ํ ์ฝ๋
JWTํ ํฐ ๊ด๋ฆฌ ๋ฐฉ์ ํบ์๋ณด๊ธฐ
0. ๋ค์ด๊ฐ๋ฉฐ ๐ฏ ์๋น์ค์ ์ ๊ทผํ๋ ค๋ ์ฌ์ฉ์๊ฐ ๋๊ตฌ์ธ์ง ํ์ธํ๋ ๊ณผ์ ์ ์ฌ์ฉ์ ์ธ์ฆ์ด๋ผ๊ณ ํฉ๋๋ค. ์ธ์ฆ๋ ์ฌ์ฉ์์๊ฒ ์ฃผ์ด์ง ๊ถํ์ ํ์ธํ๋ ์์ ์ ์ธ๊ฐ๋ผ๊ณ ๋ถ๋ฆ ๋๋ค. ์ด๋ฒ ๊ธ์์๋ ์ธ๊ฐ๋ ๋ค๋ฃจ์ง ์์ต๋๋ค. ์ฌ์ฉ์ ์ธ์ฆ์๋ ๋ง์ ๋ฐฉ์์ด ์์ง๋ง, ์ค๋์ ์ธ์ ์ธ์ฆ ๋ฐฉ
A2AA2A / MCP ๋ฉํฐ ์์ด์ ํธ ์ค์ผ์คํธ๋ ์ด์
0. ๋ค์ด๊ฐ๋ฉฐ โ๏ธ Google for Developers์, ๋ ์คํ ๋ ๊ณต๊ธ๋ง ์๋๋ฆฌ์ค๋ก ์ฎ์ 6๋ ํ๋กํ ์ฝ(MCP, A2A, UCP, AP2, A2UI, AG-UI)์ ๋ํ ๊ฐ์ด๋๊ฐ ๊ฒ์๋ ์ดํ, MCP์ A2A๋ถํฐ ๊ตฌํํด ๋ณด๋ ๊ฒ์ด ์ข์ ๊ฒ ๊ฐ๋ค๋ ์๊ฐ์ด ๋ค์์ต๋