diff --git a/web/src/lib/components/repo/issues/IssueCard.svelte b/web/src/lib/components/repo/issues/IssueCard.svelte
new file mode 100644
index 00000000..494c6371
--- /dev/null
+++ b/web/src/lib/components/repo/issues/IssueCard.svelte
@@ -0,0 +1,45 @@
+
+
+
diff --git a/web/src/lib/components/repo/issues/IssueList.svelte b/web/src/lib/components/repo/issues/IssueList.svelte
new file mode 100644
index 00000000..9e2132ac
--- /dev/null
+++ b/web/src/lib/components/repo/issues/IssueList.svelte
@@ -0,0 +1,23 @@
+
+
+{#if issues.length === 0}
+
+{:else}
+
+ {#each issues as issue (issue.id)}
+
+ {/each}
+
+{/if}
diff --git a/web/src/lib/components/repo/issues/IssueStatePill.svelte b/web/src/lib/components/repo/issues/IssueStatePill.svelte
new file mode 100644
index 00000000..88071b42
--- /dev/null
+++ b/web/src/lib/components/repo/issues/IssueStatePill.svelte
@@ -0,0 +1,38 @@
+
+
+
+
+
+
+ {label}
+
diff --git a/web/src/lib/components/repo/issues/IssueToolbar.svelte b/web/src/lib/components/repo/issues/IssueToolbar.svelte
new file mode 100644
index 00000000..dfbf11c4
--- /dev/null
+++ b/web/src/lib/components/repo/issues/IssueToolbar.svelte
@@ -0,0 +1,65 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/web/src/lib/components/repo/types.ts b/web/src/lib/components/repo/types.ts
index 142dc2eb..54494677 100644
--- a/web/src/lib/components/repo/types.ts
+++ b/web/src/lib/components/repo/types.ts
@@ -38,3 +38,13 @@ export interface LanguageSlice {
percentage: number;
share: number;
}
+
+export interface IssueSummary {
+ id: number;
+ title: string;
+ state: "open" | "closed";
+ authorHandle: string;
+ authorDid: string;
+ createdAt: string;
+ commentCount: number;
+}
diff --git a/web/src/routes/[handle]/[repo]/issues/+page.svelte b/web/src/routes/[handle]/[repo]/issues/+page.svelte
new file mode 100644
index 00000000..4c80616e
--- /dev/null
+++ b/web/src/routes/[handle]/[repo]/issues/+page.svelte
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
diff --git a/web/src/routes/[handle]/[repo]/issues/+page.ts b/web/src/routes/[handle]/[repo]/issues/+page.ts
new file mode 100644
index 00000000..c5ae7b27
--- /dev/null
+++ b/web/src/routes/[handle]/[repo]/issues/+page.ts
@@ -0,0 +1,18 @@
+import type { IssueSummary } from "$lib/components/repo/types";
+import type { PageLoad } from "./$types";
+
+export const load: PageLoad = async (event) => {
+ const parent = await event.parent();
+ const state = event.url.searchParams.get("state") === "closed" ? "closed" : "open";
+
+ // TODO: fetch via sh.tangled.repo.listIssues and resolve author handles
+ const issues: IssueSummary[] = [];
+ const closedCount = 0;
+
+ return {
+ state: state as "open" | "closed",
+ issues,
+ openCount: parent.counts.issues,
+ closedCount
+ };
+};