diff --git a/src/components/repo/RepoIssues.tsx b/src/components/repo/RepoIssues.tsx new file mode 100644 index 0000000..269883e --- /dev/null +++ b/src/components/repo/RepoIssues.tsx @@ -0,0 +1,56 @@ +import type { Did } from '@atcute/lexicons' +import { IconCircleDot, IconMessageCircle } from '@tabler/icons-react' +import { useRepoIssues } from '../../hooks/useRepoIssues' +import { SurfaceCard } from '../shared/SurfaceCard' + +type RepoIssuesProps = { + repoDid: Did +} + +export function RepoIssues({ repoDid }: RepoIssuesProps) { + const { issues, error } = useRepoIssues(repoDid) + + if (error) { + return

Could not load issues: {error.message}

+ } + + if (issues === null) { + return

Loading issues...

+ } + + if (issues.items.length === 0) { + return

No issues found.

+ } + + return ( + + ) +} diff --git a/src/hooks/useRepoIssues.ts b/src/hooks/useRepoIssues.ts new file mode 100644 index 0000000..5193b9b --- /dev/null +++ b/src/hooks/useRepoIssues.ts @@ -0,0 +1,25 @@ +import type { Did } from '@atcute/lexicons' +import { useEffect, useState } from 'react' +import { listIssues, type IssueList } from '../lib/tangled/repo' + +const INITIAL_ISSUE_LIMIT = 20 + +export function useRepoIssues(repoDid: Did) { + const [issues, setIssues] = useState(null) + const [error, setError] = useState(null) + + useEffect(() => { + async function loadIssues() { + setError(null) + try { + const result = await listIssues(repoDid, { limit: INITIAL_ISSUE_LIMIT }) + setIssues(result) + } catch (caught) { + setError(caught instanceof Error ? caught : new Error('Unable to load issues.')) + } + } + + void loadIssues() + }, [repoDid]) + return { issues, error } +} diff --git a/src/lib/tangled/repo/index.ts b/src/lib/tangled/repo/index.ts index db45660..470db78 100644 --- a/src/lib/tangled/repo/index.ts +++ b/src/lib/tangled/repo/index.ts @@ -7,8 +7,8 @@ export { getRepoByRepoDid } from './getRepoByRepoDid' export { getRepoLog } from './getRepoLog' export type { RepoLogOptions } from './getRepoLog' export { getRepoTree } from './getRepoTree' -export { listIssues } from './issues' -export type { Issue, IssueList, ListIssuesOptions } from './issues' +export { listIssues } from './listIssues' +export type { Issue, IssueList, ListIssuesOptions } from './listIssues' export { listRepos } from './listRepos' export { getRepoName, getRepoRkey } from './types' export type { Repo, RepoList } from './types' diff --git a/src/lib/tangled/repo/issues.ts b/src/lib/tangled/repo/listIssues.ts similarity index 100% rename from src/lib/tangled/repo/issues.ts rename to src/lib/tangled/repo/listIssues.ts diff --git a/src/pages/RepoPage.tsx b/src/pages/RepoPage.tsx index 074f48f..0299dfd 100644 --- a/src/pages/RepoPage.tsx +++ b/src/pages/RepoPage.tsx @@ -2,6 +2,7 @@ import { useEffect, useState } from 'react' import { useParams, useSearchParams } from 'react-router-dom' import { PageContainer } from '../components/layout/PageContainer' import { ProfileByline } from '../components/profile/ProfileByline' +import { RepoIssues } from '../components/repo/RepoIssues' import { RepoReadme } from '../components/repo/RepoReadme' import { parseRepoSection } from '../components/repo/repoSections' import { RepoTabs } from '../components/repo/RepoTabs' @@ -73,7 +74,9 @@ export function RepoPage() { )} - {activeSection === 'issues' && } + {activeSection === 'issues' && repo.value.repoDid !== undefined && ( + + )} {activeSection === 'pulls' && } {activeSection === 'pipelines' && }