Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,11 @@ This project is a React-based web interface for the [Ergogen](https://github.com
- **Centralized Theming**: All colors and other theme-related properties (e.g., font sizes, spacing) should be centralized in `src/theme/theme.ts`. Components should import and use variables from this theme file instead of using hardcoded values.
- **Styled Components for Styling**: All styling, including global styles, should be managed using `styled-components`. Global styles should be defined in a `GlobalStyle` component to ensure consistency and encapsulation within the React component architecture, avoiding the use of separate CSS files like `index.css`.

## Architecture

- **GitHub Pages Hosting**: The application is hosted on GitHub Pages, which only serves static files. This means that client-side routing needs a workaround to handle direct navigation to sub-paths.
- **404-based Redirect**: To handle client-side routing on GitHub Pages, a custom `public/404.html` file is used. This file contains a script that captures the requested path from `window.location.pathname`, stores it in `sessionStorage`, and then redirects the user to the root of the application (`/`). The main `App.tsx` component then reads this path from `sessionStorage` on load and navigates the user to the correct client-side route.

## Development environment

### Linting and formatting
Expand Down
8 changes: 8 additions & 0 deletions e2e/routing.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,12 @@ test.describe('Routing and Welcome Page', () => {
expect(parsed).toContain('points:');
}).toPass();
});

test('navigating directly to /new shows the welcome page after redirect', async ({
page,
}) => {
await page.goto('/new');
await expect(page).toHaveURL(/.*\/new/);
await expect(page.getByText('Welcome to Ergogen Web UI')).toBeVisible();
});
});
19 changes: 19 additions & 0 deletions public/404.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Redirecting...</title>
<script type="text/javascript">
// Store the path that the user tried to access.
const path = window.location.pathname;
if (path) {
sessionStorage.setItem('redirectPath', path);
}
// Redirect to the root, where the React app will handle the stored path.
window.location.replace('/');
</script>
</head>
<body>
If you are not redirected automatically, please <a href="/">click here</a>.
</body>
</html>
14 changes: 12 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import { Routes, Route, Navigate } from 'react-router-dom';
import React, { useEffect } from 'react';
import { Routes, Route, Navigate, useNavigate } from 'react-router-dom';
import { useLocalStorage } from 'react-use';
import styled from 'styled-components';

Expand All @@ -24,6 +24,16 @@ const App = () => {
initialConfig
);

const navigate = useNavigate();

useEffect(() => {
const redirectPath = sessionStorage.getItem('redirectPath');
if (redirectPath) {
sessionStorage.removeItem('redirectPath');
navigate(redirectPath, { replace: true });
}
}, [navigate]);

return (
// Pass the state and the setter function down to the context provider.
<ConfigContextProvider
Expand Down