Implement Repository Wiki page

swadhinbiswas committed 10 months ago
f86dd0b
1 parent 926bcc4
commit f86dd0b
2 files changed
+130 -46
▼scripts/debug_search.ts
+0-46
1
-
2
-import { drizzle } from 'drizzle-orm/better-sqlite3';
3
-import Database from 'better-sqlite3';
4
-import * as schema from '../src/db/schema';
5
-import { like, or } from 'drizzle-orm';
6
-
7
-const sqlite = new Database('./data/opencodehub.db');
8
-const db = drizzle(sqlite, { schema });
9
-
10
-async function run() {
11
- console.log('Running search debug...');
12
- const query = 'swadhin';
13
-
14
- console.log(`Query: "${query}"`);
15
-
16
- // Search Users
17
- const users = await db.query.users.findMany({
18
- where: or(
19
- like(schema.users.username, `%${query}%`),
20
- like(schema.users.displayName, `%${query}%`)
21
- ),
22
- limit: 3
23
- });
24
- console.log('Users found:', users.length);
25
- users.forEach(u => console.log(` - ${u.username} (${u.displayName})`));
26
-
27
- // Search Repos
28
- const repos = await db.query.repositories.findMany({
29
- where: or(
30
- like(schema.repositories.name, `%${query}%`),
31
- like(schema.repositories.description, `%${query}%`)
32
- ),
33
- with: { owner: true },
34
- limit: 5
35
- });
36
- console.log('Repos found:', repos.length);
37
- repos.forEach(r => console.log(` - ${r.namespace}/${r.name}`));
38
-
39
- if (users.length === 0 && repos.length === 0) {
40
- console.log('WARNING: No results found in DB!');
41
- } else {
42
- console.log('SUCCESS: DB returns results.');
43
- }
44
-}
45
-
46
-run().catch(console.error);
47
0
▼src/pages/[owner]/[repo]/wiki/index.astro
+130-0
1
+---
2
+import RepoHeader from "@/components/repo/RepoHeader.astro";
3
+import { Button } from "@/components/ui/button";
4
+import { getDatabase, schema } from "@/db";
5
+import BaseLayout from "@/layouts/BaseLayout.astro";
6
+import { canReadRepo } from "@/lib/permissions";
7
+import { and, eq } from "drizzle-orm";
8
+import { Book, Plus } from "lucide-react";
9
+import { marked } from "marked";
10
+
11
+const { owner: ownerName, repo: repoName } = Astro.params;
12
+const db = getDatabase();
13
+
14
+// 1. Fetch Repo & Owner
15
+const user = await db.query.users.findFirst({
16
+ where: eq(schema.users.username, ownerName!),
17
+});
18
+
19
+if (!user) return Astro.redirect("/404");
20
+
21
+const repoData = await db.query.repositories.findFirst({
22
+ where: and(
23
+ eq(schema.repositories.ownerId, user.id),
24
+ eq(schema.repositories.name, repoName!)
25
+ ),
26
+ with: {
27
+ owner: true,
28
+ },
29
+});
30
+
31
+if (!repoData) return Astro.redirect("/404");
32
+
33
+// Check permissions
34
+const currentUser = Astro.locals.user;
35
+const hasAccess = await canReadRepo(currentUser?.id, repoData);
36
+
37
+if (!hasAccess) {
38
+ return Astro.redirect("/404");
39
+}
40
+
41
+// Check if Wiki is enabled
42
+if (!repoData.hasWiki) {
43
+ return Astro.redirect("/404");
44
+}
45
+
46
+const repo = {
47
+ owner: repoData.owner.username,
48
+ name: repoData.name,
49
+ description: repoData.description,
50
+ visibility: repoData.visibility,
51
+ defaultBranch: repoData.defaultBranch,
52
+ stars: repoData.starCount,
53
+ forks: repoData.forkCount,
54
+ watchers: repoData.watchCount,
55
+ topics: repoData.topics ? JSON.parse(repoData.topics) : [],
56
+ openIssueCount: repoData.openIssueCount,
57
+ openPrCount: repoData.openPrCount,
58
+};
59
+
60
+// Fetch Wiki Home Page
61
+// Assuming 'home' is the default slug
62
+const homePage = await db.query.wikiPages.findFirst({
63
+ where: and(
64
+ eq(schema.wikiPages.repositoryId, repoData.id),
65
+ eq(schema.wikiPages.slug, 'home')
66
+ )
67
+});
68
+
69
+let contentHtml = '';
70
+if (homePage) {
71
+ contentHtml = await marked.parse(homePage.content);
72
+}
73
+---
74
+
75
+<BaseLayout title={`Wiki · ${repo.owner}/${repo.name}`}>
76
+ <div class="container py-6">
77
+ <RepoHeader repo={repo} activeTab="wiki" />
78
+
79
+ <div class="flex flex-col md:flex-row gap-6 mt-6">
80
+ <!-- Sidebar (Page List) - Placeholder for now -->
81
+ <div class="w-full md:w-64 flex-shrink-0 space-y-4">
82
+ <div class="flex items-center justify-between">
83
+ <h3 class="font-semibold">Pages</h3>
84
+ {homePage && (
85
+ <Button size="sm" variant="outline" asChild>
86
+ <a href={`/${repo.owner}/${repo.name}/wiki/_new`}>
87
+ <Plus className="h-4 w-4" />
88
+ </a>
89
+ </Button>
90
+ )}
91
+ </div>
92
+ {/* List pages here if needed */}
93
+ <nav class="flex flex-col space-y-1">
94
+ <a href={`/${repo.owner}/${repo.name}/wiki`} class:list={["px-3 py-2 rounded-md text-sm font-medium", !homePage || homePage.slug === 'home' ? "bg-muted text-foreground" : "text-muted-foreground hover:bg-muted/50"]}>
95
+ Home
96
+ </a>
97
+ </nav>
98
+ </div>
99
+
100
+ {/* Main Content */}
101
+ <div class="flex-1 min-w-0">
102
+ {homePage ? (
103
+ <div class="space-y-4">
104
+ <div class="flex items-center justify-between border-b pb-4">
105
+ <h1 class="text-3xl font-bold">{homePage.title}</h1>
106
+ <div class="flex gap-2">
107
+ <Button variant="outline" size="sm">Edit</Button>
108
+ <Button variant="outline" size="sm">History</Button>
109
+ </div>
110
+ </div>
111
+ <div class="prose max-w-none dark:prose-invert" set:html={contentHtml} />
112
+ </div>
113
+ ) : (
114
+ <div class="p-12 text-center border rounded-lg bg-muted/10">
115
+ <Book className="h-12 w-12 text-muted-foreground mx-auto mb-4" />
116
+ <h3 class="text-lg font-semibold mb-2">Welcome to the Wiki!</h3>
117
+ <p class="text-muted-foreground mb-6">
118
+ This repository has no wiki pages yet. Start by creating the home page.
119
+ </p>
120
+ <Button asChild>
121
+ <a href={`/${repo.owner}/${repo.name}/wiki/_new`}>
122
+ Create the first page
123
+ </a>
124
+ </Button>
125
+ </div>
126
+ )}
127
+ </div>
128
+ </div>
129
+ </div>
130
+</BaseLayout>
0
131