PluginProbe ʕ •ᴥ•ʔ
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI / 3.5.2
Everest Forms – Contact Form, Payment Form, Quiz, Survey & Custom Form Builder with AI v3.5.2
3.5.2 3.5.1 3.5.0 3.4.8 3.4.7 3.4.6 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.5.1 1.1.6 1.1.7 1.1.8 1.1.9 1.2.0 1.2.1 1.2.2 1.2.3 1.2.4 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.10 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.6.1 1.6.7 1.7.0 1.7.0.1 1.7.0.2 1.7.0.3 1.7.1 1.7.2 1.7.2.1 1.7.2.2 1.7.3 1.7.4 1.7.5 1.7.5.1 1.7.5.2 1.7.6 1.7.7 1.7.7.1 1.7.7.2 1.7.8 1.7.9 1.8.0 1.8.0.1 1.8.1 1.8.2 1.8.2.1 1.8.2.2 1.8.2.3 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.0.1 1.9.1 1.9.2 1.9.3 1.9.4 1.9.4.1 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.0.1 2.0.1 2.0.2 2.0.3 2.0.3.1 2.0.4 2.0.4.1 2.0.5 2.0.6 2.0.7 2.0.8 2.0.8.1 2.0.9 3.0.0 3.0.0.1 3.0.1 3.0.2 3.0.3 3.0.3.1 3.0.4 3.0.4.1 3.0.4.2 3.0.5 3.0.5.1 3.0.5.2 3.0.6 3.0.6.1 3.0.7.1 3.0.8 3.0.8.1 3.0.9 3.0.9.1 3.0.9.2 3.0.9.3 3.0.9.4 3.0.9.5 3.1.0 3.1.1 3.1.2 3.2.0 3.2.1 3.2.2 3.2.3 3.2.4 3.2.5 3.2.6 3.3.0 3.4.0 3.4.1 3.4.2 3.4.2.1 3.4.3 3.4.4 3.4.5 trunk 1.0 1.0.1 1.0.2 1.0.3
everest-forms / src / dashboard / components / Header / Header.js
everest-forms / src / dashboard / components / Header Last commit date
Header.js 3 months ago
Header.js
320 lines
1 /**
2 * External Dependencies
3 */
4 import {
5 Box,
6 Button,
7 Center,
8 Container,
9 Divider,
10 Drawer,
11 DrawerBody,
12 DrawerCloseButton,
13 DrawerContent,
14 DrawerHeader,
15 DrawerOverlay,
16 Image,
17 Link,
18 Stack,
19 Tag,
20 Tooltip,
21 useDisclosure,
22 } from '@chakra-ui/react';
23 import { __ } from '@wordpress/i18n';
24 import { useEffect, useMemo, useRef } from 'react';
25 import { NavLink, useLocation } from 'react-router-dom';
26
27 /**
28 * Internal Dependencies
29 */
30 import ROUTES, {
31 convertRoute,
32 isExternalRoute,
33 isRouteActive,
34 } from '../../Constants';
35 import announcement from '../../images/announcement.gif';
36 import Changelog from '../Changelog/Changelog';
37 import { EVF, ExternalLink } from '../Icon/Icon';
38 import IntersectObserver from '../IntersectionObserver/IntersectionObserver';
39
40 const Header = ({ hideSiteAssistant = false }) => {
41 const { isOpen, onOpen, onClose } = useDisclosure();
42 const ref = useRef();
43 const location = useLocation();
44
45 /* global _EVF_DASHBOARD_ */
46 const { version, isPro, upgradeURL, pageType, adminURL, currentPage } =
47 typeof _EVF_DASHBOARD_ !== 'undefined' && _EVF_DASHBOARD_;
48
49 const isSettingsPage = pageType === 'settings';
50 const isEntriesPage = pageType === 'entries';
51 const isAnalyticsPage = pageType === 'analytics';
52 const isNonDashboardPage =
53 isSettingsPage ||
54 isEntriesPage ||
55 isAnalyticsPage ||
56 (currentPage && currentPage !== 'evf-dashboard');
57
58 // ------------------------------------------------------------------
59 // Dismiss PHP skeleton once React has painted.
60 // requestAnimationFrame guarantees the browser has rendered this
61 // component before we remove the skeleton — prevents any white flash.
62 // ------------------------------------------------------------------
63 useEffect(() => {
64 requestAnimationFrame(() => {
65 if (typeof window.evfHeaderReady === 'function') {
66 window.evfHeaderReady();
67 }
68 });
69 }, []); // runs once on mount only.
70
71 // ------------------------------------------------------------------
72 // Keep existing modal body-class logic unchanged.
73 // ------------------------------------------------------------------
74 useEffect(() => {
75 if (isOpen) {
76 document.body.classList.add('ur-modal-open');
77 } else {
78 document.body.classList.remove('ur-modal-open');
79 }
80 return () => {
81 document.body.classList.remove('ur-modal-open');
82 };
83 }, [isOpen]);
84
85 const { leftRoutes, rightRoutes } = useMemo(() => {
86 const allRoutes = hideSiteAssistant
87 ? ROUTES.filter((route) => route.key !== 'siteAssistant')
88 : ROUTES;
89
90 const rightRoutePaths = ['/help', 'https://everestforms.net/free-vs-pro/'];
91
92 return {
93 leftRoutes: allRoutes.filter(
94 (route) => !rightRoutePaths.includes(route.route),
95 ),
96 rightRoutes: allRoutes
97 .filter((route) => rightRoutePaths.includes(route.route))
98 .sort(
99 (a, b) =>
100 rightRoutePaths.indexOf(a.route) - rightRoutePaths.indexOf(b.route),
101 ),
102 };
103 }, [hideSiteAssistant]);
104
105 const renderNavLink = (route, label, external, showExternalIcon = false) => {
106 const convertedRoute = convertRoute(route, isNonDashboardPage, adminURL);
107 const isExternal = external || isExternalRoute(convertedRoute);
108 const isActive = isRouteActive(route, location.pathname, pageType);
109 const shouldUseExternalLink = isNonDashboardPage || isExternal;
110 const shouldShowIcon = showExternalIcon;
111
112 return shouldUseExternalLink ? (
113 <Link
114 data-target={route}
115 key={route}
116 href={convertedRoute}
117 isExternal={route === 'https://everestforms.net/free-vs-pro/'}
118 fontSize="14px"
119 fontWeight="medium"
120 lineHeight="150%"
121 color={isActive ? 'primary.500' : '#383838'}
122 borderBottom="2px solid"
123 // borderBottom={isActive ? '3px solid' : 'none'}
124 borderColor={isActive ? 'primary.500' : 'transparent'}
125 // marginBottom={isActive ? '-2px' : '0'}
126 _hover={{ color: 'primary.500' }}
127 _focus={{ boxShadow: 'none' }}
128 display="inline-flex"
129 alignItems="center"
130 gap="1"
131 px="2"
132 h="full"
133 >
134 {label}
135 {shouldShowIcon && (
136 <ExternalLink w="16px" h="16px" fill="currentColor" />
137 )}
138 </Link>
139 ) : (
140 <Link
141 data-target={route}
142 key={route}
143 as={NavLink}
144 to={route}
145 fontSize="14px"
146 fontWeight="medium"
147 lineHeight="150%"
148 color="#383838"
149 borderBottom="2px solid"
150 borderColor={isActive ? 'primary.500' : 'transparent'}
151 _hover={{ color: 'primary.500' }}
152 _focus={{ boxShadow: 'none' }}
153 _activeLink={{
154 color: 'primary.500',
155 // borderBottom: '3px solid',
156 borderColor: 'primary.500',
157 // marginBottom: '-2px',
158 }}
159 display="inline-flex"
160 alignItems="center"
161 gap="1"
162 px="2"
163 h="full"
164 >
165 {label}
166 {shouldShowIcon && (
167 <ExternalLink w="16px" h="16px" fill="currentColor" />
168 )}
169 </Link>
170 );
171 };
172
173 return (
174 <>
175 <Box
176 // bg={'white'}
177 bg="white"
178 borderBottom="1px solid #e1e1e1"
179 width="100%"
180 position={'relative'}
181 >
182 <Container maxW="full">
183 <Stack direction="row" minH="60px" justify="space-between">
184 {/* Left Side — Logo and Main Navigation */}
185 <Stack direction="row" align="center" gap="16px">
186 <Box>
187 <EVF h="36px" w="36px" />
188 </Box>
189 <IntersectObserver routes={leftRoutes}>
190 {leftRoutes.map(({ route, label, external }) =>
191 renderNavLink(route, label, external),
192 )}
193 </IntersectObserver>
194 </Stack>
195
196 {/* Right Side */}
197 <Stack direction="row" align="center" spacing="12px">
198 <Stack direction="row" align="center" gap="1" h={'full'}>
199 {rightRoutes.map(({ route, label, external }) =>
200 renderNavLink(
201 route,
202 label,
203 external,
204 route === 'https://everestforms.net/free-vs-pro/',
205 ),
206 )}
207 </Stack>
208
209 {rightRoutes.length > 0 && (
210 <Center height="18px">
211 <Divider orientation="vertical" />
212 </Center>
213 )}
214
215 {!isPro && (
216 <Link
217 color="orange"
218 fontSize="15px"
219 height="18px"
220 href={
221 upgradeURL +
222 'utm_medium=evf-dashboard&utm_source=evf-free&utm_campaign=header-upgrade-btn&utm_content=Upgrade%20to%20Pro'
223 }
224 isExternal
225 display="inline-flex"
226 alignItems="center"
227 gap="1"
228 >
229 {__('Upgrade To Pro', 'everest-forms')}
230 <ExternalLink w="16px" h="16px" fill="currentColor" />
231 </Link>
232 )}
233
234 <Tooltip
235 label={sprintf(
236 __(
237 'You are currently using Everest Forms %s',
238 'everest-forms',
239 ),
240 (isPro && 'Pro ') + 'v' + version,
241 )}
242 maxW={'180px'}
243 >
244 <Tag
245 display={'inline-flex !important'}
246 variant="outline"
247 // colorScheme="primary"
248 // borderRadius="xl"
249 bgColor="#F8FAFF"
250 // fontSize="xs"
251 p="2px 6px"
252 fontWeight="medium"
253 borderRadius="4px"
254 fontSize="12px"
255 color="#8f8f8f"
256 bg="#f3f3f3"
257 border="1px solid #e1e1e1"
258 outline="none"
259 boxShadow="none"
260 >
261 {'v' + version}
262 </Tag>
263 </Tooltip>
264
265 <Button
266 onClick={onOpen}
267 variant="unstyled"
268 borderRadius="full"
269 border="2px"
270 borderColor="gray.200"
271 w="40px"
272 h="40px"
273 position="relative"
274 >
275 <Tooltip label={__('Latest Updates', 'everest-forms')}>
276 <Image
277 src={announcement}
278 alt="announcement"
279 h="35px"
280 w="35px"
281 position="absolute"
282 top="50%"
283 left="50%"
284 transform="translate(-40%, -50%)"
285 />
286 </Tooltip>
287 </Button>
288 </Stack>
289 </Stack>
290 </Container>
291 </Box>
292
293 <Drawer
294 isOpen={isOpen}
295 placement="right"
296 onClose={onClose}
297 finalFocusRef={ref}
298 size="md"
299 >
300 <DrawerOverlay
301 bgColor="rgb(0,0,0,0.05)"
302 sx={{ backdropFilter: 'blur(1px)' }}
303 />
304 <DrawerContent
305 className="everest-forms-announcement"
306 top="var(--wp-admin--admin-bar--height, 0) !important"
307 >
308 <DrawerCloseButton />
309 <DrawerHeader>{__('Latest Updates', 'everest-forms')}</DrawerHeader>
310 <DrawerBody>
311 <Changelog />
312 </DrawerBody>
313 </DrawerContent>
314 </Drawer>
315 </>
316 );
317 };
318
319 export default Header;
320