@legendarymediatv/bootstrap
Version:
additional Bootstrap-based React components for extending functionality to react-bootstrap and gatsby
173 lines (141 loc) • 4.56 kB
JavaScript
// dependencies
import React from "react";
import { combine, prepare } from "../functions/functions";
// components
import RBSAlert from "react-bootstrap/Alert";
import Button from "react-bootstrap/Button";
import Link from "../Link/Link";
const AlertLink = (props) => {
// prepare properties
const [properties, children] = prepare(props);
// convert to Gatsby-friendly link
properties.as = Link;
// merge classes
properties.className = combine(properties.className);
return <RBSAlert.Link {...properties}>{children}</RBSAlert.Link>;
};
export default class Alert extends React.Component {
// sub-components
static Heading = RBSAlert.Heading;
static Link = AlertLink;
render() {
// prepare properties
const [properties, children] = prepare(this.props);
// extract error
let error = properties.error;
let errorURL;
let errorMethod;
if (error && typeof error === "object" && !Array.isArray(error)) {
if (error.url) errorURL = error.url;
if (error.method) errorMethod = error.method;
if (error.error) error = error.error;
else if (error.message) error = error.message;
}
delete properties.error;
// only submission errors should come in as arrays
const submissionError = error && Array.isArray(error);
// custom title
let title = properties.title ? properties.title : null;
if (error && !title)
title = submissionError ? "Submission Error" : "Process Error";
delete properties.title;
// custom subtitle
let subtitle = properties.subtitle ? properties.subtitle : null;
delete properties.subtitle;
// set default theme
if (error && !properties.variant) properties.variant = "danger";
if (error && !subtitle) {
if (
typeof error === "string" &&
error.indexOf("Request failed with status code") !== -1
) {
// extract the HTML error code
const code = parseInt(error.substring(error.length - 3));
switch (code) {
case 400:
subtitle =
"The server could not understand the request due to invalid syntax";
break;
case 401:
subtitle = "You must authenticate before proceeding";
break;
case 403:
subtitle = "You do not have access to the requested content";
break;
case 404:
subtitle =
"The URL is invalid or the requested resource does not exist";
break;
case 429:
subtitle = "You have sent too many requests recently";
break;
case 500:
subtitle =
"The server has encountered a situation it doesn’t know how to handle";
break;
case 503:
subtitle = "The server is not ready to handle the request";
break;
default:
subtitle = error;
}
}
// generic network error
else if (error === "Network Error")
subtitle = "The server is currently unreachable";
// all other errors
else {
subtitle = submissionError
? "Please fix the following error(s):"
: error ??
"The server has encountered a situation it doesn’t know how to handle";
}
}
// extract retry handler
const onRetry = properties.onRetry;
delete properties.onRetry;
// merge classes
properties.className = combine(properties.className);
return (
<RBSAlert {...properties}>
{title ? (
<Alert.Heading as="div" className="h3">
{title}
</Alert.Heading>
) : null}
{subtitle ? <p className="lead">{subtitle}</p> : null}
{submissionError ? (
<ul>
{error.map((errorMessage, errorIndex) => (
<li key={errorIndex}>{errorMessage}</li>
))}
</ul>
) : null}
{children}
{!submissionError ? (
<>
{errorURL ? (
<p>
<b>URL:</b> {errorURL}
</p>
) : null}
{errorMethod ? (
<p>
<b>Method:</b> {errorMethod}
</p>
) : null}
</>
) : null}
{onRetry ? (
<Button
variant={properties.variant}
className="w-100 w-md-auto"
onClick={onRetry}
>
Retry
</Button>
) : null}
</RBSAlert>
);
}
}