diff --git a/apps/client/app/api-client/types.gen.ts b/apps/client/app/api-client/types.gen.ts index 6bfc979..4d0d9ef 100644 --- a/apps/client/app/api-client/types.gen.ts +++ b/apps/client/app/api-client/types.gen.ts @@ -13,9 +13,25 @@ export type ListVolumesResponses = { */ 200: { volumes: Array<{ + config: + | { + backend: "directory"; + } + | { + backend: "nfs"; + exportPath: string; + server: string; + version: "3" | "4" | "4.1"; + port?: number | string; + } + | { + backend: "smb"; + }; createdAt: number; name: string; path: string; + type: "directory" | "nfs" | "smb"; + updatedAt: number; }>; }; }; @@ -153,7 +169,7 @@ export type GetVolumeResponses = { createdAt: number; name: string; path: string; - type: string; + type: "directory" | "nfs" | "smb"; updatedAt: number; }; }; diff --git a/apps/client/app/components/volume-icon.tsx b/apps/client/app/components/volume-icon.tsx new file mode 100644 index 0000000..0a5ceab --- /dev/null +++ b/apps/client/app/components/volume-icon.tsx @@ -0,0 +1,47 @@ +import type { BackendType } from "@ironmount/schemas"; +import { Folder, Server, Share2 } from "lucide-react"; + +type VolumeIconProps = { + backend: BackendType; + size?: number; +}; + +const getIconAndColor = (backend: BackendType) => { + switch (backend) { + case "directory": + return { + icon: Folder, + color: "text-blue-600 dark:text-blue-400", + label: "Directory", + }; + case "nfs": + return { + icon: Server, + color: "text-orange-600 dark:text-orange-400", + label: "NFS", + }; + case "smb": + return { + icon: Share2, + color: "text-purple-600 dark:text-purple-400", + label: "SMB", + }; + default: + return { + icon: Folder, + color: "text-gray-600 dark:text-gray-400", + label: "Unknown", + }; + } +}; + +export const VolumeIcon = ({ backend, size = 10 }: VolumeIconProps) => { + const { icon: Icon, color, label } = getIconAndColor(backend); + + return ( + + + {label} + + ); +}; diff --git a/apps/client/app/routes/home.tsx b/apps/client/app/routes/home.tsx index 47e3571..6274c1e 100644 --- a/apps/client/app/routes/home.tsx +++ b/apps/client/app/routes/home.tsx @@ -1,5 +1,5 @@ import { useMutation, useQuery } from "@tanstack/react-query"; -import { Copy, Folder } from "lucide-react"; +import { Copy } from "lucide-react"; import { useState } from "react"; import { toast } from "sonner"; import { type ListVolumesResponse, listVolumes } from "~/api-client"; @@ -10,6 +10,7 @@ import { Button } from "~/components/ui/button"; import { Input } from "~/components/ui/input"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "~/components/ui/select"; import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "~/components/ui/table"; +import { VolumeIcon } from "~/components/volume-icon"; import { parseError } from "~/lib/errors"; import { cn } from "~/lib/utils"; import type { Route } from "./+types/home"; @@ -114,10 +115,7 @@ export default function Home({ loaderData }: Route.ComponentProps) { {volume.name} - - - Volume - + diff --git a/apps/server/src/db/schema.ts b/apps/server/src/db/schema.ts index b050044..00ad3eb 100644 --- a/apps/server/src/db/schema.ts +++ b/apps/server/src/db/schema.ts @@ -1,4 +1,4 @@ -import type { volumeConfigSchema } from "@ironmount/schemas"; +import type { BackendType, volumeConfigSchema } from "@ironmount/schemas"; import { sql } from "drizzle-orm"; import { int, sqliteTable, text } from "drizzle-orm/sqlite-core"; @@ -6,7 +6,7 @@ export const volumesTable = sqliteTable("volumes_table", { id: int().primaryKey({ autoIncrement: true }), name: text().notNull().unique(), path: text().notNull(), - type: text().notNull(), + type: text().$type().notNull(), createdAt: int("created_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`), updatedAt: int("updated_at", { mode: "timestamp" }).notNull().default(sql`(unixepoch())`), config: text("config", { mode: "json" }).$type().notNull(), diff --git a/apps/server/src/modules/volumes/volume.dto.ts b/apps/server/src/modules/volumes/volume.dto.ts index 80cf10f..eef74c5 100644 --- a/apps/server/src/modules/volumes/volume.dto.ts +++ b/apps/server/src/modules/volumes/volume.dto.ts @@ -6,7 +6,7 @@ import { resolver } from "hono-openapi/arktype"; const volumeSchema = type({ name: "string", path: "string", - type: "string", + type: type.enumerated("nfs", "smb", "directory"), createdAt: "number", updatedAt: "number", config: volumeConfigSchema,