From c7f83fc65a692cfc9eb81d8942abcf731c3db9db Mon Sep 17 00:00:00 2001 From: kenneth Date: Wed, 17 Sep 2025 00:04:12 +0000 Subject: [PATCH] feat: basic directory navigation --- bun.lock | 4 + convex.json | 4 + package.json | 3 +- packages/convex/files.ts | 5 +- packages/convex/model/directories.ts | 27 +++- packages/convex/schema.ts | 2 +- packages/path/index.ts | 9 ++ packages/web/convex/_generated/api.d.ts | 33 ++++ packages/web/convex/_generated/api.js | 22 +++ packages/web/convex/_generated/dataModel.d.ts | 58 +++++++ packages/web/convex/_generated/server.d.ts | 142 ++++++++++++++++++ packages/web/convex/_generated/server.js | 89 +++++++++++ packages/web/src/files/file-table.tsx | 28 ++-- packages/web/src/files/files-page.tsx | 19 ++- packages/web/src/routeTree.gen.ts | 37 ++--- .../_sidebar-layout/files.$.tsx | 15 ++ .../_authenticated/_sidebar-layout/files.tsx | 6 - 17 files changed, 456 insertions(+), 47 deletions(-) create mode 100644 convex.json create mode 100644 packages/web/convex/_generated/api.d.ts create mode 100644 packages/web/convex/_generated/api.js create mode 100644 packages/web/convex/_generated/dataModel.d.ts create mode 100644 packages/web/convex/_generated/server.d.ts create mode 100644 packages/web/convex/_generated/server.js create mode 100644 packages/web/src/routes/_authenticated/_sidebar-layout/files.$.tsx delete mode 100644 packages/web/src/routes/_authenticated/_sidebar-layout/files.tsx diff --git a/bun.lock b/bun.lock index f20c79d..c436573 100644 --- a/bun.lock +++ b/bun.lock @@ -6,10 +6,14 @@ "devDependencies": { "@biomejs/biome": "2.2.4", "@types/bun": "latest", + "convex": "^1.27.0", }, }, "packages/convex": { "name": "@fileone/convex", + "dependencies": { + "@fileone/path": "workspace:*", + }, "peerDependencies": { "convex": "^1.27.0", "typescript": "^5", diff --git a/convex.json b/convex.json new file mode 100644 index 0000000..c8f178e --- /dev/null +++ b/convex.json @@ -0,0 +1,4 @@ +{ + "$schema": "https://raw.githubusercontent.com/get-convex/convex-backend/refs/heads/main/npm-packages/convex/schemas/convex.schema.json", + "functions": "packages/convex" +} diff --git a/package.json b/package.json index 6ff7eb6..c57f24a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ }, "devDependencies": { "@biomejs/biome": "2.2.4", - "@types/bun": "latest" + "@types/bun": "latest", + "convex": "^1.27.0" } } \ No newline at end of file diff --git a/packages/convex/files.ts b/packages/convex/files.ts index dd10e9c..f493dc4 100644 --- a/packages/convex/files.ts +++ b/packages/convex/files.ts @@ -28,9 +28,10 @@ export const fetchFiles = authenticatedQuery({ export const fetchDirectoryContent = authenticatedQuery({ args: { directoryId: v.optional(v.id("directories")), + path: v.optional(v.string()), }, - handler: async (ctx, { directoryId }): Promise => { - return await Directories.fetchContent(ctx, directoryId) + handler: async (ctx, { directoryId, path }): Promise => { + return await Directories.fetchContent(ctx, { directoryId, path }) }, }) diff --git a/packages/convex/model/directories.ts b/packages/convex/model/directories.ts index 8dbf984..3b14bff 100644 --- a/packages/convex/model/directories.ts +++ b/packages/convex/model/directories.ts @@ -21,15 +21,34 @@ export type DirectoryItemKind = DirectoryItem["kind"] export async function fetchContent( ctx: AuthenticatedQueryCtx, - directoryId?: Id<"directories">, + { + path, + directoryId, + }: { path?: string; directoryId?: Id<"directories"> } = {}, ): Promise { + let dirId: Id<"directories"> | undefined + if (path) { + dirId = await ctx.db + .query("directories") + .withIndex("byPath", (q) => + q + .eq("userId", ctx.user._id) + .eq("path", path) + .eq("deletedAt", undefined), + ) + .first() + .then((dir) => dir?._id) + } else if (directoryId) { + dirId = directoryId + } + const [files, directories] = await Promise.all([ ctx.db .query("files") .withIndex("byDirectoryId", (q) => q .eq("userId", ctx.user._id) - .eq("directoryId", directoryId) + .eq("directoryId", dirId) .eq("deletedAt", undefined), ) .collect(), @@ -38,7 +57,7 @@ export async function fetchContent( .withIndex("byParentId", (q) => q .eq("userId", ctx.user._id) - .eq("parentId", directoryId) + .eq("parentId", dirId) .eq("deletedAt", undefined), ) .collect(), @@ -95,7 +114,7 @@ export async function create( userId: ctx.user._id, createdAt: now, updatedAt: now, - path: parentDir ? joinPath(parentDir.path, name) : PATH_SEPARATOR, + path: parentDir ? joinPath(parentDir.path, name) : joinPath("", name), }) } diff --git a/packages/convex/schema.ts b/packages/convex/schema.ts index 6bb1424..b1365a4 100644 --- a/packages/convex/schema.ts +++ b/packages/convex/schema.ts @@ -42,7 +42,7 @@ const schema = defineSchema({ "name", "deletedAt", ]) - .index("byPath", ["path", "deletedAt"]), + .index("byPath", ["userId", "path", "deletedAt"]), }) export default schema diff --git a/packages/path/index.ts b/packages/path/index.ts index 07c9b3f..3291f5b 100644 --- a/packages/path/index.ts +++ b/packages/path/index.ts @@ -4,6 +4,15 @@ export function baseName(path: string): string { return path.split(PATH_SEPARATOR).pop() ?? "" } +export function isPathAbsolute(path: string): boolean { + return path.startsWith(PATH_SEPARATOR) +} + export function joinPath(...paths: string[]): string { return paths.join(PATH_SEPARATOR) } + +export function splitPath(path: string): string[] { + const parts = path.split(PATH_SEPARATOR) + return isPathAbsolute(path) ? parts.slice(1) : parts +} diff --git a/packages/web/convex/_generated/api.d.ts b/packages/web/convex/_generated/api.d.ts new file mode 100644 index 0000000..7d71a01 --- /dev/null +++ b/packages/web/convex/_generated/api.d.ts @@ -0,0 +1,33 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import type { + ApiFromModules, + FilterApi, + FunctionReference, +} from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +declare const fullApi: ApiFromModules<{}>; +export declare const api: FilterApi< + typeof fullApi, + FunctionReference +>; +export declare const internal: FilterApi< + typeof fullApi, + FunctionReference +>; diff --git a/packages/web/convex/_generated/api.js b/packages/web/convex/_generated/api.js new file mode 100644 index 0000000..3f9c482 --- /dev/null +++ b/packages/web/convex/_generated/api.js @@ -0,0 +1,22 @@ +/* eslint-disable */ +/** + * Generated `api` utility. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { anyApi } from "convex/server"; + +/** + * A utility for referencing Convex functions in your app's API. + * + * Usage: + * ```js + * const myFunctionReference = api.myModule.myFunction; + * ``` + */ +export const api = anyApi; +export const internal = anyApi; diff --git a/packages/web/convex/_generated/dataModel.d.ts b/packages/web/convex/_generated/dataModel.d.ts new file mode 100644 index 0000000..fb12533 --- /dev/null +++ b/packages/web/convex/_generated/dataModel.d.ts @@ -0,0 +1,58 @@ +/* eslint-disable */ +/** + * Generated data model types. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { AnyDataModel } from "convex/server"; +import type { GenericId } from "convex/values"; + +/** + * No `schema.ts` file found! + * + * This generated code has permissive types like `Doc = any` because + * Convex doesn't know your schema. If you'd like more type safety, see + * https://docs.convex.dev/using/schemas for instructions on how to add a + * schema file. + * + * After you change a schema, rerun codegen with `npx convex dev`. + */ + +/** + * The names of all of your Convex tables. + */ +export type TableNames = string; + +/** + * The type of a document stored in Convex. + */ +export type Doc = any; + +/** + * An identifier for a document in Convex. + * + * Convex documents are uniquely identified by their `Id`, which is accessible + * on the `_id` field. To learn more, see [Document IDs](https://docs.convex.dev/using/document-ids). + * + * Documents can be loaded using `db.get(id)` in query and mutation functions. + * + * IDs are just strings at runtime, but this type can be used to distinguish them from other + * strings when type checking. + */ +export type Id = + GenericId; + +/** + * A type describing your Convex data model. + * + * This type includes information about what tables you have, the type of + * documents stored in those tables, and the indexes defined on them. + * + * This type is used to parameterize methods like `queryGeneric` and + * `mutationGeneric` to make them type-safe. + */ +export type DataModel = AnyDataModel; diff --git a/packages/web/convex/_generated/server.d.ts b/packages/web/convex/_generated/server.d.ts new file mode 100644 index 0000000..7f337a4 --- /dev/null +++ b/packages/web/convex/_generated/server.d.ts @@ -0,0 +1,142 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + ActionBuilder, + HttpActionBuilder, + MutationBuilder, + QueryBuilder, + GenericActionCtx, + GenericMutationCtx, + GenericQueryCtx, + GenericDatabaseReader, + GenericDatabaseWriter, +} from "convex/server"; +import type { DataModel } from "./dataModel.js"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const query: QueryBuilder; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export declare const internalQuery: QueryBuilder; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const mutation: MutationBuilder; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export declare const internalMutation: MutationBuilder; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export declare const action: ActionBuilder; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export declare const internalAction: ActionBuilder; + +/** + * Define an HTTP action. + * + * This function will be used to respond to HTTP requests received by a Convex + * deployment if the requests matches the path and method where this action + * is routed. Be sure to route your action in `convex/http.js`. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Import this function from `convex/http.js` and route it to hook it up. + */ +export declare const httpAction: HttpActionBuilder; + +/** + * A set of services for use within Convex query functions. + * + * The query context is passed as the first argument to any Convex query + * function run on the server. + * + * This differs from the {@link MutationCtx} because all of the services are + * read-only. + */ +export type QueryCtx = GenericQueryCtx; + +/** + * A set of services for use within Convex mutation functions. + * + * The mutation context is passed as the first argument to any Convex mutation + * function run on the server. + */ +export type MutationCtx = GenericMutationCtx; + +/** + * A set of services for use within Convex action functions. + * + * The action context is passed as the first argument to any Convex action + * function run on the server. + */ +export type ActionCtx = GenericActionCtx; + +/** + * An interface to read from the database within Convex query functions. + * + * The two entry points are {@link DatabaseReader.get}, which fetches a single + * document by its {@link Id}, or {@link DatabaseReader.query}, which starts + * building a query. + */ +export type DatabaseReader = GenericDatabaseReader; + +/** + * An interface to read from and write to the database within Convex mutation + * functions. + * + * Convex guarantees that all writes within a single mutation are + * executed atomically, so you never have to worry about partial writes leaving + * your data in an inconsistent state. See [the Convex Guide](https://docs.convex.dev/understanding/convex-fundamentals/functions#atomicity-and-optimistic-concurrency-control) + * for the guarantees Convex provides your functions. + */ +export type DatabaseWriter = GenericDatabaseWriter; diff --git a/packages/web/convex/_generated/server.js b/packages/web/convex/_generated/server.js new file mode 100644 index 0000000..566d485 --- /dev/null +++ b/packages/web/convex/_generated/server.js @@ -0,0 +1,89 @@ +/* eslint-disable */ +/** + * Generated utilities for implementing server-side Convex query and mutation functions. + * + * THIS CODE IS AUTOMATICALLY GENERATED. + * + * To regenerate, run `npx convex dev`. + * @module + */ + +import { + actionGeneric, + httpActionGeneric, + queryGeneric, + mutationGeneric, + internalActionGeneric, + internalMutationGeneric, + internalQueryGeneric, +} from "convex/server"; + +/** + * Define a query in this Convex app's public API. + * + * This function will be allowed to read your Convex database and will be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const query = queryGeneric; + +/** + * Define a query that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to read from your Convex database. It will not be accessible from the client. + * + * @param func - The query function. It receives a {@link QueryCtx} as its first argument. + * @returns The wrapped query. Include this as an `export` to name it and make it accessible. + */ +export const internalQuery = internalQueryGeneric; + +/** + * Define a mutation in this Convex app's public API. + * + * This function will be allowed to modify your Convex database and will be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const mutation = mutationGeneric; + +/** + * Define a mutation that is only accessible from other Convex functions (but not from the client). + * + * This function will be allowed to modify your Convex database. It will not be accessible from the client. + * + * @param func - The mutation function. It receives a {@link MutationCtx} as its first argument. + * @returns The wrapped mutation. Include this as an `export` to name it and make it accessible. + */ +export const internalMutation = internalMutationGeneric; + +/** + * Define an action in this Convex app's public API. + * + * An action is a function which can execute any JavaScript code, including non-deterministic + * code and code with side-effects, like calling third-party services. + * They can be run in Convex's JavaScript environment or in Node.js using the "use node" directive. + * They can interact with the database indirectly by calling queries and mutations using the {@link ActionCtx}. + * + * @param func - The action. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped action. Include this as an `export` to name it and make it accessible. + */ +export const action = actionGeneric; + +/** + * Define an action that is only accessible from other Convex functions (but not from the client). + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument. + * @returns The wrapped function. Include this as an `export` to name it and make it accessible. + */ +export const internalAction = internalActionGeneric; + +/** + * Define a Convex HTTP action. + * + * @param func - The function. It receives an {@link ActionCtx} as its first argument, and a `Request` object + * as its second. + * @returns The wrapped endpoint function. Route a URL path to this function in `convex/http.js`. + */ +export const httpAction = httpActionGeneric; diff --git a/packages/web/src/files/file-table.tsx b/packages/web/src/files/file-table.tsx index 5c7b44d..8103fdc 100644 --- a/packages/web/src/files/file-table.tsx +++ b/packages/web/src/files/file-table.tsx @@ -1,6 +1,8 @@ import { api } from "@fileone/convex/_generated/api" +import type { Doc } from "@fileone/convex/_generated/dataModel" import type { DirectoryItem } from "@fileone/convex/model/directories" import { useMutation } from "@tanstack/react-query" +import { Link } from "@tanstack/react-router" import { type ColumnDef, flexRender, @@ -81,12 +83,7 @@ const columns: ColumnDef[] = [ case "file": return case "directory": - return ( -
- - {row.original.doc.name} -
- ) + return } }, size: 1000, @@ -116,11 +113,11 @@ const columns: ColumnDef[] = [ }, ] -export function FileTable() { +export function FileTable({ path }: { path: string }) { return (
- +
) @@ -184,8 +181,8 @@ export function FileTableContextMenu({ ) } -export function FileTableContent() { - const directory = useQuery(api.files.fetchDirectoryContent, {}) +export function FileTableContent({ path }: { path: string }) { + const directory = useQuery(api.files.fetchDirectoryContent, { path }) const optimisticDeletedItems = useAtomValue(optimisticDeletedItemsAtom) const setContextMenuTargetItem = useSetAtom(contextMenuTargeItemAtom) @@ -377,6 +374,17 @@ function NewItemRow() { ) } +function DirectoryNameCell({ directory }: { directory: Doc<"directories"> }) { + return ( +
+ + + {directory.name} + +
+ ) +} + function FileNameCell({ initialName }: { initialName: string }) { return (
diff --git a/packages/web/src/files/files-page.tsx b/packages/web/src/files/files-page.tsx index aace853..7b2e180 100644 --- a/packages/web/src/files/files-page.tsx +++ b/packages/web/src/files/files-page.tsx @@ -1,5 +1,7 @@ import { api } from "@fileone/convex/_generated/api" +import { splitPath } from "@fileone/path" import { useMutation } from "@tanstack/react-query" +import { useParams } from "@tanstack/react-router" import { useMutation as useConvexMutation } from "convex/react" import { useSetAtom } from "jotai" import { @@ -8,7 +10,7 @@ import { PlusIcon, UploadCloudIcon, } from "lucide-react" -import { type ChangeEvent, useRef } from "react" +import { type ChangeEvent, Fragment, useRef } from "react" import { toast } from "sonner" import { DropdownMenu, @@ -29,16 +31,23 @@ import { Button } from "../components/ui/button" import { FileTable } from "./file-table" import { newItemKindAtom } from "./state" -export function FilesPage() { +export function FilesPage({ path }: { path: string }) { return ( <> -
+
All Files - + {splitPath(path).map((p) => ( + + + + {p} + + + ))}
@@ -47,7 +56,7 @@ export function FilesPage() {
- +
) diff --git a/packages/web/src/routeTree.gen.ts b/packages/web/src/routeTree.gen.ts index 5d9165c..2edaade 100644 --- a/packages/web/src/routeTree.gen.ts +++ b/packages/web/src/routeTree.gen.ts @@ -14,7 +14,7 @@ import { Route as AuthenticatedRouteImport } from './routes/_authenticated' import { Route as AuthenticatedIndexRouteImport } from './routes/_authenticated/index' import { Route as LoginCallbackRouteImport } from './routes/login_.callback' import { Route as AuthenticatedSidebarLayoutRouteImport } from './routes/_authenticated/_sidebar-layout' -import { Route as AuthenticatedSidebarLayoutFilesRouteImport } from './routes/_authenticated/_sidebar-layout/files' +import { Route as AuthenticatedSidebarLayoutFilesSplatRouteImport } from './routes/_authenticated/_sidebar-layout/files.$' const LoginRoute = LoginRouteImport.update({ id: '/login', @@ -40,10 +40,10 @@ const AuthenticatedSidebarLayoutRoute = id: '/_sidebar-layout', getParentRoute: () => AuthenticatedRoute, } as any) -const AuthenticatedSidebarLayoutFilesRoute = - AuthenticatedSidebarLayoutFilesRouteImport.update({ - id: '/files', - path: '/files', +const AuthenticatedSidebarLayoutFilesSplatRoute = + AuthenticatedSidebarLayoutFilesSplatRouteImport.update({ + id: '/files/$', + path: '/files/$', getParentRoute: () => AuthenticatedSidebarLayoutRoute, } as any) @@ -51,13 +51,13 @@ export interface FileRoutesByFullPath { '/login': typeof LoginRoute '/login/callback': typeof LoginCallbackRoute '/': typeof AuthenticatedIndexRoute - '/files': typeof AuthenticatedSidebarLayoutFilesRoute + '/files/$': typeof AuthenticatedSidebarLayoutFilesSplatRoute } export interface FileRoutesByTo { '/login': typeof LoginRoute '/login/callback': typeof LoginCallbackRoute '/': typeof AuthenticatedIndexRoute - '/files': typeof AuthenticatedSidebarLayoutFilesRoute + '/files/$': typeof AuthenticatedSidebarLayoutFilesSplatRoute } export interface FileRoutesById { __root__: typeof rootRouteImport @@ -66,13 +66,13 @@ export interface FileRoutesById { '/_authenticated/_sidebar-layout': typeof AuthenticatedSidebarLayoutRouteWithChildren '/login_/callback': typeof LoginCallbackRoute '/_authenticated/': typeof AuthenticatedIndexRoute - '/_authenticated/_sidebar-layout/files': typeof AuthenticatedSidebarLayoutFilesRoute + '/_authenticated/_sidebar-layout/files/$': typeof AuthenticatedSidebarLayoutFilesSplatRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath - fullPaths: '/login' | '/login/callback' | '/' | '/files' + fullPaths: '/login' | '/login/callback' | '/' | '/files/$' fileRoutesByTo: FileRoutesByTo - to: '/login' | '/login/callback' | '/' | '/files' + to: '/login' | '/login/callback' | '/' | '/files/$' id: | '__root__' | '/_authenticated' @@ -80,7 +80,7 @@ export interface FileRouteTypes { | '/_authenticated/_sidebar-layout' | '/login_/callback' | '/_authenticated/' - | '/_authenticated/_sidebar-layout/files' + | '/_authenticated/_sidebar-layout/files/$' fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -126,23 +126,24 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof AuthenticatedSidebarLayoutRouteImport parentRoute: typeof AuthenticatedRoute } - '/_authenticated/_sidebar-layout/files': { - id: '/_authenticated/_sidebar-layout/files' - path: '/files' - fullPath: '/files' - preLoaderRoute: typeof AuthenticatedSidebarLayoutFilesRouteImport + '/_authenticated/_sidebar-layout/files/$': { + id: '/_authenticated/_sidebar-layout/files/$' + path: '/files/$' + fullPath: '/files/$' + preLoaderRoute: typeof AuthenticatedSidebarLayoutFilesSplatRouteImport parentRoute: typeof AuthenticatedSidebarLayoutRoute } } } interface AuthenticatedSidebarLayoutRouteChildren { - AuthenticatedSidebarLayoutFilesRoute: typeof AuthenticatedSidebarLayoutFilesRoute + AuthenticatedSidebarLayoutFilesSplatRoute: typeof AuthenticatedSidebarLayoutFilesSplatRoute } const AuthenticatedSidebarLayoutRouteChildren: AuthenticatedSidebarLayoutRouteChildren = { - AuthenticatedSidebarLayoutFilesRoute: AuthenticatedSidebarLayoutFilesRoute, + AuthenticatedSidebarLayoutFilesSplatRoute: + AuthenticatedSidebarLayoutFilesSplatRoute, } const AuthenticatedSidebarLayoutRouteWithChildren = diff --git a/packages/web/src/routes/_authenticated/_sidebar-layout/files.$.tsx b/packages/web/src/routes/_authenticated/_sidebar-layout/files.$.tsx new file mode 100644 index 0000000..1500a6c --- /dev/null +++ b/packages/web/src/routes/_authenticated/_sidebar-layout/files.$.tsx @@ -0,0 +1,15 @@ +import { joinPath, PATH_SEPARATOR } from "@fileone/path" +import { createFileRoute } from "@tanstack/react-router" +import { FilesPage } from "@/files/files-page" + +export const Route = createFileRoute("/_authenticated/_sidebar-layout/files/$")( + { + component: RouteComponent, + }, +) + +function RouteComponent() { + const { _splat } = Route.useParams() + const path = _splat ? joinPath("", _splat) : PATH_SEPARATOR + return +} diff --git a/packages/web/src/routes/_authenticated/_sidebar-layout/files.tsx b/packages/web/src/routes/_authenticated/_sidebar-layout/files.tsx deleted file mode 100644 index 3aeee9a..0000000 --- a/packages/web/src/routes/_authenticated/_sidebar-layout/files.tsx +++ /dev/null @@ -1,6 +0,0 @@ -import { createFileRoute } from "@tanstack/react-router" -import { FilesPage } from "@/files/files-page" - -export const Route = createFileRoute("/_authenticated/_sidebar-layout/files")({ - component: FilesPage, -})