feat(app): banner, style tweaks

This commit is contained in:
rektdeckard
2023-03-03 22:39:42 -07:00
parent baeec27267
commit d379cea5bc
15 changed files with 215 additions and 40 deletions

View File

@@ -1,26 +1,80 @@
import { Medal } from "phosphor-react";
import { ReactNode, Dispatch, SetStateAction } from "react";
import { motion, AnimatePresence, Variants } from "framer-motion";
import { XCircle } from "phosphor-react";
import ReactGA from "react-ga4";
import { useLocalStorage } from "@/hooks";
import "./Banner.css";
const Banner = () => {
const handleClick = () => {
ReactGA.event({ category: "Outbound", action: "Click", label: "Vote" });
window.open(
"https://www.figma.com/community/file/903830135544202908",
"_blank",
"noopener noreferrer"
);
type BannerState = {
seen: Record<string, boolean>;
};
type BannerProps = {
id: string;
children?: ReactNode;
onClose?: (dispatch: Dispatch<SetStateAction<BannerState>>) => void;
};
const variants: Variants = {
initial: { y: -120 },
animate: { y: 0 },
exit: { y: -120 },
};
const BANNER_STATE_KEY = "banner_state";
const Banner = ({ id, children, onClose }: BannerProps) => {
const [
{
seen: { [id]: seen },
},
setBannerState,
] = useLocalStorage<BannerState>(BANNER_STATE_KEY, {
seen: { [id]: false },
});
const handleClose = () => {
ReactGA.event({
category: "Banner",
action: "Dismiss",
label: id,
});
onClose
? onClose(setBannerState)
: setBannerState((state) => ({
...state,
seen: { ...state.seen, [id]: true },
}));
};
return (
<div className="banner">
The 2022 Figma Community Awards are here!
<button className="main-button" onClick={handleClick}>
<Medal size={24} weight="fill" />
Vote for Phosphor
</button>
</div>
<AnimatePresence initial={true}>
{!seen && (
<motion.aside
className="card banner"
initial="initial"
animate="animate"
exit="exit"
variants={variants}
>
<div className="banner-content">
{children}
<button
tabIndex={0}
className="banner-button"
onClick={handleClose}
onKeyDown={(e) => {
e.key === "Enter" && handleClose();
}}
>
<XCircle color="currentColor" size={28} weight="fill" />
</button>
</div>
</motion.aside>
)}
</AnimatePresence>
);
};