separate dashboard page components
This commit is contained in:
parent
11dfc0f637
commit
5045c4ce9a
@ -18,6 +18,8 @@ import ProjectCard from "./projectCard"
|
||||
import { Sandbox } from "@/lib/types"
|
||||
import Image from "next/image"
|
||||
import ProjectCardDropdown from "./projectCard/dropdown"
|
||||
import DashboardProjects from "./projects"
|
||||
import DashboardSharedWithMe from "./shared"
|
||||
|
||||
type TScreen = "projects" | "shared" | "settings" | "search"
|
||||
|
||||
@ -51,7 +53,7 @@ export default function Dashboard({ sandboxes }: { sandboxes: Sandbox[] }) {
|
||||
className={activeScreen("shared")}
|
||||
>
|
||||
<Users className="w-4 h-4 mr-2" />
|
||||
Shared Rooms
|
||||
Shared With Me
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
@ -80,37 +82,10 @@ export default function Dashboard({ sandboxes }: { sandboxes: Sandbox[] }) {
|
||||
</div>
|
||||
</div>
|
||||
{screen === "projects" ? (
|
||||
<div className="grow p-4 grid lg:grid-cols-3 2xl:grid-cols-4 md:grid-cols-2 gap-4">
|
||||
{sandboxes.map((sandbox) => (
|
||||
<ProjectCard key={sandbox.id}>
|
||||
<div className="space-x-2 flex items-center justify-start w-full">
|
||||
<Image
|
||||
alt=""
|
||||
src={
|
||||
sandbox.type === "react"
|
||||
? "/project-icons/react.svg"
|
||||
: "/project-icons/node.svg"
|
||||
}
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
<div className="font-medium static whitespace-nowrap w-full text-ellipsis overflow-hidden">
|
||||
{sandbox.name}
|
||||
</div>
|
||||
<ProjectCardDropdown sandbox={sandbox} />
|
||||
</div>
|
||||
<div className="flex flex-col text-muted-foreground space-y-0.5 text-sm">
|
||||
<div className="flex items-center">
|
||||
<Globe className="w-3 h-3 mr-2" /> Public
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Clock className="w-3 h-3 mr-2" /> 3d ago
|
||||
</div>
|
||||
</div>
|
||||
</ProjectCard>
|
||||
))}
|
||||
</div>
|
||||
) : screen === "shared" ? null : screen === "settings" ? null : null}
|
||||
<DashboardProjects sandboxes={sandboxes} />
|
||||
) : screen === "shared" ? (
|
||||
<DashboardSharedWithMe sandboxes={sandboxes} />
|
||||
) : screen === "settings" ? null : null}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -15,7 +15,13 @@ import {
|
||||
export default function ProjectCardDropdown({ sandbox }: { sandbox: Sandbox }) {
|
||||
return (
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger className="h-6 w-6 flex items-center justify-center transition-colors bg-transparent hover:bg-muted-foreground/25 rounded-sm">
|
||||
<DropdownMenuTrigger
|
||||
onClick={(e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
}}
|
||||
className="h-6 w-6 flex items-center justify-center transition-colors bg-transparent hover:bg-muted-foreground/25 rounded-sm"
|
||||
>
|
||||
<Ellipsis className="w-4 h-4" />
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent className="w-40">
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { cn } from "@/lib/utils"
|
||||
import Link from "next/link"
|
||||
|
||||
export default function ProjectCard({
|
||||
children,
|
||||
id,
|
||||
className,
|
||||
}: {
|
||||
children: React.ReactNode
|
||||
id: string
|
||||
className?: string
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
tabIndex={0}
|
||||
<Link
|
||||
href={`/code/${id}`}
|
||||
className={cn(
|
||||
"rounded-lg border bg-card text-card-foreground shadow h-48 p-[1px] gradient-project-card-bg cursor-pointer transition-all focus-visible:outline-none focus-visible:ring-offset-2 focus-visible:ring-offset-background focus-visible:ring-2 focus-visible:ring-ring"
|
||||
)}
|
||||
@ -17,6 +20,6 @@ export default function ProjectCard({
|
||||
<div className="rounded-[7px] p-4 h-full flex flex-col justify-between gradient-project-card">
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
47
frontend/components/dashboard/projects.tsx
Normal file
47
frontend/components/dashboard/projects.tsx
Normal file
@ -0,0 +1,47 @@
|
||||
import { Sandbox } from "@/lib/types"
|
||||
import ProjectCard from "./projectCard"
|
||||
import Image from "next/image"
|
||||
import ProjectCardDropdown from "./projectCard/dropdown"
|
||||
import { Clock, Globe } from "lucide-react"
|
||||
|
||||
export default function DashboardProjects({
|
||||
sandboxes,
|
||||
}: {
|
||||
sandboxes: Sandbox[]
|
||||
}) {
|
||||
return (
|
||||
<div className="grow p-4 flex flex-col">
|
||||
<div className="text-xl font-medium mb-8">My Projects</div>
|
||||
<div className="grow w-full grid lg:grid-cols-3 2xl:grid-cols-4 md:grid-cols-2 gap-4">
|
||||
{sandboxes.map((sandbox) => (
|
||||
<ProjectCard key={sandbox.id} id={sandbox.id}>
|
||||
<div className="space-x-2 flex items-center justify-start w-full">
|
||||
<Image
|
||||
alt=""
|
||||
src={
|
||||
sandbox.type === "react"
|
||||
? "/project-icons/react.svg"
|
||||
: "/project-icons/node.svg"
|
||||
}
|
||||
width={20}
|
||||
height={20}
|
||||
/>
|
||||
<div className="font-medium static whitespace-nowrap w-full text-ellipsis overflow-hidden">
|
||||
{sandbox.name}
|
||||
</div>
|
||||
<ProjectCardDropdown sandbox={sandbox} />
|
||||
</div>
|
||||
<div className="flex flex-col text-muted-foreground space-y-0.5 text-sm">
|
||||
<div className="flex items-center">
|
||||
<Globe className="w-3 h-3 mr-2" /> Public
|
||||
</div>
|
||||
<div className="flex items-center">
|
||||
<Clock className="w-3 h-3 mr-2" /> 3d ago
|
||||
</div>
|
||||
</div>
|
||||
</ProjectCard>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
71
frontend/components/dashboard/shared.tsx
Normal file
71
frontend/components/dashboard/shared.tsx
Normal file
@ -0,0 +1,71 @@
|
||||
import { Sandbox } from "@/lib/types"
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCaption,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow,
|
||||
} from "@/components/ui/table"
|
||||
import Image from "next/image"
|
||||
import Button from "../ui/customButton"
|
||||
import { ChevronRight } from "lucide-react"
|
||||
|
||||
export default function DashboardSharedWithMe({
|
||||
sandboxes,
|
||||
}: {
|
||||
sandboxes: Sandbox[]
|
||||
}) {
|
||||
return (
|
||||
<div className="grow p-4 flex flex-col">
|
||||
<div className="text-xl font-medium mb-8">Shared With Me</div>
|
||||
<div className="grow w-full">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="hover:bg-background">
|
||||
<TableHead>Sandbox Name</TableHead>
|
||||
<TableHead>Shared By</TableHead>
|
||||
<TableHead>Opened</TableHead>
|
||||
<TableHead className="text-right"></TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{sandboxes.map((sandbox) => (
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<div className="font-medium flex items-center">
|
||||
<Image
|
||||
alt=""
|
||||
src={
|
||||
sandbox.type === "react"
|
||||
? "/project-icons/react.svg"
|
||||
: "/project-icons/node.svg"
|
||||
}
|
||||
width={20}
|
||||
height={20}
|
||||
className="mr-2"
|
||||
/>
|
||||
{sandbox.name}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex items-center">
|
||||
<div className="h-5 w-5 bg-red-500 rounded-full mr-2" />
|
||||
Ishaan Dey
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell>{new Date().toLocaleDateString()}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<Button>
|
||||
Open <ChevronRight className="w-4 h-4 ml-2" />
|
||||
</Button>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -20,8 +20,7 @@ const Button = ({
|
||||
)}
|
||||
>
|
||||
<div className="rounded-[6px] w-full gradient-button flex items-center justify-center whitespace-nowrap px-4 py-2 h-9">
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
New Project
|
||||
{children}
|
||||
</div>
|
||||
</button>
|
||||
)
|
||||
|
120
frontend/components/ui/table.tsx
Normal file
120
frontend/components/ui/table.tsx
Normal file
@ -0,0 +1,120 @@
|
||||
import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Table = React.forwardRef<
|
||||
HTMLTableElement,
|
||||
React.HTMLAttributes<HTMLTableElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div className="relative w-full overflow-auto">
|
||||
<table
|
||||
ref={ref}
|
||||
className={cn("w-full caption-bottom text-sm", className)}
|
||||
{...props}
|
||||
/>
|
||||
</div>
|
||||
))
|
||||
Table.displayName = "Table"
|
||||
|
||||
const TableHeader = React.forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<thead ref={ref} className={cn("[&_tr]:border-b", className)} {...props} />
|
||||
))
|
||||
TableHeader.displayName = "TableHeader"
|
||||
|
||||
const TableBody = React.forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tbody
|
||||
ref={ref}
|
||||
className={cn("[&_tr:last-child]:border-0", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableBody.displayName = "TableBody"
|
||||
|
||||
const TableFooter = React.forwardRef<
|
||||
HTMLTableSectionElement,
|
||||
React.HTMLAttributes<HTMLTableSectionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tfoot
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableFooter.displayName = "TableFooter"
|
||||
|
||||
const TableRow = React.forwardRef<
|
||||
HTMLTableRowElement,
|
||||
React.HTMLAttributes<HTMLTableRowElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<tr
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableRow.displayName = "TableRow"
|
||||
|
||||
const TableHead = React.forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.ThHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<th
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"h-10 px-2 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableHead.displayName = "TableHead"
|
||||
|
||||
const TableCell = React.forwardRef<
|
||||
HTMLTableCellElement,
|
||||
React.TdHTMLAttributes<HTMLTableCellElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<td
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableCell.displayName = "TableCell"
|
||||
|
||||
const TableCaption = React.forwardRef<
|
||||
HTMLTableCaptionElement,
|
||||
React.HTMLAttributes<HTMLTableCaptionElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<caption
|
||||
ref={ref}
|
||||
className={cn("mt-4 text-sm text-muted-foreground", className)}
|
||||
{...props}
|
||||
/>
|
||||
))
|
||||
TableCaption.displayName = "TableCaption"
|
||||
|
||||
export {
|
||||
Table,
|
||||
TableHeader,
|
||||
TableBody,
|
||||
TableFooter,
|
||||
TableHead,
|
||||
TableRow,
|
||||
TableCell,
|
||||
TableCaption,
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user