HTML and AJAX tabs on /integration.

This commit is contained in:
fiatjaf 2018-09-06 23:19:08 +00:00
parent 35004e25a1
commit 978333a473
7 changed files with 133 additions and 30 deletions

View File

@ -269,7 +269,7 @@ module.exports = class CreateForm extends React.Component {
}
toastr.success('Form created!')
this.props.history.push(`/forms/${r.hashid}/integrations`)
this.props.history.push(`/forms/${r.hashid}/integration`)
} catch (e) {
console.error(e)
toastr.error('Failed to create form, see the console for more details.')

View File

@ -1,13 +1,12 @@
/** @format */
const React = require('react')
const render = require('react-dom').render
const {BrowserRouter: Router, Route} = require('react-router-dom')
const FormList = require('./FormList')
const FormPage = require('./FormPage')
class Dashboard extends React.Component {
module.exports = class Dashboard extends React.Component {
render() {
return (
<Router>
@ -20,8 +19,3 @@ class Dashboard extends React.Component {
)
}
}
if (document.querySelector('body.forms.dashboard')) {
document.querySelector('.menu .item:nth-child(2)').innerHTML = ''
render(<Dashboard />, document.querySelector('.container.block'))
}

View File

@ -186,7 +186,7 @@ class FormItem extends React.Component {
<td className="n-submissions" data-label="Submissions counter">
{form.counter === 0 ? (
<Link
to={`/forms/${form.hashid}/integrations`}
to={`/forms/${form.hashid}/integration`}
className="no-underline"
>
<span className="never">never submitted</span>

View File

@ -5,7 +5,9 @@ const fetch = window.fetch
const React = require('react')
const {Route, Link, NavLink, Redirect} = require('react-router-dom')
const CodeMirror = require('react-codemirror2')
const cs = require('class-set')
require('codemirror/mode/xml/xml')
require('codemirror/mode/javascript/javascript')
const Portal = require('../Portal')
@ -44,10 +46,10 @@ module.exports = class FormPage extends React.Component {
<>
<h4 className="tabs">
<NavLink
to={`/forms/${hashid}/integrations`}
to={`/forms/${hashid}/integration`}
activeStyle={{color: 'inherit', cursor: 'normal'}}
>
Integrations
Integration
</NavLink>
<NavLink
to={`/forms/${hashid}/submissions`}
@ -63,9 +65,9 @@ module.exports = class FormPage extends React.Component {
</NavLink>
</h4>
<Route
path="/forms/:hashid/integrations"
path="/forms/:hashid/integration"
render={() => (
<FormIntegrations
<FormIntegration
form={this.state.form}
onUpdate={this.fetchForm}
/>
@ -121,12 +123,27 @@ module.exports = class FormPage extends React.Component {
}
}
class FormIntegrations extends React.Component {
class FormIntegration extends React.Component {
constructor(props) {
super(props)
this.changeTab = this.changeTab.bind(this)
this.state = {
activeTab: 'HTML',
availableTabs: ['HTML', 'AJAX']
}
}
render() {
let {form} = this.props
let htmlSample = `<!-- Use this code in your HTML, modifying it according to your needs -->
<form
var codeSample
var modeSample
switch (this.state.activeTab) {
case 'HTML':
modeSample = 'xml'
codeSample = `<form
action="${form.url}"
method="POST"
>
@ -143,30 +160,76 @@ class FormIntegrations extends React.Component {
<button type="submit">Send</button>
</form>`
break
case 'AJAX':
modeSample = 'javascript'
codeSample = `// There should be an HTML form elsewhere on the page. See the "HTML" tab.
var form = document.querySelector('form')
var data = new FormData(form)
var req = new XMLHttpRequest()
req.open(form.method, form.action)
req.send(data)`
break
}
var integrationSnippet
if (this.state.activeTab === 'AJAX' && !form.captcha_disabled) {
integrationSnippet = (
<div className="integration-nocode CodeMirror cm-s-oceanic-next">
<p>Want to submit your form through AJAX?</p>
<p>
<Link to={`/forms/${form.hashid}/settings`}>Disable reCAPTCHA</Link>{' '}
for this form to make it possible!
</p>
</div>
)
} else {
integrationSnippet = (
<CodeMirror.UnControlled
value={codeSample}
options={{
theme: 'oceanic-next',
mode: modeSample,
viewportMargin: Infinity
}}
/>
)
}
return (
<>
<div className="col-1-1">
<FormDescription prefix="Integrating" form={form} />
<h3>HTML</h3>
<div className="container">
<div className="row">
<div className="col-1-1">
<CodeMirror.UnControlled
value={htmlSample}
options={{
theme: 'oceanic-next',
mode: 'xml',
viewportMargin: Infinity
}}
/>
<div className="integration">
<p>
Paste this code in your HTML, modifying it according to your
needs:
</p>
<div className="integration-tabs">
{this.state.availableTabs.map(tabName => (
<div
key={tabName}
data-tab={tabName}
onClick={this.changeTab}
className={cs({active: this.state.activeTab === tabName})}
>
{tabName}
</div>
))}
</div>
{integrationSnippet}
</div>
</div>
</div>
</>
)
}
changeTab(e) {
e.preventDefault()
this.setState({activeTab: e.target.dataset.tab})
}
}
class FormSubmissions extends React.Component {

View File

@ -0,0 +1,11 @@
/** @format */
const render = require('react-dom').render
const React = require('react') // eslint-disable-line no-unused-vars
const Dashboard = require('./Dashboard')
if (document.querySelector('body.forms.dashboard')) {
document.querySelector('.menu .item:nth-child(2)').innerHTML = ''
render(<Dashboard />, document.querySelector('.container.block'))
}

View File

@ -77,7 +77,7 @@ $('a.resend').on('click', function() {
})
/* scripts at other files */
require('./forms/dashboard.js')
require('./forms/main.js')
/* toggle the card management menu */
$(function() {

View File

@ -125,6 +125,42 @@
font-size: 20px;
}
.integration-tabs {
& > * {
display: inline-block;
cursor: pointer;
border-radius: 2px 2px 0 0;
padding: 7px 15px;
margin-right: 2px;
background-color: #9a9a9a;
color: white;
font-family: monospace;
&:hover {
background-color: #737373;
}
&.active {
background-color: #304148;
color: #f8f8f2;
}
}
}
.integration-nocode {
color: #f8f8f2;
text-align: center;
padding: 18px;
p {
color: inherit;
}
a {
font-weight: bold;
}
}
.row:after {
content: "";
display: none;
@ -466,7 +502,6 @@ a.button.export {
}
.CodeMirror {
border: 1px solid #eee;
padding: 10px;
height: auto;
font-size: 90%;