FE ์ฝ”๋“œ ํ€„๋ฆฌํ‹ฐ (ํ† ์Šค)

๊ฐ€๋…์„ฑ 1 : ๋งฅ๋ฝ ์ค„์ด๊ธฐ

date:
2025-12-03
order:
1
tags:
null

๋งฅ๋ฝ ์ค„์ด๊ธฐ

1. ๊ฐ™์ด ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ ๋ถ„๋ฆฌํ•˜๊ธฐ

๋ฌธ์ œ ์ฝ”๋“œ

์•„๋ž˜์˜ ์˜ˆ์‹œ์—์„œ ๊ฐ™์ด ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋Š” ๋ฌด์—‡์ด๊ณ  ๊ฐ™์ด ์‹คํ–‰๋˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋Š” ๋ฌด์—‡์ผ๊นŒ?

function SubmitButton() {
  const isViewer = useRole() === "viewer";

  useEffect(() => {
    if (isViewer) {
      return;
    }
    showButtonAnimation();
  }, [isViewer]);

  return isViewer ? (
    <TextButton disabled>Submit</TextButton>
  ) : (
    <Button type="submit">Submit</Button>
  );
}

์œ„์˜ SubmitButton ์ปดํฌ๋„ŒํŠธ๋Š” isViewer ์— ๋”ฐ๋ผ ๋‹ค๋ฅธ ํ–‰๋™์„ ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์ด๋‹ค.

  • ์ฐธ : TextButton ๋ Œ๋”๋ง.
  • ๊ฑฐ์ง“ : showButtonAnimation ํ˜ธ์ถœ, Button ์„ ๋ Œ๋”๋ง.

์ฆ‰ '์ฐธ or ๊ฑฐ์ง“' ์— ๋”ฐ๋ผ ์–ด๋–ค ์ฝ”๋“œ๋Š” ์ „ํ˜€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์–˜๊ธฐ๋‹ค.

๊ฐœ์„  ์ฝ”๋“œ

function SubmitButton() {
  const isViewer = useRole() === "viewer";

  return isViewer ? <ViewerSubmitButton /> : <AdminSubmitButton />;
}

function ViewerSubmitButton() {
  return <TextButton disabled>Submit</TextButton>;
}

function AdminSubmitButton() {
  useEffect(() => {
    showButtonAnimation();
  }, []);

  return <Button type="submit">Submit</Button>;
}

์œ„ ์ฒ˜๋Ÿผ isViewer ๊ฐ€ ์ฐธ์ผ๋•Œ๋งŒ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ์™€ ๊ฑฐ์ง“์ผ๋•Œ๋งŒ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ๋ฅผ ๋ถ„๋ฆฌํ•˜์—ฌ ๋ณ„๋„์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๋งŒ๋“ค๋ฉด ํ›จ์”ฌ ๊ฐ€๋…์„ฑ์ด ๊ฐœ์„ ๋œ๋‹ค.

2. ๊ตฌํ˜„ ์ƒ์„ธ ์ถ”์ƒํ™”ํ•˜๊ธฐ

๋ฌธ์ œ ์ฝ”๋“œ

์•„๋ž˜์˜ ์˜ˆ์‹œ๋Š” ํ•œ ์ปดํฌ๋„ŒํŠธ ์•ˆ์— ์ƒ์„ธ ๋กœ์ง๊ณผ UI ๋ Œ๋”๋ง ์ฑ…์ž„์ด ํ•จ๊ป˜ ์žˆ๋Š” ๊ฒฝ์šฐ๋‹ค.

