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
11 changes: 8 additions & 3 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,15 @@ export default tseslint.config(
'@typescript-eslint/no-unsafe-call': 'off',
'@typescript-eslint/no-unsafe-return': 'off',
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
'@typescript-eslint/no-unnecessary-type-assertion': 'off',
'@typescript-eslint/no-redundant-type-constituents': 'off',
},
},
{
// Test files: `async` test callbacks and `act(async () => {})` wrappers are
// idiomatic even when they contain no `await` (async `act` flushes the
// microtask queue). Relaxing require-await here avoids churn in test infra.
files: ['**/*.spec.{ts,tsx}', '**/*.test.{ts,tsx}'],
rules: {
'@typescript-eslint/require-await': 'off',
'@typescript-eslint/no-misused-promises': 'off',
},
},
prettierRecommended,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,9 +315,7 @@ export default function AccountNotifications(): React.ReactElement {
<Select
value={defaultFrequency}
onChange={(e) => {
setDefaultFrequency(
e.target.value as NotificationSettings['frequency'],
);
setDefaultFrequency(e.target.value);
}}
size='small'
>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export default function CompleteRegistration(): React.ReactElement {
validationSchema: CompleteRegistrationSchema,
validateOnChange: isSubmitted,
validateOnBlur: true,
onSubmit: async (values) => {
onSubmit: (values) => {
if (user != null) {
dispatch(
refreshUserInformation({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,11 @@ export default function FormFirstStep({

return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<form
onSubmit={(e) => {
void handleSubmit(onSubmit)(e);
}}
>
<Grid container direction={'column'} rowSpacing={2}>
<Grid>
<FormControl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@ export default function FormFourthStep({

return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<form
onSubmit={(e) => {
void handleSubmit(onSubmit)(e);
}}
>
<Grid container direction={'column'} rowSpacing={2}>
<Grid>
<FormControl component='fieldset' fullWidth>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ export default function FormSecondStep({
return (
<>
<Typography gutterBottom>{t('gtfsScheduleFeed')}</Typography>
<form onSubmit={handleSubmit(onSubmit)}>
<form
onSubmit={(e) => {
void handleSubmit(onSubmit)(e);
}}
>
<Grid container direction={'column'} rowSpacing={2}>
<Grid>
<FormControl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,11 @@ export default function FormSecondStepRT({
>
{t('gtfsRealtimeFeed')}
</Typography>
<form onSubmit={handleSubmit(onSubmit)}>
<form
onSubmit={(e) => {
void handleSubmit(onSubmit)(e);
}}
>
<Grid container direction={'column'} rowSpacing={2}>
<Grid>
<FormControl
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,11 @@ export default function FormThirdStep({

return (
<>
<form onSubmit={handleSubmit(onSubmit)}>
<form
onSubmit={(e) => {
void handleSubmit(onSubmit)(e);
}}
>
<Grid container direction={'column'} rowSpacing={2}>
{/* Show required emptyLicenseUsage if official producer and no license provided */}
{isOfficialProducer && noLicenseProvided && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ interface Props {
* from the clean URLs like /feeds/gtfs/mdb-123.
* TODO: Now that legacy catch-all route is removed, change this to a private route `_static` and update proxy and links accordingly.
*/
export default async function StaticFeedLayout({
export default function StaticFeedLayout({
children,
params,
}: Props): Promise<React.ReactElement> {
}: Props): React.ReactElement {
return <>{children}</>;
}
2 changes: 1 addition & 1 deletion src/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export default async function LocaleLayout({
}

// At this point, locale is guaranteed to be a valid Locale type
const validLocale = locale as Locale;
const validLocale = locale;

// Enable static rendering for this locale
setRequestLocale(validLocale);
Expand Down
6 changes: 3 additions & 3 deletions src/app/api/revalidate/route.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ describe('GET /api/revalidate', () => {
},
});

const response = await GET(request);
const response = GET(request);
const json = await response.json();

expect(response.status).toBe(500);
Expand All @@ -65,7 +65,7 @@ describe('GET /api/revalidate', () => {
},
});

const response = await GET(request);
const response = GET(request);
const json = await response.json();

expect(response.status).toBe(401);
Expand All @@ -87,7 +87,7 @@ describe('GET /api/revalidate', () => {
},
});

const response = await GET(request);
const response = GET(request);
const json = await response.json();

expect(response.status).toBe(200);
Expand Down
2 changes: 1 addition & 1 deletion src/app/api/revalidate/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ const defaultRevalidateOptions: RevalidateBody = {
* Vercel automatically passes Authorization: Bearer <CRON_SECRET> with each invocation.
* Configured in vercel.json under "crons" for 4am UTC Monday-Saturday and 7am UTC Sunday.
*/
export async function GET(req: Request): Promise<NextResponse> {
export function GET(req: Request): NextResponse {
const authHeader = req.headers.get('authorization');
const cronSecret = process.env.CRON_SECRET;

Expand Down
4 changes: 2 additions & 2 deletions src/app/api/session/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ export async function POST(req: NextRequest): Promise<NextResponse> {
}
}

export async function GET(req: NextRequest): Promise<NextResponse> {
export function GET(req: NextRequest): NextResponse {
try {
const cookie = req.cookies.get(COOKIE_NAME)?.value;
if (cookie == null) {
Expand All @@ -88,7 +88,7 @@ export async function GET(req: NextRequest): Promise<NextResponse> {
}
}

export async function DELETE(req: NextRequest): Promise<NextResponse> {
export function DELETE(req: NextRequest): NextResponse {
// Clear the session cookie so that subsequent requests have no session.
const response = NextResponse.json({ status: 'logged_out' });
// Use the built-in delete helper to ensure the cookie is removed.
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/GtfsVisualizationMap.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ describe('generateStopColorExpression', () => {

describe('generateRouteOutlineColorExpression', () => {
// Helper to safely index into nested unknown arrays
type NestedArr = Array<unknown | NestedArr>;
type NestedArr = unknown[];
const at = (arr: NestedArr, ...indices: number[]): NestedArr =>
indices.reduce<NestedArr>((a, i) => (a as NestedArr[])[i], arr);
it('returns an array expression starting with "let" and "rgba"', () => {
Expand Down
2 changes: 1 addition & 1 deletion src/app/components/Map/SelectedRoutesStopsPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ export const SelectedRoutesStopsPanel = (
key={s.stopId}
role='button'
tabIndex={0}
aria-selected={isActive ? 'true' : 'false'}
aria-pressed={isActive ? 'true' : 'false'}
onClick={() => {
focusStopFromPanel(s);
}}
Expand Down
3 changes: 2 additions & 1 deletion src/app/components/ThemeToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,14 @@ import { IconButton } from '@mui/material';
import Brightness4Icon from '@mui/icons-material/Brightness4';
import Brightness7Icon from '@mui/icons-material/Brightness7';
import { useTheme } from '../context/ThemeProvider';
import { ThemeModeEnum } from '../Theme';

const ThemeToggle = (): React.ReactElement => {
const { mode, toggleTheme } = useTheme();

return (
<IconButton onClick={toggleTheme} color='inherit' aria-label='Theme Toggle'>
{mode === 'dark' ? <Brightness7Icon /> : <Brightness4Icon />}
{mode === ThemeModeEnum.dark ? <Brightness7Icon /> : <Brightness4Icon />}
</IconButton>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,7 @@ export default function NotificationSettingsDialog({
<Select
value={frequency}
onChange={(e) => {
setFrequency(
e.target.value as NotificationSettings['frequency'],
);
setFrequency(e.target.value);
}}
size='small'
>
Expand Down
8 changes: 6 additions & 2 deletions src/app/screens/FeedSubmitted.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { Typography, Box, Container, useTheme, Button } from '@mui/material';
import Image from 'next/image';

export default function FeedSubmitted(): React.ReactElement {
const theme = useTheme();
Expand All @@ -21,10 +22,13 @@ export default function FeedSubmitted(): React.ReactElement {
🚀 Your feed has been submitted!
</Typography>
<Box sx={{ display: 'flex', flexDirection: 'row', p: 2 }}>
<img
<Image
src='/assets/rocket.gif'
alt='rocket'
style={{ width: '300px', height: '300px', marginRight: '60px' }}
width={300}
height={300}
unoptimized
style={{ marginRight: '60px' }}
/>
<Box sx={{ maxWidth: '615px', justifyContent: 'center' }}>
<Typography variant='body1' sx={{ mb: 2, fontSize: '20px' }}>
Expand Down
8 changes: 5 additions & 3 deletions src/app/screens/GbfsValidator/GbfsFeedSearchInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default function GbfsFeedSearchInput({
initialFeedUrl ?? '',
);
const [requiresAuth, setRequiresAuth] = useState(false);
const [authType, setAuthType] = useState<string>('');
const [authType, setAuthType] = useState<AuthTypeEnum | ''>('');
const [basicAuthUsername, setBasicAuthUsername] = useState<
string | undefined
>(undefined);
Expand Down Expand Up @@ -65,7 +65,9 @@ export default function GbfsFeedSearchInput({
// Used to keep the auth inputs up to date
useEffect(() => {
setRequiresAuth(auth !== undefined);
setAuthType(auth == undefined ? '' : (auth.authType ?? ''));
setAuthType(
auth == undefined ? '' : ((auth.authType as AuthTypeEnum) ?? ''),
);
setBasicAuthUsername(
auth != null && 'username' in auth ? auth.username : undefined,
);
Expand All @@ -91,7 +93,7 @@ export default function GbfsFeedSearchInput({
};

const handleAuthTypeChange = (event: SelectChangeEvent<string>): void => {
setAuthType(event.target.value);
setAuthType(event.target.value as AuthTypeEnum);
setBasicAuthUsername(undefined);
setBasicAuthPassword(undefined);
setBearerAuthValue(undefined);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,15 +431,15 @@ export function ErrorDetailsDialog({
</Box>
)}
{renderHighlightedObject(
parentContextData as JSONValue,
parentContextData,
null,
null,
)}
</Box>
);
}
return renderHighlightedObject(
parentContextData as JSONValue,
parentContextData,
lastPointerSegment ?? null,
lastArrayIndex,
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/services/api-auth-middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const generateAuthMiddlewareWithToken = (
userContextJwt?: string,
): Middleware => {
return {
async onRequest(req) {
onRequest(req) {
// Always attach the bearer token for IAP/GCIP.
req.headers.set('Authorization', `Bearer ${accessToken}`);

Expand Down
2 changes: 1 addition & 1 deletion src/app/services/profile-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const sendEmailVerification = async (): Promise<void> => {
/**
* Return the current user or null if the user is not logged in.
*/
export const getUserFromSession = async (): Promise<User | null> => {
export const getUserFromSession = (): User | null => {
const currentUser = app.auth().currentUser;
if (currentUser === null) {
return null;
Expand Down
6 changes: 3 additions & 3 deletions src/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,19 @@ export enum LicenseErrorSource {
}

export interface ProfileError {
code: string | 'unknown';
code: string;
message: string;
source?: ProfileErrorSource;
}

export interface FeedError {
code: string | 'unknown';
code: string;
message: string;
source?: FeedErrorSource;
}

export interface LicenseError {
code: string | 'unknown';
code: string;
message: string;
source?: LicenseErrorSource;
}
Expand Down
8 changes: 1 addition & 7 deletions src/app/utils/precompute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,7 @@ export interface PrecomputeDeps {

/** Small helper: wait once for a map event */
async function once(map: maplibregl.Map, ev: string): Promise<void> {
await new Promise<void>(
// eslint-disable-next-line no-async-promise-executor
async (resolve) =>
await map.once(ev, () => {
resolve();
}),
);
await map.once(ev);
}

// Extend helpers for [minLng,minLat,maxLng,maxLat]
Expand Down
Loading