import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useRef } from 'react';
import { isRouteErrorResponse, useRouteError } from 'react-router';
import styled, { ThemeProvider, theme } from '@darajs/styled-components';
import { Button } from '@darajs/ui-components';
import { useConfig } from '../shared';
import { LoaderError } from '../types';
import ErrorStatusCodePage, { errorMessages } from './error-status-code-page';
const CenteredDivWithGap = styled.div `
    display: flex;
    flex: 1;
    flex-direction: column;
    gap: 2rem;

    min-width: 0;
    margin: auto;
    padding: 0.5rem;

    text-align: center;

    code {
        padding: 0.2rem;
        background-color: ${(props) => props.theme.colors.grey2};
        border-radius: 0.5rem;
    }
`;
const Title = styled.h1 `
    margin: 0;
    font-weight: 500;
`;
const ErrorMessage = styled.p `
    font-size: 0.875rem;
    line-height: 1.5;
`;
const ErrorStack = styled.pre `
    overflow-x: auto;
    display: flex;
    flex-shrink: 1;

    min-width: 0;

    font-size: 0.825rem;
    text-align: left;
`;
const ButtonBar = styled.div `
    display: flex;
    justify-content: center;

    button {
        width: fit-content;
    }
`;
function isProductionBuild(config) {
    return config.build_mode === 'PRODUCTION' && !config.build_dev;
}
function RouteErrorBoundary() {
    const error = useRouteError();
    const config = useConfig();
    const firstRender = useRef(true);
    if (firstRender.current) {
        // eslint-disable-next-line no-console
        console.error(error);
        firstRender.current = false;
    }
    // explicit errors from loaders
    if (isRouteErrorResponse(error)) {
        // show a regular error page when the error code is known
        if (String(error.status) in errorMessages) {
            return _jsx(ErrorStatusCodePage, { code: String(error.status) });
        }
        return (_jsxs(CenteredDivWithGap, { children: [_jsxs(Title, { children: [error.status, " ", error.statusText] }), _jsx(ErrorMessage, { children: "Try again or contact the application owner" }), _jsx(ButtonBar, { children: _jsx(Button, { href: "/login", styling: "error", children: "Go to home" }) })] }));
    }
    // in prod, always show the error page
    if (isProductionBuild(config)) {
        return (_jsxs(CenteredDivWithGap, { children: [_jsx(Title, { children: "Unexpected error occurred" }), _jsx(ErrorMessage, { children: "Try again or contact the application owner" }), _jsx(ButtonBar, { children: _jsx(Button, { href: "/login", styling: "error", children: "Go to home" }) })] }));
    }
    // Otherwise, show the actual error to the user (developer mode)
    if (error instanceof LoaderError) {
        // Explicitly handle loader errors
        return (_jsxs(CenteredDivWithGap, { children: [_jsxs(Title, { children: ["Error loading page ", _jsx("code", { children: error.payload.path })] }), _jsxs(ErrorMessage, { children: ["Error was thrown by action ", _jsx("code", { children: error.payload.action_name }), ". ", _jsx("br", {}), "To ensure security and integrity of the page content, errors raised within ", _jsx("code", { children: "on_load" }), ' ', "actions trigger this error boundary page rather than only showing a notification. For best user experience, gracefully handle any exceptions raised within those actions."] }), _jsx(ErrorStack, { children: error.payload.stacktrace }), _jsx(ButtonBar, { children: _jsx(Button, { href: "/login", styling: "error", children: "Go to home" }) })] }));
    }
    return (_jsxs(CenteredDivWithGap, { children: [_jsx(Title, { children: "Unknown error occurred" }), _jsx(ErrorStack, { children: String(error) }), _jsx(ButtonBar, { children: _jsx(Button, { href: "/login", styling: "error", children: "Go to home" }) })] }));
}
function RouteErrorBoundaryPage() {
    return (_jsx(ThemeProvider, { theme: theme, children: _jsx(RouteErrorBoundary, {}) }));
}
export default RouteErrorBoundaryPage;
//# sourceMappingURL=route-error-boundary.js.map