From e8060b071949bd06476560e5c7029df5293f0d14 Mon Sep 17 00:00:00 2001 From: Jack Merrill Date: Fri, 4 Apr 2025 01:51:12 -0400 Subject: [PATCH] Add document page and enhance upload functionality with user-specific document handling --- app/dashboard/documents/[id]/page.tsx | 117 ++++++++++++++++++++++++++ app/dashboard/upload/page.tsx | 23 ++++- app/dashboard/upload/process/route.ts | 4 +- app/globals.css | 1 + bun.lockb | Bin 127328 -> 157196 bytes components/UploadZone.tsx | 10 +-- components/app-sidebar.tsx | 63 ++------------ package.json | 3 + 8 files changed, 156 insertions(+), 65 deletions(-) create mode 100644 app/dashboard/documents/[id]/page.tsx diff --git a/app/dashboard/documents/[id]/page.tsx b/app/dashboard/documents/[id]/page.tsx new file mode 100644 index 0000000..a9384c6 --- /dev/null +++ b/app/dashboard/documents/[id]/page.tsx @@ -0,0 +1,117 @@ +import { AppSidebar } from "@/components/app-sidebar"; +import { NavActions } from "@/components/nav-actions"; +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbList, + BreadcrumbPage, +} from "@/components/ui/breadcrumb"; +import { Separator } from "@/components/ui/separator"; +import { + SidebarInset, + SidebarProvider, + SidebarTrigger, +} from "@/components/ui/sidebar"; +import { createClient } from "@/utils/supabase/server"; +import { redirect } from "next/navigation"; +import { remark } from "remark"; +import remarkHtml from "remark-html"; + +export default async function DocumentPage({ + params, +}: { + params: { id: string }; +}) { + const supabase = await createClient(); + + const { + data: { user }, + } = await supabase.auth.getUser(); + + if (!user) { + return redirect("/login"); + } + + // Fetch the document details based on the ID from params + const { data: document, error } = await supabase + .from("documents") + .select("*") + .eq("id", params.id) + .single(); + + if (error || !document) { + console.error("Error fetching document:", error); + } + + // If the document doesn't exist, redirect to the documents page or handle it accordingly + if (!document) { + return redirect("/dashboard"); + } + const { data: documents, error: documentsError } = await supabase + .from("documents") + .select("id, file_name, created_at, owner") + .eq("owner", user.id) + .order("created_at", { ascending: false }); + + if (documentsError) { + console.error("Error fetching documents:", error); + return
Error loading documents.
; + } + + const pages = (document.ocr_data as any).pages.map( + (page: any) => page.markdown + ); + + const processedContent = await remark() + .use(remarkHtml) + .process(pages.join(" ")); + + return ( + + { + return { + name: d.file_name, + url: `/dashboard/documents/${d.id}`, + emoji: "📄", + }; + })} + /> + +
+
+ + + + + + + {document.file_name || "Document Details"} + + + + +
+
+ +
+
+
+
+
+ ); +} diff --git a/app/dashboard/upload/page.tsx b/app/dashboard/upload/page.tsx index 2d02584..6d378fc 100644 --- a/app/dashboard/upload/page.tsx +++ b/app/dashboard/upload/page.tsx @@ -28,9 +28,28 @@ export default async function Page() { return redirect("/login"); } + const { data: documents, error } = await supabase + .from("documents") + .select("id, file_name, created_at, owner") + .eq("owner", user.id) + .order("created_at", { ascending: false }); + + if (error) { + console.error("Error fetching documents:", error); + return
Error loading documents.
; + } + return ( - + { + return { + name: d.file_name, + url: `/dashboard/documents/${d.id}`, + emoji: "📄", + }; + })} + />
@@ -50,7 +69,7 @@ export default async function Page() {
- +
); diff --git a/app/dashboard/upload/process/route.ts b/app/dashboard/upload/process/route.ts index 425f284..f9ccf03 100644 --- a/app/dashboard/upload/process/route.ts +++ b/app/dashboard/upload/process/route.ts @@ -1,6 +1,7 @@ import { createClient } from "@/utils/supabase/server"; import { NextResponse } from "next/server"; import { Mistral } from "@mistralai/mistralai"; +import { redirect } from "next/navigation"; const apiKey = process.env.MISTRAL_API_KEY; const client = new Mistral({ apiKey: apiKey }); @@ -42,6 +43,5 @@ export async function POST(request: Request) { console.error(error); return NextResponse.json({ error: error.message }, { status: 500 }); } - console.log("Document updated successfully:", data); - return NextResponse.json({ message: "File processed successfully" }); + return redirect(`/dashboard/documents/${id}`); // Redirect to the document page after processing } diff --git a/app/globals.css b/app/globals.css index a356309..710611b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -1,5 +1,6 @@ @import "tailwindcss"; @import "tw-animate-css"; +@plugin "@tailwindcss/typography"; @custom-variant dark (&:is(.dark *)); diff --git a/bun.lockb b/bun.lockb index dffef7bda07e35672bf3f93eab36f2b781113cbb..e6603c539bd2d67c51f9eacbe675527c98f016a6 100755 GIT binary patch delta 42511 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 YwMq-7c9Qdb#h}M5zM$a{`D&&A0n}nY6aWAK diff --git a/components/UploadZone.tsx b/components/UploadZone.tsx index 4e50314..095f03d 100644 --- a/components/UploadZone.tsx +++ b/components/UploadZone.tsx @@ -2,19 +2,15 @@ import { createClient } from "@/utils/supabase/client"; import { CloudUpload } from "lucide-react"; -export default async function UploadZone() { - const supabase = await createClient(); - - const { - data: { user }, - } = await supabase.auth.getUser(); +export default function UploadZone({ user }: { user?: { id: string } }) { + const supabase = createClient(); const onUpload = async (file: File) => { const uuid = crypto.randomUUID(); const { data: fileData, error: fileError } = await supabase.storage .from("documents") - .upload(`public/${uuid}.pdf`, file); + .upload(`${user!.id}/${uuid}.pdf`, file); if (fileError) { console.error(fileError); diff --git a/components/app-sidebar.tsx b/components/app-sidebar.tsx index 16c1ecf..9a60b9b 100644 --- a/components/app-sidebar.tsx +++ b/components/app-sidebar.tsx @@ -27,8 +27,14 @@ import { SidebarMenuButton, SidebarRail, } from "@/components/ui/sidebar"; +import { createClient } from "@/utils/supabase/client"; -export function AppSidebar({ ...props }: React.ComponentProps) { +export function AppSidebar({ + documents, + ...props +}: React.ComponentProps & { + documents?: Array<{ name: string; url: string; emoji?: string }>; +}) { const data = { navMain: [ { @@ -65,59 +71,8 @@ export function AppSidebar({ ...props }: React.ComponentProps) { icon: MessageCircleQuestion, }, ], - favorites: [ - { - name: "Project Management & Task Tracking", - url: "#", - emoji: "📊", - }, - { - name: "Family Recipe Collection & Meal Planning", - url: "#", - emoji: "🍳", - }, - { - name: "Fitness Tracker & Workout Routines", - url: "#", - emoji: "💪", - }, - { - name: "Book Notes & Reading List", - url: "#", - emoji: "📚", - }, - { - name: "Sustainable Gardening Tips & Plant Care", - url: "#", - emoji: "🌱", - }, - { - name: "Language Learning Progress & Resources", - url: "#", - emoji: "🗣️", - }, - { - name: "Home Renovation Ideas & Budget Tracker", - url: "#", - emoji: "🏠", - }, - { - name: "Personal Finance & Investment Portfolio", - url: "#", - emoji: "💰", - }, - { - name: "Movie & TV Show Watchlist with Reviews", - url: "#", - emoji: "🎬", - }, - { - name: "Daily Habit Tracker & Goal Setting", - url: "#", - emoji: "✅", - }, - ], }; + return ( @@ -130,7 +85,7 @@ export function AppSidebar({ ...props }: React.ComponentProps) { - + diff --git a/package.json b/package.json index b8034e2..dcaf4c6 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@supabase/ssr": "latest", "@supabase/supabase-js": "latest", "@tailwindcss/postcss": "^4.1.0", + "@tailwindcss/typography": "^0.5.16", "ai": "^4.2.11", "autoprefixer": "10.4.20", "class-variance-authority": "^0.7.1", @@ -31,6 +32,8 @@ "prettier": "^3.3.3", "react": "19.0.0", "react-dom": "19.0.0", + "remark": "^15.0.1", + "remark-html": "^16.0.1", "tw-animate-css": "^1.2.5", "zod": "^3.24.2" },