Add image upload to cases with cleanup
This commit is contained in:
+22
-10
@@ -1,15 +1,18 @@
|
||||
---
|
||||
import { and, asc, desc, eq, gt, lt, max } from "drizzle-orm";
|
||||
import AdminLayout from "../../layouts/AdminLayout.astro";
|
||||
import ImageField from "../../components/admin/ImageField.astro";
|
||||
import { cases } from "../../db/schema";
|
||||
import { getDb } from "../../lib/db";
|
||||
import { getEnv } from "../../lib/env";
|
||||
import { parseForm } from "../../lib/form";
|
||||
import { deleteMedia } from "../../lib/media";
|
||||
import { caseInput } from "../../schemas";
|
||||
|
||||
export const prerender = false;
|
||||
|
||||
const db = getDb(getEnv().DB);
|
||||
const env = getEnv();
|
||||
const db = getDb(env.DB);
|
||||
|
||||
let errors: Record<string, string> = {};
|
||||
let failedId = "";
|
||||
@@ -44,6 +47,11 @@ if (Astro.request.method === "POST") {
|
||||
});
|
||||
} else {
|
||||
const id = str(form, "id");
|
||||
const newImage = parsed.data.imageUrl || null;
|
||||
const [current] = await db.select().from(cases).where(eq(cases.id, id)).limit(1);
|
||||
if (current && current.imageUrl !== newImage) {
|
||||
await deleteMedia(env, current.imageUrl);
|
||||
}
|
||||
await db
|
||||
.update(cases)
|
||||
.set({
|
||||
@@ -51,14 +59,17 @@ if (Astro.request.method === "POST") {
|
||||
location: parsed.data.location || null,
|
||||
completedAt: parsed.data.completedAt || null,
|
||||
description: parsed.data.description || null,
|
||||
imageUrl: parsed.data.imageUrl || null,
|
||||
imageUrl: newImage,
|
||||
status: parsed.data.status,
|
||||
updatedAt: new Date(),
|
||||
})
|
||||
.where(eq(cases.id, id));
|
||||
}
|
||||
} else if (action === "delete") {
|
||||
await db.delete(cases).where(eq(cases.id, str(form, "id")));
|
||||
const id = str(form, "id");
|
||||
const [current] = await db.select().from(cases).where(eq(cases.id, id)).limit(1);
|
||||
await deleteMedia(env, current?.imageUrl);
|
||||
await db.delete(cases).where(eq(cases.id, id));
|
||||
} else if (action === "up" || action === "down") {
|
||||
const id = str(form, "id");
|
||||
const [current] = await db.select().from(cases).where(eq(cases.id, id)).limit(1);
|
||||
@@ -109,8 +120,7 @@ const list = await db.select().from(cases).orderBy(asc(cases.sortOrder));
|
||||
<input id="a-date" name="completedAt" type="text" placeholder="例:2026年2月" />
|
||||
</div>
|
||||
<div>
|
||||
<label for="a-img">圖片 URL</label>
|
||||
<input id="a-img" name="imageUrl" type="text" placeholder="https://..." />
|
||||
<ImageField name="imageUrl" label="圖片" scope="cases" id="a-img" />
|
||||
</div>
|
||||
<div style="grid-column:1/-1">
|
||||
<label for="a-desc">描述</label>
|
||||
@@ -144,8 +154,13 @@ const list = await db.select().from(cases).orderBy(asc(cases.sortOrder));
|
||||
<input name="completedAt" type="text" value={item.completedAt ?? ""} />
|
||||
</div>
|
||||
<div>
|
||||
<label>圖片 URL</label>
|
||||
<input name="imageUrl" type="text" value={item.imageUrl ?? ""} />
|
||||
<ImageField
|
||||
name="imageUrl"
|
||||
label="圖片"
|
||||
scope="cases"
|
||||
value={item.imageUrl}
|
||||
id={`img-${item.id}`}
|
||||
/>
|
||||
</div>
|
||||
<div style="grid-column:1/-1">
|
||||
<label>描述</label>
|
||||
@@ -159,9 +174,6 @@ const list = await db.select().from(cases).orderBy(asc(cases.sortOrder));
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
{item.imageUrl && (
|
||||
<img src={item.imageUrl} alt={item.title} style="margin-top:14px;max-width:220px;border-radius:10px;" />
|
||||
)}
|
||||
<div class="actions">
|
||||
<button type="submit" name="action" value="save">儲存</button>
|
||||
<button type="submit" name="action" value="up" class="secondary mini" disabled={i === 0}>↑ 上移</button>
|
||||
|
||||
Reference in New Issue
Block a user