import React, { useState, useEffect } from "react";
import {
SimpleGrid,
Box,
Image,
Text,
Badge,
Button,
Modal,
ModalOverlay,
ModalContent,
ModalHeader,
ModalBody,
ModalCloseButton,
useDisclosure,
Input,
VStack,
Divider,
useToast,
HStack,
Icon,
Heading,
Center,
ModalFooter,
Spacer,
} from "@chakra-ui/react";
import apiFetch from "@wordpress/api-fetch";
import { templatesScriptData } from "../utils/global";
import PluginStatus from "./PluginStatus";
import { FaHeart } from "react-icons/fa";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { __, sprintf } from '@wordpress/i18n';
import notFoundImage from "../images/not-found-image.png";
import { IoPlayOutline } from "react-icons/io5";
import { FaRegHeart } from "react-icons/fa";
import { MdOutlineRemoveRedEye } from "react-icons/md";
interface Template {
id: number;
title: string;
slug: string;
imageUrl: string;
description: string;
isPro: boolean;
preview_link?: string;
addons?: { [key: string]: string };
categories?: string[];
}
interface TemplateListProps {
selectedCategory: string;
templates: Template[];
}
const { restURL, security } = templatesScriptData;
const LockIcon = (props) => (
);
interface CreateTemplateResponse {
success: boolean;
data?: {
id: number;
redirect: string;
status: number;
};
message?: string;
}
const TemplateList: React.FC = ({ selectedCategory, templates }) => {
const [previewTemplate, setPreviewTemplate] = useState(null);
const [formTemplateName, setFormTemplateName] = useState("");
const [selectedTemplateSlug, setSelectedTemplateSlug] = useState("");
const { isOpen, onOpen, onClose } = useDisclosure();
const [hoverCardId, setHoverCardId] = useState(null);
const [favorites, setFavorites] = useState([]);
const toast = useToast();
const queryClient = useQueryClient();
const [isPluginModalOpen, setIsPluginModalOpen] = useState(false);
const openModal = () => onOpen();
const closeModal = () => onClose();
const openPluginModal = () => setIsPluginModalOpen(true);
const closePluginModal = () => setIsPluginModalOpen(false);
useEffect(() => {
const savedFavorites = localStorage.getItem('favorites');
if (savedFavorites) {
setFavorites(JSON.parse(savedFavorites));
} else {
const fetchFavorites = async () => {
try {
const response: any = await apiFetch({
path: `${restURL}everest-forms/v1/templates/favorite_forms`,
method: 'GET',
headers: {
'X-WP-Nonce': security,
},
});
if (response && Array.isArray(response)) {
setFavorites(response);
localStorage.setItem('favorites', JSON.stringify(response));
}
} catch (error) {
console.error('Error fetching favorites:', error);
}
};
fetchFavorites();
}
}, []);
const handleTemplateClick = async (template: Template) => {
const requiredPlugins = template.addons ? Object.keys(template.addons) : [];
try {
const response = await apiFetch({
path: `${restURL}everest-forms/v1/plugin/upgrade`,
method: "POST",
body: JSON.stringify({ requiredPlugins }),
headers: {
"Content-Type": "application/json",
"X-WP-Nonce": security,
},
});
const { plugin_status } = response as { plugin_status: Record };
if (!plugin_status) {
setFormTemplateName(template.title);
openPluginModal();
return;
}
setSelectedTemplateSlug(template.slug);
setPreviewTemplate(template);
setFormTemplateName(template.title);
openModal();
} catch (error) {
toast({
title: __("Error", "everest-forms"),
description: __("An error occurred while checking the plugin status. Please try again.", "everest-forms"),
status: "error",
position: "bottom-right",
duration: 5000,
isClosable: true,
variant: "subtle",
});
}
};
const handleFormTemplateSave = async () => {
if (!formTemplateName) {
toast({
title: __("Form name required", "everest-forms"),
description: __("Please provide a name for your form.", "everest-forms"),
status: "warning",
position: "bottom-right",
duration: 5000,
isClosable: true,
variant: "subtle",
});
return;
}
try {
const response = (await apiFetch({
path: `${restURL}everest-forms/v1/templates/create`,
method: "POST",
body: JSON.stringify({
title: formTemplateName,
slug: selectedTemplateSlug,
}),
headers: {
"Content-Type": "application/json",
"X-WP-Nonce": security,
},
})) as CreateTemplateResponse;
if (response.success && response.data) {
window.location.href = response.data.redirect;
} else {
toast({
title: __("Error", "everest-forms"),
description: response.message || __("Failed to create form template.", "everest-forms"),
status: "error",
position: "bottom-right",
duration: 5000,
isClosable: true,
variant: "subtle",
});
}
} catch (error) {
toast({
title: __("Error", "everest-forms"),
description: __("An error occurred while creating the form template.", "everest-forms"),
status: "error",
position: "bottom-right",
duration: 5000,
isClosable: true,
variant: "subtle",
});
}
};
const mutation = useMutation(
async (slug: string) => {
const newFavorites = favorites.includes(slug)
? favorites.filter((item) => item !== slug)
: [...favorites, slug];
setFavorites(newFavorites);
localStorage.setItem("favorites", JSON.stringify(newFavorites));
await apiFetch({
path: `${restURL}everest-forms/v1/templates/favorite`,
method: "POST",
body: JSON.stringify({
action: newFavorites.includes(slug) ? "add_favorite" : "remove_favorite",
slug,
}),
headers: {
"Content-Type": "application/json",
"X-WP-Nonce": security,
},
});
return newFavorites;
},
{
onError: () => {
toast({
title: __("Error", "everest-forms"),
description: __("An error occurred while updating favorites.", "everest-forms"),
status: "error",
position: "bottom-right",
duration: 5000,
isClosable: true,
variant: "subtle",
});
},
onSuccess: (newFavorites) => {
queryClient.invalidateQueries(['templates']);
setFavorites(newFavorites);
localStorage.setItem("favorites", JSON.stringify(newFavorites));
queryClient.invalidateQueries(['favorites']);
},
}
);
const handleFavoriteToggle = (slug: string) => {
mutation.mutate(slug);
};
const addonEntries = previewTemplate?.addons
? Object.entries(previewTemplate.addons).map(([key, value]) => ({ key, value }))
: [];
const requiredPlugins = addonEntries.map((addon) => ({
key: addon.key,
value: addon.value,
}));
return (
{selectedCategory}
{templates?.length ? (
{templates.map((template) => (
setHoverCardId(template.id)}
onMouseLeave={() => setHoverCardId(null)}
textAlign="center"
bg="white"
p={0}
transition="all .3s"
_hover={{
boxShadow: "0px 5px 24px rgba(58, 34, 93, 0.12)",
"::before": {
content: '""',
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "250px",
bg: "rgba(0, 0, 0, 0.4)",
zIndex: 1,
},
"& > div > .template-title": {
color: "#7545BB",
},
}}
>
{template.isPro && (
{__("Pro", "everest-forms")}
)}
{/* Hover Buttons */}
{hoverCardId === template.id && (
} colorScheme="purple" onClick={() => handleTemplateClick(template)}>
{__("Get Started", "everest-forms")}
{template.preview_link && (
}
color="white"
variant="outline"
onClick={() => window.open(template.preview_link, "_blank")}
_hover={{ color: "black", bg: "white" }}
>
{__("Preview", "everest-forms")}
)}
)}
{hoverCardId === template.id && (
handleFavoriteToggle(template.slug)}
aria-label={`Toggle favorite for ${template.title}`}
position="absolute"
top={2}
right={2}
zIndex={3}
bg="transparent"
border="none"
_hover={{ color: "red.600" }}
>
)}
{template.title}
{template.description}
))}
) : (
{__("No Templates Found", "everest-forms")}
{__("Sorry, we didn't find any templates that match your criteria", "everest-forms")}
)}
{sprintf(__("%s is a Premium Template", "everest-forms"), formTemplateName)}
{__("This template requires premium addons. Please upgrade to the Premium to unlock all these awesome templates.", "everest-forms")}
{__("OK", "everest-forms")}
{__("Upgrade Plan", "everest-forms")}
{__("Uplift your form experience to the next level.","everest-forms")}
{__("Give it a name","everest-forms")}
setFormTemplateName(e.target.value)}
placeholder="Give it a name."
size="md"
_focus={{
borderColor: "#7545BB",
outline: "none",
boxShadow: "none"
}}
/>
);
};
export default TemplateList;