Files
meditation-admin/components/MediaPreview.tsx
T
2026-06-03 03:08:57 +03:30

104 lines
3.0 KiB
TypeScript

"use client";
// Press-to-play / press-to-view preview for uploaded assets.
// - audio: a play button that toggles a compact inline <audio> player.
// - video: a button that opens the video in a modal player.
// - image: a thumbnail that opens the full image in a modal.
// Renders a muted dash when no source is available.
import { useState } from "react";
import { Modal } from "./ui";
import { PlayIcon, PauseIcon, EyeIcon } from "./icons";
type Kind = "audio" | "video" | "image";
export function MediaPreview({
src,
kind,
label,
}: {
src?: string | null;
kind: Kind;
label?: string;
}) {
const [audioOpen, setAudioOpen] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
if (!src) return <span className="text-muted"></span>;
if (kind === "audio") {
return (
<div className="flex items-center gap-2">
<button
type="button"
onClick={() => setAudioOpen((v) => !v)}
className="inline-flex h-8 w-8 items-center justify-center rounded-full bg-primary-soft text-primary transition hover:bg-primary hover:text-white"
aria-label={audioOpen ? "توقف" : "پخش"}
>
{audioOpen ? (
<PauseIcon className="h-4 w-4" />
) : (
<PlayIcon className="h-4 w-4" />
)}
</button>
{audioOpen && (
// eslint-disable-next-line jsx-a11y/media-has-caption
<audio
src={src}
controls
autoPlay
className="h-8 max-w-[220px]"
onEnded={() => setAudioOpen(false)}
/>
)}
</div>
);
}
if (kind === "image") {
return (
<>
<button
type="button"
onClick={() => setModalOpen(true)}
className="block overflow-hidden rounded-lg border border-border transition hover:opacity-80"
aria-label="نمایش تصویر"
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={src} alt={label ?? ""} className="h-12 w-12 object-cover" />
</button>
<Modal
open={modalOpen}
onClose={() => setModalOpen(false)}
title={label ?? "تصویر"}
>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={src} alt={label ?? ""} className="mx-auto max-h-[70vh] rounded-lg" />
</Modal>
</>
);
}
// video
return (
<>
<button
type="button"
onClick={() => setModalOpen(true)}
className="inline-flex h-8 w-8 items-center justify-center rounded-full bg-primary-soft text-primary transition hover:bg-primary hover:text-white"
aria-label="نمایش ویدیو"
>
<EyeIcon className="h-4 w-4" />
</button>
<Modal
open={modalOpen}
onClose={() => setModalOpen(false)}
title={label ?? "ویدیو"}
>
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
<video src={src} controls autoPlay className="w-full rounded-lg" />
</Modal>
</>
);
}