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 / templates / App.tsx
everest-forms / src / templates Last commit date
components 3 weeks ago images 1 year ago types 4 weeks ago utils 1 year ago App.tsx 4 weeks ago index.tsx 1 year ago
App.tsx
164 lines
1 import { __ } from '@wordpress/i18n';
2 import React, { useState, useEffect } from "react";
3 import {
4 ChakraProvider,
5 Box,
6 Flex,
7 Heading,
8 Link,
9 } from "@chakra-ui/react";
10 import Main from "./components/Main";
11 import CreateWithAI from "./components/CreateWithAI";
12
13 // The AI view's PageShell is a fixed full-viewport overlay at z-index 100000.
14 // Chakra's toast manager renders into a portal on document.body at
15 // `zIndex: var(--toast-z-index, 5500)` — well below the overlay — so toasts
16 // fired from that screen were painted underneath and never seen. Chakra does
17 // NOT bind --toast-z-index to the theme, so the only fix is to set the CSS
18 // variable on an ancestor of the portal (the <html> element).
19 const TOAST_Z_INDEX = 200001;
20
21 const WP_ELEMENTS = [
22 '#wpadminbar',
23 '#adminmenuwrap',
24 '#adminmenuback',
25 '#wpfooter',
26 '#evf-react-header-root',
27 ];
28
29 const enterFullscreen = () => {
30 WP_ELEMENTS.forEach(sel => {
31 const el = document.querySelector<HTMLElement>(sel);
32 if (el) el.style.display = 'none';
33 });
34
35 const wpContent = document.querySelector<HTMLElement>('#wpcontent');
36 if (wpContent) {
37 wpContent.dataset.origMargin = wpContent.style.marginLeft;
38 wpContent.style.marginLeft = '0';
39 wpContent.style.paddingTop = '0';
40 }
41 document.body.dataset.origPaddingTop = document.body.style.paddingTop;
42 document.body.style.paddingTop = '0';
43 document.body.style.marginTop = '0';
44
45 document.documentElement.dataset.origPaddingTop = document.documentElement.style.paddingTop;
46 document.documentElement.style.paddingTop = '0';
47 };
48
49 const exitFullscreen = () => {
50 WP_ELEMENTS.forEach(sel => {
51 const el = document.querySelector<HTMLElement>(sel);
52 if (el) el.style.display = '';
53 });
54 const wpContent = document.querySelector<HTMLElement>('#wpcontent');
55 if (wpContent) {
56 wpContent.style.marginLeft = wpContent.dataset.origMargin ?? '';
57 wpContent.style.paddingTop = '';
58 }
59 document.body.style.paddingTop = document.body.dataset.origPaddingTop ?? '';
60 document.body.style.marginTop = '';
61 document.documentElement.style.paddingTop = document.documentElement.dataset.origPaddingTop ?? '';
62 };
63
64 const App = () => {
65 const [currentView, setCurrentView] = useState<'templates' | 'ai'>(() => {
66 const params = new URLSearchParams(window.location.search);
67 return params.get('view') === 'ai' ? 'ai' : 'templates';
68 });
69 // When entering the AI view from a template's "Edit with AI", the draft form to
70 // preload (0 = fresh "Create with AI").
71 const [aiFormId, setAiFormId] = useState(0);
72 const [aiTitle, setAiTitle] = useState('');
73
74 // Lift Chakra's toast layer above the AI overlay (PageShell, z-index 100000).
75 // The toast portal mounts on document.body, so the --toast-z-index variable
76 // must live on an ancestor of it — set it on <html> for the App's lifetime.
77 useEffect(() => {
78 const root = document.documentElement;
79 const prev = root.style.getPropertyValue('--toast-z-index');
80 root.style.setProperty('--toast-z-index', String(TOAST_Z_INDEX));
81 return () => {
82 if (prev) root.style.setProperty('--toast-z-index', prev);
83 else root.style.removeProperty('--toast-z-index');
84 };
85 }, []);
86
87 useEffect(() => {
88 if (currentView === 'ai') {
89 enterFullscreen();
90 } else {
91 exitFullscreen();
92 }
93
94 return () => { if (currentView === 'ai') exitFullscreen(); };
95 }, [currentView]);
96
97 useEffect(() => {
98 const onPopState = () => {
99 const params = new URLSearchParams(window.location.search);
100 setCurrentView(params.get('view') === 'ai' ? 'ai' : 'templates');
101 };
102 window.addEventListener('popstate', onPopState);
103 return () => window.removeEventListener('popstate', onPopState);
104 }, []);
105
106 const navigateToAI = (formId: number = 0, title: string = '') => {
107 // Coerce: only a real positive form id loads a prefilled form; anything else
108 // (e.g. a stray click event passed by a button) opens the blank prompt screen.
109 const id = typeof formId === 'number' && Number.isFinite(formId) && formId > 0 ? formId : 0;
110 const t = typeof title === 'string' ? title : '';
111 setAiFormId(id);
112 setAiTitle(t);
113 const url = new URL(window.location.href);
114 url.searchParams.set('view', 'ai');
115 history.pushState({ view: 'ai' }, '', url.toString());
116 setCurrentView('ai');
117 };
118
119 const navigateBack = () => {
120 setAiFormId(0);
121 setAiTitle('');
122 const url = new URL(window.location.href);
123 url.searchParams.delete('view');
124 history.pushState({ view: 'templates' }, '', url.toString());
125 setCurrentView('templates');
126 };
127
128 return (
129 <ChakraProvider>
130 {currentView === 'ai' ? (
131 <Box bg="#f3f3f5" minHeight="100vh">
132 <CreateWithAI onBack={navigateBack} initialFormId={aiFormId} initialTitle={aiTitle} />
133 </Box>
134 ) : (
135 <Box
136 bg="white"
137 margin="20px"
138 border="1px solid #e2e8f0"
139 borderRadius="16px"
140 overflow="hidden"
141 >
142 {/* Page title */}
143 <Flex
144 align="center"
145 px="8"
146 py="5"
147 borderBottom="1px solid #e2e8f0"
148 >
149 <Heading as="h2" fontSize="18px" fontWeight="600" color="#0e0e0e" m="0" letterSpacing="-0.01em">
150 {__("Add New Form", "everest-forms")}
151 </Heading>
152 </Flex>
153
154 <Box>
155 <Main onCreateWithAI={navigateToAI} />
156 </Box>
157 </Box>
158 )}
159 </ChakraProvider>
160 );
161 };
162
163 export default App;
164