Skip to content

Commit 0b93132

Browse files
Merge pull request #43 from MobilityData/feat/23-feeds-ux
feat: UX Improvements + SSG additions
2 parents 939bb9c + 714a7f2 commit 0b93132

File tree

42 files changed

+1403
-585
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1403
-585
lines changed

cypress/e2e/home.cy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ describe('Home page', () => {
66
it('should render page header', () => {
77
cy.get('[data-testid=websiteTile]')
88
.should('exist')
9-
.contains('Mobility Database');
9+
.contains('MobilityDatabase');
1010
});
1111

1212
it('should render home page title', () => {

cypress/e2e/signin.cy.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ describe('Sign In page', () => {
66
it('should render page header', () => {
77
cy.get('[data-testid=websiteTile]')
88
.should('exist')
9-
.contains('Mobility Database');
9+
.contains('MobilityDatabase');
1010
});
1111

1212
it('should render signin', () => {

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"redux-persist": "^6.0.0",
5252
"redux-saga": "^1.2.3",
5353
"server-only": "^0.0.1",
54+
"swr": "^2.4.0",
5455
"yup": "^1.3.2"
5556
},
5657
"scripts": {

src/app/App.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ function App({ locale }: AppProps): React.ReactElement {
4141
const initialPath = buildPathFromNextRouter(pathname, searchParams, locale);
4242

4343
useEffect(() => {
44-
app.auth().onAuthStateChanged((user) => {
44+
const unsubscribe = app.auth().onAuthStateChanged((user) => {
4545
if (user != null) {
4646
setIsAppReady(true);
4747
} else {
@@ -50,6 +50,9 @@ function App({ locale }: AppProps): React.ReactElement {
5050
}
5151
});
5252
dispatch(anonymousLogin());
53+
return () => {
54+
unsubscribe();
55+
};
5356
}, [dispatch]);
5457

5558
return (

src/app/[locale]/about/components/AboutPage.tsx

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Container, Typography, Button } from '@mui/material';
22
import OpenInNewIcon from '@mui/icons-material/OpenInNew';
33
import { type ReactElement } from 'react';
44
import { getTranslations } from 'next-intl/server';
5+
import Link from 'next/link';
56

67
export default async function AboutPage(): Promise<ReactElement> {
78
const t = await getTranslations('about');
@@ -72,15 +73,11 @@ export default async function AboutPage(): Promise<ReactElement> {
7273
<li>{t('benefits.mirrored')}</li>
7374
<li>{t('benefits.boundingBoxes')}</li>
7475
<li>
75-
<Button
76-
variant='text'
77-
className='line-start inline'
78-
href='/contribute'
79-
rel='noreferrer'
80-
target='_blank'
81-
>
82-
{t('benefits.addFeeds')}
83-
</Button>
76+
<Link href='/contribute' rel='noreferrer' target='_blank'>
77+
<Button variant='text' className='line-start inline'>
78+
{t('benefits.addFeeds')}
79+
</Button>
80+
</Link>
8481
</li>
8582
<li>{t('benefits.openSource')}</li>
8683
</ul>

src/app/[locale]/components/HomePage.tsx

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import OpenInNewIcon from '@mui/icons-material/OpenInNew';
1010
import SearchBox from './SearchBox';
1111
import { getTranslations } from 'next-intl/server';
1212
import '../../styles/TextShimmer.css';
13+
import Link from 'next/link';
1314

1415
interface ActionBoxProps {
1516
IconComponent: React.ElementType;
@@ -35,9 +36,11 @@ const ActionBox = ({
3536
}}
3637
>
3738
<IconComponent sx={{ width: '100%', height: iconHeight }} />
38-
<Button variant='contained' href={buttonHref} sx={{ m: 2, px: 2 }}>
39-
{buttonText}
40-
</Button>
39+
<Link href={buttonHref}>
40+
<Button variant='contained' sx={{ m: 2, px: 2 }}>
41+
{buttonText}
42+
</Button>
43+
</Link>
4144
</Box>
4245
);
4346

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { type ReactElement } from 'react';
2+
import { setRequestLocale } from 'next-intl/server';
3+
import { type Locale, routing } from '../../../i18n/routing';
4+
import ContactUs from '../../screens/ContactUs';
5+
6+
export const dynamic = 'force-static';
7+
8+
export function generateStaticParams(): Array<{
9+
locale: Locale;
10+
}> {
11+
return routing.locales.map((locale) => ({ locale }));
12+
}
13+
14+
interface PageProps {
15+
params: Promise<{ locale: string }>;
16+
}
17+
18+
export default async function ContactUsPage({
19+
params,
20+
}: PageProps): Promise<ReactElement> {
21+
const { locale } = await params;
22+
23+
setRequestLocale(locale);
24+
25+
return <ContactUs />;
26+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { type ReactElement } from 'react';
2+
import { setRequestLocale } from 'next-intl/server';
3+
import { type Locale, routing } from '../../../i18n/routing';
4+
import FeedSubmissionFAQ from '../../screens/FeedSubmissionFAQ';
5+
6+
export const dynamic = 'force-static';
7+
8+
export function generateStaticParams(): Array<{
9+
locale: Locale;
10+
}> {
11+
return routing.locales.map((locale) => ({ locale }));
12+
}
13+
14+
interface PageProps {
15+
params: Promise<{ locale: string }>;
16+
}
17+
18+
export default async function ContributeFAQPage({
19+
params,
20+
}: PageProps): Promise<ReactElement> {
21+
const { locale } = await params;
22+
23+
setRequestLocale(locale);
24+
25+
return <FeedSubmissionFAQ />;
26+
}

src/app/[locale]/faq/page.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { type ReactElement } from 'react';
2+
import { setRequestLocale } from 'next-intl/server';
3+
import { type Locale, routing } from '../../../i18n/routing';
4+
import FAQ from '../../screens/FAQ';
5+
6+
export const dynamic = 'force-static';
7+
8+
export function generateStaticParams(): Array<{
9+
locale: Locale;
10+
}> {
11+
return routing.locales.map((locale) => ({ locale }));
12+
}
13+
14+
interface PageProps {
15+
params: Promise<{ locale: string }>;
16+
}
17+
18+
export default async function FAQPage({
19+
params,
20+
}: PageProps): Promise<ReactElement> {
21+
const { locale } = await params;
22+
23+
setRequestLocale(locale);
24+
25+
return <FAQ />;
26+
}
Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { type ReactNode } from 'react';
22
import { notFound } from 'next/navigation';
33
import { headers } from 'next/headers';
4-
import { fetchCompleteFeedData } from '../lib/feed-data';
54
import { AUTHED_PROXY_HEADER } from '../../../../../utils/proxy-helpers';
65

76
/**
@@ -12,7 +11,6 @@ export const dynamic = 'force-dynamic';
1211

1312
interface Props {
1413
children: ReactNode;
15-
params: Promise<{ feedDataType: string; feedId: string }>;
1614
}
1715

1816
/**
@@ -28,23 +26,12 @@ interface Props {
2826
*/
2927
export default async function AuthedFeedLayout({
3028
children,
31-
params,
3229
}: Props): Promise<React.ReactElement> {
3330
// Block direct access - only allow requests that came through the proxy
3431
const headersList = await headers();
3532
if (headersList.get(AUTHED_PROXY_HEADER) !== '1') {
3633
notFound();
3734
}
3835

39-
const { feedId, feedDataType } = await params;
40-
41-
// Fetch complete feed data (cached per-user)
42-
// This will be reused by child pages without additional API calls
43-
const feedData = await fetchCompleteFeedData(feedDataType, feedId);
44-
45-
if (feedData == null) {
46-
notFound();
47-
}
48-
4936
return <>{children}</>;
5037
}

0 commit comments

Comments
 (0)