Skip to content

Commit 99f4a31

Browse files
authored
Merge pull request #194 from quick-fix/small-tweaks
fix: duplicate page title on /app and scroll-to-top on privacy/terms
2 parents 647c45b + fca457c commit 99f4a31

8 files changed

Lines changed: 46 additions & 3 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,11 @@
2222

2323
## What it is
2424

25-
Bayan Flow is a an open source educational tool with **45 algorithms** across five categories. Choose an algorithm and step through or autoplay the visualization. Optional **Python** implementations run in the browser (Pyodide `0.27.5`), with a **complexity** panel after completion and **video export** (horizontal or vertical MP4) when you want to share or study offline.
25+
Bayan Flow is an open source educational tool with **45 algorithms** across five categories. Choose an algorithm and step through or autoplay the visualization. Optional **Python** implementations run in the browser (Pyodide `0.27.5`), with a **complexity** panel after completion and **video export** (horizontal or vertical MP4) when you want to share or study offline.
2626

2727
## Features (overview)
2828

29-
| Mode | Algorithms | What you get |
29+
| Category | Algorithms | What you get |
3030
| -------------------- | ---------- | ------------ |
3131
| **Sorting** | 14 | Random array, color-coded bars, ascending/descending order, comparison and non-comparison families |
3232
| **Pathfinding** | 9 | Grid-based search on configurable presets; start/end, walls, open/closed/path highlighting |

src/components/DocumentTitle.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const ROUTE_TITLE_KEYS = {
1313
'/privacy': 'legal.privacyTitle',
1414
'/terms': 'legal.termsTitle',
1515
'/roadmap': 'roadmap.hero.title',
16-
'/app': 'header.title',
16+
'/app': 'app.pageTitle',
1717
};
1818

1919
function getRouteDescriptions(pathname, t) {

src/components/DocumentTitle.test.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,20 @@ describe('DocumentTitle', () => {
193193
);
194194
});
195195

196+
it('should set app route title', () => {
197+
render(
198+
<I18nextProvider i18n={i18n}>
199+
<MemoryRouter initialEntries={['/app']}>
200+
<DocumentTitle />
201+
</MemoryRouter>
202+
</I18nextProvider>
203+
);
204+
205+
const baseTitle = i18n.t('header.title');
206+
const appTitle = i18n.t('app.pageTitle');
207+
expect(document.title).toBe(`${baseTitle} - ${appTitle}`);
208+
});
209+
196210
it('should set canonical and og:url for the active route', () => {
197211
render(
198212
<I18nextProvider i18n={i18n}>

src/components/LegalDocument.jsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
* See LICENSE for details.
55
*/
66

7+
import { useEffect } from 'react';
78
import { Link } from 'react-router-dom';
89
import Footer from './Footer';
910
import ThemeToggle from './ThemeToggle';
@@ -16,6 +17,12 @@ import LanguageSwitcher from './LanguageSwitcher';
1617
* @param {Array<{ id: string, title: string, paragraphs: string[], list?: string[] }>} props.sections
1718
*/
1819
function LegalDocument({ title, lastUpdated, sections }) {
20+
useEffect(() => {
21+
if (!window.location.hash) {
22+
window.scrollTo(0, 0);
23+
}
24+
}, []);
25+
1926
return (
2027
<div className="min-h-screen relative overflow-x-hidden flex flex-col">
2128
<div className="fixed inset-0 bg-linear-to-b from-bg via-bg to-surface-elevated pointer-events-none" />

src/components/LegalDocument.test.jsx

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const renderLegalDocument = () =>
5050
describe('LegalDocument', () => {
5151
beforeEach(async () => {
5252
await i18n.changeLanguage('en');
53+
window.scrollTo = vi.fn();
5354
});
5455

5556
it('renders title, last updated, and section content', () => {
@@ -67,6 +68,18 @@ describe('LegalDocument', () => {
6768
expect(screen.getByTestId('legal-footer')).toBeInTheDocument();
6869
});
6970

71+
it('scrolls to top when no hash fragment is present', () => {
72+
renderLegalDocument();
73+
expect(window.scrollTo).toHaveBeenCalledWith(0, 0);
74+
});
75+
76+
it('preserves scroll position when a hash fragment is present', () => {
77+
window.location.hash = '#intro';
78+
renderLegalDocument();
79+
expect(window.scrollTo).not.toHaveBeenCalled();
80+
window.location.hash = '';
81+
});
82+
7083
it('links back to the home page', () => {
7184
renderLegalDocument();
7285

src/i18n/locales/ar/translation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"backToHome": "عودة إلى الرئيسية",
55
"save": "حفظ"
66
},
7+
"app": {
8+
"pageTitle": "مُصوِّر الخوارزميات التفاعلي"
9+
},
710
"header": {
811
"title": "بيان Flow",
912
"subtitle": "الوضوح في الخوارزميات",

src/i18n/locales/en/translation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"backToHome": "Back to Home",
55
"save": "Save"
66
},
7+
"app": {
8+
"pageTitle": "Interactive Algorithm Visualizer"
9+
},
710
"header": {
811
"title": "Bayan Flow",
912
"subtitle": "Clarity in Algorithms",

src/i18n/locales/fr/translation.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
"backToHome": "Retour à l'Accueil",
55
"save": "Enregistrer"
66
},
7+
"app": {
8+
"pageTitle": "Visualiseur Interactif d'Algorithmes"
9+
},
710
"header": {
811
"title": "Bayan Flow",
912
"subtitle": "Clarté dans les Algorithmes",

0 commit comments

Comments
 (0)