|
| 1 | +import React, { useEffect, useState } from "react"; |
| 2 | +import { Anchor, Flex, Button } from "@mantine/core"; |
| 3 | + |
| 4 | +export const BANNER_HEIGHT = |
| 5 | + process.env.NEXT_PUBLIC_DISABLE_EXTERNAL_MODE === "true" ? "0px" : "40px"; |
| 6 | + |
| 7 | +const BANNER_LIST = [ |
| 8 | + "Save and store your diagrams with ToDiagram", |
| 9 | + "Explore the ToDiagram from the creators of JSON Crack", |
| 10 | + "Generate AI diagrams with single prompt", |
| 11 | + "Try ToDiagram for free, no sign-up required", |
| 12 | + "Edit data directly inside diagrams", |
| 13 | + "Explore larger datasets (up to 50 MB) easily", |
| 14 | +]; |
| 15 | + |
| 16 | +export const Banner = () => { |
| 17 | + const ROTATION_INTERVAL = 6000; // ms between label changes |
| 18 | + const FADE_DURATION = 500; // ms for fade transition |
| 19 | + |
| 20 | + const [index, setIndex] = useState(0); |
| 21 | + const [visible, setVisible] = useState(true); |
| 22 | + |
| 23 | + useEffect(() => { |
| 24 | + let fadeTimeout: ReturnType<typeof setTimeout> | undefined; |
| 25 | + const intervalId = setInterval(() => { |
| 26 | + setVisible(false); |
| 27 | + fadeTimeout = setTimeout(() => { |
| 28 | + setIndex(i => (i + 1) % BANNER_LIST.length); |
| 29 | + setVisible(true); |
| 30 | + }, FADE_DURATION); |
| 31 | + }, ROTATION_INTERVAL); |
| 32 | + |
| 33 | + return () => { |
| 34 | + clearInterval(intervalId); |
| 35 | + if (fadeTimeout) clearTimeout(fadeTimeout); |
| 36 | + }; |
| 37 | + }, []); |
| 38 | + |
| 39 | + return ( |
| 40 | + <Anchor |
| 41 | + href="https://todiagram.com/editor?utm_source=jsoncrack&utm_medium=top_banner" |
| 42 | + target="_blank" |
| 43 | + rel="noopener" |
| 44 | + underline="never" |
| 45 | + > |
| 46 | + <Flex |
| 47 | + h={BANNER_HEIGHT} |
| 48 | + justify="center" |
| 49 | + align="center" |
| 50 | + fw="500" |
| 51 | + gap="xs" |
| 52 | + style={{ |
| 53 | + background: "linear-gradient(90deg, #FF75B7 0%, #FED761 100%)", |
| 54 | + color: "black", |
| 55 | + }} |
| 56 | + > |
| 57 | + <span |
| 58 | + style={{ |
| 59 | + transition: `opacity ${FADE_DURATION}ms ease`, |
| 60 | + opacity: visible ? 1 : 0, |
| 61 | + willChange: "opacity", |
| 62 | + display: "inline-block", |
| 63 | + }} |
| 64 | + > |
| 65 | + {BANNER_LIST[index]}{" "} |
| 66 | + </span> |
| 67 | + <Button size="xs" color="gray"> |
| 68 | + Try now |
| 69 | + </Button> |
| 70 | + </Flex> |
| 71 | + </Anchor> |
| 72 | + ); |
| 73 | +}; |
0 commit comments