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: "📄",
+ };
+ })}
+ />
+
+
+
+
+
+ );
+}
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: "📄",
+ };
+ })}
+ />
-
+
);
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 dffef7b..e6603c5 100755
Binary files a/bun.lockb and b/bun.lockb differ
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"
},