107 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-05-07 21:19:32 -07:00
"use client";
2024-05-07 21:19:32 -07:00
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";
2024-05-09 22:16:56 -07:00
import { useState } from "react";
2024-05-16 10:47:34 -07:00
import { CanvasRevealEffect } from "./projectCard/revealEffect";
const colors = {
react: [
[71, 207, 237],
[30, 126, 148],
],
node: [
[86, 184, 72],
[59, 112, 52],
],
};
2024-04-18 14:42:47 -04:00
export default function DashboardProjects({
sandboxes,
2024-05-01 08:53:37 -04:00
q,
2024-04-18 14:42:47 -04:00
}: {
2024-05-07 21:19:32 -07:00
sandboxes: Sandbox[];
q: string | null;
2024-04-18 14:42:47 -04:00
}) {
2024-05-16 10:47:34 -07:00
const [focusedId, setFocusedId] = useState<string | null>(null);
2024-05-09 22:16:56 -07:00
const [deletingId, setDeletingId] = useState<string>("");
const onDelete = async (sandbox: Sandbox) => {
2024-05-09 22:16:56 -07:00
setDeletingId(sandbox.id);
2024-05-07 21:19:32 -07:00
toast(`Project ${sandbox.name} deleted.`);
await deleteSandbox(sandbox.id);
2024-05-09 22:16:56 -07:00
setTimeout(() => {
// timeout to wait for revalidatePath and avoid flashing
setDeletingId("");
}, 200);
2024-05-07 21:19:32 -07:00
};
const onVisibilityChange = async (sandbox: Sandbox) => {
2024-05-07 21:19:32 -07:00
const newVisibility =
sandbox.visibility === "public" ? "private" : "public";
toast(`Project ${sandbox.name} is now ${newVisibility}.`);
2024-05-01 08:53:37 -04:00
await updateSandbox({
id: sandbox.id,
visibility: newVisibility,
2024-05-07 21:19:32 -07:00
});
};
2024-04-18 14:42:47 -04:00
return (
<div className="grow p-4 flex flex-col">
2024-05-01 08:53:37 -04:00
<div className="text-xl font-medium mb-8">
{q && q.length > 0 ? `Showing search results for: ${q}` : "My Projects"}
</div>
2024-04-27 16:22:35 -04:00
<div className="grow w-full ">
2024-05-07 21:19:32 -07:00
{sandboxes.length > 0 ? (
<div className="w-full grid lg:grid-cols-3 2xl:grid-cols-4 md:grid-cols-2 gap-4">
{sandboxes.map((sandbox) => {
if (q && q.length > 0) {
if (!sandbox.name.toLowerCase().includes(q.toLowerCase())) {
return null;
}
2024-05-01 08:53:37 -04:00
}
2024-05-07 21:19:32 -07:00
return (
<Link
key={sandbox.id}
href={`/code/${sandbox.id}`}
2024-05-16 10:47:34 -07:00
onFocus={() => setFocusedId(sandbox.id)}
2024-05-09 22:16:56 -07:00
className={`${
deletingId === sandbox.id
? "pointer-events-none opacity-50"
: ""
} 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`}
2024-05-07 21:19:32 -07:00
>
2024-05-16 10:47:34 -07:00
<ProjectCard
sandbox={sandbox}
onVisibilityChange={onVisibilityChange}
onDelete={onDelete}
>
<CanvasRevealEffect
animationSpeed={3}
containerClassName="bg-black"
colors={colors[sandbox.type]}
dotSize={2}
/>
<div className="absolute inset-0 [mask-image:radial-gradient(400px_at_center,white,transparent)] bg-background/75" />
</ProjectCard>
2024-05-07 21:19:32 -07:00
</Link>
);
})}
</div>
) : (
<div className="text-muted-foreground text-sm">
You don't have any projects yet. Create one to get started!
</div>
)}
2024-04-18 14:42:47 -04:00
</div>
</div>
2024-05-07 21:19:32 -07:00
);
2024-04-18 14:42:47 -04:00
}