diff --git a/src/api/PrsApi.ts b/src/api/PrsApi.ts index 817d19c8..553db2ca 100644 --- a/src/api/PrsApi.ts +++ b/src/api/PrsApi.ts @@ -1,6 +1,10 @@ // Pull Request API hooks - uses /prs endpoints import { useApiQuery } from './ApiUtils'; -import { type CommitLog, type PullRequestDetails } from './models/Dashboard'; +import { + type CommitLog, + type PullRequestComment, + type PullRequestDetails, +} from './models/Dashboard'; /** * Helper to create /prs endpoint queries @@ -54,7 +58,12 @@ export const usePullRequestDetails = ( * @param number - Pull request number */ export const usePullRequestComments = (repo: string, number: number) => - usePrsQuery('usePullRequestComments', '/comments', undefined, { - repo, - number, - }); + usePrsQuery( + 'usePullRequestComments', + '/comments', + undefined, + { + repo, + number, + }, + ); diff --git a/src/api/models/Dashboard.ts b/src/api/models/Dashboard.ts index e3006fa5..dfc991fb 100644 --- a/src/api/models/Dashboard.ts +++ b/src/api/models/Dashboard.ts @@ -48,7 +48,7 @@ export type Stats = { percentChange24h: number; percentChange7d: number; lastUpdated: string; - metadata: any; + metadata: Record; } | null; lastUpdated: string | null; }; @@ -60,7 +60,7 @@ export type Stats = { percentChange24h: number; percentChange7d: number; lastUpdated: string; - metadata: any; + metadata: Record; } | null; lastUpdated: string | null; }; diff --git a/src/components/issues/IssueConversation.tsx b/src/components/issues/IssueConversation.tsx index 1a5ba1da..4bdb13ba 100644 --- a/src/components/issues/IssueConversation.tsx +++ b/src/components/issues/IssueConversation.tsx @@ -6,15 +6,30 @@ import remarkGfm from 'remark-gfm'; import rehypeRaw from 'rehype-raw'; import { type IssueDetails } from '../../api/models/Issues'; import { STATUS_COLORS } from '../../theme'; + import 'github-markdown-css/github-markdown-dark.css'; +/** An issue comment or the issue body rendered in the conversation timeline. */ +type ConversationItem = { + id: string; + user: { + login: string | null; + avatarUrl: string; + htmlUrl: string; + }; + body: string; + createdAt: string; + authorAssociation: string; + isDescription?: boolean; +}; + interface IssueConversationProps { issue: IssueDetails; } const IssueConversation: React.FC = ({ issue }) => { const theme = useTheme(); - const allItems = [ + const allItems: ConversationItem[] = [ { id: 'issue-description', user: { @@ -63,7 +78,7 @@ const IssueConversation: React.FC = ({ issue }) => { position: 'relative', }} > - {allItems.map((item: any, index: number) => ( + {allItems.map((item, index) => ( = ({ issue }) => { > ; title?: string; action?: React.ReactNode; centerContent?: React.ReactNode; diff --git a/src/components/leaderboard/TopRepositoriesTable.tsx b/src/components/leaderboard/TopRepositoriesTable.tsx index 2c997ded..644063a3 100644 --- a/src/components/leaderboard/TopRepositoriesTable.tsx +++ b/src/components/leaderboard/TopRepositoriesTable.tsx @@ -30,6 +30,8 @@ import { Button, Switch, FormControlLabel, + type SxProps, + type Theme, } from '@mui/material'; import SearchIcon from '@mui/icons-material/Search'; import BarChartIcon from '@mui/icons-material/BarChart'; @@ -412,7 +414,7 @@ const TopRepositoriesTable: React.FC = ({ column: SortColumn; children: React.ReactNode; align?: 'left' | 'right'; - sx?: any; + sx?: SxProps; }) => ( = ({ githubId }) => { const rankings = useMemo(() => { if (!allMinersStats || !minerStats) return null; - const rank = (_key: string, extract: (m: any) => number) => + const rank = (_key: string, extract: (m: MinerEvaluation) => number) => allMinersStats .slice() .sort((a, b) => extract(b) - extract(a)) diff --git a/src/components/prs/PRComments.tsx b/src/components/prs/PRComments.tsx index 88126824..67d9ae24 100644 --- a/src/components/prs/PRComments.tsx +++ b/src/components/prs/PRComments.tsx @@ -12,10 +12,22 @@ import ReactMarkdown from 'react-markdown'; import remarkGfm from 'remark-gfm'; import rehypeRaw from 'rehype-raw'; import { usePullRequestComments } from '../../api'; -import { type PullRequestDetails } from '../../api/models/Dashboard'; +import { + type PullRequestComment, + type PullRequestDetails, +} from '../../api/models/Dashboard'; import { STATUS_COLORS } from '../../theme'; import 'github-markdown-css/github-markdown-dark.css'; // Import standard GitHub Dark styles +/** A comment or the PR description rendered in the conversation timeline. */ +type ConversationItem = Omit< + PullRequestComment, + 'id' | 'updatedAt' | 'htmlUrl' +> & { + id: number | string; + isDescription?: boolean; +}; + interface PRCommentsProps { repository: string; pullRequestNumber: number; @@ -51,7 +63,7 @@ const PRComments: React.FC = ({ ); } - const allItems = [ + const allItems: ConversationItem[] = [ { id: 'pr-description', user: { @@ -102,7 +114,7 @@ const PRComments: React.FC = ({ position: 'relative', }} > - {allItems.map((item: any, index: number) => ( + {allItems.map((item, index) => ( = ({ diff --git a/src/components/repositories/ContributingViewer.tsx b/src/components/repositories/ContributingViewer.tsx index 01d59abd..a368c8a3 100644 --- a/src/components/repositories/ContributingViewer.tsx +++ b/src/components/repositories/ContributingViewer.tsx @@ -177,7 +177,11 @@ const ContributingViewer: React.FC = ({ remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} components={{ - a: ({ href, children, ...rest }: any) => ( + a: ({ + href, + children, + ...rest + }: React.AnchorHTMLAttributes) => ( = ({ {children} ), - img: ({ src, alt, ...rest }: any) => ( + img: ({ + src, + alt, + ...rest + }: React.ImgHTMLAttributes) => ( { +export const buildFileTree = ( + flatFiles: { path: string; type: 'blob' | 'tree' }[], +): FileNode[] => { const root: FileNode[] = []; const map: Record = {}; diff --git a/src/components/repositories/ReadmeViewer.tsx b/src/components/repositories/ReadmeViewer.tsx index 98be1556..bd66af6d 100644 --- a/src/components/repositories/ReadmeViewer.tsx +++ b/src/components/repositories/ReadmeViewer.tsx @@ -179,7 +179,11 @@ const ReadmeViewer: React.FC = ({ repositoryFullName }) => { remarkPlugins={[remarkGfm]} rehypePlugins={[rehypeRaw]} components={{ - a: ({ href, children, ...rest }: any) => ( + a: ({ + href, + children, + ...rest + }: React.AnchorHTMLAttributes) => ( = ({ repositoryFullName }) => { {children} ), - img: ({ src, alt, ...rest }: any) => ( + img: ({ + src, + alt, + ...rest + }: React.ImgHTMLAttributes) => ( = ({ `https://api.github.com/repos/${repositoryFullName}/git/trees/${branch}?recursive=1`, ); if (treeRes.data.tree) { - setFileTree(treeRes.data.tree.map((node: any) => node.path)); + setFileTree( + treeRes.data.tree.map((node: { path: string }) => node.path), + ); } // Fetch issue counts @@ -96,7 +98,7 @@ const RepositoryCheckTab: React.FC = ({ setOpenIssuesCount(repoData.open_issues_count); } } - } catch (err: any) { + } catch (err: unknown) { console.error('Failed to fetch repo check data', err); setError('Failed to load repository health data.'); } finally { diff --git a/src/components/repositories/RepositoryCodeBrowser.tsx b/src/components/repositories/RepositoryCodeBrowser.tsx index 62712681..592e9cb0 100644 --- a/src/components/repositories/RepositoryCodeBrowser.tsx +++ b/src/components/repositories/RepositoryCodeBrowser.tsx @@ -67,9 +67,9 @@ const RepositoryCodeBrowser: React.FC = ({ const nodes = buildFileTree(treeResponse.data.tree); setTree(nodes); } - } catch (err: any) { + } catch (err: unknown) { console.error('Failed to load repository data', err); - if (err.response?.status === 403) { + if (axios.isAxiosError(err) && err.response?.status === 403) { setError('GitHub API rate limit exceeded. Please try again later.'); } else { setError('Failed to load repository structure.');