diff --git a/src/App.css b/src/App.css index 74b5e05..770926a 100644 --- a/src/App.css +++ b/src/App.css @@ -1,3 +1,7 @@ +body { + background-color: #282c34; +} + .App { text-align: center; } @@ -7,6 +11,10 @@ pointer-events: none; } +.Title { + color: #FFFFFF; +} + @media (prefers-reduced-motion: no-preference) { .App-logo { animation: App-logo-spin infinite 20s linear; @@ -36,3 +44,49 @@ transform: rotate(360deg); } } + +.ServiceTile { + border-radius: 12px; + padding: 1rem; + margin: 1rem; + width: 250px; + background-color: #f4f4f4; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05); + transition: transform 0.2s; +} + +.ServiceTile:hover { + transform: scale(1.03); +} + +.ServiceTile h3 { + margin-top: 0; + font-size: 1.2rem; + color: #333; +} + +.tile.up { + border-left: 5px solid #4caf50; +} + +.tile.down { + border-left: 5px solid #f44336; +} + +.status { + font-weight: bold; + margin: 0.5rem 0; +} + +.timestamp { + font-size: 0.85rem; + color: #666; +} + +.ServiceTileCollection { + display: grid; + grid-template-columns: repeat(2, 1fr); + grid-gap: 20px; + justify-items: center; + margin: 0 auto; +} diff --git a/src/App.js b/src/App.js index 3784575..dd7aeb4 100644 --- a/src/App.js +++ b/src/App.js @@ -1,23 +1,24 @@ -import logo from './logo.svg'; import './App.css'; +import {ServiceTile} from "./components/ServiceTile"; + +const services = [ + 'git.aaronic.cc', + 'jellyfin.aaronic.cc', + 'portainer.aaronic.cc', + 'dnd.aaronic.cc' +] + +const API_URL = 'https://status.aaronic.cc'; function App() { return (
-
- logo -

- Edit src/App.js and save to reload. -

- - Learn React - -
+

Health Check

+
+ {services.map(service => ( + + ))} +
); } diff --git a/src/App.test.js b/src/App.test.js deleted file mode 100644 index 1f03afe..0000000 --- a/src/App.test.js +++ /dev/null @@ -1,8 +0,0 @@ -import { render, screen } from '@testing-library/react'; -import App from './App'; - -test('renders learn react link', () => { - render(); - const linkElement = screen.getByText(/learn react/i); - expect(linkElement).toBeInTheDocument(); -}); diff --git a/src/components/ServiceTile.jsx b/src/components/ServiceTile.jsx new file mode 100644 index 0000000..34aeb20 --- /dev/null +++ b/src/components/ServiceTile.jsx @@ -0,0 +1,55 @@ +import {Component} from "react"; +import {PropTypes} from "prop-types"; + +export class ServiceTile extends Component { + + constructor(props) { + super(props); + this.state = { + isUp: false + }; + } + + // componentDidMount() { + // this.interval = setInterval(this.fetchStatus, 10000); + // } + + componentWillUnmount() { + clearInterval(this.interval); + } + + fetchStatus() { + fetch(this.props.apiURL + "/status/" + this.props.service) + .then(response => { + this.setState({isUp: response.status === 200}); + }); + } + + setIsUp(isUp) { + this.setState({isUp}); + } + + render() { + const {isUp} = this.state; + const {service, statusCode, checkedAt} = this.props; + return ( +
+

{service}

+

+ Status: {isUp ? '🟢 UP' : '🔴 DOWN'} +

+

HTTP Code: {statusCode || 'N/A'}

+

+ Checked at: {checkedAt || 'N/A'} +

+
+ ) + } +} + +ServiceTile.propTypes = { + service: PropTypes.string, + statusCode: PropTypes.number, + checkedAt: PropTypes.string, + apiURL: PropTypes.string +} \ No newline at end of file diff --git a/src/index.js b/src/index.js index d563c0f..2cb1087 100644 --- a/src/index.js +++ b/src/index.js @@ -2,7 +2,6 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; import './index.css'; import App from './App'; -import reportWebVitals from './reportWebVitals'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( @@ -10,8 +9,3 @@ root.render( ); - -// If you want to start measuring performance in your app, pass a function -// to log results (for example: reportWebVitals(console.log)) -// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals -reportWebVitals(); diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 9dfc1c0..0000000 --- a/src/logo.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/reportWebVitals.js b/src/reportWebVitals.js deleted file mode 100644 index 5253d3a..0000000 --- a/src/reportWebVitals.js +++ /dev/null @@ -1,13 +0,0 @@ -const reportWebVitals = onPerfEntry => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } -}; - -export default reportWebVitals; diff --git a/src/setupTests.js b/src/setupTests.js deleted file mode 100644 index 8f2609b..0000000 --- a/src/setupTests.js +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom';