Fix prefer-add-event-listener, no-unassigned-import, require-module-specifiers

Resolves all 9 remaining non-console lint warnings and promotes all
three rules to errors in .oxlintrc.json.

- prefer-add-event-listener: converted onchange/onclick/onload
  assignments to addEventListener in useDraftNotifications.ts and
  admin.data-sync.tsx; stored changeHandler ref for proper cleanup
  with removeEventListener
- no-unassigned-import: configured rule with allow list for legitimate
  side-effect imports (*.css, @testing-library/jest-dom,
  @testing-library/cypress/add-commands)
- require-module-specifiers: removed redundant `export {}` from
  cypress/support/e2e.ts (file already has an import)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Chris Parsons 2026-03-21 10:51:21 -07:00
parent 552fe28b99
commit 13a36e6c41
4 changed files with 14 additions and 8 deletions

View file

@ -37,9 +37,14 @@
"react/self-closing-comp": "warn",
"import/no-duplicates": "error",
"import/no-unassigned-import": ["error", {
"allow": ["**/*.css", "@testing-library/jest-dom", "@testing-library/cypress/add-commands"]
}],
"no-shadow": "error",
"unicorn/consistent-function-scoping": "error"
"unicorn/consistent-function-scoping": "error",
"unicorn/prefer-add-event-listener": "error",
"unicorn/require-module-specifiers": "error"
},
"overrides": [
{

View file

@ -44,18 +44,20 @@ export function useDraftNotifications(seasonId: string, userId: string) {
// would still be null at that point without the flag).
let aborted = false;
let permissionStatus: PermissionStatus | null = null;
let changeHandler: (() => void) | null = null;
navigator.permissions
.query({ name: "notifications" })
.then((status) => {
if (aborted) return;
permissionStatus = status;
status.onchange = () => {
changeHandler = () => {
setPermissionState(status.state as NotificationPermission);
// If permission was revoked, disable notifications
if (status.state !== "granted") {
setEnabledState(false);
}
};
status.addEventListener("change", changeHandler);
})
.catch(() => {
// Permissions API not available in all environments; silently ignore
@ -63,8 +65,8 @@ export function useDraftNotifications(seasonId: string, userId: string) {
return () => {
aborted = true;
if (permissionStatus) {
permissionStatus.onchange = null;
if (permissionStatus && changeHandler) {
permissionStatus.removeEventListener("change", changeHandler);
}
};
}, [seasonId, userId]);
@ -120,7 +122,7 @@ export function useDraftNotifications(seasonId: string, userId: string) {
body,
tag: `draft-${seasonId}`,
});
n.onclick = () => window.focus();
n.addEventListener("click", () => window.focus());
},
[enabled, seasonId]
);

View file

@ -139,14 +139,14 @@ export default function DataSync({ loaderData }: Route.ComponentProps) {
}
const reader = new FileReader();
reader.onload = (event) => {
reader.addEventListener("load", (event) => {
const fileData = event.target?.result as string;
const formData = new FormData();
formData.append("intent", "import");
formData.append("mode", importMode);
formData.append("fileData", fileData);
fetcher.submit(formData, { method: "POST" });
};
});
reader.readAsText(selectedFile);
};

View file

@ -19,4 +19,3 @@ declare global {
}
}
export {};