diff --git a/frontend/app/(app)/code/[id]/page.tsx b/frontend/app/(app)/code/[id]/page.tsx index e65b863..fe6a253 100644 --- a/frontend/app/(app)/code/[id]/page.tsx +++ b/frontend/app/(app)/code/[id]/page.tsx @@ -62,22 +62,18 @@ export default async function CodePage({ params }: { params: { id: string } }) { return (
- }> - - }> */} + + +
+ -
- -
- - +
+
+ {/*
*/}
); } diff --git a/frontend/components/dashboard/index.tsx b/frontend/components/dashboard/index.tsx index 32b7f86..3a1d5d4 100644 --- a/frontend/components/dashboard/index.tsx +++ b/frontend/components/dashboard/index.tsx @@ -1,7 +1,7 @@ -"use client" +"use client"; -import CustomButton from "@/components/ui/customButton" -import { Button } from "@/components/ui/button" +import CustomButton from "@/components/ui/customButton"; +import { Button } from "@/components/ui/button"; import { Code2, FolderDot, @@ -9,44 +9,44 @@ import { Plus, Settings, Users, -} from "lucide-react" -import { useState } from "react" -import { Sandbox } from "@/lib/types" -import DashboardProjects from "./projects" -import DashboardSharedWithMe from "./shared" -import NewProjectModal from "./newProject" -import Link from "next/link" -import { useSearchParams } from "next/navigation" -import AboutModal from "./about" -import { toast } from "sonner" +} from "lucide-react"; +import { useState } from "react"; +import { Sandbox } from "@/lib/types"; +import DashboardProjects from "./projects"; +import DashboardSharedWithMe from "./shared"; +import NewProjectModal from "./newProject"; +import Link from "next/link"; +import { useSearchParams } from "next/navigation"; +import AboutModal from "./about"; +import { toast } from "sonner"; -type TScreen = "projects" | "shared" | "settings" | "search" +type TScreen = "projects" | "shared" | "settings" | "search"; export default function Dashboard({ sandboxes, shared, }: { - sandboxes: Sandbox[] + sandboxes: Sandbox[]; shared: { - id: string - name: string - type: "react" | "node" - author: string - sharedOn: Date - }[] + id: string; + name: string; + type: "react" | "node"; + author: string; + sharedOn: Date; + }[]; }) { - const [screen, setScreen] = useState("projects") + const [screen, setScreen] = useState("projects"); - const [newProjectModalOpen, setNewProjectModalOpen] = useState(false) - const [aboutModalOpen, setAboutModalOpen] = useState(false) + const [newProjectModalOpen, setNewProjectModalOpen] = useState(false); + const [aboutModalOpen, setAboutModalOpen] = useState(false); const activeScreen = (s: TScreen) => { - if (screen === s) return "justify-start" - else return "justify-start font-normal text-muted-foreground" - } + if (screen === s) return "justify-start"; + else return "justify-start font-normal text-muted-foreground"; + }; - const searchParams = useSearchParams() - const q = searchParams.get("q") + const searchParams = useSearchParams(); + const q = searchParams.get("q"); return ( <> @@ -61,10 +61,10 @@ export default function Dashboard({ { if (sandboxes.length >= 8) { - toast.error("You reached the maximum # of sandboxes.") - return + toast.error("You reached the maximum # of sandboxes."); + return; } - setNewProjectModalOpen(true) + setNewProjectModalOpen(true); }} className="mb-4" > @@ -97,7 +97,7 @@ export default function Dashboard({ */}
- + - +
- ) + ); } diff --git a/frontend/components/dashboard/projects.tsx b/frontend/components/dashboard/projects.tsx index 80dd558..650462d 100644 --- a/frontend/components/dashboard/projects.tsx +++ b/frontend/components/dashboard/projects.tsx @@ -1,35 +1,36 @@ -"use client" +"use client"; -import { Sandbox } from "@/lib/types" -import ProjectCard from "./projectCard" -import Image from "next/image" -import ProjectCardDropdown from "./projectCard/dropdown" -import { Clock, Globe, Lock } from "lucide-react" -import Link from "next/link" -import { Card } from "../ui/card" -import { deleteSandbox, updateSandbox } from "@/lib/actions" -import { toast } from "sonner" +import { Sandbox } from "@/lib/types"; +import ProjectCard from "./projectCard"; +import Image from "next/image"; +import ProjectCardDropdown from "./projectCard/dropdown"; +import { Clock, Globe, Lock } from "lucide-react"; +import Link from "next/link"; +import { Card } from "../ui/card"; +import { deleteSandbox, updateSandbox } from "@/lib/actions"; +import { toast } from "sonner"; export default function DashboardProjects({ sandboxes, q, }: { - sandboxes: Sandbox[] - q: string | null + sandboxes: Sandbox[]; + q: string | null; }) { const onDelete = async (sandbox: Sandbox) => { - toast(`Project ${sandbox.name} deleted.`) - await deleteSandbox(sandbox.id) - } + toast(`Project ${sandbox.name} deleted.`); + await deleteSandbox(sandbox.id); + }; const onVisibilityChange = async (sandbox: Sandbox) => { - const newVisibility = sandbox.visibility === "public" ? "private" : "public" - toast(`Project ${sandbox.name} is now ${newVisibility}.`) + const newVisibility = + sandbox.visibility === "public" ? "private" : "public"; + toast(`Project ${sandbox.name} is now ${newVisibility}.`); await updateSandbox({ id: sandbox.id, visibility: newVisibility, - }) - } + }); + }; return (
@@ -37,64 +38,70 @@ export default function DashboardProjects({ {q && q.length > 0 ? `Showing search results for: ${q}` : "My Projects"}
-
- {sandboxes.map((sandbox) => { - if (q && q.length > 0) { - if (!sandbox.name.toLowerCase().includes(q.toLowerCase())) { - return null + {sandboxes.length > 0 ? ( +
+ {sandboxes.map((sandbox) => { + if (q && q.length > 0) { + if (!sandbox.name.toLowerCase().includes(q.toLowerCase())) { + return null; + } } - } - return ( - - - {/* */} -
- -
- {sandbox.name} + return ( + + + {/* */} +
+ +
+ {sandbox.name} +
+
- -
-
-
- {sandbox.visibility === "private" ? ( - <> - Private - - ) : ( - <> - Public - - )} +
+
+ {sandbox.visibility === "private" ? ( + <> + Private + + ) : ( + <> + Public + + )} +
+
+ 3d ago +
-
- 3d ago -
-
- {/* */} - - - ) - })} -
+ {/* */} + + + ); + })} +
+ ) : ( +
+ You don't have any projects yet. Create one to get started! +
+ )}
- ) + ); } diff --git a/frontend/components/dashboard/shared.tsx b/frontend/components/dashboard/shared.tsx index be28989..9e5eb03 100644 --- a/frontend/components/dashboard/shared.tsx +++ b/frontend/components/dashboard/shared.tsx @@ -1,4 +1,4 @@ -import { Sandbox } from "@/lib/types" +import { Sandbox } from "@/lib/types"; import { Table, TableBody, @@ -7,77 +7,84 @@ import { TableHead, TableHeader, TableRow, -} from "@/components/ui/table" -import Image from "next/image" -import Button from "../ui/customButton" -import { ChevronRight } from "lucide-react" -import Avatar from "../ui/avatar" -import Link from "next/link" +} from "@/components/ui/table"; +import Image from "next/image"; +import Button from "../ui/customButton"; +import { ChevronRight } from "lucide-react"; +import Avatar from "../ui/avatar"; +import Link from "next/link"; export default function DashboardSharedWithMe({ shared, }: { shared: { - id: string - name: string - type: "react" | "node" - author: string - sharedOn: Date - }[] + id: string; + name: string; + type: "react" | "node"; + author: string; + sharedOn: Date; + }[]; }) { return (
Shared With Me
-
- - - - Sandbox Name - Shared By - Sent On - - - - - {shared.map((sandbox) => ( - - -
- - {sandbox.name} -
-
- -
- - {sandbox.author} -
-
- - {new Date(sandbox.sharedOn).toLocaleDateString()} - - - - - - + {shared.length > 0 ? ( +
+
+ + + Sandbox Name + Shared By + Sent On + - ))} - -
-
+ + + {shared.map((sandbox) => ( + + +
+ + {sandbox.name} +
+
+ +
+ + {sandbox.author} +
+
+ + {new Date(sandbox.sharedOn).toLocaleDateString()} + + + + + + +
+ ))} +
+ +
+ ) : ( +
+ No sandboxes here. Get a friend to share one with you, and try out + live collaboration! +
+ )}
- ) + ); } diff --git a/frontend/components/editor/index.tsx b/frontend/components/editor/index.tsx index 49f96c2..195f75b 100644 --- a/frontend/components/editor/index.tsx +++ b/frontend/components/editor/index.tsx @@ -39,6 +39,8 @@ import { Sandbox, User, TFile, TFileData, TFolder, TTab } from "@/lib/types"; import { processFileType, validateName } from "@/lib/utils"; import { Cursors } from "./live/cursors"; import { Terminal } from "@xterm/xterm"; +import DisableAccessModal from "./live/disableModal"; +import Loading from "./loading"; export default function CodeEditor({ userData, @@ -77,6 +79,10 @@ export default function CodeEditor({ const [creatingTerminal, setCreatingTerminal] = useState(false); const [provider, setProvider] = useState(); const [ai, setAi] = useState(false); + const [disableAccess, setDisableAccess] = useState({ + isDisabled: false, + message: "", + }); const isOwner = sandboxData.userId === userData.id; const clerk = useClerk(); @@ -519,6 +525,19 @@ export default function CodeEditor({ // }) }; + if (disableAccess.isDisabled) { + return ( + <> + {}} + /> + + + ); + } + return ( <>
diff --git a/frontend/components/editor/live/disableModal.tsx b/frontend/components/editor/live/disableModal.tsx new file mode 100644 index 0000000..b66d369 --- /dev/null +++ b/frontend/components/editor/live/disableModal.tsx @@ -0,0 +1,33 @@ +"use client"; + +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; + +import { ChevronRight, FileStack, Globe, TextCursor } from "lucide-react"; + +export default function DisableAccessModal({ + open, + setOpen, + message, +}: { + open: boolean; + setOpen: (open: boolean) => void; + message: string; +}) { + return ( + + + + Live Collaboration Disabled + +
{message}
+
+
+ ); +} diff --git a/frontend/components/editor/live/room.tsx b/frontend/components/editor/live/room.tsx index a59aaf3..8c29005 100644 --- a/frontend/components/editor/live/room.tsx +++ b/frontend/components/editor/live/room.tsx @@ -1,15 +1,14 @@ -"use client" +"use client"; -import { RoomProvider } from "@/liveblocks.config" -import { ClientSideSuspense } from "@liveblocks/react" -import Loading from "../loading" +import { RoomProvider } from "@/liveblocks.config"; +import { ClientSideSuspense } from "@liveblocks/react"; export function Room({ id, children, }: { - id: string - children: React.ReactNode + id: string; + children: React.ReactNode; }) { return ( */} - ) + ); } diff --git a/frontend/components/editor/loading.tsx b/frontend/components/editor/loading.tsx index 482383a..662e354 100644 --- a/frontend/components/editor/loading.tsx +++ b/frontend/components/editor/loading.tsx @@ -5,41 +5,41 @@ import { Loader, Loader2 } from "lucide-react"; export default function Loading() { return ( -
-
-
- Logo - + //
+ //
+ //
+ // Logo + // + //
+ //
+ // + // + //
+ //
+
+
+
+
Explorer
+
+ + +
-
- - +
+
+ +
-
-
-
-
Explorer
-
- - -
-
-
-
- -
-
-
-
-
- - Loading... -
- - +
+
+ + Loading...
+ +
+ //
); }