React

[TIL/React] 2023/08/23

src/pages/EventPage.js ๐ŸŸก > src/data/EventList.js ๐ŸŸก > src/images/index.js ๐ŸŸก > ํ˜„์žฌ ๋ชจ์Šต ๐ŸŸก ์—…๋กœ๋“œ์ค‘.. > ํšŒ๊ณ  ๐ŸŸข '์ด์ƒ๋„ ์ดํ•˜๋„ ์•„๋‹ˆ๋‹ค'๋ผ๋Š” ํ‘œํ˜„์€ ๊ณผ๋Œ€ํ‰๊ฐ€์™€ ๊ณผ์†Œํ‰๊ฐ€๋ฅผ ๋ง‰์œผ๋ ค๋Š” ์˜๋„๋กœ

2023๋…„ 8์›” 23์ผ3min read

src/pages/EventPage.js ๐ŸŸก

code
import React, { useState } from "react";
import styled from "styled-components";
import { events } from "../data/EventList";

const CardContainer = styled.div`
  display: flex;
  overflow-x: scroll;
  width: 100%;
  height: 200px;
  cursor: grab;
  background-color: #424242;
`;

const Card = styled.div`
  height: 100%;
  margin: 30px;
  display: flex;
  justify-content: center;
  align-items: center;
  font-size: 20px;
  transition: transform 0.3s ease;

  &:hover {
    transform: scale(1.1);
    cursor: pointer;
  }
`;

const EventCardWrapper = styled.div``;

const EventCardImg = styled.img`
  width: 400px;
  height: 400px;
`;

const EventPage = () => {
  const [isMousePressed, setIsMousePressed] = useState(false);
  const [containerScrollLeft, setContainerScrollLeft] = useState(0);
  const [startMouseX, setStartMouseX] = useState(0);

  const handleMousePress = (e) => {
    setIsMousePressed(true);
    setStartMouseX(e.pageX - e.currentTarget.offsetLeft);
    setContainerScrollLeft(e.currentTarget.scrollLeft);
    console.log(e.currentTarget.scrollLeft);
  };

  const handleMouseMove = (e) => {
    if (!isMousePressed) return;
    const currentMouseX = e.pageX - e.currentTarget.offsetLeft;
    e.currentTarget.scrollLeft =
      containerScrollLeft - (currentMouseX - startMouseX);
  };

  const handleMouseRelease = () => setIsMousePressed(false);

  return (
    <CardContainer
      style={{ height: "1000px" }}
      onMouseDown={handleMousePress}
      onMouseMove={handleMouseMove}
      onMouseUp={handleMouseRelease}
      onMouseLeave={handleMouseRelease}
    >
      {events?.map((event) => (
        <Card key={event.id}>
          <EventCardWrapper>
            <EventCardImg src={event.image} alt={event.title} />
            <h3
              style={{
                color: "rgb(255, 255, 255)",
                fontWeight: "bolder",
                textAlign: "center",
              }}
            >
              {event.title}
            </h3>
            <p
              style={{
                color: "rgb(155, 155, 155)",
                fontWeight: "bolder",
                textAlign: "center",
              }}
            >
              {event.subtitle}
            </p>
          </EventCardWrapper>
        </Card>
      ))}
    </CardContainer>
  );
};

export default EventPage;

src/data/EventList.js ๐ŸŸก

code
import { eventImg } from "../images";

