Files
starr-philproperties/src/components/generic/AnnouncementCarouselDialog.jsx
T
kennethobsequio fa92d924f4 added
Signed-off-by: Kenneth Obsequio <k80308392@gmail.com>
2026-07-12 12:39:47 +08:00

84 lines
3.8 KiB
React

import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { resolveAssetSrc } from "@/utils/media.util";
// Shared details view for the sticky announcement bar (client + admin
// variants) — pages through every currently-active sticky announcement (max
// 3, see notificationBroadcasts.controller.js's countActiveSticky) with a
// segmented progress bar. bannerImage is ONE shared image for the whole set
// (not per-announcement) — see NotificationBroadcastList.jsx's banner picker
// and the sticky_banner_settings singleton.
export default function AnnouncementCarouselDialog({
open,
onOpenChange,
announcements,
activeIndex,
onIndexChange,
resolveClickAction,
navigate,
bannerImage,
}) {
const current = announcements[activeIndex];
if (!current) return null;
const clickAction = resolveClickAction(current);
const imageSrc = resolveAssetSrc(bannerImage);
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-2xl p-0 overflow-hidden gap-0">
<div className="grid sm:grid-cols-2">
<div className="p-6 flex flex-col gap-3 min-w-0">
<DialogHeader className="text-left">
<DialogTitle className="text-lg">
{current.title || "Announcement"}
</DialogTitle>
<DialogDescription asChild>
<p className="whitespace-pre-wrap text-left text-foreground">
{current.message || ""}
</p>
</DialogDescription>
</DialogHeader>
<div className="mt-auto flex flex-col gap-2 pt-4">
{clickAction && (
<Button
className="self-start"
onClick={() => clickAction.go(navigate)}
>
{clickAction.label}
</Button>
)}
{announcements.length > 1 && (
<div className="flex gap-1.5">
{announcements.map((a, i) => (
<button
key={a.notification_id}
type="button"
aria-label={`Show announcement ${i + 1}`}
onClick={() => onIndexChange(i)}
className={[
"h-1.5 flex-1 rounded-full transition-colors",
i === activeIndex ? "bg-foreground" : "bg-muted-foreground/25 hover:bg-muted-foreground/40",
].join(" ")}
/>
))}
</div>
)}
</div>
</div>
<div className="aspect-video sm:aspect-auto sm:h-96 bg-muted flex items-center justify-center overflow-hidden">
{imageSrc ? (
<img src={imageSrc} alt="" className="w-full h-full object-cover" />
) : (
<span className="text-xs text-muted-foreground">No image</span>
)}
</div>
</div>
</DialogContent>
</Dialog>
);
}