Add ESLint + Prettier + EditorConfig tooling at repo root

v1.0 Phase 1.1 — repo-wide lint/format baseline.

- eslint.config.mjs (flat config) lints server, client, shared
- .prettierrc.json, .prettierignore, .editorconfig, .nvmrc
- Root package.json holds shared devDeps; per-package scripts keep
  their typecheck + test runners
- Fix 7 lint issues surfaced by the baseline run:
  - TicketDetail.tsx: replace ternary-with-side-effects with if/else
  - admin/Users.tsx: escape apostrophe in JSX
  - errorHandler.ts: typed err as unknown with ErrorLike refinement
  - users.ts: Prisma.UserUpdateInput instead of Record<string, any>
  - seed.ts: drop unused goddard binding
- Run prettier across tracked sources for a clean formatting baseline
This commit is contained in:
2026-04-18 14:47:34 -04:00
parent 2a6090e473
commit 27d2ab0f0d
48 changed files with 14460 additions and 1096 deletions
+19 -18
View File
@@ -1,39 +1,40 @@
import { ReactNode, useEffect } from 'react'
import { X } from 'lucide-react'
import { ReactNode, useEffect } from 'react';
import { X } from 'lucide-react';
interface ModalProps {
title: string
onClose: () => void
children: ReactNode
size?: 'md' | 'lg'
title: string;
onClose: () => void;
children: ReactNode;
size?: 'md' | 'lg';
}
export default function Modal({ title, onClose, children, size = 'md' }: ModalProps) {
useEffect(() => {
const handler = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose()
}
document.addEventListener('keydown', handler)
return () => document.removeEventListener('keydown', handler)
}, [onClose])
if (e.key === 'Escape') onClose();
};
document.addEventListener('keydown', handler);
return () => document.removeEventListener('keydown', handler);
}, [onClose]);
return (
<div
className="fixed inset-0 z-50 flex items-center justify-center bg-black/70 backdrop-blur-sm"
onClick={(e) => { if (e.target === e.currentTarget) onClose() }}
onClick={(e) => {
if (e.target === e.currentTarget) onClose();
}}
>
<div className={`bg-gray-900 border border-gray-800 rounded-xl shadow-2xl w-full mx-4 ${size === 'lg' ? 'max-w-2xl' : 'max-w-md'}`}>
<div
className={`bg-gray-900 border border-gray-800 rounded-xl shadow-2xl w-full mx-4 ${size === 'lg' ? 'max-w-2xl' : 'max-w-md'}`}
>
<div className="flex items-center justify-between px-6 py-4 border-b border-gray-800">
<h3 className="text-base font-semibold text-gray-100">{title}</h3>
<button
onClick={onClose}
className="text-gray-500 hover:text-gray-300 transition-colors"
>
<button onClick={onClose} className="text-gray-500 hover:text-gray-300 transition-colors">
<X size={18} />
</button>
</div>
<div className="px-6 py-5">{children}</div>
</div>
</div>
)
);
}