diff --git a/frontend/src/components/AppBar/AppBar.jsx b/frontend/src/components/AppBar/AppBar.jsx
deleted file mode 100644
index 906453398..000000000
--- a/frontend/src/components/AppBar/AppBar.jsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import React from "react";
-
-import Logo from "@/components/Logo/Logo";
-
-
-// AppBar is a bar on top of the app, with navigation and title
-const AppBar = ({ title, logoClickConfirm = null }) => {
-
- return (
-
-
-
{title}
-
-
- );
-};
-
-export default AppBar;
diff --git a/frontend/src/components/AppBar/AppBar.test.jsx b/frontend/src/components/AppBar/AppBar.test.jsx
deleted file mode 100644
index 1a84c53d7..000000000
--- a/frontend/src/components/AppBar/AppBar.test.jsx
+++ /dev/null
@@ -1,48 +0,0 @@
-import React from 'react';
-import { render, fireEvent } from '@testing-library/react';
-import AppBar from './AppBar';
-import { BrowserRouter as Router } from 'react-router-dom';
-import { vi } from 'vitest';
-
-describe('AppBar', () => {
-
- const BASE_URL = 'https://www.amsterdammusiclab.nl';
-
- beforeEach(() => {
- vi.resetModules();
- import.meta.env.VITE_AML_HOME = BASE_URL;
- });
-
- it('renders correctly', () => {
- const { getByText } = render(, { wrapper: Router });
-
- const titleElement = getByText('Test Title');
- expect(document.body.contains(titleElement)).to.be.true;
- });
-
- it('renders logo as Link for relative URL', () => {
- const { getByLabelText } = render(, { wrapper: Router });
- const logo = getByLabelText('Logo');
- expect(logo.tagName).toBe('A');
- expect(logo.getAttribute('href')).toBe(BASE_URL);
- });
-
- it('renders logo as an a-element for absolute URL', () => {
- const { getByLabelText } = render(, { wrapper: Router });
- const logo = getByLabelText('Logo');
- expect(logo.tagName).toBe('A');
- expect(logo.getAttribute('href')).toBe(BASE_URL);
- });
-
- it('prevents navigation when logoClickConfirm is provided and user cancels', () => {
- // Mock window.confirm
- window.confirm = vi.fn(() => false);
-
- const { getByLabelText } = render(, { wrapper: Router });
- const logo = getByLabelText('Logo');
- fireEvent.click(logo);
-
- expect(window.confirm).toHaveBeenCalledWith('Confirm?');
- });
-
-});
diff --git a/frontend/src/components/AppBar/AppBar.test.tsx b/frontend/src/components/AppBar/AppBar.test.tsx
new file mode 100644
index 000000000..c53b6e6f2
--- /dev/null
+++ b/frontend/src/components/AppBar/AppBar.test.tsx
@@ -0,0 +1,47 @@
+import { render, fireEvent } from '@testing-library/react';
+import AppBar from './AppBar';
+import { BrowserRouter as Router } from 'react-router-dom';
+import { vi, describe, beforeEach, it, expect } from 'vitest';
+
+describe('AppBar', () => {
+
+ const BASE_URL = 'https://www.amsterdammusiclab.nl';
+
+ beforeEach(() => {
+ vi.resetModules();
+ import.meta.env.VITE_AML_HOME = BASE_URL;
+ });
+
+ it('renders correctly', () => {
+ const { getByText } = render(, { wrapper: Router });
+
+ const titleElement = getByText('Test Title');
+ expect(document.body.contains(titleElement)).to.be.true;
+ });
+
+ it('renders logo as Link for relative URL', () => {
+ const { getByLabelText } = render(, { wrapper: Router });
+ const logo = getByLabelText('Logo');
+ expect(logo.tagName).toBe('A');
+ expect(logo.getAttribute('href')).toBe(BASE_URL);
+ });
+
+ it('renders logo as an a-element for absolute URL', () => {
+ const { getByLabelText } = render(, { wrapper: Router });
+ const logo = getByLabelText('Logo');
+ expect(logo.tagName).toBe('A');
+ expect(logo.getAttribute('href')).toBe(BASE_URL);
+ });
+
+ it('prevents navigation when logoClickConfirm is provided and user cancels', () => {
+ // Mock window.confirm
+ window.confirm = vi.fn(() => false);
+
+ const { getByLabelText } = render(, { wrapper: Router });
+ const logo = getByLabelText('Logo');
+ fireEvent.click(logo);
+
+ expect(window.confirm).toHaveBeenCalledWith('Confirm?');
+ });
+
+});
diff --git a/frontend/src/components/AppBar/AppBar.tsx b/frontend/src/components/AppBar/AppBar.tsx
new file mode 100644
index 000000000..251d6d3d2
--- /dev/null
+++ b/frontend/src/components/AppBar/AppBar.tsx
@@ -0,0 +1,16 @@
+import Logo from "@/components/Logo/Logo";
+
+interface AppBarProps {
+ title: string;
+ logoClickConfirm?: string | null;
+}
+
+/** AppBar is a bar on top of the app, with navigation and title */
+const AppBar = ({ title, logoClickConfirm = null }: AppBarProps) => (
+
+
+
{title}
+
+
+);
+export default AppBar;
diff --git a/frontend/src/components/Logo/Logo.tsx b/frontend/src/components/Logo/Logo.tsx
index 27df7842c..859aeb910 100644
--- a/frontend/src/components/Logo/Logo.tsx
+++ b/frontend/src/components/Logo/Logo.tsx
@@ -2,16 +2,19 @@ import { URLS, LOGO_URL, LOGO_TITLE } from "@/config";
import { Link } from "react-router-dom";
import useBoundStore from "@/util/stores";
+interface LogoProps {
+ logoClickConfirm: string | null;
+}
-const Logo: React.FC<{ logoClickConfirm: string | null }> = ({ logoClickConfirm = null }) => {
+const Logo: React.FC = ({ logoClickConfirm }) => {
const theme = useBoundStore((state) => state.theme);
const { alt, title, file, target, rel } = theme?.logo || {};
const href = theme?.logo?.href || URLS.AMLHome;
const logoUrl = file ?? LOGO_URL;
- // Handle click on logo, to optionally confirm navigating
- const onLogoClick = (e) => {
+ /** Handle click on logo, to optionally confirm navigating */
+ const onLogoClick = (e: React.MouseEvent) => {
if (logoClickConfirm) {
if (!window.confirm(logoClickConfirm)) {
e.preventDefault();
@@ -22,7 +25,7 @@ const Logo: React.FC<{ logoClickConfirm: string | null }> = ({ logoClickConfirm
// Logo is a Link in case of relative url (/abc),
// and a-element for absolute urls (https://www.example.com/)
- const logoProps = {
+ const logoProps: React.HTMLProps = {
onClick: onLogoClick,
className: "aha__logo",
"aria-label": "Logo",
@@ -49,4 +52,4 @@ const Logo: React.FC<{ logoClickConfirm: string | null }> = ({ logoClickConfirm
)
}
-export default Logo;
\ No newline at end of file
+export default Logo;