75 lines
2.8 KiB
JavaScript
75 lines
2.8 KiB
JavaScript
import {
|
|
Dialog,
|
|
DialogContent,
|
|
DialogTitle,
|
|
DialogTrigger,
|
|
} from "@/components/ui/dialog"
|
|
import Image from "next/image"
|
|
import Link from "next/link"
|
|
import { ExternalLink } from "lucide-react"
|
|
import { skillsList } from "@/lib/skillsList"
|
|
|
|
export default function ProjectDialog({ children, project }) {
|
|
return (
|
|
<Dialog>
|
|
<DialogTrigger asChild>
|
|
{children}
|
|
</DialogTrigger>
|
|
<DialogContent className="flex flex-col md:flex-row gap-2 md:gap-4 max-w-[95vw] md:max-w-4xl px-4 bg-gray-100">
|
|
<DialogTitle className="sr-only">{project.name}</DialogTitle>
|
|
<div className="flex md:flex-col gap-1 overflow-x-auto md:overflow-x-visible md:overflow-y-auto scrollbar-thin scrollbar-thumb-gray-400 scrollbar-track-gray-200 pb-2 md:pb-0 md:pr-2 shrink-0 md:max-h-[400px]">
|
|
{project.screenshots.map((screenshot, idx) => (
|
|
<div key={idx} className="w-full p-2 rounded-lg shrink-0">
|
|
<Image
|
|
className="rounded-md w-full h-auto"
|
|
src={screenshot}
|
|
width={200}
|
|
height={50}
|
|
alt={`${project.title} screenshot ${idx + 1}`}
|
|
/>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<div className="flex flex-col gap-4 min-w-0 flex-1 pr-2">
|
|
<div className="flex flex-col gap-0.5 mx-1">
|
|
<div className="flex gap-2 items-center flex-wrap">
|
|
<Image
|
|
src={project.logo}
|
|
width={24}
|
|
height={24}
|
|
className="p-0.5 bg-white rounded-sm shrink-0"
|
|
alt={project.logoAlt}
|
|
/>
|
|
<h3 className="wrap-break-word">{project.title}</h3>
|
|
</div>
|
|
{project.url && project.hostname && (
|
|
<Link
|
|
href={project.url}
|
|
target="_blank"
|
|
className="flex gap-2 items-center text-blue-500 hover:text-blue-600 duration-200 break-all"
|
|
>
|
|
<h4>{project.hostname}</h4>
|
|
<ExternalLink size={18} className="shrink-0" />
|
|
</Link>
|
|
)}
|
|
</div>
|
|
<div className="flex flex-wrap gap-2 items-center">
|
|
{project.skills.map((skillName, idx) => {
|
|
const skill = skillsList.find(s => s.name === skillName);
|
|
return skill ? (
|
|
<div
|
|
key={idx}
|
|
className="flex items-center gap-2 rounded-full bg-white px-2 xl:px-3 py-1 shrink-0"
|
|
>
|
|
{skill.icon}
|
|
<h6 className="whitespace-nowrap">{skill.name}</h6>
|
|
</div>
|
|
) : null;
|
|
})}
|
|
</div>
|
|
<h4 className="text-sm sm:text-base wrap-break-word">{project.text}</h4>
|
|
</div>
|
|
</DialogContent>
|
|
</Dialog>
|
|
)
|
|
} |