diff options
Diffstat (limited to 'frontend/app')
| -rw-r--r-- | frontend/app/drive/[...path]/page.tsx | 58 | ||||
| -rw-r--r-- | frontend/app/drive/page.tsx | 33 | ||||
| -rw-r--r-- | frontend/app/globals.css | 122 | ||||
| -rw-r--r-- | frontend/app/layout.tsx | 6 | ||||
| -rw-r--r-- | frontend/app/page.tsx | 6 |
5 files changed, 114 insertions, 111 deletions
diff --git a/frontend/app/drive/[...path]/page.tsx b/frontend/app/drive/[...path]/page.tsx deleted file mode 100644 index be11253..0000000 --- a/frontend/app/drive/[...path]/page.tsx +++ /dev/null | |||
| @@ -1,58 +0,0 @@ | |||
| 1 | import { Drive_ls } from "@/lib/drive_server" | ||
| 2 | import { Drive_parent } from "@/lib/drive_shared" | ||
| 3 | import Link from "next/link" | ||
| 4 | import { Auth_get_user, Auth_user_can_upload } from "@/lib/auth"; | ||
| 5 | import FileUpload from "@/components/FileUpload" | ||
| 6 | import FileTable from "@/components/FileTable" | ||
| 7 | |||
| 8 | interface DrivePageProps { | ||
| 9 | params: Promise<{ | ||
| 10 | path: string[] | ||
| 11 | }> | ||
| 12 | } | ||
| 13 | |||
| 14 | export default async function DrivePage({ params }: DrivePageProps) { | ||
| 15 | // Await params as required by Next.js 15 | ||
| 16 | const { path } = await params | ||
| 17 | |||
| 18 | const user = await Auth_get_user(); | ||
| 19 | |||
| 20 | // Construct the full path from params | ||
| 21 | const fullPath = path ? `/${path.join('/')}` : "" | ||
| 22 | |||
| 23 | const entries = await Drive_ls(fullPath, false) | ||
| 24 | |||
| 25 | // Check if we have a parent directory | ||
| 26 | const parentDir = Drive_parent(fullPath) | ||
| 27 | const parentPath = path && path.length > 1 | ||
| 28 | ? `/drive/${path.slice(0, -1).join('/')}` | ||
| 29 | : path && path.length === 1 | ||
| 30 | ? '/drive' | ||
| 31 | : null | ||
| 32 | |||
| 33 | const showParent = parentDir !== null && parentPath !== null | ||
| 34 | |||
| 35 | return ( | ||
| 36 | <div className="min-h-screen bg-background"> | ||
| 37 | <div className="container mx-auto p-4"> | ||
| 38 | <Link href="/drive" className="inline-block mb-6"> | ||
| 39 | <h1 className="text-2xl font-bold text-foreground hover:text-blue-600 dark:hover:text-blue-400 transition-colors cursor-pointer">FCTDrive</h1> | ||
| 40 | </Link> | ||
| 41 | |||
| 42 | <FileTable | ||
| 43 | entries={entries} | ||
| 44 | currentPath={fullPath} | ||
| 45 | showParent={showParent} | ||
| 46 | parentPath={parentPath || undefined} | ||
| 47 | /> | ||
| 48 | |||
| 49 | {/* File Upload Component */} | ||
| 50 | {Auth_user_can_upload(user) && ( | ||
| 51 | <FileUpload | ||
| 52 | targetPath={fullPath} | ||
| 53 | /> | ||
| 54 | )} | ||
| 55 | </div> | ||
| 56 | </div> | ||
| 57 | ) | ||
| 58 | } | ||
diff --git a/frontend/app/drive/page.tsx b/frontend/app/drive/page.tsx deleted file mode 100644 index 9253c3a..0000000 --- a/frontend/app/drive/page.tsx +++ /dev/null | |||
| @@ -1,33 +0,0 @@ | |||
| 1 | import { Drive_ls } from "@/lib/drive_server" | ||
| 2 | import { Auth_get_user, Auth_user_can_upload } from "@/lib/auth" | ||
| 3 | import Link from "next/link" | ||
| 4 | import FileUpload from "@/components/FileUpload" | ||
| 5 | import FileTable from "@/components/FileTable" | ||
| 6 | |||
| 7 | export default async function DrivePage() { | ||
| 8 | const user = await Auth_get_user() | ||
| 9 | const entries = await Drive_ls("", false) | ||
| 10 | |||
| 11 | return ( | ||
| 12 | <div className="min-h-screen bg-background"> | ||
| 13 | <div className="container mx-auto p-4"> | ||
| 14 | <Link href="/drive" className="inline-block mb-6"> | ||
| 15 | <h1 className="text-2xl font-bold text-foreground hover:text-blue-600 dark:hover:text-blue-400 transition-colors cursor-pointer">FCTDrive</h1> | ||
| 16 | </Link> | ||
| 17 | |||
| 18 | <FileTable | ||
| 19 | entries={entries} | ||
| 20 | currentPath="" | ||
| 21 | showParent={false} | ||
| 22 | /> | ||
| 23 | |||
| 24 | {/* File Upload Component */} | ||
| 25 | {Auth_user_can_upload(user) && ( | ||
| 26 | <FileUpload | ||
| 27 | targetPath="" | ||
| 28 | /> | ||
| 29 | )} | ||
| 30 | </div> | ||
| 31 | </div> | ||
| 32 | ) | ||
| 33 | } \ No newline at end of file | ||
diff --git a/frontend/app/globals.css b/frontend/app/globals.css index a2dc41e..dc98be7 100644 --- a/frontend/app/globals.css +++ b/frontend/app/globals.css | |||
| @@ -1,26 +1,122 @@ | |||
| 1 | @import "tailwindcss"; | 1 | @import "tailwindcss"; |
| 2 | @import "tw-animate-css"; | ||
| 2 | 3 | ||
| 3 | :root { | 4 | @custom-variant dark (&:is(.dark *)); |
| 4 | --background: #ffffff; | ||
| 5 | --foreground: #171717; | ||
| 6 | } | ||
| 7 | 5 | ||
| 8 | @theme inline { | 6 | @theme inline { |
| 9 | --color-background: var(--background); | 7 | --color-background: var(--background); |
| 10 | --color-foreground: var(--foreground); | 8 | --color-foreground: var(--foreground); |
| 11 | --font-sans: var(--font-geist-sans); | 9 | --font-sans: var(--font-geist-sans); |
| 12 | --font-mono: var(--font-geist-mono); | 10 | --font-mono: var(--font-geist-mono); |
| 11 | --color-sidebar-ring: var(--sidebar-ring); | ||
| 12 | --color-sidebar-border: var(--sidebar-border); | ||
| 13 | --color-sidebar-accent-foreground: var(--sidebar-accent-foreground); | ||
| 14 | --color-sidebar-accent: var(--sidebar-accent); | ||
| 15 | --color-sidebar-primary-foreground: var(--sidebar-primary-foreground); | ||
| 16 | --color-sidebar-primary: var(--sidebar-primary); | ||
| 17 | --color-sidebar-foreground: var(--sidebar-foreground); | ||
| 18 | --color-sidebar: var(--sidebar); | ||
| 19 | --color-chart-5: var(--chart-5); | ||
| 20 | --color-chart-4: var(--chart-4); | ||
| 21 | --color-chart-3: var(--chart-3); | ||
| 22 | --color-chart-2: var(--chart-2); | ||
| 23 | --color-chart-1: var(--chart-1); | ||
| 24 | --color-ring: var(--ring); | ||
| 25 | --color-input: var(--input); | ||
| 26 | --color-border: var(--border); | ||
| 27 | --color-destructive: var(--destructive); | ||
| 28 | --color-accent-foreground: var(--accent-foreground); | ||
| 29 | --color-accent: var(--accent); | ||
| 30 | --color-muted-foreground: var(--muted-foreground); | ||
| 31 | --color-muted: var(--muted); | ||
| 32 | --color-secondary-foreground: var(--secondary-foreground); | ||
| 33 | --color-secondary: var(--secondary); | ||
| 34 | --color-primary-foreground: var(--primary-foreground); | ||
| 35 | --color-primary: var(--primary); | ||
| 36 | --color-popover-foreground: var(--popover-foreground); | ||
| 37 | --color-popover: var(--popover); | ||
| 38 | --color-card-foreground: var(--card-foreground); | ||
| 39 | --color-card: var(--card); | ||
| 40 | --radius-sm: calc(var(--radius) - 4px); | ||
| 41 | --radius-md: calc(var(--radius) - 2px); | ||
| 42 | --radius-lg: var(--radius); | ||
| 43 | --radius-xl: calc(var(--radius) + 4px); | ||
| 13 | } | 44 | } |
| 14 | 45 | ||
| 15 | @media (prefers-color-scheme: dark) { | 46 | :root { |
| 16 | :root { | 47 | --radius: 0.625rem; |
| 17 | --background: #0a0a0a; | 48 | --background: oklch(1 0 0); |
| 18 | --foreground: #ededed; | 49 | --foreground: oklch(0.145 0 0); |
| 19 | } | 50 | --card: oklch(1 0 0); |
| 51 | --card-foreground: oklch(0.145 0 0); | ||
| 52 | --popover: oklch(1 0 0); | ||
| 53 | --popover-foreground: oklch(0.145 0 0); | ||
| 54 | --primary: oklch(0.205 0 0); | ||
| 55 | --primary-foreground: oklch(0.985 0 0); | ||
| 56 | --secondary: oklch(0.97 0 0); | ||
| 57 | --secondary-foreground: oklch(0.205 0 0); | ||
| 58 | --muted: oklch(0.97 0 0); | ||
| 59 | --muted-foreground: oklch(0.556 0 0); | ||
| 60 | --accent: oklch(0.97 0 0); | ||
| 61 | --accent-foreground: oklch(0.205 0 0); | ||
| 62 | --destructive: oklch(0.577 0.245 27.325); | ||
| 63 | --border: oklch(0.922 0 0); | ||
| 64 | --input: oklch(0.922 0 0); | ||
| 65 | --ring: oklch(0.708 0 0); | ||
| 66 | --chart-1: oklch(0.646 0.222 41.116); | ||
| 67 | --chart-2: oklch(0.6 0.118 184.704); | ||
| 68 | --chart-3: oklch(0.398 0.07 227.392); | ||
| 69 | --chart-4: oklch(0.828 0.189 84.429); | ||
| 70 | --chart-5: oklch(0.769 0.188 70.08); | ||
| 71 | --sidebar: oklch(0.985 0 0); | ||
| 72 | --sidebar-foreground: oklch(0.145 0 0); | ||
| 73 | --sidebar-primary: oklch(0.205 0 0); | ||
| 74 | --sidebar-primary-foreground: oklch(0.985 0 0); | ||
| 75 | --sidebar-accent: oklch(0.97 0 0); | ||
| 76 | --sidebar-accent-foreground: oklch(0.205 0 0); | ||
| 77 | --sidebar-border: oklch(0.922 0 0); | ||
| 78 | --sidebar-ring: oklch(0.708 0 0); | ||
| 20 | } | 79 | } |
| 21 | 80 | ||
| 22 | body { | 81 | .dark { |
| 23 | background: var(--background); | 82 | --background: oklch(0.145 0 0); |
| 24 | color: var(--foreground); | 83 | --foreground: oklch(0.985 0 0); |
| 25 | font-family: Arial, Helvetica, sans-serif; | 84 | --card: oklch(0.205 0 0); |
| 85 | --card-foreground: oklch(0.985 0 0); | ||
| 86 | --popover: oklch(0.205 0 0); | ||
| 87 | --popover-foreground: oklch(0.985 0 0); | ||
| 88 | --primary: oklch(0.922 0 0); | ||
| 89 | --primary-foreground: oklch(0.205 0 0); | ||
| 90 | --secondary: oklch(0.269 0 0); | ||
| 91 | --secondary-foreground: oklch(0.985 0 0); | ||
| 92 | --muted: oklch(0.269 0 0); | ||
| 93 | --muted-foreground: oklch(0.708 0 0); | ||
| 94 | --accent: oklch(0.269 0 0); | ||
| 95 | --accent-foreground: oklch(0.985 0 0); | ||
| 96 | --destructive: oklch(0.704 0.191 22.216); | ||
| 97 | --border: oklch(1 0 0 / 10%); | ||
| 98 | --input: oklch(1 0 0 / 15%); | ||
| 99 | --ring: oklch(0.556 0 0); | ||
| 100 | --chart-1: oklch(0.488 0.243 264.376); | ||
| 101 | --chart-2: oklch(0.696 0.17 162.48); | ||
| 102 | --chart-3: oklch(0.769 0.188 70.08); | ||
| 103 | --chart-4: oklch(0.627 0.265 303.9); | ||
| 104 | --chart-5: oklch(0.645 0.246 16.439); | ||
| 105 | --sidebar: oklch(0.205 0 0); | ||
| 106 | --sidebar-foreground: oklch(0.985 0 0); | ||
| 107 | --sidebar-primary: oklch(0.488 0.243 264.376); | ||
| 108 | --sidebar-primary-foreground: oklch(0.985 0 0); | ||
| 109 | --sidebar-accent: oklch(0.269 0 0); | ||
| 110 | --sidebar-accent-foreground: oklch(0.985 0 0); | ||
| 111 | --sidebar-border: oklch(1 0 0 / 10%); | ||
| 112 | --sidebar-ring: oklch(0.556 0 0); | ||
| 113 | } | ||
| 114 | |||
| 115 | @layer base { | ||
| 116 | * { | ||
| 117 | @apply border-border outline-ring/50; | ||
| 118 | } | ||
| 119 | body { | ||
| 120 | @apply bg-background text-foreground; | ||
| 121 | } | ||
| 26 | } | 122 | } |
diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 2e001e4..9cc7dac 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | import type { Metadata } from "next"; | 1 | import type { Metadata } from "next"; |
| 2 | import { Geist, Geist_Mono } from "next/font/google"; | 2 | import { Geist, Geist_Mono } from "next/font/google"; |
| 3 | import "./globals.css"; | 3 | import "./globals.css"; |
| 4 | import AuthButton from "@/components/AuthButton"; | 4 | import { Toaster } from "@/components/ui/toaster"; |
| 5 | 5 | ||
| 6 | const geistSans = Geist({ | 6 | const geistSans = Geist({ |
| 7 | variable: "--font-geist-sans", | 7 | variable: "--font-geist-sans", |
| @@ -28,10 +28,8 @@ export default function RootLayout({ | |||
| 28 | <body | 28 | <body |
| 29 | className={`${geistSans.variable} ${geistMono.variable} antialiased`} | 29 | className={`${geistSans.variable} ${geistMono.variable} antialiased`} |
| 30 | > | 30 | > |
| 31 | <div className="absolute top-4 right-4 z-10"> | ||
| 32 | <AuthButton /> | ||
| 33 | </div> | ||
| 34 | {children} | 31 | {children} |
| 32 | <Toaster /> | ||
| 35 | </body> | 33 | </body> |
| 36 | </html> | 34 | </html> |
| 37 | ); | 35 | ); |
diff --git a/frontend/app/page.tsx b/frontend/app/page.tsx index 3333985..e2b6a80 100644 --- a/frontend/app/page.tsx +++ b/frontend/app/page.tsx | |||
| @@ -1,5 +1,5 @@ | |||
| 1 | import { redirect } from 'next/navigation' | 1 | import FileDrive from "../file-drive" |
| 2 | 2 | ||
| 3 | export default function Home() { | 3 | export default function Page() { |
| 4 | redirect('/drive') | 4 | return <FileDrive /> |
| 5 | } | 5 | } |
