diff --git a/src/app/components/carousel.tsx b/src/app/components/carousel.tsx
index 82b150a..c294d7e 100644
--- a/src/app/components/carousel.tsx
+++ b/src/app/components/carousel.tsx
@@ -1,10 +1,11 @@
"use client";
-import Image from "next/image";
import { useCallback, useEffect, useState } from "react";
import useEmblaCarousel from "embla-carousel-react";
import { Icon } from "@iconify/react";
+import ImageViewer from "./image-viewer";
+
interface Props {
images: string[];
className?: string;
@@ -31,7 +32,7 @@ export default function Carousel({ images, className }: Props) {
{images.map((src, index) => (
-
+
))}
diff --git a/src/app/components/image-viewer.tsx b/src/app/components/image-viewer.tsx
new file mode 100644
index 0000000..d8ac853
--- /dev/null
+++ b/src/app/components/image-viewer.tsx
@@ -0,0 +1,65 @@
+"use client";
+
+import Image from "next/image";
+import { useEffect, useState } from "react";
+import { createPortal } from "react-dom";
+import { Icon } from "@iconify/react";
+
+interface Props {
+ src: string;
+ alt: string;
+ width: number;
+ height: number;
+ className?: string;
+}
+
+export default function ImageViewer({ src, alt, width, height, className }: Props) {
+ const [isOpen, setIsOpen] = useState(false);
+ const [isVisible, setIsVisible] = useState(false);
+
+ const close = () => {
+ setIsVisible(false);
+ setTimeout(() => {
+ setIsOpen(false);
+ }, 300); // duration matches animation timing
+ };
+
+ useEffect(() => {
+ if (isOpen) {
+ // slight delay to trigger animation
+ setTimeout(() => setIsVisible(true), 10);
+ }
+ }, [isOpen]);
+
+ return (
+ <>
+ setIsOpen(true)} />
+
+ {isOpen &&
+ createPortal(
+ ,
+ document.body
+ )}
+ >
+ );
+}
diff --git a/src/app/mii/[slug]/page.tsx b/src/app/mii/[slug]/page.tsx
index 539e8e4..3ffaaba 100644
--- a/src/app/mii/[slug]/page.tsx
+++ b/src/app/mii/[slug]/page.tsx
@@ -1,4 +1,3 @@
-import Image from "next/image";
import Link from "next/link";
import { redirect } from "next/navigation";
@@ -7,6 +6,7 @@ import { prisma } from "@/lib/prisma";
import Carousel from "@/app/components/carousel";
import LikeButton from "@/app/components/like-button";
+import ImageViewer from "@/app/components/image-viewer";
interface Props {
params: Promise<{ slug: string }>;
@@ -108,12 +108,12 @@ export default async function MiiPage({ params }: Props) {
{images.map((src, index) => (
-
))}