-
Notifications
You must be signed in to change notification settings - Fork 6
new(component): StatusPage #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,86 @@ | ||
| --- | ||
| title: "StatusPage" | ||
| description: "A widget that displays the operational status of a service." | ||
| author: "@trishaprile" | ||
| version: "1.0.0" | ||
| --- | ||
|
|
||
| import { useEffect, useState } from 'react'; | ||
|
|
||
| export const StatusPage = ({ title, url}) => { | ||
| const [status, setStatus] = useState(null); | ||
| const [indicator, setIndicator] = useState(null); | ||
| const [error, setError] = useState(null); | ||
|
|
||
| useEffect(() => { | ||
| let isMounted = true; | ||
|
|
||
| if (url) { | ||
| const fetchStatus = async () => { | ||
| try { | ||
| const res = await fetch(`${url.replace(/\/$/, '')}/api/v2/status.json`); | ||
| if (!res.ok) throw new Error(`Failed to fetch status: ${res.status}`); | ||
| const data = await res.json(); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I haven't seen anywhere that describes what the response form needs to be. It might be good if the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The response from a Statuspage endpoint should include |
||
| if (!isMounted) return; | ||
|
|
||
| setStatus(data.status.description); | ||
| setIndicator(data.status.indicator); | ||
| } catch (err) { | ||
| if (!isMounted) return; | ||
|
|
||
| setError('Unable to fetch status'); | ||
| } | ||
| }; | ||
| fetchStatus(); | ||
| } | ||
|
|
||
| return () => { | ||
| isMounted = false; | ||
| }; | ||
| }, [url]); | ||
|
|
||
| return ( | ||
| <div className="relative max-w-sm p-5 rounded-lg shadow-sm border border-gray-200 dark:border-gray-400"> | ||
| <a | ||
| href={url} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="absolute top-3 right-3 text-gray-400 hover:text-gray-600" | ||
| aria-label="View full status page" | ||
| > | ||
| <i className="fa fa-arrow-up-right-from-square" /> | ||
| </a> | ||
| <h3 className="mt-0! mb-2 text-gray-600! dark:text-white!">{title}</h3> | ||
| {error ? ( | ||
| <div className="flex items-center space-x-2 text-red-600"> | ||
| <span className="w-3 h-3 rounded-full bg-red-500" /> | ||
| <span>{error}</span> | ||
| </div> | ||
| ) : !status ? ( | ||
| <div className="flex items-center space-x-2"> | ||
| <span className="w-3 h-3 rounded-full bg-gray-400 animate-pulse" /> | ||
| <span>Loading status…</span> | ||
| </div> | ||
| ) : ( | ||
| <div className="flex items-center space-x-2"> | ||
| <span | ||
| className={`fa-duotone fa-solid ${ | ||
| indicator === 'none' | ||
| ? 'fa-circle-check text-green-500' | ||
| : indicator === 'minor' | ||
| ? 'fa-circle-exclamation text-yellow-500' | ||
| : indicator === 'major' | ||
| ? 'fa-circle-exclamation text-orange-500' | ||
| : indicator === 'critical' | ||
| ? 'fa-circle-x text-red-500' | ||
| : 'fa-circle text-gray-500' | ||
| }`} | ||
| /> | ||
| <span className="text-sm font-medium">{status}</span> | ||
| </div> | ||
| )} | ||
| </div> | ||
| ); | ||
| }; | ||
|
|
||
| <StatusPage title="ReadMe Status" url="https://www.readmestatus.com" /> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| # StatusPage | ||
|
|
||
| ## Overview | ||
|
|
||
| A `<StatusPage />` can be used to embed the current operational status, health, or uptime of a service or system. It fetches live status information from a public [Statuspage](https://www.atlassian.com/software/statuspage) endpoint (e.g. https://www.githubstatus.com) and displays the status indicator and description. | ||
|
|
||
| <img src="status-page.png" width="800" /> | ||
|
|
||
| ## Usage | ||
|
|
||
| ```mdx | ||
| <StatusPage title="ReadMe Status" url="https://www.readmestatus.com" /> | ||
| ``` | ||
|
|
||
| ## Props | ||
|
|
||
| | Prop | Type | Description | | ||
| | ------- | ------ | --------------------------------- | | ||
| | `title` | string | The heading displayed at the top. | | ||
| | `url` | string | The URL of the status page. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was traveling on Friday so I didn't get a chance to ask then, but is this meant to only show ReadMe statuses?
If this is meant to be dynamic for the customer I have a couple of questions:
/api/v2/status.json? It seems strange that we would force them into a specific endpoint form instead of just taking the url and using it. If we aren't forcing them to have an endpoint ending in/api/v2/status.jsonthen I don't think this will work. It will fail because we are modifying the url by appending/api/v2/status.jsonto the end of it.E.g. if I have a status endpoint http://www.mycompany.com/service1/status, this component will modify it and make it http://www.mycompany.com/service1/status_/api/v2/status.json_.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component should only work for sites that use Atlassian's Status Page service. It seems like a lot of companies do, including ReadMe. So adding
/api/v2/status.jsonto the URL should work in these cases, for example https://www.readmestatus.com/api/v2/status.json, https://www.githubstatus.com/api/v2/status.json, and https://atlas-status.mit.edu/api/v2/status.json. Let me know if you want me to be more specific in the Overview section of the README!Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope that answers my question and the one below.
I would mention that in the
readme.mdpage and also that the url shouldn't end in/api/v2/status.json. The component assumes the passed in url doesn't end in/api/v2/status.jsonbut a customer might put the full url, eg.https://www.myservice.com/api/v2/status.jsonwhich the component will change tohttps://www.myservice.com/api/v2/status.json/api/v2/status.json. The component should only add the suffix if it isn't present or we should make the documentation clear that the passed in url should not end in/api/v2/status.json.Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
gotcha, I'll update the documentation! ideally the user should set the
urlas their actual status page site and not the.jsonversion. the open link in new tab icon button takes in the url