Skip to content

Commit 2f4fc90

Browse files
authored
Fixing Breadcrumbs (#5)
1 parent aa51290 commit 2f4fc90

4 files changed

Lines changed: 45 additions & 53 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,6 @@ Just finished up the database connection, next steps:
103103

104104
The database and UI are now connected, some improvements to make:
105105

106-
- [ ] Change folders to link components, remove all client state
106+
- [x] Change folders to link components, remove all client state
107107
- [ ] Clean up the database and data fetching patterns
108108
- [ ] Real homepage

src/app/drive-contents.tsx

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,18 @@
11
"use client";
22

33
import { ChevronRight, Upload } from "lucide-react";
4-
import { useMemo, useState } from "react";
4+
import Link from "next/link";
55

66
import { Button } from "~/components/ui/button";
77
import type { files, folders } from "~/server/db/schema";
8+
89
import { FileRow, FolderRow } from "./file-row";
910

1011
export default function DriveContents(props: {
1112
files: (typeof files.$inferSelect)[];
1213
folders: (typeof folders.$inferSelect)[];
14+
parents: (typeof folders.$inferSelect)[];
1315
}) {
14-
const [currentFolder, setCurrentFolder] = useState(1);
15-
16-
const handleFolderClick = (folderId: number) => {
17-
setCurrentFolder(folderId);
18-
};
19-
20-
const breadcrumbs = useMemo(() => {
21-
const breadcrumbs = [];
22-
let currentId = currentFolder;
23-
24-
while (currentId !== 1) {
25-
const folder = props.folders.find((file) => file.id === currentId);
26-
if (folder) {
27-
breadcrumbs.unshift(folder);
28-
currentId = folder.parent ?? 1;
29-
} else {
30-
break;
31-
}
32-
}
33-
34-
return breadcrumbs;
35-
}, [currentFolder, props.folders]);
36-
3716
const handleUpload = () => {
3817
alert("Upload functionality would be implemented here");
3918
};
@@ -43,23 +22,18 @@ export default function DriveContents(props: {
4322
<div className="mx-auto max-w-6xl">
4423
<div className="mb-6 flex items-center justify-between">
4524
<div className="flex items-center">
46-
<Button
47-
onClick={() => setCurrentFolder(1)}
48-
variant="ghost"
49-
className="mr-2 text-gray-300 hover:text-white"
50-
>
25+
<Link href="/f/1" className="mr-2 text-gray-300 hover:text-white">
5126
My Drive
52-
</Button>
53-
{breadcrumbs.map((folder) => (
27+
</Link>
28+
{props.parents.map((folder) => (
5429
<div key={folder.id} className="flex items-center">
5530
<ChevronRight className="mx-2 text-gray-500" size={16} />
56-
<Button
57-
onClick={() => handleFolderClick(folder.id)}
58-
variant="ghost"
31+
<Link
32+
href={`/f/${folder.id}`}
5933
className="text-gray-300 hover:text-white"
6034
>
6135
{folder.name}
62-
</Button>
36+
</Link>
6337
</div>
6438
))}
6539
</div>
@@ -81,11 +55,7 @@ export default function DriveContents(props: {
8155
</div>
8256
<ul>
8357
{props.folders.map((folder) => (
84-
<FolderRow
85-
key={folder.id}
86-
folder={folder}
87-
onFolderClick={() => handleFolderClick(folder.id)}
88-
/>
58+
<FolderRow key={folder.id} folder={folder} />
8959
))}
9060
{props.files.map((file) => (
9161
<FileRow key={file.id} file={file} />

src/app/f/[folderId]/page.tsx

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,24 @@ import {
99

1010
import DriveContents from "../../drive-contents";
1111

12+
async function getAllParents(folderId: number) {
13+
const parents = [];
14+
let currentId: number | null = folderId;
15+
while (currentId != null) {
16+
const folders = await db
17+
.selectDistinct()
18+
.from(folderSchema)
19+
.where(eq(folderSchema.id, currentId));
20+
21+
if (!folders[0]) throw new Error("parent folder not found");
22+
23+
parents.unshift(folders[0]);
24+
currentId = folders[0]?.parent; // parent can be null
25+
}
26+
27+
return parents;
28+
}
29+
1230
export default async function GoogleDriveClone(props: {
1331
params: Promise<{ folderId: number }>;
1432
}) {
@@ -20,16 +38,22 @@ export default async function GoogleDriveClone(props: {
2038
if (!success) return <div>Invalid Folder ID</div>;
2139

2240
const folderId = data.folderId;
23-
console.log(folderId);
41+
const parentsPromise = getAllParents(folderId);
2442

25-
const folders = await db
43+
const foldersPromise = db
2644
.select()
2745
.from(folderSchema)
2846
.where(eq(folderSchema.parent, folderId));
29-
const files = await db
47+
const filesPromise = db
3048
.select()
3149
.from(fileSchema)
3250
.where(eq(fileSchema.parent, folderId));
3351

34-
return <DriveContents folders={folders} files={files} />;
52+
const [folders, files, parents] = await Promise.all([
53+
foldersPromise,
54+
filesPromise,
55+
parentsPromise,
56+
]);
57+
58+
return <DriveContents folders={folders} files={files} parents={parents} />;
3559
}

src/app/file-row.tsx

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

34
import type { files, folders } from "~/server/db/schema";
45

@@ -28,11 +29,8 @@ export function FileRow(props: { file: typeof files.$inferSelect }) {
2829
);
2930
}
3031

31-
export function FolderRow(props: {
32-
folder: typeof folders.$inferSelect;
33-
onFolderClick: () => void;
34-
}) {
35-
const { folder, onFolderClick } = props;
32+
export function FolderRow(props: { folder: typeof folders.$inferSelect }) {
33+
const { folder } = props;
3634

3735
return (
3836
<li
@@ -41,13 +39,13 @@ export function FolderRow(props: {
4139
>
4240
<div className="grid grid-cols-12 items-center gap-4">
4341
<div className="col-span-6 flex items-center">
44-
<button
45-
onClick={onFolderClick}
42+
<Link
43+
href={`/f/${folder.id}`}
4644
className="flex items-center text-gray-100 hover:text-blue-400"
4745
>
4846
<FolderIcon className="mr-3" size={20} />
4947
{folder.name}
50-
</button>
48+
</Link>
5149
</div>
5250
<div className="col-span-3 text-gray-400"></div>
5351
<div className="col-span-3 text-gray-400"></div>

0 commit comments

Comments
 (0)