카테고리 없음

[프로젝트] 404, 500 errorPage & loadingSpinner 구현하기

ChatjihoiPT 2025. 5. 22. 13:23
 

 

1. 404 ErrorPage 구현

import { useSearchParams } from "react-router-dom";

export default function NotFoundPage() {
  const [searchParams] = useSearchParams();

  // URL 쿼리 파라미터에서 에러 메시지 추출
  const message = searchParams.get("message");

  // 메시지가 있으면 디코딩, 없으면 기본 메시지 사용
  const errorMessage = message
    ? decodeHTMLEntities(message)
    : "페이지를 찾을 수 없어요...😢";

  // HTML 엔티티 디코딩 함수
  function decodeHTMLEntities(text: string) {
    const textarea = document.createElement("textarea");
    textarea.innerHTML = text;
    return textarea.value;
  }

  return (
    <div className="flex flex-col justify-center items-center min-h-screen bg-gradient-to-b from-[#f7d9aa] to-[#a8c0ff] text-center px-6 relative overflow-hidden">
      <div className="z-10">
        <h1 className="text-[6rem] font-extrabold text-[#3b82f6] drop-shadow-md">
          404
        </h1>
        <p className="text-xl text-gray-800 mb-4">{errorMessage}</p>
        <p className="text-base text-gray-700 mb-6">
          입력한 주소를 다시 확인해 주세요.
        </p>

        <button
          onClick={() => (window.location.href = "/")}
          className="mt-4 px-6 py-2 bg-[#9DEEFB] hover:bg-[#3BDDF7] text-blue-900 font-semibold rounded-full shadow-md transition-all"
        >
          홈으로 돌아가기
        </button>
      </div>
    </div>
  );
}

2. 500 ErrorPage 구현

import { useSearchParams } from "react-router-dom";

export default function ErrorPage() {
  const [searchParams] = useSearchParams();

  // URL 쿼리 파라미터에서 에러 정보 추출
  const status = searchParams.get("status") || "500";
  const message = searchParams.get("message") || "서버가 잠시 쉬고 있어요...☔";

  // HTML 디코딩 (인코딩된 문자열 처리)
  const decodedMessage = decodeHTMLEntities(message);

  // HTML 엔티티 디코딩 함수
  function decodeHTMLEntities(text: string) {
    const textarea = document.createElement("textarea");
    textarea.innerHTML = text;
    return textarea.value;
  }

  return (
    <div className="flex flex-col justify-center items-center min-h-screen bg-gradient-to-b from-[#a8c0ff] to-[#f7d9aa] text-center px-6 relative overflow-hidden">
      <div className="z-10">
        <h1 className="text-[6rem] font-extrabold text-[#ff5f5f] drop-shadow-md">
          {status}
        </h1>
        <p className="text-xl text-gray-800 mb-4">{decodedMessage}</p>
        <p className="text-base text-gray-700 mb-6">
          잠시 후 다시 시도해 주세요.
        </p>

        <button
          onClick={() => (window.location.href = "/")}
          className="mt-4 px-6 py-2 bg-[#9DEEFB] hover:bg-[#3BDDF7] text-blue-900 font-semibold rounded-full shadow-md transition-all"
        >
          홈으로 돌아가기
        </button>
      </div>
    </div>
  );
}

3. LoadingSpinner 구현 

interface LoadingSpinnerProps {
  /**
   * hex값 string 또는 color string(red, blue, ...)
   */
  color?: string;
  /**
   * 가로 세로 크기 (px)
   */
  size?: number;
}

export function LoadingSpinner({ color = "#3BDDF7", size = 50 }: LoadingSpinnerProps) {
  return (
    <div
      role="progressbar"
      className="rounded-full border-4 border-gray-300 border-t-solid animate-spin"
      style={{
        width: size,
        height: size,
        borderTopColor: color,
      }}
    />
  );
}

 

import { LoadingSpinner } from "@/components/common/LoadingSpinner";

export const LoadingPage = () => {
  return (
    <div className="flex items-center justify-center h-screen">
      <LoadingSpinner />
    </div>
  );
};