Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,6 @@ Just finished up the database connection, next steps:

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

- [ ] Change folders to link components, remove all client state
- [x] Change folders to link components, remove all client state
- [ ] Clean up the database and data fetching patterns
- [ ] Real homepage
50 changes: 10 additions & 40 deletions src/app/drive-contents.tsx
Original file line number Diff line number Diff line change
@@ -1,39 +1,18 @@
"use client";

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

import { Button } from "~/components/ui/button";
import type { files, folders } from "~/server/db/schema";

import { FileRow, FolderRow } from "./file-row";

export default function DriveContents(props: {
files: (typeof files.$inferSelect)[];
folders: (typeof folders.$inferSelect)[];
parents: (typeof folders.$inferSelect)[];
}) {
const [currentFolder, setCurrentFolder] = useState(1);

const handleFolderClick = (folderId: number) => {
setCurrentFolder(folderId);
};

const breadcrumbs = useMemo(() => {
const breadcrumbs = [];
let currentId = currentFolder;

while (currentId !== 1) {
const folder = props.folders.find((file) => file.id === currentId);
if (folder) {
breadcrumbs.unshift(folder);
currentId = folder.parent ?? 1;
} else {
break;
}
}

return breadcrumbs;
}, [currentFolder, props.folders]);

const handleUpload = () => {
alert("Upload functionality would be implemented here");
};
Expand All @@ -43,23 +22,18 @@ export default function DriveContents(props: {
<div className="mx-auto max-w-6xl">
<div className="mb-6 flex items-center justify-between">
<div className="flex items-center">
<Button
onClick={() => setCurrentFolder(1)}
variant="ghost"
className="mr-2 text-gray-300 hover:text-white"
>
<Link href="/f/1" className="mr-2 text-gray-300 hover:text-white">
My Drive
</Button>
{breadcrumbs.map((folder) => (
</Link>
{props.parents.map((folder) => (
<div key={folder.id} className="flex items-center">
<ChevronRight className="mx-2 text-gray-500" size={16} />
<Button
onClick={() => handleFolderClick(folder.id)}
variant="ghost"
<Link
href={`/f/${folder.id}`}
className="text-gray-300 hover:text-white"
>
{folder.name}
</Button>
</Link>
</div>
))}
</div>
Expand All @@ -81,11 +55,7 @@ export default function DriveContents(props: {
</div>
<ul>
{props.folders.map((folder) => (
<FolderRow
key={folder.id}
folder={folder}
onFolderClick={() => handleFolderClick(folder.id)}
/>
<FolderRow key={folder.id} folder={folder} />
))}
{props.files.map((file) => (
<FileRow key={file.id} file={file} />
Expand Down
32 changes: 28 additions & 4 deletions src/app/f/[folderId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,24 @@ import {

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

async function getAllParents(folderId: number) {
const parents = [];
let currentId: number | null = folderId;
while (currentId != null) {
const folders = await db
.selectDistinct()
.from(folderSchema)
.where(eq(folderSchema.id, currentId));

if (!folders[0]) throw new Error("parent folder not found");

parents.unshift(folders[0]);
currentId = folders[0]?.parent; // parent can be null
}

return parents;
}

export default async function GoogleDriveClone(props: {
params: Promise<{ folderId: number }>;
}) {
Expand All @@ -20,16 +38,22 @@ export default async function GoogleDriveClone(props: {
if (!success) return <div>Invalid Folder ID</div>;

const folderId = data.folderId;
console.log(folderId);
const parentsPromise = getAllParents(folderId);

const folders = await db
const foldersPromise = db
.select()
.from(folderSchema)
.where(eq(folderSchema.parent, folderId));
const files = await db
const filesPromise = db
.select()
.from(fileSchema)
.where(eq(fileSchema.parent, folderId));

return <DriveContents folders={folders} files={files} />;
const [folders, files, parents] = await Promise.all([
foldersPromise,
filesPromise,
parentsPromise,
]);

return <DriveContents folders={folders} files={files} parents={parents} />;
}
14 changes: 6 additions & 8 deletions src/app/file-row.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { FileIcon, Folder as FolderIcon } from "lucide-react";
import Link from "next/link";

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

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

export function FolderRow(props: {
folder: typeof folders.$inferSelect;
onFolderClick: () => void;
}) {
const { folder, onFolderClick } = props;
export function FolderRow(props: { folder: typeof folders.$inferSelect }) {
const { folder } = props;

return (
<li
Expand All @@ -41,13 +39,13 @@ export function FolderRow(props: {
>
<div className="grid grid-cols-12 items-center gap-4">
<div className="col-span-6 flex items-center">
<button
onClick={onFolderClick}
<Link
href={`/f/${folder.id}`}
className="flex items-center text-gray-100 hover:text-blue-400"
>
<FolderIcon className="mr-3" size={20} />
{folder.name}
</button>
</Link>
</div>
<div className="col-span-3 text-gray-400"></div>
<div className="col-span-3 text-gray-400"></div>
Expand Down