export const events = [
  {
    id: "1",
    image: eventImg.eventImg1,
    title: "2023 ์—ฌ๋ฆ„ ์„ ๋ฌผ์„ธํŠธ",
    subtitle:
      "์–ผ๋ฆฌ๋ฒ„๋“œ ๊ธฐ๊ฐ„, ์ตœ๋Œ€ 7% ํ• ์ธ๋œ ๊ฐ€๊ฒฉ์œผ๋กœ ์ดˆ์‹ ์„ ํ•œ ๊ฐ์‚ฌ์˜ ๋งˆ์Œ์„ ์ „ํ•˜์„ธ์š”!",
  },
  {
    id: "2",
    image: eventImg.eventImg2,
    title: "ํ‘ธ์งํ•œ ๋ฐ”๋ฒ ํ ํŒŒํ‹ฐ ์ด๋ฒคํŠธ",
    subtitle: "์ตœ๋Œ€ 15,000์› ํ• ์ธ๋ฐ›๊ณ  ํ‘ธ์งํ•œ ๋ฐ”๋ฒ ํ ํŒŒํ‹ฐ๋ฅผ ์ค€๋น„ํ•˜์„ธ์š”!",
  },
  {
    id: "3",
    image: eventImg.eventImg3,
    title: "์นœ๊ตฌ ์ดˆ๋Œ€ ์ด๋ฒคํŠธ",
    subtitle: "์ฆ๊ฑฐ์šด ์ผ์ƒ์˜ ๋ณ€ํ™” '์ดˆ์‹ ์„ '์„ ์†Œ์ค‘ํ•œ ์‚ฌ๋žŒ์—๊ฒŒ ์•Œ๋ ค์ฃผ์„ธ์š”!",
  },
  {
    id: "4",
    image: eventImg.eventImg4,
    title: "์•ฑ ์„ค์น˜ ์ด๋ฒคํŠธ",
    subtitle: "์ •์œก๊ฐ ์•ฑ ์„ค์น˜ํ•˜๊ณ  ์ดˆ์‹ ์„ ํ•œ ์ผ์ƒ์„ ๋ˆ„๋ ค๋ณด์„ธ์š”!",
  },
  {
    id: "5",
    image: eventImg.eventImg5,
    title: "์ƒํ’ˆ ๋ฆฌ๋ทฐ ํ˜œํƒ",
    subtitle: "๋งŒ์กฑํ•˜์‹  ๋งˆ์Œ์„ ๋‹ด์•„ ์ƒํ’ˆ ๋ฆฌ๋ทฐ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.",
  },
  {
    id: "6",
    image: eventImg.eventImg6,
    title: "์‹ ์„ ํ”Œ๋žœ ๋ฐฐ์†ก ํ˜œํƒ",
    subtitle: "ํ•œ ๋ฒˆ ๋ฐฐ์†ก๋น„๋กœ 4ํšŒ ๋ฌด๋ฃŒ๋ฐฐ์†ก",
  },
  {
    id: "7",
    image: eventImg.eventImg1,
    title: "2023 ์—ฌ๋ฆ„ ์„ ๋ฌผ์„ธํŠธ",
    subtitle:
      "์–ผ๋ฆฌ๋ฒ„๋“œ ๊ธฐ๊ฐ„, ์ตœ๋Œ€ 7% ํ• ์ธ๋œ ๊ฐ€๊ฒฉ์œผ๋กœ ์ดˆ์‹ ์„ ํ•œ ๊ฐ์‚ฌ์˜ ๋งˆ์Œ์„ ์ „ํ•˜์„ธ์š”!",
  },
  {
    id: "8",
    image: eventImg.eventImg2,
    title: "ํ‘ธ์งํ•œ ๋ฐ”๋ฒ ํ ํŒŒํ‹ฐ ์ด๋ฒคํŠธ",
    subtitle: "์ตœ๋Œ€ 15,000์› ํ• ์ธ๋ฐ›๊ณ  ํ‘ธ์งํ•œ ๋ฐ”๋ฒ ํ ํŒŒํ‹ฐ๋ฅผ ์ค€๋น„ํ•˜์„ธ์š”!",
  },
  {
    id: "9",
    image: eventImg.eventImg3,
    title: "์นœ๊ตฌ ์ดˆ๋Œ€ ์ด๋ฒคํŠธ",
    subtitle: "์ฆ๊ฑฐ์šด ์ผ์ƒ์˜ ๋ณ€ํ™” '์ดˆ์‹ ์„ '์„ ์†Œ์ค‘ํ•œ ์‚ฌ๋žŒ์—๊ฒŒ ์•Œ๋ ค์ฃผ์„ธ์š”!",
  },
  {
    id: "10",
    image: eventImg.eventImg4,
    title: "์•ฑ ์„ค์น˜ ์ด๋ฒคํŠธ",
    subtitle: "์ •์œก๊ฐ ์•ฑ ์„ค์น˜ํ•˜๊ณ  ์ดˆ์‹ ์„ ํ•œ ์ผ์ƒ์„ ๋ˆ„๋ ค๋ณด์„ธ์š”!",
  },
  {
    id: "11",
    image: eventImg.eventImg5,
    title: "์ƒํ’ˆ ๋ฆฌ๋ทฐ ํ˜œํƒ",
    subtitle: "๋งŒ์กฑํ•˜์‹  ๋งˆ์Œ์„ ๋‹ด์•„ ์ƒํ’ˆ ๋ฆฌ๋ทฐ๋ฅผ ์ž‘์„ฑํ•ด์ฃผ์„ธ์š”.",
  },
  {
    id: "12",
    image: eventImg.eventImg6,
    title: "์‹ ์„ ํ”Œ๋žœ ๋ฐฐ์†ก ํ˜œํƒ",
    subtitle: "ํ•œ ๋ฒˆ ๋ฐฐ์†ก๋น„๋กœ 4ํšŒ ๋ฌด๋ฃŒ๋ฐฐ์†ก",
  },
];

