# tableberg/1.1.5/src/components/UpsellModal.tsx

Tableberg – Simple Gutenberg Table Block, version 1.1.5. 228 lines.

- Page: https://pluginprobe.com/plugins/tableberg/1.1.5/code/src/components/UpsellModal.tsx
- Raw: https://pluginprobe.com/plugins/tableberg/1.1.5/raw/src/components/UpsellModal.tsx
- Modified: 2026-09-16T03:30:32+00:00

Line numbers below start at 1. Link to a line or a range by appending a fragment to the
page URL, for example `https://pluginprobe.com/plugins/tableberg/1.1.5/code/src/components/UpsellModal.tsx#L10-L20`.

```tsx
import { useEffect, useState } from "react";
import { RawHTML } from "@wordpress/element";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCaretLeft, faCaretRight } from "@fortawesome/free-solid-svg-icons";
import { __ } from "@wordpress/i18n";
import blocks, { ENHANCED_FEATURES } from "@tableberg/shared/blocks";
import blockIcon from "@tableberg/shared/icons/tableberg";
import { PATTERN_UPSELLS } from "./patterns";
import { getTablebergConfig } from "../pro-status";

function getPluginUrl() {
    return getTablebergConfig().plugin_url || "";
}

function getImageBase() {
    return getPluginUrl() + "includes/Admin/images/upsell/";
}

function getProBlocks() {
    const pluginUrl = getPluginUrl();
    const patternUpsells = PATTERN_UPSELLS.map(pattern => ({
        ...pattern,
        image: pattern.image
            ? `${pluginUrl}${pattern.image.substring(1)}`
            : pattern.image,
    }));

    return [...blocks.filter((b: any) => b.isPro), ...patternUpsells];
}

interface Props {
    onClose: () => void;
    selected?: string;
    link?: string;
}

export interface BlockUpsellInfo {
    icon: any;
    title: string;
    name: string;
    image?: string;
    upsellText?: string;
}
interface ComponentProps {
    onClose: () => void;
    info: BlockUpsellInfo;
    prev?: () => void;
    next?: () => void;
    link?: string;
}

export function UpsellModalComponent({
    onClose,
    info,
    prev,
    next,
    link = "https://tableberg.com/pricing/",
}: ComponentProps) {
    return (
        <div className="tableberg-upsell-modal">
            <div
                className="tableberg-upsell-modal-backdrop"
                onClick={onClose}
            ></div>
            <div className="tableberg-upsell-modal-container">
                {!!prev && (
                    <button
                        className="tableberg-upsell-modal-prev"
                        onClick={prev}
                    >
                        <FontAwesomeIcon icon={faCaretLeft} />
                    </button>
                )}
                <div className="tableberg-upsell-modal-area" key={info.name}>
                    <h2>
                        {info.icon || blockIcon} {info.title}
                    </h2>
                    <div className="tableberg-upsell-modal-content">
                        {info.image && (
                            <img
                                src={
                                    info.image.startsWith("http")
                                        ? info.image
                                        : getImageBase() + info.image
                                }
                                alt={info.title + " " + __("Demo", "tableberg")}
                            />
                        )}
                        {info.upsellText && (
                            <RawHTML className="tableberg-upsell-modal-text">
                                {info.upsellText}
                            </RawHTML>
                        )}
                        <p>
                            {__("Limited Time: Use code", "tableberg")}{" "}
                            <b>TB20</b>{" "}
                            {__("to get a 20% discount.", "tableberg")}
                        </p>
                    </div>
                    <div className="tableberg-upsell-modal-footer">
                        <button onClick={onClose}>
                            {__("Cancel", "tableberg")}
                        </button>
                        <a href={link} target="_blank">
                            {__("Buy PRO", "tableberg")}
                        </a>
                    </div>
                </div>
                {!!next && (
                    <button
                        className="tableberg-upsell-modal-next"
                        onClick={next}
                    >
                        <FontAwesomeIcon icon={faCaretRight} />
                    </button>
                )}
            </div>
        </div>
    );
}

export function UpsellEnhancedModal({
    onClose,
    selected,
    link = "https://tableberg.com/pricing/",
}: Props) {
    const [idx, setIdx] = useState(0);
    const info = ENHANCED_FEATURES[idx];

    useEffect(() => {
        if (selected) {
            selected = selected.replace("-dummy", "");
            const idx = ENHANCED_FEATURES.findIndex(b => b.name === selected);
            if (idx > -1) {
                setIdx(idx);
            }
        }
    }, [selected]);

    const prev = () =>
        setIdx(idx => {
            if (idx > 0) {
                return idx - 1;
            }
            return ENHANCED_FEATURES.length - 1;
        });

    const next = () => setIdx((idx + 1) % ENHANCED_FEATURES.length);

    return (
        <UpsellModalComponent
            onClose={onClose}
            info={info}
            prev={prev}
            next={next}
            link={link}
        />
    );
}

export function UpsellPatternsModal({ onClose, selected }: Props) {
    const [idx, setIdx] = useState(0);
    const info = PATTERN_UPSELLS[idx];

    useEffect(() => {
        if (selected) {
            const idx = PATTERN_UPSELLS.findIndex(b => b.name === selected);
            if (idx > -1) {
                setIdx(idx);
            }
        }
    }, [selected]);

    const prev = () =>
        setIdx(idx => {
            if (idx > 0) {
                return idx - 1;
            }
            return PATTERN_UPSELLS.length - 1;
        });

    const next = () => setIdx((idx + 1) % PATTERN_UPSELLS.length);

    return (
        <UpsellModalComponent
            onClose={onClose}
            info={info as any}
            prev={prev}
            next={next}
        />
    );
}

export default function UpsellModal({ onClose, selected }: Props) {
    const proBlocks = getProBlocks();
    const [idx, setIdx] = useState(0);
    const info = proBlocks[idx];

    useEffect(() => {
        if (selected) {
            selected = selected.replace("-dummy", "");
            const idx = proBlocks.findIndex(b => b.name === selected);
            if (idx > -1) {
                setIdx(idx);
            }
        }
    }, [selected]);

    const prev = () =>
        setIdx(idx => {
            if (idx > 0) {
                return idx - 1;
            }
            return proBlocks.length - 1;
        });

    const next = () => setIdx((idx + 1) % proBlocks.length);

    return (
        <UpsellModalComponent
            onClose={onClose}
            info={info}
            prev={prev}
            next={next}
        />
    );
}

```
