From be970248686c0af7d8506cba8c64bf507419da3d Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 22 Jun 2025 13:07:02 +0200 Subject: so much stuff??? --- apps/web/src/app/api/auth/[...all]/route.ts | 4 + apps/web/src/app/editor/page.tsx | 66 ++++++-- apps/web/src/app/fonts/GeistMonoVF.woff | Bin 67864 -> 0 bytes apps/web/src/app/fonts/GeistVF.woff | Bin 66268 -> 0 bytes apps/web/src/app/globals.css | 6 +- apps/web/src/app/layout.tsx | 31 ++-- apps/web/src/app/page.tsx | 12 +- apps/web/src/components/app-provider.tsx | 42 +++++ apps/web/src/components/editor-header.tsx | 56 +++++++ apps/web/src/components/editor/media-panel.tsx | 133 ++++++++++++++++ apps/web/src/components/editor/preview-panel.tsx | 11 ++ .../web/src/components/editor/properties-panel.tsx | 100 ++++++++++++ apps/web/src/components/editor/timeline.tsx | 173 +++++++++++++++++++++ apps/web/src/components/header-base.tsx | 41 +++++ apps/web/src/components/header.tsx | 37 +++++ apps/web/src/components/landing/hero.tsx | 72 +++++++++ apps/web/src/components/media-panel.tsx | 39 ----- apps/web/src/components/preview-panel.tsx | 11 -- apps/web/src/components/properties-panel.tsx | 100 ------------ apps/web/src/components/timeline.tsx | 141 ----------------- apps/web/src/lib/auth-client.ts | 4 + apps/web/src/lib/auth.ts | 23 +++ apps/web/src/lib/db/index.tsx | 14 ++ apps/web/src/lib/db/schema.ts | 61 ++++++++ apps/web/src/stores/app-store.ts | 35 +++++ apps/web/src/stores/media-store.ts | 35 +++++ apps/web/src/stores/panel-store.ts | 79 ++++++++++ apps/web/src/stores/project-store.ts | 28 ++++ apps/web/src/stores/timeline-store.ts | 61 ++++++++ apps/web/src/types/project.ts | 6 + 30 files changed, 1096 insertions(+), 325 deletions(-) create mode 100644 apps/web/src/app/api/auth/[...all]/route.ts delete mode 100644 apps/web/src/app/fonts/GeistMonoVF.woff delete mode 100644 apps/web/src/app/fonts/GeistVF.woff create mode 100644 apps/web/src/components/app-provider.tsx create mode 100644 apps/web/src/components/editor-header.tsx create mode 100644 apps/web/src/components/editor/media-panel.tsx create mode 100644 apps/web/src/components/editor/preview-panel.tsx create mode 100644 apps/web/src/components/editor/properties-panel.tsx create mode 100644 apps/web/src/components/editor/timeline.tsx create mode 100644 apps/web/src/components/header-base.tsx create mode 100644 apps/web/src/components/header.tsx create mode 100644 apps/web/src/components/landing/hero.tsx delete mode 100644 apps/web/src/components/media-panel.tsx delete mode 100644 apps/web/src/components/preview-panel.tsx delete mode 100644 apps/web/src/components/properties-panel.tsx delete mode 100644 apps/web/src/components/timeline.tsx create mode 100644 apps/web/src/lib/auth-client.ts create mode 100644 apps/web/src/lib/auth.ts create mode 100644 apps/web/src/lib/db/index.tsx create mode 100644 apps/web/src/lib/db/schema.ts create mode 100644 apps/web/src/stores/app-store.ts create mode 100644 apps/web/src/stores/media-store.ts create mode 100644 apps/web/src/stores/panel-store.ts create mode 100644 apps/web/src/stores/project-store.ts create mode 100644 apps/web/src/stores/timeline-store.ts create mode 100644 apps/web/src/types/project.ts (limited to 'apps/web/src') diff --git a/apps/web/src/app/api/auth/[...all]/route.ts b/apps/web/src/app/api/auth/[...all]/route.ts new file mode 100644 index 00000000..1fb57443 --- /dev/null +++ b/apps/web/src/app/api/auth/[...all]/route.ts @@ -0,0 +1,4 @@ +import { auth } from "@/lib/auth"; +import { toNextJsHandler } from "better-auth/next-js"; + +export const { POST, GET } = toNextJsHandler(auth); \ No newline at end of file diff --git a/apps/web/src/app/editor/page.tsx b/apps/web/src/app/editor/page.tsx index 51a448d9..f9f64ee6 100644 --- a/apps/web/src/app/editor/page.tsx +++ b/apps/web/src/app/editor/page.tsx @@ -1,36 +1,80 @@ +"use client"; + +import { useEffect } from "react"; import { ResizablePanelGroup, ResizablePanel, ResizableHandle, } from "../../components/ui/resizable"; -import { MediaPanel } from "../../components/media-panel"; -import { PropertiesPanel } from "../../components/properties-panel"; -import { Timeline } from "../../components/timeline"; -import { PreviewPanel } from "../../components/preview-panel"; +import { MediaPanel } from "../../components/editor/media-panel"; +import { PropertiesPanel } from "../../components/editor/properties-panel"; +import { Timeline } from "../../components/editor/timeline"; +import { PreviewPanel } from "../../components/editor/preview-panel"; +import { EditorHeader } from "@/components/editor-header"; +import { usePanelStore } from "@/stores/panel-store"; +import { useProjectStore } from "@/stores/project-store"; export default function Editor() { + const { + toolsPanel, + previewPanel, + propertiesPanel, + mainContent, + timeline, + setToolsPanel, + setPreviewPanel, + setPropertiesPanel, + setMainContent, + setTimeline, + } = usePanelStore(); + + const { activeProject, createNewProject } = useProjectStore(); + + // Initialize a new project if none exists + useEffect(() => { + if (!activeProject) { + createNewProject("Untitled Project"); + } + }, [activeProject, createNewProject]); + return (
+ - + {/* Main content area */} {/* Tools Panel */} - + {/* Preview Area */} - + {/* Properties Panel */} - + @@ -39,7 +83,11 @@ export default function Editor() { {/* Timeline */} - + diff --git a/apps/web/src/app/fonts/GeistMonoVF.woff b/apps/web/src/app/fonts/GeistMonoVF.woff deleted file mode 100644 index f2ae185c..00000000 Binary files a/apps/web/src/app/fonts/GeistMonoVF.woff and /dev/null differ diff --git a/apps/web/src/app/fonts/GeistVF.woff b/apps/web/src/app/fonts/GeistVF.woff deleted file mode 100644 index 1b62daac..00000000 Binary files a/apps/web/src/app/fonts/GeistVF.woff and /dev/null differ diff --git a/apps/web/src/app/globals.css b/apps/web/src/app/globals.css index 31bd3692..2169dbbc 100644 --- a/apps/web/src/app/globals.css +++ b/apps/web/src/app/globals.css @@ -2,10 +2,6 @@ @tailwind components; @tailwind utilities; -body { - font-family: Arial, Helvetica, sans-serif; -} - @layer base { :root { --background: 0 0% 100%; @@ -32,7 +28,7 @@ body { --chart-3: 197 37% 24%; --chart-4: 43 74% 66%; --chart-5: 27 87% 67%; - --radius: 0.6rem; + --radius: 1rem; --sidebar-background: 0 0% 100%; --sidebar-foreground: 0 0% 3.9%; --sidebar-primary: 0 0% 9%; diff --git a/apps/web/src/app/layout.tsx b/apps/web/src/app/layout.tsx index d7dd18a5..6696e884 100644 --- a/apps/web/src/app/layout.tsx +++ b/apps/web/src/app/layout.tsx @@ -1,20 +1,15 @@ import type { Metadata } from "next"; -import localFont from "next/font/local"; +import { Inter } from "next/font/google"; import { ThemeProvider } from "next-themes"; import { Analytics } from "@vercel/analytics/react"; import "./globals.css"; import { Toaster } from "../components/ui/sonner"; import { TooltipProvider } from "../components/ui/tooltip"; +import { AppProvider } from "@/components/app-provider"; -const geistSans = localFont({ - src: "./fonts/GeistVF.woff", - variable: "--font-geist-sans", - weight: "100 900", -}); -const geistMono = localFont({ - src: "./fonts/GeistMonoVF.woff", - variable: "--font-geist-mono", - weight: "100 900", +const inter = Inter({ + subsets: ["latin"], + variable: "--font-inter", }); export const metadata: Metadata = { @@ -29,15 +24,15 @@ export default function RootLayout({ }>) { return ( - + - - {children} - - - + + + {children} + + + + diff --git a/apps/web/src/app/page.tsx b/apps/web/src/app/page.tsx index 9b8a74c6..57967b7a 100644 --- a/apps/web/src/app/page.tsx +++ b/apps/web/src/app/page.tsx @@ -1,3 +1,11 @@ +import { Hero } from "@/components/landing/hero"; +import { Header } from "@/components/header"; + export default function Home() { - return
Hello World
; -} \ No newline at end of file + return ( +
+
+ +
+ ); +} diff --git a/apps/web/src/components/app-provider.tsx b/apps/web/src/components/app-provider.tsx new file mode 100644 index 00000000..257fc8fa --- /dev/null +++ b/apps/web/src/components/app-provider.tsx @@ -0,0 +1,42 @@ +"use client"; + +import { useEffect } from "react"; +import { Loader2 } from "lucide-react"; +import { useAppStore } from "@/stores/app-store"; +import { usePanelStore } from "@/stores/panel-store"; + +interface AppProviderProps { + children: React.ReactNode; +} + +export function AppProvider({ children }: AppProviderProps) { + const { isInitializing, isPanelsReady, initializeApp } = useAppStore(); + const { setInitialized } = usePanelStore(); + + useEffect(() => { + const initialize = async () => { + // Initialize the app + await initializeApp(); + + // Initialize panel store for future resize events + setInitialized(); + }; + + initialize(); + }, [initializeApp, setInitialized]); + + // Show loading screen while initializing + if (isInitializing || !isPanelsReady) { + return ( +
+
+ +

Loading editor...

+
+
+ ); + } + + // App is ready, render children + return <>{children}; +} diff --git a/apps/web/src/components/editor-header.tsx b/apps/web/src/components/editor-header.tsx new file mode 100644 index 00000000..f59193d0 --- /dev/null +++ b/apps/web/src/components/editor-header.tsx @@ -0,0 +1,56 @@ +"use client"; + +import Link from "next/link"; +import { Button } from "./ui/button"; +import { ChevronLeft, Download } from "lucide-react"; +import { useProjectStore } from "@/stores/project-store"; +import { useMediaStore } from "@/stores/media-store"; +import { useTimelineStore } from "@/stores/timeline-store"; +import { HeaderBase } from "./header-base"; + +export function EditorHeader() { + const { activeProject } = useProjectStore(); + const { mediaItems } = useMediaStore(); + const { tracks } = useTimelineStore(); + + const handleExport = () => { + // TODO: Implement export functionality + console.log("Export project"); + }; + + const leftContent = ( + + + {activeProject?.name || "Loading..."} + + ); + + const centerContent = ( +
+ {mediaItems.length} media + • + {tracks.length} tracks +
+ ); + + const rightContent = ( + + ); + + return ( + + ); +} diff --git a/apps/web/src/components/editor/media-panel.tsx b/apps/web/src/components/editor/media-panel.tsx new file mode 100644 index 00000000..1e5aa465 --- /dev/null +++ b/apps/web/src/components/editor/media-panel.tsx @@ -0,0 +1,133 @@ +"use client"; + +import { Button } from "../ui/button"; +import { AspectRatio } from "../ui/aspect-ratio"; +import { useMediaStore } from "@/stores/media-store"; +import { Plus, Image, Video, Music, Upload } from "lucide-react"; +import { useState, useRef } from "react"; + +export function MediaPanel() { + const { mediaItems, addMediaItem } = useMediaStore(); + const [isDragOver, setIsDragOver] = useState(false); + const dragCounterRef = useRef(0); + + const handleAddSampleMedia = () => { + // Just for testing - add a sample media item + addMediaItem({ + name: `Sample ${mediaItems.length + 1}`, + type: "image", + }); + }; + + const getMediaIcon = (type: string) => { + switch (type) { + case "video": + return