📦 chore: update [id]

swadhinbiswas committed 3 months ago
70ffd48
1 parent ccc338f
commit 70ffd48
1 file changed
+115 -0
▼src/pages/[owner]/[repo]/milestones/[id]/edit.astro
+115-0
1
+---
2
+import BaseLayout from "@/layouts/BaseLayout.astro";
3
+import { getDatabase, schema } from "@/db";
4
+import { eq, and } from "drizzle-orm";
5
+
6
+const { owner: ownerName, repo: repoName, id } = Astro.params;
7
+const db = getDatabase();
8
+
9
+const user = await db.query.users.findFirst({
10
+ where: eq(schema.users.username, ownerName!),
11
+});
12
+if (!user) return Astro.redirect("/404");
13
+
14
+const repoData = await db.query.repositories.findFirst({
15
+ where: and(
16
+ eq(schema.repositories.ownerId, user.id),
17
+ eq(schema.repositories.name, repoName!),
18
+ ),
19
+ with: { owner: true },
20
+});
21
+if (!repoData) return Astro.redirect("/404");
22
+
23
+const milestone = await db.query.milestones.findFirst({
24
+ where: and(
25
+ eq(schema.milestones.id, id!),
26
+ eq(schema.milestones.repositoryId, repoData.id),
27
+ ),
28
+});
29
+if (!milestone) return Astro.redirect(`/${ownerName}/${repoName}/milestones`);
30
+
31
+const dueDateStr = milestone.dueDate ? new Date(milestone.dueDate).toISOString().split('T')[0] : '';
32
+---
33
+
34
+<BaseLayout title={`Edit Milestone · ${ownerName}/${repoName}`}>
35
+ <div class="container max-w-4xl py-8">
36
+ <div class="mb-6">
37
+ <a href={`/${ownerName}/${repoName}/milestones`} class="text-sm text-muted-foreground hover:text-foreground">
38
+ ← Back to milestones
39
+ </a>
40
+ </div>
41
+
42
+ <h1 class="text-2xl font-semibold mb-6">Edit Milestone</h1>
43
+
44
+ <form id="edit-milestone-form" class="space-y-6">
45
+ <div class="space-y-2">
46
+ <label class="text-sm font-medium">Title</label>
47
+ <input
48
+ type="text"
49
+ name="title"
50
+ value={milestone.title}
51
+ required
52
+ class="w-full rounded-lg border border-border bg-background px-4 py-2.5 text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
53
+ />
54
+ </div>
55
+
56
+ <div class="space-y-2">
57
+ <label class="text-sm font-medium">Description</label>
58
+ <textarea
59
+ name="description"
60
+ rows={4}
61
+ class="w-full rounded-lg border border-border bg-background px-4 py-2.5 text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
62
+ >{milestone.description || ''}</textarea>
63
+ </div>
64
+
65
+ <div class="space-y-2">
66
+ <label class="text-sm font-medium">Due Date</label>
67
+ <input
68
+ type="date"
69
+ name="dueDate"
70
+ value={dueDateStr}
71
+ class="w-full rounded-lg border border-border bg-background px-4 py-2.5 text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
72
+ />
73
+ </div>
74
+
75
+ <div class="flex justify-end gap-3">
76
+ <a
77
+ href={`/${ownerName}/${repoName}/milestones`}
78
+ class="px-4 py-2 rounded-lg border border-border bg-background text-sm text-muted-foreground hover:bg-accent"
79
+ >
80
+ Cancel
81
+ </a>
82
+ <button
83
+ type="submit"
84
+ class="px-4 py-2 rounded-lg bg-primary text-sm font-medium text-primary-foreground hover:opacity-90"
85
+ >
86
+ Save Changes
87
+ </button>
88
+ </div>
89
+ </form>
90
+ </div>
91
+
92
+ <script define:vars={{ owner: ownerName, repo: repoName, milestoneId: id }}>
93
+ document.getElementById('edit-milestone-form')?.addEventListener('submit', async (e) => {
94
+ e.preventDefault();
95
+ const formData = new FormData(e.target);
96
+ const data = {
97
+ title: formData.get('title'),
98
+ description: formData.get('description'),
99
+ dueDate: formData.get('dueDate') || null,
100
+ };
101
+
102
+ try {
103
+ const res = await fetch(`/api/repos/${owner}/${repo}/milestones/${milestoneId}`, {
104
+ method: 'PATCH',
105
+ headers: { 'Content-Type': 'application/json' },
106
+ body: JSON.stringify(data),
107
+ });
108
+ if (!res.ok) throw new Error('Failed');
109
+ window.location.href = `/${owner}/${repo}/milestones`;
110
+ } catch (err) {
111
+ alert('Failed to update milestone');
112
+ }
113
+ });
114
+ </script>
115
+</BaseLayout>
0
116