import {
Badge,
Box,
Button,
Center,
Heading,
HStack,
Icon,
Image,
Input,
Modal,
ModalBody,
ModalCloseButton,
ModalContent,
ModalFooter,
ModalHeader,
ModalOverlay,
SimpleGrid,
Text,
useDisclosure,
useToast,
VStack,
} from '@chakra-ui/react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import apiFetch from '@wordpress/api-fetch';
import { __, sprintf } from '@wordpress/i18n';
import React, { useEffect, useState } from 'react';
import { FaHeart, FaRegHeart } from 'react-icons/fa';
import { IoPlayOutline } from 'react-icons/io5';
import { MdOutlineRemoveRedEye } from 'react-icons/md';
import notFoundImage from '../images/not-found-image.png';
import { templatesScriptData } from '../utils/global';
import PluginStatus from './PluginStatus';
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 (
✦ {__('Ready-made templates', 'everest-forms')}
{__('Build faster with beautiful templates', 'everest-forms')}
{__('Pick from 49 professionally designed form templates. Customize, deploy, and start collecting responses in minutes.', 'everest-forms')}
{selectedCategory}
{templates?.length ? (
{templates.map((template) => {
if (template.slug === 'blank') {
return (
handleTemplateClick(template)}
_hover={{
borderColor: '#7545BB',
boxShadow: '0px 5px 24px rgba(58, 34, 93, 0.12)',
}}
>
{__('Start Blank', 'everest-forms')}
{__('Create from scratch', 'everest-forms')}
);
}
return (
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)',
borderColor: 'transparent',
'::before': {
content: '""',
position: 'absolute',
top: 0,
left: 0,
width: '100%',
height: '250px',
// bg: 'rgba(0, 0, 0, 0.4)',
bg: "#181818",
opacity: ".5",
zIndex: 1,
},
'& > div > .template-title': {
color: '#7545BB',
},
}}
>
{template.isPro && (
{__('Pro', 'everest-forms')}
)}
{/* Hover Buttons */}
{hoverCardId === template.id && (
}
colorScheme="purple"
onClick={() => handleTemplateClick(template)}
>
{__('Use Template', 'everest-forms')}
{template.preview_link && (
}
color="#0f0f1a"
background="#f4f4f4"
border="1px solid rgba(0,0,0,0.12)"
// 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={3}
right={3}
zIndex={3}
bg="transparent"
border="none"
display="flex"
alignItems="center"
justifyContent="center"
_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',
)}
{__(
'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;