ui improvements

This commit is contained in:
Ishaan Dey 2024-05-05 00:06:10 -07:00
parent 159e7b62e2
commit 5ae5c226ba
7 changed files with 105 additions and 26 deletions

View File

@ -52,7 +52,7 @@ export default async function CodePage({ params }: { params: { id: string } }) {
<Room id={sandboxId}>
<Navbar userData={userData} sandboxData={sandboxData} shared={shared} />
<div className="w-screen flex grow">
<CodeEditor userData={userData} sandboxId={sandboxId} />
<CodeEditor userData={userData} sandboxData={sandboxData} />
</div>
</Room>
</div>

View File

@ -0,0 +1,39 @@
"use client"
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import Image from "next/image"
import { useState } from "react"
import { Button } from "../ui/button"
import { ChevronRight } from "lucide-react"
export default function AboutModal({
open,
setOpen,
}: {
open: boolean
setOpen: (open: boolean) => void
}) {
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>About this project</DialogTitle>
</DialogHeader>
<div className="text-sm text-muted-foreground">
Sandbox is an open-source cloud-based code editing environment with
custom AI code autocompletion and real-time collaboration. The
infrastructure runs on Docker and Kubernetes to scale automatically
based on resource usage.
</div>
</DialogContent>
</Dialog>
)
}

View File

@ -17,6 +17,7 @@ import DashboardSharedWithMe from "./shared"
import NewProjectModal from "./newProject"
import Link from "next/link"
import { useSearchParams } from "next/navigation"
import AboutModal from "./about"
type TScreen = "projects" | "shared" | "settings" | "search"
@ -36,6 +37,7 @@ export default function Dashboard({
const [screen, setScreen] = useState<TScreen>("projects")
const [newProjectModalOpen, setNewProjectModalOpen] = useState(false)
const [aboutModalOpen, setAboutModalOpen] = useState(false)
const activeScreen = (s: TScreen) => {
if (screen === s) return "justify-start"
@ -51,6 +53,7 @@ export default function Dashboard({
open={newProjectModalOpen}
setOpen={setNewProjectModalOpen}
/>
<AboutModal open={aboutModalOpen} setOpen={setAboutModalOpen} />
<div className="flex grow w-full">
<div className="w-56 shrink-0 border-r border-border p-4 justify-between flex flex-col">
<div className="flex flex-col">
@ -97,6 +100,7 @@ export default function Dashboard({
</Button>
</Link>
<Button
onClick={() => setAboutModalOpen(true)}
variant="ghost"
className="justify-start font-normal text-muted-foreground"
>

View File

@ -12,6 +12,7 @@ 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,
@ -66,9 +67,11 @@ export default function DashboardSharedWithMe({
{new Date(sandbox.sharedOn).toLocaleDateString()}
</TableCell>
<TableCell className="text-right">
<Link href={`/code/${sandbox.id}`}>
<Button>
Open <ChevronRight className="w-4 h-4 ml-2" />
</Button>
</Link>
</TableCell>
</TableRow>
))}

View File

@ -39,16 +39,16 @@ import EditorTerminal from "./terminal"
import { Button } from "../ui/button"
import GenerateInput from "./generate"
import { TFile, TFileData, TFolder, TTab } from "./sidebar/types"
import { User } from "@/lib/types"
import { Sandbox, User } from "@/lib/types"
import { processFileType, validateName } from "@/lib/utils"
import { Cursors } from "./live/cursors"
export default function CodeEditor({
userData,
sandboxId,
sandboxData,
}: {
userData: User
sandboxId: string
sandboxData: Sandbox
}) {
const [files, setFiles] = useState<(TFolder | TFile)[]>([])
const [tabs, setTabs] = useState<TTab[]>([])
@ -72,6 +72,7 @@ export default function CodeEditor({
const [provider, setProvider] = useState<TypedLiveblocksProvider>()
const [ai, setAi] = useState(false)
const isOwner = sandboxData.userId === userData.id
const clerk = useClerk()
const room = useRoom()
@ -247,7 +248,7 @@ export default function CodeEditor({
}, [decorations.options])
const socket = io(
`http://localhost:4000?userId=${userData.id}&sandboxId=${sandboxId}`
`http://localhost:4000?userId=${userData.id}&sandboxId=${sandboxData.id}`
)
useEffect(() => {
@ -506,7 +507,7 @@ export default function CodeEditor({
if (type === "file") {
setFiles((prev) => [
...prev,
{ id: `projects/${sandboxId}/${name}`, name, type: "file" },
{ id: `projects/${sandboxData.id}/${name}`, name, type: "file" },
])
} else {
console.log("adding folder")

View File

@ -27,6 +27,8 @@ export default function Navbar({
const [isEditOpen, setIsEditOpen] = useState(false)
const [isShareOpen, setIsShareOpen] = useState(false)
const isOwner = sandboxData.userId === userData.id
return (
<>
<EditSandboxModal
@ -50,21 +52,25 @@ export default function Navbar({
</Link>
<div className="text-sm font-medium flex items-center">
{sandboxData.name}
{isOwner ? (
<button
onClick={() => setIsEditOpen(true)}
className="h-7 w-7 ml-2 flex items-center justify-center bg-transparent hover:bg-muted-foreground/25 cursor-pointer rounded-md ring-offset-2 transition-all ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
>
<Pencil className="w-4 h-4" />
</button>
) : null}
</div>
</div>
<div className="flex items-center space-x-4">
<Avatars />
{isOwner ? (
<Button variant="outline" onClick={() => setIsShareOpen(true)}>
<Users className="w-4 h-4 mr-2" />
Share
</Button>
) : null}
<UserButton userData={userData} />
</div>
</div>

View File

@ -5,6 +5,13 @@ import { useEffect, useRef, useState } from "react"
import { getIconForFolder, getIconForOpenFolder } from "vscode-icons-js"
import { TFile, TFolder, TTab } from "./types"
import SidebarFile from "./file"
import {
ContextMenu,
ContextMenuContent,
ContextMenuItem,
ContextMenuTrigger,
} from "@/components/ui/context-menu"
import { Pencil, Trash2 } from "lucide-react"
export default function SidebarFolder({
data,
@ -39,12 +46,9 @@ export default function SidebarFolder({
}, [editing])
return (
<>
<div
<ContextMenu>
<ContextMenuTrigger
onClick={() => setIsOpen((prev) => !prev)}
onDoubleClick={() => {
setEditing(true)
}}
className="w-full flex items-center h-7 px-1 transition-colors hover:bg-secondary rounded-sm cursor-pointer"
>
<Image
@ -74,7 +78,29 @@ export default function SidebarFolder({
}}
/>
</form>
</div>
</ContextMenuTrigger>
<ContextMenuContent>
<ContextMenuItem
onClick={() => {
console.log("rename")
setEditing(true)
}}
>
<Pencil className="w-4 h-4 mr-2" />
Rename
</ContextMenuItem>
<ContextMenuItem
// disabled={pendingDelete}
onClick={() => {
console.log("delete")
// setPendingDelete(true)
// handleDeleteFile(data)
}}
>
<Trash2 className="w-4 h-4 mr-2" />
Delete
</ContextMenuItem>
</ContextMenuContent>
{isOpen ? (
<div className="flex w-full items-stretch">
<div className="w-[1px] bg-border mx-2 h-full"></div>
@ -102,6 +128,6 @@ export default function SidebarFolder({
</div>
</div>
) : null}
</>
</ContextMenu>
)
}