function FriendInvitation() {
  const { data } = useQuery(/* ์ƒ๋žต.. */);

  // ์ด์™ธ ์ด ์ปดํฌ๋„ŒํŠธ์— ํ•„์š”ํ•œ ์ƒํƒœ ๊ด€๋ฆฌ, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฐ ๋น„๋™๊ธฐ ์ž‘์—… ๋กœ์ง...

  const handleClick = async () => {
    const canInvite = await overlay.openAsync(({ isOpen, close }) => (
      <ConfirmDialog
        title={`${data.name}๋‹˜์—๊ฒŒ ๊ณต์œ ํ•ด์š”`}
        cancelButton={
          <ConfirmDialog.CancelButton onClick={() => close(false)}>
            ๋‹ซ๊ธฐ
          </ConfirmDialog.CancelButton>
        }
        confirmButton={
          <ConfirmDialog.ConfirmButton onClick={() => close(true)}>
            ํ™•์ธ
          </ConfirmDialog.ConfirmButton>
        }
        /* ์ค‘๋žต */
      />
    ));

    if (canInvite) {
      await sendPush();
    }
  };

  // ์ด์™ธ ์ด ์ปดํฌ๋„ŒํŠธ์— ํ•„์š”ํ•œ ์ƒํƒœ ๊ด€๋ฆฌ, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฐ ๋น„๋™๊ธฐ ์ž‘์—… ๋กœ์ง...

  return (
    <>
      <Button onClick={handleClick}>์ดˆ๋Œ€ํ•˜๊ธฐ</Button>
      {/* UI๋ฅผ ์œ„ํ•œ JSX ๋งˆํฌ์—…... */}
    </>
  );
}

์ด ์ปดํฌ๋„ŒํŠธ๋Š” ์ง€๊ธˆ ์—ฌ๋Ÿฌ ๋งฅ๋ฝ์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.

๊ฐœ์„  ์ฝ”๋“œ

export function FriendInvitation() {
  const { data } = useQuery(/* ์ƒ๋žต.. */);

  // ์ด์™ธ ์ด ์ปดํฌ๋„ŒํŠธ์— ํ•„์š”ํ•œ ์ƒํƒœ ๊ด€๋ฆฌ, ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ ๋ฐ ๋น„๋™๊ธฐ ์ž‘์—… ๋กœ์ง...

  return (
    <>
      <InviteButton name={data.name} />
      {/* UI๋ฅผ ์œ„ํ•œ JSX ๋งˆํฌ์—… */}
    </>
  );
}

function InviteButton({ name }) {
  return (
    <Button
      onClick={async () => {
        const canInvite = await overlay.openAsync(({ isOpen, close }) => (
          <ConfirmDialog
            title={`${name}๋‹˜์—๊ฒŒ ๊ณต์œ ํ•ด์š”`}
            cancelButton={
              <ConfirmDialog.CancelButton onClick={() => close(false)}>
                ๋‹ซ๊ธฐ
              </ConfirmDialog.CancelButton>
            }
            confirmButton={
              <ConfirmDialog.ConfirmButton onClick={() => close(true)}>
                ํ™•์ธ
              </ConfirmDialog.ConfirmButton>
            }
            /* ์ค‘๋žต */
          />
        ));

        if (canInvite) {
          await sendPush();
        }
      }}
    >
      ์ดˆ๋Œ€ํ•˜๊ธฐ
    </Button>
  );
}

๋กœ์ง ์ข…๋ฅ˜์— ๋”ฐ๋ผ ํ•ฉ์ณ์ง„ ํ•จ์ˆ˜ ์ชผ๊ฐœ๊ธฐ

2. ์ด๋ฆ„ ๋ถ™์ด๊ธฐ

๋ณต์žกํ•œ ์กฐ๊ฑด์— ์ด๋ฆ„ ๋ถ™์ด๊ธฐ

๋งค์ง ๋„˜๋ฒ„์— ์ด๋ฆ„ ๋ถ™์ด๊ธฐ

3. ์œ„์—์„œ ์•„๋ž˜๋กœ ์ฝํžˆ๊ฒŒ ํ•˜๊ธฐ

์‹œ์  ์ด๋™ ์ค„์ด๊ธฐ

์‚ผํ•ญ ์—ฐ์‚ฐ์ž ๋‹จ์ˆœํ•˜๊ฒŒ ํ•˜๊ธฐ