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 { Sandbox } from "@/lib/types"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import ProjectCardDropdown from "./projectCard/dropdown"
|
import ProjectCardDropdown from "./projectCard/dropdown"
|
||||||
|
import DashboardProjects from "./projects"
|
||||||
|
import DashboardSharedWithMe from "./shared"
|
||||||
|
|
||||||
type TScreen = "projects" | "shared" | "settings" | "search"
|
type TScreen = "projects" | "shared" | "settings" | "search"
|
||||||
|
|
||||||
@ -51,7 +53,7 @@ export default function Dashboard({ sandboxes }: { sandboxes: Sandbox[] }) {
|
|||||||
className={activeScreen("shared")}
|
className={activeScreen("shared")}
|
||||||
>
|
>
|
||||||
<Users className="w-4 h-4 mr-2" />
|
<Users className="w-4 h-4 mr-2" />
|
||||||
Shared Rooms
|
Shared With Me
|
||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
@ -80,37 +82,10 @@ export default function Dashboard({ sandboxes }: { sandboxes: Sandbox[] }) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{screen === "projects" ? (
|
{screen === "projects" ? (
|
||||||
<div className="grow p-4 grid lg:grid-cols-3 2xl:grid-cols-4 md:grid-cols-2 gap-4">
|
<DashboardProjects sandboxes={sandboxes} />
|
||||||
{sandboxes.map((sandbox) => (
|
) : screen === "shared" ? (
|
||||||
<ProjectCard key={sandbox.id}>
|
<DashboardSharedWithMe sandboxes={sandboxes} />
|
||||||
<div className="space-x-2 flex items-center justify-start w-full">
|
) : screen === "settings" ? null : null}
|
||||||
<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}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,13 @@ import {
|
|||||||
export default function ProjectCardDropdown({ sandbox }: { sandbox: Sandbox }) {
|
export default function ProjectCardDropdown({ sandbox }: { sandbox: Sandbox }) {
|
||||||
return (
|
return (
|
||||||
<DropdownMenu>
|
<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" />
|
<Ellipsis className="w-4 h-4" />
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent className="w-40">
|
<DropdownMenuContent className="w-40">
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
|
import Link from "next/link"
|
||||||
|
|
||||||
export default function ProjectCard({
|
export default function ProjectCard({
|
||||||
children,
|
children,
|
||||||
|
id,
|
||||||
className,
|
className,
|
||||||
}: {
|
}: {
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
|
id: string
|
||||||
className?: string
|
className?: string
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<div
|
<Link
|
||||||
tabIndex={0}
|
href={`/code/${id}`}
|
||||||
className={cn(
|
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"
|
"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">
|
<div className="rounded-[7px] p-4 h-full flex flex-col justify-between gradient-project-card">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</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">
|
<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" />
|
{children}
|
||||||
New Project
|
|
||||||
</div>
|
</div>
|
||||||
</button>
|
</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