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 (
-
+
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';