aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/app/components/ErrorDisplay.tsx
blob: f63c9957e4670fe20b0560386181b7b8f4e34663 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import React from "react";
import { AlertTriangle, RefreshCw, Wifi, WifiOff } from "lucide-react";
import { useTranslation } from "react-i18next";
import "./ErrorDisplay.css";

interface ErrorDisplayProps {
  error: {
    type: "network" | "server" | "unknown";
    status?: number;
    message?: string;
  };
  onRetry?: () => void;
  title?: string;
  className?: string;
}

export const ErrorDisplay: React.FC<ErrorDisplayProps> = ({
  error,
  onRetry,
  title,
  className = "",
}) => {
  const { t } = useTranslation();

  const getErrorIcon = () => {
    switch (error.type) {
      case "network":
        return <WifiOff className="error-icon" />;
      case "server":
        return <AlertTriangle className="error-icon" />;
      default:
        return <AlertTriangle className="error-icon" />;
    }
  };

  const getErrorMessage = () => {
    switch (error.type) {
      case "network":
        return t(
          "errors.network",
          "No hay conexión a internet. Comprueba tu conexión y vuelve a intentarlo.",
        );
      case "server":
        if (error.status === 404) {
          return t(
            "errors.not_found",
            "No se encontraron datos para esta parada.",
          );
        }
        if (error.status === 500) {
          return t(
            "errors.server_error",
            "Error del servidor. Inténtalo de nuevo más tarde.",
          );
        }
        if (error.status && error.status >= 400) {
          return t(
            "errors.client_error",
            "Error en la solicitud. Verifica que la parada existe.",
          );
        }
        return t("errors.server_generic", "Error del servidor ({{status}})", {
          status: error.status || "desconocido",
        });
      default:
        return (
          error.message ||
          t("errors.unknown", "Ha ocurrido un error inesperado.")
        );
    }
  };

  const getErrorTitle = () => {
    if (title) return title;

    switch (error.type) {
      case "network":
        return t("errors.network_title", "Sin conexión");
      case "server":
        return t("errors.server_title", "Error del servidor");
      default:
        return t("errors.unknown_title", "Error");
    }
  };

  return (
    <div className={`error-display ${className}`}>
      <div className="error-content">
        {getErrorIcon()}
        <h3 className="error-title">{getErrorTitle()}</h3>
        <p className="error-message">{getErrorMessage()}</p>
        {onRetry && (
          <button className="error-retry-button" onClick={onRetry}>
            <RefreshCw className="retry-icon" />
            {t("errors.retry", "Reintentar")}
          </button>
        )}
      </div>
    </div>
  );
};