mirror of
https://github.com/rgrgogu/new_starr.git
synced 2026-09-27 00:12:54 +08:00
84 lines
3.8 KiB
React
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>
|
|
);
|
|
}
|