From 3c2afb2d0b78e1a477689f40cd0434820ecf90d2 Mon Sep 17 00:00:00 2001 From: Ryan Waits Date: Wed, 21 Aug 2024 18:24:58 -0500 Subject: [PATCH 1/5] add banner component --- components/ui/banner.tsx | 122 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 components/ui/banner.tsx diff --git a/components/ui/banner.tsx b/components/ui/banner.tsx new file mode 100644 index 00000000..40274496 --- /dev/null +++ b/components/ui/banner.tsx @@ -0,0 +1,122 @@ +"use client"; + +import { type HTMLAttributes, useCallback, useEffect, useState } from "react"; +import { Button } from "./button"; +import Link from "next/link"; +import { X } from "lucide-react"; +import { cn } from "@/utils/cn"; +import { cva } from "class-variance-authority"; +import { isWithinInterval, parseISO } from "date-fns"; + +export const buttonVariants = cva( + "bg-[#CEEFD0] inline-flex items-center justify-center rounded-md p-2 text-sm text-primary font-medium transition-colors duration-100 disabled:pointer-events-none disabled:opacity-50", + { + variants: { + color: { + outline: "border hover:bg-accent hover:text-accent-foreground", + ghost: "hover:bg-accent hover:text-accent-foreground", + secondary: + "border bg-secondary text-secondary-foreground hover:bg-accent hover:text-accent-foreground", + }, + size: { + sm: "gap-1 p-0.5 text-xs", + icon: "p-1.5 [&_svg]:size-5", + }, + }, + } +); + +export function Banner({ + id, + cta = "Call to Action", + url = "/", + startDate, + endDate, + ...props +}: HTMLAttributes & { + cta?: string; + url?: string; + startDate?: string; + endDate?: string; +}): React.ReactElement | null { + const [open, setOpen] = useState(true); + const [isWithinDateRange, setIsWithinDateRange] = useState(false); + + useEffect(() => { + const now = new Date(); + if (startDate && endDate) { + const start = parseISO(startDate); + const end = parseISO(endDate); + setIsWithinDateRange(isWithinInterval(now, { start, end })); + } else { + setIsWithinDateRange(true); + } + + if (id) setOpen(localStorage.getItem(`nd-banner-${id}`) !== "true"); + }, [id, startDate, endDate]); + + useEffect(() => { + if (id) setOpen(localStorage.getItem(`nd-banner-${id}`) !== "true"); + }, [id]); + + const onClick = useCallback(() => { + setOpen(false); + if (id) localStorage.setItem(`nd-banner-${id}`, "true"); + }, [id]); + + if (!isWithinDateRange) return null; + + return ( +
+ {id ? ( +