Skip to content

Commit 46dc54f

Browse files
authored
Tidying Up (#11)
1 parent a713373 commit 46dc54f

File tree

5 files changed

+69
-6
lines changed

5 files changed

+69
-6
lines changed

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ Tracking progress on key features and tasks for the project.
9191
- [x] 📁 Enable file upload functionality
9292
- [x] 📊 Add analytics tracking
9393

94+
<details>
95+
<summary>Click to expand the logbook</summary>
96+
9497
### 📝 Note from 5-28-2025
9598

9699
Just finished up the database connection, next steps:
@@ -114,5 +117,14 @@ can be approved:
114117

115118
- [x] Add "ownership" to files and folders
116119
- [x] Upload files to the right folder
117-
- [ ] Delete file button
120+
- [x] Delete file button
118121
- [x] Allow files that are not images to be uploaded
122+
123+
</details>
124+
125+
## 🎯 Fun Follow Ups
126+
127+
### Folder deletion
128+
129+
Make sure to fetch all of the folders that have it as a parent, and their
130+
children too.

src/app/f/drive-contents.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ export default function DriveContents(props: {
5151
<div className="border-b border-gray-700 px-6 py-4">
5252
<div className="grid grid-cols-12 gap-4 text-sm font-medium text-gray-400">
5353
<div className="col-span-6">Name</div>
54-
<div className="col-span-3">Type</div>
54+
<div className="col-span-2">Type</div>
5555
<div className="col-span-3">Size</div>
56+
<div className="col-span-1 text-right">Actions</div>
5657
</div>
5758
</div>
5859
<ul>

src/app/f/file-row.tsx

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
import { FileIcon, Folder as FolderIcon } from "lucide-react";
1+
import { FileIcon, Folder as FolderIcon, Trash2Icon } from "lucide-react";
22
import Link from "next/link";
33

4+
import { Button } from "~/components/ui/button";
5+
import { deleteFile } from "~/server/actions";
46
import type { File, Folder } from "~/server/db/schema";
57

68
export function FileRow(props: { file: File }) {
@@ -22,8 +24,17 @@ export function FileRow(props: { file: File }) {
2224
{file.name}
2325
</a>
2426
</div>
25-
<div className="col-span-3 text-gray-400">{"file"}</div>
27+
<div className="col-span-2 text-gray-400">{"File"}</div>
2628
<div className="col-span-3 text-gray-400">{file.size}</div>
29+
<div className="col-span-1 text-right text-gray-400">
30+
<Button
31+
aria-label="Delete file"
32+
variant="ghost"
33+
onClick={() => deleteFile(file.id)}
34+
>
35+
<Trash2Icon className="" size={20} />
36+
</Button>
37+
</div>
2738
</div>
2839
</li>
2940
);

src/server/actions.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"use server";
2+
3+
import { auth } from "@clerk/nextjs/server";
4+
import { and, eq } from "drizzle-orm";
5+
import { cookies } from "next/headers";
6+
import { UTApi } from "uploadthing/server";
7+
8+
import { db } from "~/server/db";
9+
import { files_table as fileSchema } from "~/server/db/schema";
10+
11+
const utApi = new UTApi();
12+
13+
export async function deleteFile(fileId: number) {
14+
const session = await auth();
15+
if (!session.userId) return { error: "Unauthorized" };
16+
17+
const [file] = await db
18+
.select()
19+
.from(fileSchema)
20+
.where(
21+
and(eq(fileSchema.id, fileId), eq(fileSchema.ownerId, session.userId)),
22+
);
23+
24+
if (!file) return { error: "File not found" };
25+
26+
await utApi.deleteFiles([file.url.replace("https://utfs.io/f/", "")]); // TODO: add fileKey to db schema
27+
await db.delete(fileSchema).where(eq(fileSchema.id, fileId));
28+
29+
const c = await cookies();
30+
c.set("force-refresh", JSON.stringify(Math.random()));
31+
32+
return { success: true };
33+
}

src/server/db/queries.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
export async function getAllParentsForFolder(folderId: number) {
1212
const parents = [];
1313
let currentId: number | null = folderId;
14+
1415
while (currentId != null) {
1516
const folders = await db
1617
.selectDistinct()
@@ -30,7 +31,8 @@ export function getAllFolders(folderId: number) {
3031
return db
3132
.select()
3233
.from(folderSchema)
33-
.where(eq(folderSchema.parent, folderId));
34+
.where(eq(folderSchema.parent, folderId))
35+
.orderBy(folderSchema.name);
3436
}
3537

3638
export async function getFolderById(folderId: number) {
@@ -42,5 +44,9 @@ export async function getFolderById(folderId: number) {
4244
}
4345

4446
export function getAllFiles(folderId: number) {
45-
return db.select().from(fileSchema).where(eq(fileSchema.parent, folderId));
47+
return db
48+
.select()
49+
.from(fileSchema)
50+
.where(eq(fileSchema.parent, folderId))
51+
.orderBy(fileSchema.name);
4652
}

0 commit comments

Comments
 (0)