src/images/index.js ๐ŸŸก

code
import logo from "./logo.jpeg";
import backgroundImg from "./background.png";
import termsImg from "./terms.jpeg";
import porkImg from "./porkbelly-fresh-list.png";
import chickenImg from "./chickef-cut-list.png";
import porkcutletImg from "./porkcutlet-sirloin-list.png";
import eggImg from "./egg-fresh-list.png";
import milkImg from "./milk-fresh-list.png";
import hanuroundImg from "./baby-hanuround-bmix-list.png";
import carthegardenImg from "./carthegarden.jpeg";
import eventImg1 from "./eventImg1.png";
import eventImg2 from "./eventImg2.png";
import eventImg3 from "./eventImg3.png";
import eventImg4 from "./eventImg4.png";
import eventImg5 from "./eventImg5.png";
import eventImg6 from "./eventImg6.png";

const eventImg = {
  eventImg1,
  eventImg2,
  eventImg3,
  eventImg4,
  eventImg5,
  eventImg6,
};

export {
  logo,
  backgroundImg,
  termsImg,
  porkImg,
  chickenImg,
  porkcutletImg,
  eggImg,
  milkImg,
  hanuroundImg,
  carthegardenImg,
  eventImg,
};

ํ˜„์žฌ ๋ชจ์Šต ๐ŸŸก

hover๋˜๋ฉด ์•ฝ๊ฐ„ ์ปค์ง„๋‹ค.

ํšŒ๊ณ  ๐ŸŸข

'์ด์ƒ๋„ ์ดํ•˜๋„ ์•„๋‹ˆ๋‹ค'๋ผ๋Š” ํ‘œํ˜„์€ ๊ณผ๋Œ€ํ‰๊ฐ€์™€ ๊ณผ์†Œํ‰๊ฐ€๋ฅผ ๋ง‰์œผ๋ ค๋Š” ์˜๋„๋กœ ์ž์ฃผ ์‚ฌ์šฉํ•œ๋‹ค. '์ด์ ์˜ ๋‹จ์–ด๋“ค'์ด๋ผ๋Š” ์ฑ…์—์„œ๋Š” ํ•ด๋‹น ํ‘œํ˜„์ด, ์‹ค์ƒ ์•„๋ฌด๊ฒƒ๋„ ๋งํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋Œ€๋ถ€๋ถ„์ด๋ผ, ๋ฉ€์ฉกํ•œ ๋ฌธ์žฅ์— ์ƒํˆฌ์ ์œผ๋กœ ๋ฌด์˜๋ฏธํ•œ ๋‹จ์–ด๋“ค์„ ๋ง๋ถ™์ด๋Š” ๋ฏผ๋ง์Šค๋Ÿฌ์šด ๋ง์žฅ๋‚œ์ด๋ผ๊ณ  ์„œ์ˆ ํ•œ๋‹ค.

์šฐ๋ฆฌ๋Š” '์ด์ƒ๋„ ์ดํ•˜๋„ ์•„๋‹ˆ๋‹ค'๋ผ๋Š” ํ‘œํ˜„์„ ์‚ฌ์šฉํ•  ๋•Œ, ๊ณผ๋Œ€ํ‰๊ฐ€๋˜๊ธฐ ์‰ฌ์šด ๋Œ€์ƒ์˜ ๊ฐ€์น˜๋ฅผ ํŠน์ • ๊ธฐ์ค€์ ์— ๊ณ ์ •ํ•˜๋Š” ์—ญํ• ์— ์ง‘์ค‘ํ•œ๋‹ค. ๋ฐ˜๋ฉด ๊ณผ์†Œํ‰๊ฐ€๋˜๋Š” ๋Œ€์ƒ์„ ์˜นํ˜ธํ•˜๋Š” ์—ญํ• ์€ ๋“ฑํ•œ์‹œํ•˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค.

