react-router-dom#Prompt JavaScript Examples
The following examples show how to use
react-router-dom#Prompt.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Important.js From ReactCookbook-source with MIT License | 6 votes |
Important = () => {
let initialValue = 'Initial value'
const [data, setData] = useState(initialValue)
const [dirty, setDirty] = useState(false)
useEffect(() => {
if (data !== initialValue) {
setDirty(true)
}
}, [data, initialValue])
return (
<div className="Important">
<textarea
onChange={(evt) => setData(evt.target.value)}
cols={40}
rows={12}
>
{data}
</textarea>
<br />
<button onClick={() => setDirty(false)} disabled={!dirty}>
Save
</button>
<Prompt
when={dirty}
message={() => 'Do you really want to leave?'}
/>
</div>
)
}
Example #2
Source File: CreatePost.js From Mumble with Apache License 2.0 | 5 votes |
CreatePost = () => {
let dispatch = useDispatch();
const [message, setMessage] = useState('');
const [error, setError] = useState(null);
const onFormSubmit = (e) => {
e.preventDefault();
if (!message.trim()) {
return setError('Post cannot be empty!');
} else {
dispatch(createPost({ content: message, isComment: false }));
}
setMessage('');
};
const handleMessageChange = (e) => {
setMessage(e.target.value);
if (error && e.target.value) {
setError(null);
}
};
return (
<div className="card create-post">
<div className="card__body">
<div className="create-post__body">
<form className="form" onSubmit={onFormSubmit}>
<TextArea
style={{ minHeight: '10rem' }}
name="create-post"
placeholder="Ask a question!"
onChange={handleMessageChange}
value={message}
label="Create Post"
hideLabel={true}
error={error}
/>
<Button type="submit" size="md" color="main" text="Post Question" iconName="comment-alt" />
</form>
<Prompt
when={message.length > 0}
message="Are you sure you want to leave without posting?"
/>
</div>
</div>
</div>
);
}
Example #3
Source File: PostAction.js From Mumble with Apache License 2.0 | 5 votes |
PostAction = ({ onMessageIconClick, comments, shares, postId, setComments, ancestors }) => {
let dispatch = useDispatch();
const [showCommentBox, setShowCommentBox] = useState(false);
const [comment, setComment] = useState('');
const toggleCommentBox = () => {
setShowCommentBox((prev) => !prev);
};
const handleCommentChange = (e) => setComment(e.target.value);
const handleCommentSubmit = (e) => {
e.preventDefault();
dispatch(
createComment(setComments, postId, { content: comment, isComment: true, postId: postId }),
);
let newComment = true;
onMessageIconClick(newComment);
for (let ancestor of ancestors) {
ancestor((count) => count + 1);
}
setComment('');
toggleCommentBox();
};
let toggleRemumble = () => {
dispatch(createRemumble(postId));
};
return (
<div>
<div className="post-actions-wrapper">
<div
onClick={onMessageIconClick}
className={classNames('action-wrapper', {
'action-wrapper--disabled': parseInt(comments) === 0,
})}
>
<i className="fas fa-comments"></i>
<span className="post-action-text">{comments}</span>
</div>
<div className="action-wrapper" onClick={toggleCommentBox}>
{/* <Link role="button" className="post-comment-wrapper"> */}
<i className="fas fa-comment-lines"> </i>
<span className="post-action-text">Comment</span>
{/* </Link> */}
</div>
<div className="action-wrapper">
<i onClick={toggleRemumble} className="fas fa-paper-plane"></i>
<span onClick={toggleRemumble} className="post-action-text">
{shares}
</span>
</div>
</div>
{/* comment Textarea */}
{showCommentBox && (
<form onSubmit={handleCommentSubmit}>
<textarea
className="input input--textarea input--textarea--sm"
onChange={handleCommentChange}
value={comment}
autoFocus
required
></textarea>
<Button size="sm" color="main" type="submit">
Submit
</Button>
</form>
)}
<Prompt
when={comment.length > 0}
message="Do you want to leave without finishing your comment?"
/>
</div>
);
}
Example #4
Source File: CreateDiscussionPage.js From Mumble with Apache License 2.0 | 5 votes |
CreateDiscussionPage = () => {
const history = useHistory();
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
const [isDiscussionSubmitted, setIsDiscussionSubmitted] = useState(false);
const handleTitleChange = (e) => setTitle(e.target.value);
const handleBodyChange = (e) => setBody(e.target.value);
const handleFormSubmit = (e) => {
e.preventDefault();
window.onbeforeunload = null;
// use the form data and make a request to API
alert('Discussion Created!! \n Now you will be directed to the Discussion Page');
// set isArticleSubmitted variables
setIsDiscussionSubmitted(true);
// reset title and body variables
setTitle('');
setBody('');
};
window.onbeforeunload = function (e) {
e.preventDefault();
if (title.trim() || body.trim()) {
return 'Discard changes?';
}
};
useEffect(() => {
if (isDiscussionSubmitted) {
// redirect to the articles page, in the real request slug should be changed to created article's slug
history.push(`/article/article1`);
}
}, [history, isDiscussionSubmitted]);
return (
<Page>
<section>
<div className="card">
<div className="card__body">
<div className="discussion-header">
<h1 className="discussion-headline">Create Discussion</h1>
</div>
<form onSubmit={handleFormSubmit}>
<div className="form__field">
<label>Title</label>
<input
value={title}
onChange={handleTitleChange}
type="text"
className="input"
required
/>
</div>
<div className="form__field">
<label>Body</label>
<textarea
value={body}
onChange={handleBodyChange}
className="input input--textarea"
required
></textarea>
</div>
<Button color="main" type="submit">
Submit
</Button>
</form>
<Prompt
when={title.length > 0 || body.length > 0}
message="Are you sure you want to leave without finishing your discussion?"
/>
</div>
</div>
</section>
<section></section>
</Page>
);
}
Example #5
Source File: index.js From strapi-plugin-import-export-content with MIT License | 4 votes |
function DataMapper({ analysis, target, onImport }) {
const { fieldsInfo, parsedData } = analysis;
const { kind, attributes, options } = target;
const isSingleType = kind === "singleType";
const [uploadAsDraft, setUploadAsDraft] = useState(options.draftAndPublish);
const filteredAttributes = useMemo(
() => Object.keys(attributes).filter(filterIgnoreFields),
[attributes]
);
const [mappedFields, setMappedFields] = useState(() => {
const fields = {};
Object.keys(fieldsInfo).forEach((field) => {
const { format } = fieldsInfo[field];
const targetField = filteredAttributes.includes(field) ? field : "none";
const targetFormat = attributes[targetField]
? attributes[targetField].type
: null;
fields[field] = { format, targetField, targetFormat };
});
return fields;
});
// Mapping Table Headers
const headers = useMemo(
() =>
Object.keys(mappedFields).map((field) => ({
name: field,
format: mappedFields[field].format,
value: mappedFields[field].targetField,
})),
[mappedFields]
);
// Options to Map
const destinationOptions = useMemo(
() =>
[{ label: "None", value: "none" }].concat(
filteredAttributes.map((field) => ({ label: field, value: field }))
),
[filteredAttributes]
);
// Handler Mapping
const selectDestinationField = useCallback(
(source) => ({ target: { value } }) => {
setMappedFields((fields) => ({
...fields,
[source]: {
...fields[source],
targetField: value,
targetFormat: value !== "none" ? attributes[value].type : undefined,
},
}));
},
[attributes]
);
// Mapping Table Rows
const [importItems, setImportItems] = useState(parsedData);
const deleteItem = useCallback((deleteItem) => () =>
setImportItems((items) => items.filter((item) => item !== deleteItem))
);
// Upload Data
const [isLoading, setIsLoadig] = useState(false);
const uploadData = async () => {
// Prevent Upload Empty Data;
if (importItems.length === 0) {
strapi.notification.toggle({
type: "warning",
message: "import.items.empty",
});
// Finish with the import
return onImport();
}
try {
setIsLoadig(true);
const { message } = await request(`/${pluginId}/import`, {
method: "POST",
body: {
target,
fields: mappedFields,
items: importItems,
asDraft: uploadAsDraft,
},
});
strapi.notification.toggle({ type: "info", message });
} catch (error) {
console.log(error);
strapi.notification.toggle({
type: "warning",
message: `import.items.error`,
});
}
setIsLoadig(false);
onImport();
};
return (
<>
{isLoading && <Loader />}
<div className="pt-3 col-12">
<Prompt message="import.mapper.unsaved" />
<Row>
<h2>Map the Import Data to Destination Field</h2>
<MappingTable
mappingHeaders={headers}
mappingRows={importItems}
mappingRowsHeaders={importItems}
headersMappingOptions={destinationOptions}
onChangeMapping={selectDestinationField}
onDeleteRow={deleteItem}
onlyFistRow={isSingleType}
/>
</Row>
<Row>
<span className="mr-3">Count of Items to Import:</span>
<strong>{kind === "singleType" ? 1 : importItems.length}</strong>
</Row>
{options.draftAndPublish && (
<Row>
<Checkbox
message="Upload as Draft"
name="uploadAsDraft"
value={uploadAsDraft}
onChange={() => setUploadAsDraft(!uploadAsDraft)}
/>
</Row>
)}
<Row>
<Button label="Import Data" onClick={uploadData} />
<Button
className="ml-3"
label="Cancel"
color="delete"
onClick={() => onImport()}
/>
</Row>
</div>
</>
);
}
Example #6
Source File: adminChallengeCreate.js From ctf_platform with MIT License | 4 votes |
CreateChallengeForm = (props) => {
const [form] = Form.useForm();
const [editorValue, setEditorValue] = React.useState("")
const [existingCats, setExistingCats] = React.useState([])
const [finalSortedChalls, setfinalSortedChalls] = React.useState([])
useEffect(() => {
var currentValues = form.getFieldsValue()
currentValues.flags = [""]
form.setFieldsValue(currentValues)
//Render existing categories select options
let existCats = []
for (let i = 0; i < props.allCat.length; i++) {
existCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
}
setExistingCats(existCats)
//Render existing challenges select options
let existChalls = {}
for (let i = 0; i < props.challenges.length; i++) {
if (!(props.challenges[i].category in existChalls)) existChalls[props.challenges[i].category] = []
existChalls[props.challenges[i].category].push({
value: props.challenges[i]._id,
label: props.challenges[i].name
})
}
let finalChalls = []
for (const category in existChalls) {
finalChalls.push({
value: category,
label: category,
children: existChalls[category]
})
}
setfinalSortedChalls(finalChalls)
}, [])
return (
<Form
form={form}
name="create_challenge_form"
className="create_challenge_form"
onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
onFinish={async (values) => {
props.setState({ edited: false })
if (typeof values.flags === "undefined") {
message.warn("Please enter at least 1 flag")
}
else {
//console.log(values)
props.setState({ loading: true })
if (values.visibility === "false") {
values.visibility = false
}
else {
values.visibility = true
}
if (values.dynamic === "false") {
values.dynamic = false
}
else {
values.dynamic = true
}
if (typeof values.writeup !== "undefined") {
if (typeof values.writeupComplete === "undefined") {
values.writeupComplete = true
}
}
const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
let requires = undefined
if (values.requires && values.requires.length > 0) requires = values.requires[1]
await fetch(window.ipAddress + "/v1/challenge/new", {
method: 'post',
headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
body: JSON.stringify({
"name": values.name,
"category": category,
"description": values.description,
"points": values.points,
"flags": values.flags,
"tags": values.tags,
"hints": values.hints,
"max_attempts": values.max_attempts,
"visibility": values.visibility,
"writeup": values.writeup,
"writeupComplete": values.writeupComplete,
"requires": requires,
"dynamic": values.dynamic,
"initial": values.initial,
"minSolves": values.minSolves,
"minimum": values.minimum
})
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
//console.log(data)
if (data.success === true) {
message.success({ content: "Created challenge " + values.name + " successfully!" })
form.resetFields()
props.handleCreateBack()
}
else if (data.error === "exists") {
message.warn("A challenge with an existing name exists")
}
else {
message.error({ content: "Oops. Unknown error, please contact an admin." })
}
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. Issue connecting with the server or client error, please check console and report the error. " });
})
props.setState({ loading: false })
}
}}
>
<Prompt
when={props.state.edited}
message='The challenge details you entered have not been saved. Are you sure you want to leave?'
/>
<h1>Challenge Name:</h1>
<Form.Item
name="name"
rules={[{ required: true, message: 'Please enter a challenge name' }]}
>
<Input allowClear placeholder="Challenge name" />
</Form.Item>
<Divider />
<h1>Challenge Category:</h1>
<h4>Select an Existing Category: </h4>
<Form.Item
name="category1"
rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
>
<Select
disabled={props.state.selectCatDisabled}
allowClear
showSearch
placeholder="Select an existing Category"
onChange={(value) => {
if (value) {
props.setState({ inputCatDisabled: true })
}
else {
props.setState({ inputCatDisabled: false })
}
}}
>
{existingCats}
</Select>
</Form.Item>
<h4>Enter a New Category</h4>
<Form.Item
name="category2"
rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
>
<Input onChange={(e) => {
e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
}} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
</Form.Item>
<Divider />
<Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
</div>}>
<h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>):</h1>
<Form.Item
name="description"
rules={[{ required: true, message: 'Please enter a description' }]}
valuePropName={editorValue}
>
<MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
</Form.Item>
<h3>Challenge Description Preview</h3>
<Card
type="inner"
bordered={true}
bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
className="challengeModal"
>
<MarkdownRender>{editorValue}</MarkdownRender>
</Card>
</Suspense>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "center" }}>
<Card>
<h1>Challenge Points:</h1>
<Form.Item
name="points"
rules={[{ required: true, message: 'Please enter challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={0}
>
<InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
</Form.Item>
</Card>
<Card>
<h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
<Form.Item
name="max_attempts"
rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
style={{ alignText: 'center' }}
initialValue={0}
>
<InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }} />
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="flags" >
{(fields, { add, remove }) => {
return (
<Card>
<h1>Flags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
>
<Input style={{ width: "50ch" }} placeholder="Flag" />
</Form.Item>
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
) : null}
</Space>
))}
<Form.Item>
<Button
type="dashed"
onLoad={() => { if (fields.length < 1) add() }}
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Flag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Form.List name="tags">
{(fields, { add, remove }) => {
return (
<Card>
<h1>Tags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing tag' }]}
>
<Input placeholder="Tag" style={{ width: "50ch" }} />
</Form.Item>
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Tag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
</div>
</div>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="hints" >
{(fields, { add, remove }) => {
return (
<Card>
<h1>Hints</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name, "hint"]}
fieldKey={[field.fieldKey, "hint"]}
rules={[{ required: true, message: 'Missing hint' }]}
>
<Input placeholder="Hint" style={{ width: "20vw" }} />
</Form.Item>
<Form.Item
{...field}
name={[field.name, "cost"]}
fieldKey={[field.fieldKey, "cost"]}
rules={[{ required: true, message: 'Missing cost for hint' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
>
<InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
</Form.Item>
<MinusCircleOutlined
style={{ color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Hint
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Card>
<h1>Writeup Link (Optional)</h1>
<Form.Item
name="writeup"
rules={[
{
type: 'url',
message: "Please enter a valid link",
}]}
>
<Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
</Form.Item>
<div style={{ display: "flex", alignContent: "center" }}>
<h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
<Form.Item
name="writeupComplete"
>
<Switch defaultChecked />
</Form.Item>
</div>
</Card>
<Card>
<h1>Visibility</h1>
<Form.Item
name="visibility"
rules={[{ required: true, message: 'Please set the challenge visibility' }]}
initialValue="false"
>
<Select style={{ width: "20ch" }}>
<Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
</Select>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }} />
<div style={{ display: "flex", flexDirection: "column" }}>
<Card>
<h1>Challenge Required: </h1>
<Form.Item
name="requires"
>
<Cascader
options={finalSortedChalls}
allowClear
showSearch
placeholder="Select an existing challenge" />
</Form.Item>
<p>Locks this challenge until the provided challenge above has been solved.</p>
</Card>
<Card>
<h1>Dynamic Scoring</h1>
<Form.Item
name="dynamic"
rules={[{ required: true, message: 'Please set whether the challenge uses dynamic scoring' }]}
initialValue="false"
>
<Select onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }} style={{ width: "20ch" }}>
<Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
</Select>
</Form.Item>
<h1>Initial Points:</h1>
<Form.Item
name="initial"
rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={500}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Initial number of points when there are 0/1 solves on a challenge</p>
<h1>Minimum Points:</h1>
<Form.Item
name="minimum"
rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={100}
>
<InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
</Form.Item>
<p>Minimum amount of points that the challenge can decay too</p>
<h1>Solves to Minimum:</h1>
<Form.Item
name="minSolves"
rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={50}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Number of solves on the challenge till it decays to the minimum point.</p>
</Card>
</div>
</div>
<Form.Item>
<div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "2vh" }}>
<div>
<Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()); }}>Preview</Button>
<Button loading={props.loadingStatus} type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }}>Create Challenge</Button>
</div>
<div>
<Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
</div>
</div>
</Form.Item>
</Form>
);
}
Example #7
Source File: adminChallengeEdit.js From ctf_platform with MIT License | 4 votes |
CreateChallengeForm = (props) => {
const [form] = Form.useForm();
const [editorValue, setEditorValue] = React.useState("")
const [existingCats, setExistingCats] = React.useState([])
const [finalSortedChalls, setFinalSortedChalls] = React.useState([])
//Render existing categories select options
useEffect(() => {
let existingCats = []
for (let i = 0; i < props.allCat.length; i++) {
existingCats.push(<Option key={props.allCat[i].key} value={props.allCat[i].key}>{props.allCat[i].key}</Option>)
}
//Render existing challenges select options minus the challenge itself
let existingChalls = {}
for (let i = 0; i < props.challenges.length; i++) {
if (props.challenges[i].name !== props.initialData.name) {
if (!(props.challenges[i].category in existingChalls)) existingChalls[props.challenges[i].category] = []
existingChalls[props.challenges[i].category].push({
value: props.challenges[i]._id,
label: props.challenges[i].name
})
}
}
setExistingCats(existingCats)
let finalSortedChalls = []
for (const category in existingChalls) {
finalSortedChalls.push({
value: category,
label: category,
children: existingChalls[category]
})
}
setFinalSortedChalls(finalSortedChalls)
let initialData = JSON.parse(JSON.stringify(props.initialData))
if (props.initialData.visibility === false) {
initialData.visibility = "false"
}
else if (props.initialData.visibility === true) {
initialData.visibility = "true"
}
// if we put only props.initialData.requires, we are merely putting a reference to props.initialData.requires, which is this array, creating a "loop"
if (props.initialData.requires) initialData.requires = [props.IDNameMapping[props.initialData.requires], props.initialData.requires]
if (props.initialData.dynamic === false) {
initialData.dynamic = "false"
}
else if (props.initialData.dynamic === true) {
initialData.dynamic = "true"
props.setState({ dynamic: true })
}
else {
initialData.dynamic = "false"
}
initialData.category1 = initialData.category
form.setFieldsValue(initialData)
setEditorValue(initialData.description)
}, [])
return (
<Form
form={form}
name="create_challenge_form"
className="create_challenge_form"
onValuesChange={() => { if (props.state.edited === false) props.setState({ edited: true }) }}
onFinish={async (values) => {
props.setState({ edited: false })
if (typeof values.flags === "undefined") {
message.warn("Please enter at least 1 flag")
}
else {
if (values.visibility === "false") {
values.visibility = false
}
else {
values.visibility = true
}
if (values.dynamic === "false") {
values.dynamic = false
}
else {
values.dynamic = true
}
if (typeof values.writeup !== "undefined") {
if (typeof values.writeupComplete === "undefined") {
values.writeupComplete = true
}
}
const category = (typeof values.category1 !== "undefined") ? values.category1 : values.category2
props.setState({ editLoading: true })
let requires = ""
if (values.requires && values.requires.length > 0) requires = values.requires[1]
await fetch(window.ipAddress + "/v1/challenge/edit", {
method: 'post',
headers: { 'Content-Type': 'application/json', "Authorization": window.IRSCTFToken },
body: JSON.stringify({
"id": props.initialData._id,
"name": values.name,
"category": category,
"description": values.description,
"points": values.points,
"flags": values.flags,
"tags": values.tags,
"hints": values.hints,
"max_attempts": values.max_attempts,
"visibility": values.visibility,
"writeup": values.writeup,
"writeupComplete": values.writeupComplete,
"requires": requires,
"dynamic": values.dynamic,
"initial": values.initial,
"minSolves": values.minSolves,
"minimum": values.minimum
})
}).then((results) => {
return results.json(); //return data in JSON (since its JSON data)
}).then((data) => {
if (data.success === true) {
message.success({ content: "Edited challenge \"" + props.initialData.name + "\" successfully!" })
props.handleEditChallBack()
setEditorValue("")
form.resetFields()
}
else if (data.error === "exists") {
message.warn("A challenge with an existing name exists")
}
else {
message.error({ content: "Oops. Unknown error" })
}
}).catch((error) => {
console.log(error)
message.error({ content: "Oops. There was an issue connecting with the server" });
})
props.setState({ editLoading: false })
}
}}
>
<Prompt
when={props.state.edited}
message='The challenge details you modified have not been saved. Are you sure you want to leave?'
/>
<p><b><u>ID:</u></b> <code>{props.initialData._id}</code></p>
<h1>Challenge Name:</h1>
<Form.Item
name="name"
rules={[{ required: true, message: 'Please enter a challenge name' }]}
>
<Input allowClear placeholder="Challenge name" />
</Form.Item>
<Divider />
<h1>Challenge Category:</h1>
<h4>Select an Existing Category: </h4>
<Form.Item
name="category1"
initialValue={""}
rules={[{ required: !props.state.selectCatDisabled, message: 'Please enter a challenge category' }]}
>
<Select
disabled={props.state.selectCatDisabled}
allowClear
showSearch
placeholder="Select an existing Category"
onChange={(value) => {
if (value) {
props.setState({ inputCatDisabled: true })
}
else {
props.setState({ inputCatDisabled: false })
}
}}
>
{existingCats}
</Select>
</Form.Item>
<h4>Enter a New Category</h4>
<Form.Item
name="category2"
rules={[{ required: !props.state.inputCatDisabled, message: 'Please enter a challenge category' }]}
>
<Input onChange={(e) => {
e.target.value.length > 0 ? props.setState({ selectCatDisabled: true }) : props.setState({ selectCatDisabled: false })
}} disabled={props.state.inputCatDisabled} allowClear placeholder="Enter a new challenge category" />
</Form.Item>
<Divider />
<h1>Challenge Description (Supports <a href="https://guides.github.com/features/mastering-markdown/" target="_blank" rel="noreferrer">Markdown</a> and <a href="https://github.com/rehypejs/rehype-raw" target="_blank" rel="noreferrer">HTML</a>)):</h1>
<Suspense fallback={<div style={{ height: "100%", width: "100%", display: "flex", justifyContent: "center", alignItems: "center", zIndex: 15 }}>
<Ellipsis color="#177ddc" size={120} ></Ellipsis>
</div>}>
<Form.Item
name="description"
rules={[{ required: true, message: 'Please enter a description' }]}
valuePropName={editorValue}
>
<MDEditor value={editorValue} onChange={(value) => { setEditorValue(value) }} preview="edit" />
</Form.Item>
<h3>Challenge Description Preview</h3>
<Card
type="inner"
bordered={true}
bodyStyle={{ backgroundColor: "#262626", textAlign: "center" }}
className="challengeModal"
>
<MarkdownRender>{editorValue}</MarkdownRender>
</Card>
</Suspense>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignContent: "center" }}>
<Card className="settings-card">
<h1>Challenge Points:</h1>
<Form.Item
name="points"
rules={[{ required: true, message: 'Please enter challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={0}
>
<InputNumber disabled={props.state.dynamic} min={0} max={100000} style={{ width: "30ch" }} ></InputNumber>
</Form.Item>
</Card>
<Card className="settings-card">
<h1>Maximum Number of Attempts (Set to 0 for unlimited)</h1>
<Form.Item
name="max_attempts"
rules={[{ required: true, message: 'Please enter the maximum number of attempts' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
style={{ alignText: 'center' }}
initialValue={0}
>
<InputNumber min={0} max={10000} style={{ width: "30ch" }}></InputNumber>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }}></Divider>
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="flags" >
{(fields, { add, remove }) => {
return (
<Card className="settings-card">
<h1>Flags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing flag' }, { message: "Please enter a flag that is < 1000 characters", pattern: /^.{1,1000}$/ }]}
>
<Input style={{ width: "50ch" }} placeholder="Flag" />
</Form.Item>
{fields.length > 1 ? (
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
) : null}
</Space>
))}
<Form.Item>
<Button
type="dashed"
onLoad={() => { if (fields.length < 1) add() }}
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Flag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Form.List name="tags">
{(fields, { add, remove }) => {
return (
<Card className="settings-card">
<h1>Tags</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name]}
fieldKey={[field.fieldKey]}
rules={[{ required: true, message: 'Missing tag' }]}
>
<Input placeholder="Tag" style={{ width: "50ch" }} />
</Form.Item>
<MinusCircleOutlined
className="dynamic-delete-button"
style={{ margin: '0 8px', color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Tag
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
</div>
</div>
<Divider />
<div className="settings-responsive2" style={{ display: "flex", justifyContent: "space-around" }}>
<div style={{ display: "flex", flexDirection: "column" }}>
<Form.List name="hints" >
{(fields, { add, remove }) => {
return (
<Card className="settings-card">
<h1>Hints</h1>
{fields.map(field => (
<Space key={field.key} style={{ display: 'flex', marginBottom: 8 }} align="start">
<Form.Item
{...field}
name={[field.name, "hint"]}
fieldKey={[field.fieldKey, "hint"]}
rules={[{ required: true, message: 'Missing hint' }]}
>
<Input placeholder="Hint" style={{ width: "20vw" }} />
</Form.Item>
<Form.Item
{...field}
name={[field.name, "cost"]}
fieldKey={[field.fieldKey, "cost"]}
rules={[{ required: true, message: 'Missing cost for hint' }, {
type: 'integer',
message: "Please enter a valid integer between 0-10000",
},]}
>
<InputNumber min={0} max={10000} placeholder="Cost"></InputNumber>
</Form.Item>
<MinusCircleOutlined
style={{ color: "red" }}
onClick={() => {
remove(field.name);
}}
/>
</Space>
))}
<Form.Item>
<Button
type="dashed"
onClick={() => {
add();
}}
block
style={{ width: "50ch" }}
>
<PlusOutlined /> Add Hint
</Button>
</Form.Item>
</Card>
);
}}
</Form.List>
<Card className="settings-card">
<h1>Writeup Link (Optional)</h1>
<Form.Item
name="writeup"
rules={[
{
type: 'url',
message: "Please enter a valid link",
}]}
>
<Input allowClear style={{ width: "50ch" }} placeholder="Enter a writeup link for this challenge" />
</Form.Item>
<div style={{ display: "flex", alignContent: "center" }}>
<h4 style={{ marginRight: "2ch" }}>Release Writeup Only After Completion: </h4>
<Form.Item
name="writeupComplete"
>
<Switch defaultChecked />
</Form.Item>
</div>
</Card>
<Card className="settings-card">
<h1>Visibility</h1>
<Form.Item
name="visibility"
rules={[{ required: true, message: 'Please set the challenge visibility' }]}
initialValue="false"
>
<Select style={{ width: "20ch" }}>
<Option value="false"><span style={{ color: "#d32029" }}>Hidden <EyeInvisibleOutlined /></span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Visible <EyeOutlined /></span></Option>
</Select>
</Form.Item>
</Card>
</div>
<Divider type="vertical" style={{ height: "inherit" }} />
<div style={{ display: "flex", flexDirection: "column" }}>
<Card>
<h1>Challenge Required: </h1>
<Form.Item
name="requires"
>
{/*
The issue with this is that displayRender is supposed to return an array,
but setting a value causes it to become a string and error out
*/}
<Cascader
options={finalSortedChalls}
allowClear
showSearch
placeholder="Select an existing challenge" />
</Form.Item>
<p>Locks this challenge until the provided challenge above has been solved.</p>
</Card>
<Card className="settings-card">
<h1>Dynamic Scoring</h1>
<Form.Item
name="dynamic"
rules={[{ required: props.state.dynamic, message: 'Please set whether the challenge uses dynamic scoring' }]}
initialValue="false"
>
<Select style={{ width: "20ch" }} onSelect={(option) => { option === "false" ? props.setState({ dynamic: false }) : props.setState({ dynamic: true }) }}>
<Option value="false"><span style={{ color: "#d32029" }}>Disabled</span></Option>
<Option value="true"><span style={{ color: "#49aa19" }}>Enabled</span></Option>
</Select>
</Form.Item>
<h1>Initial Points:</h1>
<Form.Item
name="initial"
rules={[{ required: props.state.dynamic, message: 'Please enter the initial challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={500}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Initial number of points when there are 0/1 solves on a challenge</p>
<h1>Minimum Points:</h1>
<Form.Item
name="minimum"
rules={[{ required: props.state.dynamic, message: 'Please enter the minimum challenge points' }, {
type: 'integer',
message: "Please enter a valid integer between 0-100000",
},]}
initialValue={100}
>
<InputNumber disabled={!props.state.dynamic} min={0} max={100000} ></InputNumber>
</Form.Item>
<p>Minimum amount of points that the challenge can decay too</p>
<h1>Solves to Minimum:</h1>
<Form.Item
name="minSolves"
rules={[{ required: props.state.dynamic, message: 'Please enter the solves to minimum' }, {
type: 'integer',
message: "Please enter a valid integer between 1-100000",
},]}
initialValue={50}
>
<InputNumber disabled={!props.state.dynamic} min={1} max={100000} ></InputNumber>
</Form.Item>
<p>Number of solves on the challenge till it decays to the minimum point.</p>
</Card>
</div>
</div>
<Form.Item>
<div style={{ display: "flex", justifyContent: "space-between", flexDirection: "row", marginTop: "3ch" }}>
<div>
<Button style={{ marginBottom: "1.5vh", marginRight: "2vw", backgroundColor: "#d4b106", borderColor: "", color: "white" }} onClick={() => { props.previewChallenge(form.getFieldsValue()) }}>Preview</Button>
<Button type="primary" htmlType="submit" className="login-form-button" style={{ marginBottom: "1.5vh" }} loading={props.editLoading}>Edit Challenge</Button>
</div>
<div>
<Button style={{ marginRight: "2vw" }} type="primary" danger onClick={() => { form.resetFields() }}>Clear</Button>
</div>
</div>
</Form.Item>
</Form>
);
}
Example #8
Source File: MatchContent.js From FRCScout2020 with MIT License | 4 votes |
render() {
const matchTypes = this.state.matchTypes.map(type => (
<Dropdown.Item
eventKey={type.key}
key={type.id}
style={{ fontFamily: 'Helvetica, Arial' }}
>
{type.name}
</Dropdown.Item>
));
if (this.state.retrieved === '') {
return null;
} else if (this.state.retrieved === 'invalid') {
return (
<div className='div-main' style={{ minHeight: this.state.heightSize }}>
<h1 className='pt-4'>Invalid match form request</h1>
</div>
);
} else {
if (this.state.formStage === 0) {
return (
<div
className='div-main'
style={{ minHeight: this.state.heightSize }}
>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<div className='justify-content-center'>
<img
alt='Logo'
src={Logo}
style={{
width: this.state.widthSize === '90%' ? '70%' : '30%',
marginTop: '20px',
marginLeft: '10px'
}}
/>
</div>
<div style={{ width: this.state.widthSize }} className='div-second'>
<div>
<span
onClick={() => this.changeStage(0)}
className='dot'
style={{
borderColor:
this.state.formStage === 0 ? 'black' : 'transparent',
backgroundColor: this.state.validStage0
? '#57c24f'
: '#d4463b'
}}
>
1
</span>
<span
onClick={() => this.changeStage(1)}
className='dot'
style={{
borderColor:
this.state.formStage === 1 ? 'black' : 'transparent',
backgroundColor: this.state.validStage1
? '#57c24f'
: '#d4463b'
}}
>
2
</span>
<span
onClick={() => this.changeStage(2)}
className='dot'
style={{
borderColor:
this.state.formStage === 2 ? 'black' : 'transparent',
backgroundColor: this.state.validStage2
? '#57c24f'
: '#d4463b'
}}
>
3
</span>
<span
onClick={() => this.changeStage(3)}
className='dot'
style={{
borderColor:
this.state.formStage === 3 ? 'black' : 'transparent',
backgroundColor: this.state.validStage3
? '#57c24f'
: '#d4463b'
}}
>
4
</span>
<span
onClick={() => this.changeStage(4)}
className='dot'
style={{
borderColor:
this.state.formStage === 4 ? 'black' : 'transparent',
backgroundColor: this.state.validStage4
? '#57c24f'
: '#d4463b'
}}
>
5
</span>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-2'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Competition: {this.state.competition}
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-2'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Scouter: {this.state.scout}
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Match Number:
</Form.Label>
</Form.Group>
<div style={{ marginLeft: '-6%' }}>
<Dropdown
style={{
marginBottom: '10px',
display: 'inline-block'
}}
focusFirstItemOnShow={false}
onSelect={this.changeMatchType}
>
<Dropdown.Toggle
style={{
fontFamily: 'Helvetica, Arial',
textAlign: 'center'
}}
size='xs'
variant='success'
id='dropdown-basic'
>
{this.state.matchTypeLabel}
</Dropdown.Toggle>
<Dropdown.Menu style={{ minWidth: '3%' }}>
{matchTypes}
</Dropdown.Menu>
</Dropdown>
<Form.Control
value={this.state.matchNum1}
autoComplete='off'
type='number'
max={200}
min={1}
placeholder='Match Number'
onChange={this.handleMatchNum1}
isValid={
this.state.validatedStage0 && this.state.matchNum1 !== ''
}
isInvalid={
this.state.validatedStage0 && this.state.matchNum1 === ''
}
className='mb-1'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial',
marginLeft: '2%',
display: 'inline-block',
width: this.state.matchTypeKey === 'qm' ? '50%' : '25%'
}}
/>
{this.state.matchTypeKey !== 'qm' ? (
<React.Fragment>
<span>-</span>
<Form.Control
value={this.state.matchNum2}
autoComplete='off'
type='number'
max={200}
min={1}
placeholder='Match Number'
onChange={this.handleMatchNum2}
isValid={
this.state.validatedStage0 &&
this.state.matchTypeKey !== 'qm' &&
this.state.matchNum2 !== ''
}
isInvalid={
this.state.validatedStage0 &&
this.state.matchTypeKey !== 'qm' &&
this.state.matchNum2 === ''
}
className='mb-1'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial',
display: 'inline-block',
width: '25%'
}}
/>
</React.Fragment>
) : null}
</div>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Alliance Station:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Control
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
className='mb-1'
as='select'
onChange={this.handleStationChange}
value={this.state.allianceStation}
>
<option>Red Station 1</option>
<option>Red Station 2</option>
<option>Red Station 3</option>
<option>Blue Station 1</option>
<option>Blue Station 2</option>
<option>Blue Station 3</option>
</Form.Control>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Team Number:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Check
checked={!this.state.autoTeam}
onChange={this.handleModeSwitch}
type='switch'
label={this.state.autoTeam ? 'Automatic' : 'Manual'}
id='switchMode'
style={{ fontFamily: 'Helvetica, Arial', fontSize: '110%' }}
/>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
{this.state.autoTeam ? (
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
onChange={this.checkStage0}
>
{this.state.teamNum}
</Form.Label>
) : (
<Form.Control
value={this.state.teamNum}
autoComplete='off'
type='number'
max={9999}
min={1}
placeholder='Team Number'
onChange={this.handleTeamNum}
isValid={
this.state.validatedStage0 && this.state.teamNum !== ''
}
isInvalid={
this.state.validatedStage0 && this.state.teamNum === ''
}
className='mb-1'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
)}
</Form.Group>
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
</div>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginRight: '8%'
}}
onClick={this.handleStage0Increment}
className='btn-lg'
>
Next
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '8%'
}}
onClick={this.handleSubmit}
className='btn-lg'
>
Submit
</Button>
</div>
</div>
);
} else if (this.state.formStage === 1) {
return (
<div
className='div-main'
style={{ minHeight: this.state.heightSize }}
>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<div className='justify-content-center'>
<img
alt='Logo'
src={Logo}
style={{
width: this.state.widthSize === '90%' ? '70%' : '30%',
marginTop: '20px',
marginLeft: '10px'
}}
/>
</div>
<div style={{ width: this.state.widthSize }} className='div-second'>
<div>
<span
onClick={() => this.changeStage(0)}
className='dot'
style={{
borderColor:
this.state.formStage === 0 ? 'black' : 'transparent',
backgroundColor: this.state.validStage0
? '#57c24f'
: '#d4463b'
}}
>
1
</span>
<span
onClick={() => this.changeStage(1)}
className='dot'
style={{
borderColor:
this.state.formStage === 1 ? 'black' : 'transparent',
backgroundColor: this.state.validStage1
? '#57c24f'
: '#d4463b'
}}
>
2
</span>
<span
onClick={() => this.changeStage(2)}
className='dot'
style={{
borderColor:
this.state.formStage === 2 ? 'black' : 'transparent',
backgroundColor: this.state.validStage2
? '#57c24f'
: '#d4463b'
}}
>
3
</span>
<span
onClick={() => this.changeStage(3)}
className='dot'
style={{
borderColor:
this.state.formStage === 3 ? 'black' : 'transparent',
backgroundColor: this.state.validStage3
? '#57c24f'
: '#d4463b'
}}
>
4
</span>
<span
onClick={() => this.changeStage(4)}
className='dot'
style={{
borderColor:
this.state.formStage === 4 ? 'black' : 'transparent',
backgroundColor: this.state.validStage4
? '#57c24f'
: '#d4463b'
}}
>
5
</span>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
{'Pre-Loaded Power Cells: ' + this.state.autoPowerCells}
</Form.Label>
</Form.Group>
<input
min={0}
max={3}
step={1}
className='slidercell'
value={this.state.autoPowerCells}
onChange={this.handleSliderAutoCells}
type='range'
id='autoPowerCellSlider'
/>
</div>
<div className='div-form'>
<img
alt='Guide'
src={AllianceStation}
style={{
width: '100%',
marginTop: '20px',
marginBottom: '20px'
}}
/>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Starting Position:
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
className='mb-3'
>
{this.state.startingPositions.map(position => (
<Form.Check
style={{ fontFamily: 'Helvetica, Arial' }}
isInvalid={
this.state.validatedStage1 &&
this.state.startingPosition === ''
}
isValid={
this.state.validatedStage1 &&
this.state.startingPosition !== ''
}
inline
custom
label={position.label}
type='radio'
onChange={() => this.handlePositionChange(position)}
checked={this.state.startingPosition === position.label}
id={'position' + position.id}
key={'position' + position.id}
/>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Did the robot cross the initiation line?
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
className='mb-3'
>
{this.state.crossLineOptions.map(option => (
<Form.Check
style={{ fontFamily: 'Helvetica, Arial' }}
isInvalid={
this.state.validatedStage1 &&
this.state.crossLine === ''
}
isValid={
this.state.validatedStage1 &&
this.state.crossLine !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleCrossLineChange(option)}
checked={this.state.crossLine === option.label}
id={'cross' + option.id}
key={'cross' + option.id}
/>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Power Cells Scored in Auto:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '100%' }}>
{this.state.autoScored.map(goal => (
<Form.Row
className='mb-2 justify-content-center'
key={'autoGoalRow' + goal.id}
>
<Counter
minWidth='170px'
count={goal.value}
margin={'3px 0px 0px 0px'}
colon=': '
onIncrement={() => this.handleAutoGoalIncrement(goal)}
onDecrement={() => this.handleAutoGoalDecrement(goal)}
label={goal.label}
disabled={false}
dynamic={goal.value === 0}
size='xs'
marginRight='0px'
id={'autoGoal' + goal.id}
key={'autoGoal' + goal.id}
/>
</Form.Row>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Auto Comments:
</Form.Label>
</Form.Group>
<div
style={{
display: 'inline-block',
width: '80%',
marginTop: '5px'
}}
>
<Form.Group>
<Form.Control
value={this.state.autoComments}
as='textarea'
type='text'
placeholder='Comments concerning auto'
onChange={this.handleAutoComment}
rows='3'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
</div>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginRight: '4%'
}}
onClick={this.handleStage1Decrement}
className='btn-lg'
>
Back
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '4%',
marginRight: '4%'
}}
onClick={this.handleStage1Increment}
className='btn-lg'
>
Next
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '4%'
}}
onClick={this.handleSubmit}
className='btn-lg'
>
Submit
</Button>
</div>
</div>
);
} else if (this.state.formStage === 2) {
return (
<div
className='div-main'
style={{ minHeight: this.state.heightSize }}
>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<div className='justify-content-center'>
<img
alt='Logo'
src={Logo}
style={{
width: this.state.widthSize === '90%' ? '70%' : '30%',
marginTop: '20px',
marginLeft: '10px'
}}
/>
</div>
<div style={{ width: this.state.widthSize }} className='div-second'>
<div>
<span
onClick={() => this.changeStage(0)}
className='dot'
style={{
borderColor:
this.state.formStage === 0 ? 'black' : 'transparent',
backgroundColor: this.state.validStage0
? '#57c24f'
: '#d4463b'
}}
>
1
</span>
<span
onClick={() => this.changeStage(1)}
className='dot'
style={{
borderColor:
this.state.formStage === 1 ? 'black' : 'transparent',
backgroundColor: this.state.validStage1
? '#57c24f'
: '#d4463b'
}}
>
2
</span>
<span
onClick={() => this.changeStage(2)}
className='dot'
style={{
borderColor:
this.state.formStage === 2 ? 'black' : 'transparent',
backgroundColor: this.state.validStage2
? '#57c24f'
: '#d4463b'
}}
>
3
</span>
<span
onClick={() => this.changeStage(3)}
className='dot'
style={{
borderColor:
this.state.formStage === 3 ? 'black' : 'transparent',
backgroundColor: this.state.validStage3
? '#57c24f'
: '#d4463b'
}}
>
4
</span>
<span
onClick={() => this.changeStage(4)}
className='dot'
style={{
borderColor:
this.state.formStage === 4 ? 'black' : 'transparent',
backgroundColor: this.state.validStage4
? '#57c24f'
: '#d4463b'
}}
>
5
</span>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Power Cells Scored in Teleop:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '100%' }}>
{this.state.teleopScored.map(goal => (
<Form.Row
className='mb-2 justify-content-center'
key={'teleopGoalRow' + goal.id}
>
<Counter
minWidth='170px'
count={goal.value}
margin={'3px 0px 0px 0px'}
colon=': '
onIncrement={() => this.handleTeleopGoalIncrement(goal)}
onDecrement={() => this.handleTeleopGoalDecrement(goal)}
label={goal.label}
disabled={false}
dynamic={goal.value === 0}
size='xs'
marginRight='0px'
id={'teleopGoal' + goal.id}
key={'teleopGoal' + goal.id}
/>
</Form.Row>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Rotation Control:
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '90%'
}}
>
Last Rotation Time: {this.state.oldRotationTimer}
</Form.Label>
</Form.Group>
<StopWatch
value={this.state.rotationTimer}
parentCallback={this.handleRotationControlTimer}
/>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
className='mb-3'
>
{this.state.rotationOptions.map(option => (
<Form.Row key={'rotationRow' + option.id} className='mb-2'>
<Form.Check
style={{
fontFamily: 'Helvetica, Arial',
textAlign: 'left'
}}
isInvalid={
this.state.validatedStage2 &&
this.state.rotationControl === ''
}
isValid={
this.state.validatedStage2 &&
this.state.rotationControl !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleRotationControl(option)}
checked={this.state.rotationControl === option.label}
id={'rotationOption' + option.id}
key={'rotationOption' + option.id}
/>
</Form.Row>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Position Control:
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '90%'
}}
>
Last Position Time: {this.state.oldPositionTimer}
</Form.Label>
</Form.Group>
<StopWatch
value={this.state.positionTimer}
parentCallback={this.handlePositionControlTimer}
/>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
className='mb-3'
>
{this.state.positionOptions.map(option => (
<Form.Row key={'positionRow' + option.id} className='mb-2'>
<Form.Check
style={{
fontFamily: 'Helvetica, Arial',
textAlign: 'left'
}}
isInvalid={
this.state.validatedStage2 &&
this.state.positionControl === ''
}
isValid={
this.state.validatedStage2 &&
this.state.positionControl !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handlePositionControl(option)}
checked={this.state.positionControl === option.label}
id={'positionOption' + option.id}
key={'positionOption' + option.id}
/>
</Form.Row>
))}
</Form.Group>
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
</div>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginRight: '4%'
}}
onClick={this.handleStage2Decrement}
className='btn-lg'
>
Back
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '4%',
marginRight: '4%'
}}
onClick={this.handleStage2Increment}
className='btn-lg'
>
Next
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '4%'
}}
onClick={this.handleSubmit}
className='btn-lg'
>
Submit
</Button>
</div>
</div>
);
} else if (this.state.formStage === 3) {
return (
<div
className='div-main'
style={{ minHeight: this.state.heightSize }}
>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<div className='justify-content-center'>
<img
alt='Logo'
src={Logo}
style={{
width: this.state.widthSize === '90%' ? '70%' : '30%',
marginTop: '20px',
marginLeft: '10px'
}}
/>
</div>
<div style={{ width: this.state.widthSize }} className='div-second'>
<div>
<span
onClick={() => this.changeStage(0)}
className='dot'
style={{
borderColor:
this.state.formStage === 0 ? 'black' : 'transparent',
backgroundColor: this.state.validStage0
? '#57c24f'
: '#d4463b'
}}
>
1
</span>
<span
onClick={() => this.changeStage(1)}
className='dot'
style={{
borderColor:
this.state.formStage === 1 ? 'black' : 'transparent',
backgroundColor: this.state.validStage1
? '#57c24f'
: '#d4463b'
}}
>
2
</span>
<span
onClick={() => this.changeStage(2)}
className='dot'
style={{
borderColor:
this.state.formStage === 2 ? 'black' : 'transparent',
backgroundColor: this.state.validStage2
? '#57c24f'
: '#d4463b'
}}
>
3
</span>
<span
onClick={() => this.changeStage(3)}
className='dot'
style={{
borderColor:
this.state.formStage === 3 ? 'black' : 'transparent',
backgroundColor: this.state.validStage3
? '#57c24f'
: '#d4463b'
}}
>
4
</span>
<span
onClick={() => this.changeStage(4)}
className='dot'
style={{
borderColor:
this.state.formStage === 4 ? 'black' : 'transparent',
backgroundColor: this.state.validStage4
? '#57c24f'
: '#d4463b'
}}
>
5
</span>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Did the robot hang or park?
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '90%'
}}
>
Last End Game Time: {this.state.oldEndGameTimer}
</Form.Label>
</Form.Group>
<StopWatch
value={this.state.endGameTimer}
parentCallback={this.handleEndGameTimer}
/>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
className='mb-3'
>
{this.state.endGameOptions.map(option => (
<Form.Row key={'endGameRow' + option.id} className='mb-2'>
<Form.Check
style={{
fontFamily: 'Helvetica, Arial',
textAlign: 'left'
}}
isInvalid={
this.state.validatedStage3 &&
this.state.endGame === ''
}
isValid={
this.state.validatedStage3 &&
this.state.endGame !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleEndGame(option)}
checked={this.state.endGame === option.label}
id={'endGameOption' + option.id}
key={'endGameOption' + option.id}
/>
</Form.Row>
))}
</Form.Group>
{this.state.endGame !== 'Hang' ? (
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
) : null}
</div>
{this.state.endGame === 'Hang' ? (
<React.Fragment>
<div className='div-form'>
<Form.Group
style={{ width: '80%', marginLeft: '1%' }}
as={Row}
>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
How did the robot hang?
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
className='mb-3'
>
{this.state.climbOptions.map(option => (
<Form.Row key={'climbRow' + option.id} className='mb-2'>
<Form.Check
style={{
fontFamily: 'Helvetica, Arial',
textAlign: 'left'
}}
isInvalid={
this.state.validatedStage3 &&
this.state.climb === ''
}
isValid={
this.state.validatedStage3 &&
this.state.climb !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleClimb(option)}
checked={this.state.climb === option.label}
id={'climbOption' + option.id}
key={'climbOption' + option.id}
/>
</Form.Row>
))}
</Form.Group>
{this.state.climb !== '' &&
this.state.climb !== 'Assisted Climb' ? (
<React.Fragment>
<Form.Group
style={{ width: '80%', marginLeft: '1%' }}
as={Row}
>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Where did it hang?
</Form.Label>
</Form.Group>
<div>{this.state.levelPosition}</div>
<input
min={0}
max={2}
step={0.125}
className='sliderlevel'
value={this.state.levelPosition}
onChange={this.handleLevelChange}
type='range'
id='autoPowerCellSlider'
/>
</React.Fragment>
) : null}
</div>
<div className='div-form'>
<Form.Group
style={{ width: '80%', marginLeft: '1%' }}
as={Row}
>
<Form.Label
className='mb-0'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
How did the robot level?
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
className='mb-3'
>
{this.state.levelOptions.map(option => (
<Form.Row key={'levelRow' + option.id} className='mb-2'>
<Form.Check
style={{
fontFamily: 'Helvetica, Arial',
textAlign: 'left'
}}
isInvalid={
this.state.validatedStage3 &&
this.state.level === ''
}
isValid={
this.state.validatedStage3 &&
this.state.level !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleLevel(option)}
checked={this.state.level === option.label}
id={'levelOption' + option.id}
key={'levelOption' + option.id}
/>
</Form.Row>
))}
</Form.Group>
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
</div>
</React.Fragment>
) : null}
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginRight: '4%'
}}
onClick={this.handleStage3Decrement}
className='btn-lg'
>
Back
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '4%',
marginRight: '4%'
}}
onClick={this.handleStage3Increment}
className='btn-lg'
>
Next
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '4%'
}}
onClick={this.handleSubmit}
className='btn-lg'
>
Submit
</Button>
</div>
</div>
);
} else if (this.state.formStage === 4) {
return (
<div
className='div-main'
style={{ minHeight: this.state.heightSize }}
>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<div className='justify-content-center'>
<img
alt='Logo'
src={Logo}
style={{
width: this.state.widthSize === '90%' ? '70%' : '30%',
marginTop: '20px',
marginLeft: '10px'
}}
/>
</div>
<div style={{ width: this.state.widthSize }} className='div-second'>
<div>
<span
onClick={() => this.changeStage(0)}
className='dot'
style={{
borderColor:
this.state.formStage === 0 ? 'black' : 'transparent',
backgroundColor: this.state.validStage0
? '#57c24f'
: '#d4463b'
}}
>
1
</span>
<span
onClick={() => this.changeStage(1)}
className='dot'
style={{
borderColor:
this.state.formStage === 1 ? 'black' : 'transparent',
backgroundColor: this.state.validStage1
? '#57c24f'
: '#d4463b'
}}
>
2
</span>
<span
onClick={() => this.changeStage(2)}
className='dot'
style={{
borderColor:
this.state.formStage === 2 ? 'black' : 'transparent',
backgroundColor: this.state.validStage2
? '#57c24f'
: '#d4463b'
}}
>
3
</span>
<span
onClick={() => this.changeStage(3)}
className='dot'
style={{
borderColor:
this.state.formStage === 3 ? 'black' : 'transparent',
backgroundColor: this.state.validStage3
? '#57c24f'
: '#d4463b'
}}
>
4
</span>
<span
onClick={() => this.changeStage(4)}
className='dot'
style={{
borderColor:
this.state.formStage === 4 ? 'black' : 'transparent',
backgroundColor: this.state.validStage4
? '#57c24f'
: '#d4463b'
}}
>
5
</span>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Did the robot lose communication at any time?
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
className='mb-3'
>
{this.state.communicationOptions.map(option => (
<Form.Check
style={{ fontFamily: 'Helvetica, Arial' }}
isInvalid={
this.state.validatedStage4 &&
this.state.communication === ''
}
isValid={
this.state.validatedStage4 &&
this.state.communication !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleCommunication(option)}
checked={this.state.communication === option.label}
id={'communication' + option.id}
key={'communication' + option.id}
/>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Did the robot break during the match?
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
as={Row}
className='mb-3'
>
{this.state.breakOptions.map(option => (
<Form.Check
style={{ fontFamily: 'Helvetica, Arial' }}
isInvalid={
this.state.validatedStage4 && this.state.break === ''
}
isValid={
this.state.validatedStage4 && this.state.break !== ''
}
inline
custom
label={option.label}
type='radio'
onChange={() => this.handleBreak(option)}
checked={this.state.break === option.label}
id={'break' + option.id}
key={'break' + option.id}
/>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Penalties/Yellow Cards/Red Cards:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '100%' }}>
{this.state.negatives.map(negative => (
<Form.Row
className='mb-2 justify-content-center'
key={'negativeRow' + negative.id}
>
{negative.label === 'Penalties' ? (
<PenaltyCounter
// maxWidth='1000px'
minWidth='170px'
count={negative.value}
margin={'3px 0px 0px 0px'}
colon=': '
onIncrement={() =>
this.handleNegativeIncrement(negative)
}
onDecrement={() =>
this.handleNegativeDecrement(negative)
}
onIncrementLarger={() =>
this.handleNegativeLargerIncrement(negative)
}
onDecrementLarger={() =>
this.handleNegativeLargerDecrement(negative)
}
label={negative.label}
disabled={false}
dynamic={negative.value === 0}
size='xs'
marginRight='0px'
id={'negative' + negative.id}
key={'negative' + negative.id}
/>
) : (
<Counter
minWidth='170px'
count={negative.value}
margin={'3px 0px 0px 0px'}
colon=': '
onIncrement={() =>
this.handleNegativeIncrement(negative)
}
onDecrement={() =>
this.handleNegativeDecrement(negative)
}
label={negative.label}
disabled={false}
dynamic={negative.value === 0}
size='xs'
marginRight='0px'
id={'negative' + negative.id}
key={'negative' + negative.id}
/>
)}
</Form.Row>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%',
textAlign: 'left'
}}
>
Ending Comments:
</Form.Label>
</Form.Group>
<div
style={{
display: 'inline-block',
width: '80%',
marginTop: '5px'
}}
>
<Form.Group>
<Form.Control
value={this.state.reflectionComments}
as='textarea'
type='text'
placeholder='Any ending comments'
onChange={this.handleReflectionComment}
rows='3'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
</div>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginRight: '8%'
}}
onClick={this.handleStage4Decrement}
className='btn-lg'
>
Back
</Button>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black',
marginLeft: '8%'
}}
onClick={this.handleSubmit}
className='btn-lg'
>
Submit
</Button>
</div>
</div>
);
}
}
}
Example #9
Source File: PitContent.js From FRCScout2020 with MIT License | 4 votes |
render() {
if (this.state.retrieved === '') {
return null;
} else if (this.state.retrieved === 'invalid') {
return (
<div className='div-main' style={{ minHeight: this.state.heightSize }}>
<h1 className='pt-4'>Invalid pit form request</h1>
</div>
);
} else {
if (this.state.cameraActivated) {
return (
<div>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<Camera
idealResolution={{
width: 1600,
height: 1200
}}
imageType={IMAGE_TYPES.JPG}
isFullscreen={false}
isMaxResolution={false}
isImageMirror={false}
// imageCompression={1}
// sizeFactor={0.1}
idealFacingMode={FACING_MODES.ENVIRONMENT}
onTakePhotoAnimationDone={dataUri => {
this.handleTakePhoto(dataUri);
}}
/>
</div>
);
} else {
return (
<div className='div-main'>
<Prompt
when={!this.state.submitting}
message='Are you sure you want to leave?'
/>
<div className='justify-content-center'>
<img
alt='Logo'
src={Logo}
style={{
width: this.state.widthSize === '90%' ? '70%' : '30%',
marginTop: '20px',
marginLeft: '10px'
}}
/>
</div>
<div style={{ width: this.state.widthSize }} className='div-second'>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-2'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Competition: {this.state.competition}
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-2'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Team Number: {this.state.teamNumber}
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '1%' }}
as={Row}
>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Team Name: {this.state.teamName}
</Form.Label>
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Group:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Control
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
className='mb-1'
as='select'
onChange={this.handleGroupChange}
value={this.state.group}
>
<option>Group 1 Red Alliance</option>
<option>Group 2 Red Alliance</option>
<option>Group 3 Red Alliance</option>
<option>Group 1 Blue Alliance</option>
<option>Group 2 Blue Alliance</option>
<option>Group 3 Blue Alliance</option>
</Form.Control>
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Weight:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Control
value={this.state.weight}
autoComplete='off'
type='number'
max={500}
min={0}
placeholder='Weight (lbs)'
onChange={this.checkWeight}
isValid={
this.state.validated &&
this.state.weight !== '' &&
!this.state.markForFollowUp
}
isInvalid={
this.state.validated &&
this.state.weight === '' &&
!this.state.markForFollowUp
}
className='mb-1'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Starting Height:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Control
value={this.state.height}
autoComplete='off'
type='number'
max={100}
min={0}
isValid={
this.state.validated &&
this.state.height !== '' &&
!this.state.markForFollowUp
}
isInvalid={
this.state.validated &&
this.state.height === '' &&
!this.state.markForFollowUp
}
placeholder='Height (inches)'
onChange={this.checkHeight}
className='mb-1'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Drive Train:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Type:
</Form.Label>
</Form.Group>
<Form.Group
style={{
width: '100%',
marginLeft: '3%',
fontFamily: 'Helvetica, Arial'
}}
as={Row}
className='mb-3'
>
{this.state.driveTrains.map(driveTrain => (
<Form.Check
isValid={
this.state.validated &&
!this.state.driveTrain !== '' &&
!this.state.markForFollowUp
}
isInvalid={
this.state.validated &&
this.state.driveTrain === '' &&
!this.state.markForFollowUp
}
style={{ fontFamily: 'Helvetica, Arial' }}
inline
custom
onChange={() => this.handleDriveChange(driveTrain)}
label={driveTrain.label}
type='radio'
autoComplete='off'
checked={this.state.driveTrain === driveTrain.label}
id={'driveTrain' + driveTrain.id}
key={'driveTrain' + driveTrain.id}
/>
))}
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Motors:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '100%' }}>
{this.state.driveTrainMotors.map(motor => (
<Form.Row
className='mb-2 justify-content-center'
key={'driveTrainMotorRow' + motor.id}
>
<Counter
minWidth='170px'
count={motor.value}
margin={
motor.label !== 'Other'
? '7px 0px 0px 0px'
: '3px 0px 0px 0px'
}
colon=': '
onIncrement={() => this.handleMotorIncrement(motor)}
onDecrement={() => this.handleMotorDecrement(motor)}
label={
motor.label !== 'Other' ? (
motor.label
) : (
<span
style={{
fontFamily: 'Helvetica, Arial',
maxWidth: '170px',
width: '100px',
display: 'inline-block',
marginLeft: '10px'
}}
>
<Form.Control
autoComplete='off'
type='text'
placeholder={motor.label}
value={motor.motorName}
onChange={event =>
this.handleOtherMotor(event, motor)
}
style={{
fontFamily: 'Helvetica, Arial',
textJustify: 'center',
textAlign: 'center',
fontSize: '90%',
backgroundImage: 'none',
background: 'none',
backgroundSize: '0px'
}}
/>
</span>
)
}
disabled={false}
dynamic={motor.value === 0}
size='xs'
marginRight='0px'
id={'driveTrainMotor' + motor.id}
key={'driveTrainMotor' + motor.id}
/>
</Form.Row>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Wheels:
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '2%' }}
className='mt-4'
>
{this.state.wheels.map(wheel => (
<Form.Row
key={'driveTrainWheelRow' + wheel.id}
className='mb-2'
>
<Col xs='4' style={{ textAlign: 'left' }}>
<Form.Check
isInvalid={
this.state.validated &&
!this.state.driveTrainWheelsValid &&
!this.state.markForFollowUp
}
isValid={
this.state.validated &&
this.state.driveTrainWheelsValid &&
!this.state.markForFollowUp
}
onChange={() => this.handleWheelClick(wheel)}
custom
style={{
fontSize: '90%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
checked={wheel.value}
id={'driveTrainWheel' + wheel.id}
key={'driveTrainWheel' + wheel.id}
label={
wheel.label !== 'Other' ? (
wheel.label
) : (
<Form.Control
autoComplete='off'
isInvalid={
this.state.validated &&
wheel.value &&
wheel.wheelName === '' &&
!this.state.markForFollowUp
}
isValid={
this.state.validated &&
wheel.value &&
wheel.wheelName !== '' &&
!this.state.markForFollowUp
}
type='text'
placeholder={wheel.label}
disabled={!wheel.value}
onChange={event =>
this.handleOtherWheel(event, wheel)
}
value={wheel.wheelName}
style={{
fontFamily: 'Helvetica, Arial',
maxWidth: '80px',
fontSize: '90%',
backgroundColor: 'transparent'
}}
/>
)
}
/>
</Col>
<Col xs='3' style={{ textAlign: 'center' }}>
<Form.Control
autoComplete='off'
type='number'
max={12}
min={1}
placeholder='Size (in)'
isInvalid={
this.state.validated &&
wheel.value &&
wheel.size === '' &&
!this.state.markForFollowUp
}
isValid={
this.state.validated &&
wheel.value &&
wheel.size !== '' &&
!this.state.markForFollowUp
}
disabled={!wheel.value}
onChange={event => this.checkWheelSize(event, wheel)}
value={wheel.size}
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '65%',
textAlign: 'center',
marginLeft: '10px',
backgroundColor: 'transparent'
}}
/>
</Col>
<Col>
<Counter
count={wheel.count}
onDecrement={() => this.handleWheelDecrement(wheel)}
onIncrement={() => this.handleWheelIncrement(wheel)}
colon=''
label=''
minWidth='24px'
maxWidth='24px'
margin='0% 0% 0% 20%'
disabled={!wheel.value}
dynamic={!wheel.value}
size='sm'
marginRight='0px'
key={'driveTrainWheelCounter' + wheel.id}
/>
</Col>
</Form.Row>
))}
</Form.Group>
<div
style={{
display: 'inline-block',
width: '80%',
marginTop: '5px'
}}
>
<Form.Group>
<Form.Control
value={this.state.driveComments}
as='textarea'
type='text'
placeholder='Any additional comments about drive train'
onChange={this.handleDriveComment}
rows='3'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Autonomous:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Programming Language:
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '3%' }}
as={Row}
className='mb-3'
>
{this.state.programmingLanguages.map(language => (
<Form.Check
style={{ fontFamily: 'Helvetica, Arial' }}
isInvalid={
this.state.validated &&
this.state.programmingLanguage === '' &&
!this.state.markForFollowUp
}
isValid={
this.state.validated &&
this.state.programmingLanguage !== '' &&
!this.state.markForFollowUp
}
inline
custom
label={language.label}
type='radio'
onChange={() => this.handleProgrammingChange(language)}
checked={
this.state.programmingLanguage === language.label
}
id={'language' + language.id}
key={'language' + language.id}
/>
))}
</Form.Group>
<Form.Group style={{ width: '80%', marginLeft: '2%' }} as={Row}>
<Form.Label
className='mb-1'
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '100%'
}}
>
Starting Position:
</Form.Label>
</Form.Group>
<Form.Group
style={{ width: '100%', marginLeft: '3%' }}
as={Row}
className='mb-3'
>
{this.state.startingPositions.map(position => (
<Form.Check
style={{ fontFamily: 'Helvetica, Arial' }}
isInvalid={
this.state.validated &&
this.state.startingPosition === '' &&
!this.state.markForFollowUp
}
isValid={
this.state.validated &&
this.state.startingPosition !== '' &&
!this.state.markForFollowUp
}
inline
custom
label={position.label}
type='radio'
onChange={() => this.handlePositionChange(position)}
checked={this.state.startingPosition === position.label}
id={'position' + position.id}
key={'position' + position.id}
/>
))}
</Form.Group>
<div
style={{
display: 'inline-block',
width: '80%',
marginTop: '5px'
}}
>
<Form.Group>
<Form.Control
value={this.state.autoComments}
as='textarea'
type='text'
onChange={this.handleAutoComment}
placeholder='What is their usual strategy in auto?'
className='mb-0'
rows='3'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Abilities:
</Form.Label>
</Form.Group>
<Form.Group style={{ width: '100%', marginLeft: '2%' }}>
{this.state.mechanisms.map(mechanism => (
<Form.Row
key={'mechanismRow' + mechanism.id}
className='mb-2'
>
<Form.Check
isInvalid={
this.state.validated &&
!this.state.mechanismsValid &&
!this.state.markForFollowUp
}
isValid={
this.state.validated &&
this.state.mechanismsValid &&
!this.state.markForFollowUp
}
onChange={() => this.handleMechanismClick(mechanism)}
custom
style={{
fontSize: '90%',
fontFamily: 'Helvetica, Arial'
}}
label={mechanism.label}
type='checkbox'
checked={mechanism.value}
id={'mechanism' + mechanism.id}
key={'mechanism' + mechanism.id}
/>
</Form.Row>
))}
</Form.Group>
</div>
<div className='div-form'>
<Form.Group style={{ width: '80%', marginLeft: '1%' }} as={Row}>
<Form.Label
style={{
fontFamily: 'Helvetica, Arial',
fontSize: '110%'
}}
>
Closing:
</Form.Label>
</Form.Group>
<div
style={{
display: 'inline-block',
width: '80%',
marginTop: '5px'
}}
>
<Form.Group>
<Form.Control
value={this.state.workingOnComments}
as='textarea'
type='text'
placeholder='Is there anything that the team is still working on?'
onChange={this.handleWorkingOnComment}
className='mb-0'
rows='3'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
<div
style={{
display: 'inline-block',
width: '80%',
marginTop: '5px'
}}
>
<Form.Group>
<Form.Control
value={this.state.closingComments}
as='textarea'
type='text'
placeholder='Additional comments'
onChange={this.handleClosingComment}
className='mb-0'
rows='2'
style={{
background: 'none',
fontFamily: 'Helvetica, Arial'
}}
/>
</Form.Group>
</div>
<div>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow:
'-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black'
}}
onClick={this.handleCameraActivation}
className='btn-xs mb-3'
>
{this.state.cameraActivated
? 'Close Camera'
: 'Open Camera'}
</Button>
</div>
{this.state.dataUri === '' ? null : (
<ImagePreview
dataUri={this.state.dataUri}
isFullscreen={false}
/>
)}
<Form.Check
onChange={this.handleFollowUp}
checked={this.state.markForFollowUp}
custom
style={{
fontSize: '100%',
fontFamily: 'Helvetica, Arial'
}}
type='checkbox'
label='Mark for follow up'
id='followUp'
/>
</div>
<Button
variant='success'
type='btn'
style={{
fontFamily: 'Helvetica, Arial',
boxShadow: '-3px 3px black, -2px 2px black, -1px 1px black',
border: '1px solid black'
}}
onClick={this.handleSumbit}
className='btn-lg'
>
Submit form
</Button>
</div>
</div>
);
}
}
}
Example #10
Source File: MenuSetting.js From choerodon-front-base with Apache License 2.0 | 4 votes |
render() {
const { intl, AppState } = this.props;
const menuType = this.props.AppState.currentMenuType.type;
const { menuGroup, type: typeState, selectType, sidebar, submitting, loading } = this.state;
// Prompt 只能传单个字符串,所以用 STRING_DEVIDER 对 title 和 msg 进行了分离
const promptMsg = intl.formatMessage({ id: `${intlPrefix}.prompt.inform.title` }) + STRING_DEVIDER + intl.formatMessage({ id: `${intlPrefix}.prompt.inform.message` });
const columns = [{
title: <FormattedMessage id={`${intlPrefix}.directory`} />,
dataIndex: 'name',
key: 'name',
width: '25%',
render: (text, { type, default: dft }) => {
let icon = '';
if (type === 'menu_item') {
icon = 'dehaze';
} else if (!dft) {
icon = 'folder';
} else if (type === 'tab') {
icon = 'tab';
} else {
icon = 'custom_Directory';
}
return (
<MouseOverWrapper text={text} width={0.2} className="c7n-iam-menusetting-name">
<Icon type={icon} style={{ verticalAlign: 'text-bottom' }} /> {text}
</MouseOverWrapper>
);
},
onCell: this.handleCell,
}, {
title: '',
width: '50px',
key: 'action',
align: 'right',
render: (text, record) => {
const { type, default: dft, subMenus } = record;
const actionDatas = [];
if (type === 'menu_item' || type === 'tab') {
actionDatas.push({
text: '查看详情',
action: this.detailMenu.bind(this, record),
});
} else if (!dft) {
const canDel = canDelete(record);
actionDatas.push({
text: '修改目录',
action: this.changeMenu.bind(this, record),
});
if (canDel) {
actionDatas.push({
text: '删除目录',
action: this.handleDelete.bind(this, record),
});
}
}
if (actionDatas.length === 0 || record.subMenus) {
return null;
}
return (
<Action data={actionDatas} />
);
},
}, {
title: <FormattedMessage id={`${intlPrefix}.icon`} />,
dataIndex: 'icon',
key: 'icon',
width: '10%',
className: 'menu-table-icon',
render: text => (
<MouseOverWrapper text={text} width={0.8}>
<Icon type={text} style={{ fontSize: 18 }} />
</MouseOverWrapper>
),
}, {
title: <FormattedMessage id={`${intlPrefix}.code`} />,
dataIndex: 'code',
key: 'code',
className: 'menu-table-icon',
render: text => (
<MouseOverWrapper text={text} width={0.3}>
{text}
</MouseOverWrapper>
),
}, {
title: <FormattedMessage id={`${intlPrefix}.type`} />,
dataIndex: 'default',
key: 'default',
className: 'menu-table-icon',
width: '15%',
render: (text, { type, default: dft }) => {
if (type === 'menu_item') {
return (
<MouseOverWrapper text={text} width={0.10}>
<span style={{ cursor: 'default' }}>菜单</span>
</MouseOverWrapper>
);
} else if (!dft) {
return (
<MouseOverWrapper text={text} width={0.10}>
<span style={{ cursor: 'default' }}>自设目录</span>
</MouseOverWrapper>
);
} else if (type === 'tab') {
return (
<MouseOverWrapper text={text} width={0.10}>
<span style={{ cursor: 'default' }}>预置标签页</span>
</MouseOverWrapper>
);
} else {
return (
<MouseOverWrapper text={text} width={0.10}>
<span style={{ cursor: 'default' }}>预置目录</span>
</MouseOverWrapper>
);
}
},
}];
return (
<Page>
<Header title={<FormattedMessage id={`${intlPrefix}.header.title`} />}>
<Prompt message={promptMsg} wrapper="c7n-iam-confirm-modal" when={edited} />
<Button
onClick={this.addDir}
icon="playlist_add"
>
<FormattedMessage id={`${intlPrefix}.create.org`} />
</Button>
<Button
onClick={this.handleRefresh}
icon="refresh"
>
<FormattedMessage id="refresh" />
</Button>
</Header>
<Breadcrumb />
<Content className="menu-setting">
<Tabs defaultActiveKey="site" onChange={this.selectMenuType} activeKey={typeState}>
{hasLevel('site') ? <TabPane tab={<FormattedMessage id={`${intlPrefix}.global`} />} key="site" /> : null}
{hasLevel('organization') ? <TabPane tab={<FormattedMessage id={`${intlPrefix}.org`} />} key="organization" /> : null}
{hasLevel('project') ? <TabPane tab={<FormattedMessage id={`${intlPrefix}.pro`} />} key="project" /> : null}
{hasLevel('user') ? <TabPane tab={<FormattedMessage id={`${intlPrefix}.personcenter`} />} key="user" /> : null}
</Tabs>
<Table
loading={loading}
className="menu-table"
filterBar={false}
pagination={false}
columns={columns}
defaultExpandAllRows={false}
dataSource={menuGroup[typeState]}
childrenColumnName="subMenus"
rowKey={this.getRowKey}
onRow={this.handleRow}
/>
<Sidebar
title={this.getSidebarTitle(selectType)}
onOk={selectType === 'detail' ? this.closeSidebar : this.handleOk}
okText={this.getOkText(selectType)}
cancelText={<FormattedMessage id="cancel" />}
okCancel={selectType !== 'detail'}
onCancel={this.closeSidebar}
visible={sidebar}
className="permission-list-modal"
>
{this.getSidebarContent(selectType)}
</Sidebar>
<div style={{ marginTop: 25 }}>
<Button
funcType="raised"
type="primary"
onClick={this.saveMenu}
loading={submitting}
>
<FormattedMessage id="save" />
</Button>
<Button
funcType="raised"
onClick={this.handleRefresh}
style={{ marginLeft: 16, color: '#3F51B5' }}
disabled={submitting}
>
<FormattedMessage id="cancel" />
</Button>
</div>
</Content>
</Page>
);
}
Example #11
Source File: index.js From Codelabz with Apache License 2.0 | 4 votes |
Editor = ({ id, data, tutorial_id }) => {
const [allSaved, setAllSaved] = useState(true);
// const [synced, setSynced] = useState(false);
const firebase = useFirebase();
const editorRef = useRef(null);
let noteID = id || "test_note";
const dispatch = useDispatch();
const currentUserHandle = useSelector(
({
firebase: {
profile: { handle },
},
}) => handle
);
useEffect(() => {
let firepad;
window.CodeMirror = CodeMirror;
window.firebase = firebase;
let ref = firebase.database().ref().child("notes").child(tutorial_id);
const codeMirror = CodeMirror(editorRef.current, {
lineWrapping: true,
lineNumbers: true,
mode: { name: "javascript", json: true },
});
const script = document.createElement("script");
script.src = "/firepad.js";
script.async = true;
script.onload = () => {
const firepadRef = ref.child(noteID);
firepad = window.Firepad.fromCodeMirror(firepadRef, codeMirror, {
richTextToolbar: false,
richTextShortcuts: true,
userId: currentUserHandle,
});
firepad.on("ready", function () {
if (firepad.isHistoryEmpty() && data) {
firepad.setText(data);
}
});
firepad.on("synced", function (isSynced) {
setCurrentStep(firepad.getText())(dispatch);
isSynced && firepadRef.child("text").set(firepad.getText());
});
};
document.body.appendChild(script);
return () => {
// firepad && firepad.dispose();
document.body.removeChild(script);
};
}, [tutorial_id, firebase, currentUserHandle, noteID, data, dispatch]);
useEffect(() => {
setAllSaved(true);
// const confirmBeforeExit = (e) => {
// e.preventDefault();
// e.returnValue = "";
// };
// window.addEventListener("beforeunload", confirmBeforeExit);
return () => {
// window.removeEventListener("beforeunload", confirmBeforeExit);
};
}, [id]);
return (
<div>
<Prompt
when={!allSaved}
message="You have unsaved changes, are you sure you want to leave?"
/>
<Grid>
<Grid xs={24} md={24}>
<div id="firepad-container" ref={editorRef} />
</Grid>
</Grid>
</div>
);
}