initial app

This commit is contained in:
Arnie
2023-06-01 20:24:59 +02:00
parent bb19e15a40
commit daf399eb3c
38 changed files with 9279 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
import { Global } from "@emotion/react";
import normalizeCss from "normalize.css/normalize.css?inline";
import React from "react";
import { IntlProvider } from "react-intl";
import Router from "./views/Router";
const App: React.FC = () => {
return (
<IntlProvider locale="en" defaultLocale="en">
<Global styles={normalizeCss} />
<Router />
</IntlProvider>
);
};
export default App;
@@ -0,0 +1,67 @@
import React from "react";
type ErrorHandler = (error: Error, info: React.ErrorInfo) => void;
type ErrorHandlingComponent<Props> = (
props: Props,
error?: Error
) => React.ReactNode;
type ErrorState = { error?: Error };
function Catch<Props extends object>(
component: ErrorHandlingComponent<Props>,
errorHandler?: ErrorHandler
): React.ComponentType<Props> {
function Inner({ error, props }: { error?: Error; props: Props }) {
return <React.Fragment>{component(props, error)}</React.Fragment>;
}
return class CatchClass extends React.Component<Props, ErrorState> {
state: ErrorState = {
error: undefined,
};
static getDerivedStateFromError(error: Error) {
return { error };
}
componentDidCatch(error: Error, info: React.ErrorInfo) {
if (errorHandler) {
errorHandler(error, info);
}
}
render() {
return <Inner error={this.state.error} props={this.props} />;
}
};
}
const divStyles: React.CSSProperties = {
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
};
const ErrorBoundary = Catch(function (
props: React.PropsWithChildren,
error?: Error
) {
if (error) {
return (
<div style={divStyles}>
<h2>
There was an error on the page. Please reload the application and try
again.
</h2>
<p />
<p>{error.message}</p>
</div>
);
}
return <>{props.children}</>;
});
export default ErrorBoundary;
@@ -0,0 +1 @@
export { default as ErrorBoundary } from "./ErrorBoundary";
@@ -0,0 +1,56 @@
import styled from "@emotion/styled";
import React from "react";
import MainNavigation from "../Navigation/MainNavigation";
const Root = styled("div")({
background: "rgb(215, 215, 215)",
});
const Container = styled("div")({
alignItems: "stretch",
display: "flex",
margin: "0 auto",
maxWidth: 1600,
minHeight: "100vh",
width: "100vw",
});
const Nav = styled("nav")({
background: "rgb(41, 62, 73)",
color: "white",
flex: "0 0 280px",
padding: "8px 20px",
"@media (max-width: 600px)": {
display: "none",
},
"& a": {
color: "white",
},
});
const Main = styled("main")({
background: "rgb(245, 245, 245)",
color: "rgb(25, 25, 25)",
flex: "1 0 500px",
padding: "8px 20px",
});
const MainLayout: React.FC<React.PropsWithChildren> = (props) => {
const { children } = props;
return (
<Root>
<Container>
<Nav>
<MainNavigation />
</Nav>
<Main>{children}</Main>
</Container>
</Root>
);
};
export default MainLayout;
@@ -0,0 +1,8 @@
import styled from "@emotion/styled";
import { Link as RouterLink } from "react-router-dom";
const Link = styled(RouterLink)({
color: "rgb(35, 115, 220)",
});
export default Link;
@@ -0,0 +1 @@
export { default as Link } from "./Link";
@@ -0,0 +1,12 @@
import React from "react";
const MainNavigation: React.FC = () => {
return (
<>
<p>Contact</p>
<a href="mailto:linkedin@c3c.cz">linkedin@c3c.cz</a>
</>
);
};
export default MainNavigation;
+13
View File
@@ -0,0 +1,13 @@
interface ConfigFromBackend {
commitTime: string;
}
interface MyWindow extends Window {
APP_CONFIG?: ConfigFromBackend;
}
declare const window: MyWindow;
export const BUILD_TIMESTAMP: Date = window.APP_CONFIG?.commitTime
? new Date(window.APP_CONFIG.commitTime)
: new Date();
+10
View File
@@ -0,0 +1,10 @@
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
+15
View File
@@ -0,0 +1,15 @@
import React from "react";
import MainLayout from "../components/Layout/MainLayout";
const Dashboard: React.FC = () => {
return (
<MainLayout>
<h1>Lukáš Čech</h1>
<h2>DevOps Engineer</h2>
<p>(For the lack of a better name)</p>
</MainLayout>
);
};
export default Dashboard;
+34
View File
@@ -0,0 +1,34 @@
import styled from "@emotion/styled";
import React from "react";
import { defineMessages, useIntl } from "react-intl";
import { Link } from "../components/Link";
const messages = defineMessages({
notFound: {
defaultMessage: "Nothing to see here",
id: "Router.NotFound",
},
});
const Root = styled("div")({
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
height: "100vh",
width: "100vw",
});
const NotFound = () => {
const intl = useIntl();
return (
<Root>
<p>{intl.formatMessage(messages.notFound)}</p>
<Link to="/">Go home</Link>
</Root>
);
};
export default NotFound;
+39
View File
@@ -0,0 +1,39 @@
import React from "react";
import { Outlet, RouterProvider } from "react-router-dom";
import { createBrowserRouter } from "react-router-dom";
import { ErrorBoundary } from "../components/ErrorBoundary";
import Dashboard from "./Dashboard";
const Layout: React.FC = () => {
return (
<ErrorBoundary>
<Outlet />
</ErrorBoundary>
);
};
const NotFound = React.lazy(() => import("./NotFound"));
const router = createBrowserRouter([
{
path: "/",
element: <Layout />,
children: [
{
index: true,
element: <Dashboard />,
},
{
path: "*",
element: <NotFound />,
},
],
},
]);
const Router = (): JSX.Element => {
return <RouterProvider router={router} />;
};
export default Router;
+1
View File
@@ -0,0 +1 @@
/// <reference types="vite/client" />