๋ฌด์˜๋ฏธํ•œ ๋ง์žฅ๋‚œ๊นŒ์ง€๋Š” ์•„๋‹ˆ๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค. ์Šค์Šค๋กœ์— ๋Œ€ํ•œ(ํ˜น์€ ๋ฌด์—‡์ธ๊ฐ€์— ๋Œ€ํ•œ) ํ‰๊ฐ€๊ฐ€ ์•ผ๋ฐ•ํ•ด์งˆ ๋•Œ ๊ณผ์†Œํ‰๊ฐ€๋ฅผ ๋ง‰์•„์คŒ์œผ๋กœ์จ ๋ฉ˜ํƒˆ์„ ์ ์ •์„ ์œผ๋กœ ์œ ์ง€ํ•ด ์ค€๋‹ค. ๋‚ด ์ƒ๊ฐ ๊ทธ ์ด์ƒ๋„ ์ดํ•˜๋„ ์•„๋‹ˆ๋‹ค.

More to read

REST API

ํ”„๋ก ํŠธ์—”๋“œ์™€ ๋ฐฑ์—”๋“œ ์‚ฌ์ด

HTTP ์ƒํƒœ ์ฝ”๋“œ๋Š” ํ”„๋ก ํŠธ์—”๋“œ์—์„œ ๋ฐฑ์—”๋“œ๋กœ ๋ณด๋ƒˆ๋˜ ์š”์ฒญ์˜ ์ˆ˜ํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์˜๋ฏธํ•˜๋Š” ์ผ์ข…์˜ ์•ฝ์†์ด๋ฉฐ, API๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ํ•ต์‹ฌ ์š”์†Œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. ์ƒํƒœ ์ฝ”๋“œ์™€ ๊ด€๋ จํ•˜์—ฌ, ๋ฐฑ์—”๋“œ๋Š” ์ž˜ ๋ชจ๋ฅด๋Š” ํ”„๋ก ํŠธ์—”๋“œ์˜ ์Šฌํ”ˆ ์‚ฌ์ •์ด ์žˆ์Šต๋‹ˆ๋‹ค.์•„๋ž˜๋Š” ์š”์ฒญ์ด ์‹คํŒจํ–ˆ์Œ์—๋„, ๋ฐฑ์—”๋“œ์—์„œ ์ƒํƒœ ์ฝ”๋“œ

JWT

ํ† ํฐ ๊ด€๋ฆฌ ๋ฐฉ์‹ ํ†บ์•„๋ณด๊ธฐ

0. ๋“ค์–ด๊ฐ€๋ฉฐ ๐ŸŽฏ ์„œ๋น„์Šค์— ์ ‘๊ทผํ•˜๋ ค๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ํ™•์ธํ•˜๋Š” ๊ณผ์ •์„ ์‚ฌ์šฉ์ž ์ธ์ฆ์ด๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ฆ๋œ ์‚ฌ์šฉ์ž์—๊ฒŒ ์ฃผ์–ด์ง„ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๋Š” ์ž‘์—…์€ ์ธ๊ฐ€๋ผ๊ณ  ๋ถ€๋ฆ…๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์ธ๊ฐ€๋Š” ๋‹ค๋ฃจ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ธ์ฆ์—๋Š” ๋งŽ์€ ๋ฐฉ์‹์ด ์žˆ์ง€๋งŒ, ์˜ค๋Š˜์€ ์„ธ์…˜ ์ธ์ฆ ๋ฐฉ

A2A

A2A / MCP ๋ฉ€ํ‹ฐ ์—์ด์ „ํŠธ ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ด์…˜

0. ๋“ค์–ด๊ฐ€๋ฉฐ โœ๏ธ Google for Developers์—, ๋ ˆ์Šคํ† ๋ž‘ ๊ณต๊ธ‰๋ง ์‹œ๋‚˜๋ฆฌ์˜ค๋กœ ์—ฎ์€ 6๋Œ€ ํ”„๋กœํ† ์ฝœ(MCP, A2A, UCP, AP2, A2UI, AG-UI)์— ๋Œ€ํ•œ ๊ฐ€์ด๋“œ๊ฐ€ ๊ฒŒ์‹œ๋œ ์ดํ›„, MCP์™€ A2A๋ถ€ํ„ฐ ๊ตฌํ˜„ํ•ด ๋ณด๋Š” ๊ฒƒ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๋Š” ์ƒ๊ฐ์ด ๋“ค์—ˆ์Šต๋‹ˆ