summaryrefslogtreecommitdiffstats
path: root/front/odiparpack/app/containers/Forms
diff options
context:
space:
mode:
authorgabrhr <[email protected]>2022-04-20 10:19:29 -0500
committergabrhr <[email protected]>2022-04-20 10:19:29 -0500
commite13e630cd6e4fc0b1ff92098a28a770794c7bb9a (patch)
treee68ad2f947d1b3ec454529b35f37ca2f223e5431 /front/odiparpack/app/containers/Forms
parent457816ac1129fcc6019d2fc795b6693ee6776d59 (diff)
downloadDP1_project-e13e630cd6e4fc0b1ff92098a28a770794c7bb9a.tar.gz
DP1_project-e13e630cd6e4fc0b1ff92098a28a770794c7bb9a.tar.bz2
DP1_project-e13e630cd6e4fc0b1ff92098a28a770794c7bb9a.zip
Añadir plantilla
Base para front
Diffstat (limited to 'front/odiparpack/app/containers/Forms')
-rw-r--r--front/odiparpack/app/containers/Forms/Autocomplete.js91
-rw-r--r--front/odiparpack/app/containers/Forms/Buttons.js58
-rw-r--r--front/odiparpack/app/containers/Forms/CheckboxRadio.js46
-rw-r--r--front/odiparpack/app/containers/Forms/DateTimePicker.js52
-rw-r--r--front/odiparpack/app/containers/Forms/Rating.js46
-rw-r--r--front/odiparpack/app/containers/Forms/ReduxForm.js51
-rw-r--r--front/odiparpack/app/containers/Forms/Selectbox.js58
-rw-r--r--front/odiparpack/app/containers/Forms/SliderRange.js46
-rw-r--r--front/odiparpack/app/containers/Forms/Switches.js40
-rw-r--r--front/odiparpack/app/containers/Forms/TextEditor.js40
-rw-r--r--front/odiparpack/app/containers/Forms/Textbox.js58
-rw-r--r--front/odiparpack/app/containers/Forms/Upload.js52
-rw-r--r--front/odiparpack/app/containers/Forms/demos/AutoSuggest.js184
-rw-r--r--front/odiparpack/app/containers/Forms/demos/Checkboxes.js242
-rw-r--r--front/odiparpack/app/containers/Forms/demos/ComplexButtons.js154
-rw-r--r--front/odiparpack/app/containers/Forms/demos/ControlledSelectbox.js200
-rw-r--r--front/odiparpack/app/containers/Forms/demos/CustomButtons.js257
-rw-r--r--front/odiparpack/app/containers/Forms/demos/DateInput.js193
-rw-r--r--front/odiparpack/app/containers/Forms/demos/DateTimeInput.js123
-rw-r--r--front/odiparpack/app/containers/Forms/demos/FloatingButtons.js185
-rw-r--r--front/odiparpack/app/containers/Forms/demos/FormattedInputs.js109
-rw-r--r--front/odiparpack/app/containers/Forms/demos/HighlightSuggest.js198
-rw-r--r--front/odiparpack/app/containers/Forms/demos/InputAdornments.js221
-rw-r--r--front/odiparpack/app/containers/Forms/demos/MultipleSelectbox.js165
-rw-r--r--front/odiparpack/app/containers/Forms/demos/NativeSelectbox.js153
-rw-r--r--front/odiparpack/app/containers/Forms/demos/RadioButton.js212
-rw-r--r--front/odiparpack/app/containers/Forms/demos/RangeInput.js92
-rw-r--r--front/odiparpack/app/containers/Forms/demos/RatingCustom.js176
-rw-r--r--front/odiparpack/app/containers/Forms/demos/RatingNormal.js92
-rw-r--r--front/odiparpack/app/containers/Forms/demos/ReduxFormDemo.js229
-rw-r--r--front/odiparpack/app/containers/Forms/demos/SelectSuggestionTags.js379
-rw-r--r--front/odiparpack/app/containers/Forms/demos/SelectSuggestions.js378
-rw-r--r--front/odiparpack/app/containers/Forms/demos/SimpleSelectbox.js180
-rw-r--r--front/odiparpack/app/containers/Forms/demos/SliderInput.js104
-rw-r--r--front/odiparpack/app/containers/Forms/demos/StandardButtons.js223
-rw-r--r--front/odiparpack/app/containers/Forms/demos/SwitchesInput.js210
-rw-r--r--front/odiparpack/app/containers/Forms/demos/TagSuggestions.js249
-rw-r--r--front/odiparpack/app/containers/Forms/demos/TextFields.js124
-rw-r--r--front/odiparpack/app/containers/Forms/demos/TextFieldsLayout.js174
-rw-r--r--front/odiparpack/app/containers/Forms/demos/TimeInput.js124
-rw-r--r--front/odiparpack/app/containers/Forms/demos/UploadInputAll.js31
-rw-r--r--front/odiparpack/app/containers/Forms/demos/UploadInputBtn.js32
-rw-r--r--front/odiparpack/app/containers/Forms/demos/UploadInputImg.js32
-rw-r--r--front/odiparpack/app/containers/Forms/demos/Wysiwyg.js91
-rw-r--r--front/odiparpack/app/containers/Forms/demos/index.js44
45 files changed, 6198 insertions, 0 deletions
diff --git a/front/odiparpack/app/containers/Forms/Autocomplete.js b/front/odiparpack/app/containers/Forms/Autocomplete.js
new file mode 100644
index 0000000..23c6a13
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Autocomplete.js
@@ -0,0 +1,91 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { Grid } from '@material-ui/core';
+import {
+ AutoSuggest,
+ TagSuggestions,
+ SelectSuggestions,
+ SelectSuggestionTags,
+ HighlightSuggest
+} from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class Textbox extends React.Component {
+ render() {
+ const { classes } = this.props;
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <div className={classes.root}>
+ <Grid container spacing={3}>
+ <Grid item md={12}>
+ <PapperBlock title="Highlight Suggestion" desc="In the following example, we demonstrate how to use react-autosuggest. It's also using autosuggest-highlight for the highlighting logic.">
+ <div>
+ <HighlightSuggest />
+ <SourceReader componentName={docSrc + 'HighlightSuggest.js'} />
+ </div>
+ </PapperBlock>
+ </Grid>
+ <Grid item md={6}>
+ <PapperBlock title="Auto Suggestion" desc="The autocomplete is a normal text input enhanced by a panel of suggested options.">
+ <div>
+ <AutoSuggest />
+ <SourceReader componentName={docSrc + 'AutoSuggest.js'} />
+ </div>
+ </PapperBlock>
+ </Grid>
+ <Grid item md={6}>
+ <PapperBlock title="Tag Suggestion" desc="In the following example, we demonstrate with tag input and how to use downshift. It mean press Shift + down to show autocomplete">
+ <div>
+ <TagSuggestions />
+ <SourceReader componentName={docSrc + 'TagSuggestions.js'} />
+ </div>
+ </PapperBlock>
+ </Grid>
+ <Grid item md={6}>
+ <PapperBlock title="Select Suggestion" desc="In the following example, we demonstrate how to use react-select.">
+ <div>
+ <SelectSuggestions />
+ <SourceReader componentName={docSrc + 'SelectSuggestions.js'} />
+ </div>
+ </PapperBlock>
+ </Grid>
+ <Grid item md={6}>
+ <PapperBlock title="Select Tag Suggestion" desc="In the following example, we demonstrate how to combine tag input and react-select.">
+ <div>
+ <SelectSuggestionTags />
+ <SourceReader componentName={docSrc + 'SelectSuggestionTags.js'} />
+ </div>
+ </PapperBlock>
+ </Grid>
+ </Grid>
+ </div>
+ </div>
+ );
+ }
+}
+
+Textbox.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(Textbox);
diff --git a/front/odiparpack/app/containers/Forms/Buttons.js b/front/odiparpack/app/containers/Forms/Buttons.js
new file mode 100644
index 0000000..0935ac2
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Buttons.js
@@ -0,0 +1,58 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { StandardButtons, FloatingButtons, CustomButtons, ComplexButtons } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class Buttons extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Standard Buttons" desc="Buttons communicate the action that will occur when the user touches them.">
+ <div>
+ <StandardButtons />
+ <SourceReader componentName={docSrc + 'StandardButtons.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Floating Action Buttons" desc="A floating action button represents the primary action in an application. Shaped like a circled icon floating above the UI, it has an ink wash upon focus and lifts upon selection.">
+ <div>
+ <FloatingButtons />
+ <SourceReader componentName={docSrc + 'FloatingButtons.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Customized Buttons" desc="">
+ <div>
+ <CustomButtons />
+ <SourceReader componentName={docSrc + 'CustomButtons.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Complex Buttons" desc="The Flat Buttons, Raised Buttons, Floating Action Buttons and Icon Buttons are built on top of the same component: the ButtonBase. You can take advantage of this lower level component to build custom interactions.">
+ <div>
+ <ComplexButtons />
+ <SourceReader componentName={docSrc + 'ComplexButtons.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(Buttons);
diff --git a/front/odiparpack/app/containers/Forms/CheckboxRadio.js b/front/odiparpack/app/containers/Forms/CheckboxRadio.js
new file mode 100644
index 0000000..9833964
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/CheckboxRadio.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { Checkboxes, RadioButton } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Checkbox" desc="Checkboxes allow the user to select multiple options from a set. If you have multiple options appearing in a list, you can preserve space by using checkboxes instead of on/off switches. If you have a single option, avoid using a checkbox and use an on/off switch instead.">
+ <div>
+ <Checkboxes />
+ <SourceReader componentName={docSrc + 'Checkboxes.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Radio Button" desc="Radio buttons allow the user to select one option from a set. Use radio buttons for exclusive selection if you think that the user needs to see all available options side-by-side; otherwise, consider a dropdown, which uses less space than displaying all options.">
+ <div>
+ <RadioButton />
+ <SourceReader componentName={docSrc + 'RadioButton.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/DateTimePicker.js b/front/odiparpack/app/containers/Forms/DateTimePicker.js
new file mode 100644
index 0000000..b079d2e
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/DateTimePicker.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { DateInput, TimeInput, DateTimeInput } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Date Picker" desc="Date pickers use a dialog window to select a single date. The selected day is indicated by a filled circle. The current day is indicated by a different color and type weight.">
+ <div>
+ <DateInput />
+ <SourceReader componentName={docSrc + 'DateInput.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Time Picker" desc="Time pickers use a dialog to select a single time (in the hours:minutes format). The selected time is indicated by the filled circle at the end of the clock hand.">
+ <div>
+ <TimeInput />
+ <SourceReader componentName={docSrc + 'TimeInput.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Date &amp; Time Picker" desc="Its a combination of date & time picker and allows that uses the modal to select both date and time with one control.">
+ <div>
+ <DateTimeInput />
+ <SourceReader componentName={docSrc + 'DateTimeInput.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/Rating.js b/front/odiparpack/app/containers/Forms/Rating.js
new file mode 100644
index 0000000..5d28bca
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Rating.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { RatingNormal, RatingCustom } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Ratting" desc="Basic React component for star (or any other icon based) rating elements">
+ <div>
+ <RatingNormal />
+ <SourceReader componentName={docSrc + 'RatingNormal.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Ratting Custom" desc="">
+ <div>
+ <RatingCustom />
+ <SourceReader componentName={docSrc + 'RatingNormal.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/ReduxForm.js b/front/odiparpack/app/containers/Forms/ReduxForm.js
new file mode 100644
index 0000000..d8ef3a7
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/ReduxForm.js
@@ -0,0 +1,51 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { ReduxFormDemo } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class ReduxForm extends React.Component {
+ state = {
+ valueForm: []
+ }
+
+ showResult(values) {
+ setTimeout(() => {
+ this.setState({ valueForm: values });
+ window.alert(`You submitted:\n\n${this.state.valueForm}`);
+ }, 500); // simulate server latency
+ }
+
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Redux Form" desc="This is a simple demonstration of how to connect all the standard material-ui form elements to redux-form.">
+ <div>
+ <ReduxFormDemo onSubmit={(values) => this.showResult(values)} />
+ <SourceReader componentName={docSrc + 'ReduxFormDemo.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(ReduxForm);
diff --git a/front/odiparpack/app/containers/Forms/Selectbox.js b/front/odiparpack/app/containers/Forms/Selectbox.js
new file mode 100644
index 0000000..4f0c090
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Selectbox.js
@@ -0,0 +1,58 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { SimpleSelectbox, NativeSelectbox, MultipleSelectbox, ControlledSelectbox } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class Selectbox extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Simple Selectbox" desc="Menus are positioned over their emitting elements such that the currently selected menu item appears on top of the emitting element.">
+ <div>
+ <SimpleSelectbox />
+ <SourceReader componentName={docSrc + 'SimpleSelectbox.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Native Selectbox" desc="As the user experience can be improved on mobile using the native select of the platform, we allow such pattern.">
+ <div>
+ <NativeSelectbox />
+ <SourceReader componentName={docSrc + 'NativeSelectbox.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Multiple Selectbox" desc="The Select component can handle multiple selections. It's enabled with the multiple property.">
+ <div>
+ <MultipleSelectbox />
+ <SourceReader componentName={docSrc + 'MultipleSelectbox.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Controlled open Select" desc="">
+ <div>
+ <ControlledSelectbox />
+ <SourceReader componentName={docSrc + 'ContorlledSelectbox.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(Selectbox);
diff --git a/front/odiparpack/app/containers/Forms/SliderRange.js b/front/odiparpack/app/containers/Forms/SliderRange.js
new file mode 100644
index 0000000..779e251
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/SliderRange.js
@@ -0,0 +1,46 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { SliderInput, RangeInput } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Slider Input" desc="React component for inputting numeric values within a range (range slider)">
+ <div>
+ <SliderInput />
+ <SourceReader componentName={docSrc + 'SliderInput.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Range Input" desc="InputRange is a React component allowing users to input numeric values within a specific range. It can accept a single value, or a range of values (min/max). By default, basic styles are applied, but can be overridden depending on your design requirements.">
+ <div>
+ <RangeInput />
+ <SourceReader componentName={docSrc + 'RangeInput.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/Switches.js b/front/odiparpack/app/containers/Forms/Switches.js
new file mode 100644
index 0000000..988e0a3
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Switches.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { SwitchesInput } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Switches" desc="On/off switches toggle the state of a single settings option. The option that the switch controls, as well as the state it’s in, should be made clear from the corresponding inline label.">
+ <div>
+ <SwitchesInput />
+ <SourceReader componentName={docSrc + 'SwitchesInput.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/TextEditor.js b/front/odiparpack/app/containers/Forms/TextEditor.js
new file mode 100644
index 0000000..84a1a82
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/TextEditor.js
@@ -0,0 +1,40 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { Wysiwyg } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Text Editor" desc="A Wysiwyg Built on ReactJS and DraftJS. Editor can be simply imported and used as a React Component. Make sure to also include react-draft-wysiwyg.css from node_modules.">
+ <div>
+ <Wysiwyg />
+ <SourceReader componentName={docSrc + 'Wysiwyg.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/Textbox.js b/front/odiparpack/app/containers/Forms/Textbox.js
new file mode 100644
index 0000000..3eff0ba
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Textbox.js
@@ -0,0 +1,58 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { TextFields, TextFieldsLayout, InputAdornments, FormattedInputs } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class Textbox extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Textfield Components" desc="Text fields allow users to input text and usually appear in forms. Users may enter text, numbers, or mixed-format types of input.">
+ <div>
+ <TextFields />
+ <SourceReader componentName={docSrc + 'TextFields.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Textfield Layout and Design" desc="">
+ <div>
+ <TextFieldsLayout />
+ <SourceReader componentName={docSrc + 'TextFieldsLayout.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Input with Additonal Icon" desc="Input allows the provision of InputAdornment. These can be used to add a prefix, a suffix or an action to an input.">
+ <div>
+ <InputAdornments />
+ <SourceReader componentName={docSrc + 'InputAdornments.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Formatted inputs" desc="We demonstrate how you could be using third-party libraries to format your input. In the following demo, we are using react-text-mask and react-number-format libraries. ">
+ <div>
+ <FormattedInputs />
+ <SourceReader componentName={docSrc + 'FormattedInputs.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(Textbox);
diff --git a/front/odiparpack/app/containers/Forms/Upload.js b/front/odiparpack/app/containers/Forms/Upload.js
new file mode 100644
index 0000000..99ef3bf
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/Upload.js
@@ -0,0 +1,52 @@
+import React from 'react';
+import { Helmet } from 'react-helmet';
+import brand from 'ba-api/brand';
+import { withStyles } from '@material-ui/core/styles';
+import { SourceReader, PapperBlock } from 'ba-components';
+import { UploadInputAll, UploadInputImg, UploadInputBtn } from './demos';
+
+const styles = ({
+ root: {
+ flexGrow: 1,
+ }
+});
+
+class DateTime extends React.Component {
+ render() {
+ const title = brand.name + ' - Form';
+ const description = brand.desc;
+ const docSrc = 'containers/Forms/demos/';
+ return (
+ <div>
+ <Helmet>
+ <title>{title}</title>
+ <meta name="description" content={description} />
+ <meta property="og:title" content={title} />
+ <meta property="og:description" content={description} />
+ <meta property="twitter:title" content={title} />
+ <meta property="twitter:description" content={description} />
+ </Helmet>
+ <PapperBlock title="Upload with Drop Zone" desc="Simple HTML5-compliant drag'n'drop zone for files built with React Drop Zone. The component containing a file upload (dropzone) area, images and files preview and some snazzy File Allowed/Not Allowed effects.">
+ <div>
+ <UploadInputAll />
+ <SourceReader componentName={docSrc + 'UploadInputAll.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Upload only Images" desc="This example allowing users to upload images only">
+ <div>
+ <UploadInputImg />
+ <SourceReader componentName={docSrc + 'UploadInputImg.js'} />
+ </div>
+ </PapperBlock>
+ <PapperBlock title="Upload Button" desc="Trigger upload file via button with ref attribute">
+ <div>
+ <UploadInputBtn />
+ <SourceReader componentName={docSrc + 'UploadInputBtn.js'} />
+ </div>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+export default withStyles(styles)(DateTime);
diff --git a/front/odiparpack/app/containers/Forms/demos/AutoSuggest.js b/front/odiparpack/app/containers/Forms/demos/AutoSuggest.js
new file mode 100644
index 0000000..6d90ed3
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/AutoSuggest.js
@@ -0,0 +1,184 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Downshift from 'downshift';
+import { withStyles } from '@material-ui/core/styles';
+import { TextField, Paper, MenuItem } from '@material-ui/core';
+
+const suggestions = [
+ { label: 'Afghanistan' },
+ { label: 'Aland Islands' },
+ { label: 'Albania' },
+ { label: 'Algeria' },
+ { label: 'American Samoa' },
+ { label: 'Andorra' },
+ { label: 'Angola' },
+ { label: 'Anguilla' },
+ { label: 'Antarctica' },
+ { label: 'Antigua and Barbuda' },
+ { label: 'Argentina' },
+ { label: 'Armenia' },
+ { label: 'Aruba' },
+ { label: 'Australia' },
+ { label: 'Austria' },
+ { label: 'Azerbaijan' },
+ { label: 'Bahamas' },
+ { label: 'Bahrain' },
+ { label: 'Bangladesh' },
+ { label: 'Barbados' },
+ { label: 'Belarus' },
+ { label: 'Belgium' },
+ { label: 'Belize' },
+ { label: 'Benin' },
+ { label: 'Bermuda' },
+ { label: 'Bhutan' },
+ { label: 'Bolivia, Plurinational State of' },
+ { label: 'Bonaire, Sint Eustatius and Saba' },
+ { label: 'Bosnia and Herzegovina' },
+ { label: 'Botswana' },
+ { label: 'Bouvet Island' },
+ { label: 'Brazil' },
+ { label: 'British Indian Ocean Territory' },
+ { label: 'Brunei Darussalam' },
+];
+
+function renderInput(inputProps) {
+ const {
+ InputProps,
+ classes,
+ ref,
+ ...other
+ } = inputProps;
+
+ return (
+ <TextField
+ InputProps={{
+ inputRef: ref,
+ classes: {
+ root: classes.inputRoot,
+ },
+ ...InputProps,
+ }}
+ {...other}
+ />
+ );
+}
+
+function renderSuggestion({
+ suggestion,
+ index,
+ itemProps,
+ highlightedIndex,
+ selectedItem
+}) {
+ const isHighlighted = highlightedIndex === index;
+ const isSelected = (selectedItem || '').indexOf(suggestion.label) > -1;
+
+ return (
+ <MenuItem
+ {...itemProps}
+ key={suggestion.label}
+ selected={isHighlighted}
+ component="div"
+ style={{
+ fontWeight: isSelected ? 500 : 400,
+ }}
+ >
+ {suggestion.label}
+ </MenuItem>
+ );
+}
+
+renderSuggestion.propTypes = {
+ highlightedIndex: PropTypes.number.isRequired,
+ index: PropTypes.number.isRequired,
+ itemProps: PropTypes.object.isRequired,
+ selectedItem: PropTypes.string.isRequired,
+ suggestion: PropTypes.shape({ label: PropTypes.string }).isRequired,
+};
+
+function getSuggestions(inputValue) {
+ let count = 0;
+
+ return suggestions.filter(suggestion => {
+ const keep = (!inputValue || suggestion.label.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1)
+ && count < 5;
+
+ if (keep) {
+ count += 1;
+ }
+
+ return keep;
+ });
+}
+
+const styles = theme => ({
+ root: {
+ flexGrow: 1,
+ height: 100,
+ },
+ container: {
+ flexGrow: 1,
+ position: 'relative',
+ },
+ paper: {
+ position: 'absolute',
+ zIndex: 1,
+ marginTop: theme.spacing(1),
+ left: 0,
+ right: 0,
+ },
+ chip: {
+ margin: `${theme.spacing(0.5)}px ${theme.spacing(0.25)}px`,
+ },
+ inputRoot: {
+ flexWrap: 'wrap',
+ },
+});
+
+function AutoSuggest(props) {
+ const { classes } = props;
+
+ return (
+ <div className={classes.root}>
+ <Downshift>
+ {({
+ getInputProps,
+ getItemProps,
+ isOpen,
+ inputValue,
+ selectedItem,
+ highlightedIndex
+ }) => (
+ <div className={classes.container}>
+ {renderInput({
+ fullWidth: true,
+ classes,
+ InputProps: getInputProps({
+ placeholder: 'Search a country (start with a)',
+ id: 'integration-downshift-simple',
+ }),
+ })}
+ {isOpen ? (
+ <Paper className={classes.paper} square>
+ {getSuggestions(inputValue).map((suggestion, index) => renderSuggestion({
+ suggestion,
+ index,
+ itemProps: getItemProps({ item: suggestion.label }),
+ highlightedIndex,
+ selectedItem,
+ }),
+ )}
+ </Paper>
+ ) : null}
+ </div>
+ )}
+ </Downshift>
+ </div>
+ );
+}
+
+AutoSuggest.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(AutoSuggest);
diff --git a/front/odiparpack/app/containers/Forms/demos/Checkboxes.js b/front/odiparpack/app/containers/Forms/demos/Checkboxes.js
new file mode 100644
index 0000000..4979e60
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/Checkboxes.js
@@ -0,0 +1,242 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import CheckBoxOutlineBlankIcon from '@material-ui/icons/CheckBoxOutlineBlank';
+import CheckBoxIcon from '@material-ui/icons/CheckBox';
+import Favorite from '@material-ui/icons/Favorite';
+import FavoriteBorder from '@material-ui/icons/FavoriteBorder';
+import { green } from '@material-ui/core/colors';
+
+import {
+ Checkbox,
+ Typography,
+ Grid,
+ FormControl,
+ FormLabel,
+ FormControlLabel,
+ FormHelperText,
+ FormGroup,
+} from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ root: {
+ color: green[600],
+ '&$checked': {
+ color: green[500],
+ },
+ },
+ checked: {},
+ size: {
+ width: 40,
+ height: 40,
+ },
+ sizeIcon: {
+ fontSize: 20,
+ },
+});
+
+class Checkboxes extends PureComponent {
+ state = {
+ checkedA: true,
+ checkedB: true,
+ checkedF: true,
+ checkedG: true,
+ gilad: true,
+ jason: false,
+ antoine: true,
+ };
+
+ handleChange = name => event => {
+ this.setState({ [name]: event.target.checked });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={3}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Basic usage</Typography>
+ <div>
+ <Checkbox
+ checked={this.state.checkedA}
+ onChange={this.handleChange('checkedA')}
+ value="checkedA"
+ />
+ <Checkbox
+ checked={this.state.checkedB}
+ onChange={this.handleChange('checkedB')}
+ value="checkedB"
+ color="primary"
+ />
+ <Checkbox value="checkedC" />
+ <Checkbox disabled value="checkedD" />
+ <Checkbox disabled checked value="checkedE" />
+ <Checkbox
+ checked={this.state.checkedF}
+ onChange={this.handleChange('checkedF')}
+ value="checkedF"
+ indeterminate
+ />
+ <Checkbox defaultChecked color="default" value="checkedG" />
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={5}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Checkbox with label</Typography>
+ <Typography className={classes.divider}>Checkbox can also be used with a label description thanks to the FormControlLabel component.</Typography>
+ <div>
+ <FormGroup row>
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.checkedA}
+ onChange={this.handleChange('checkedA')}
+ value="checkedA"
+ />
+ )}
+ label="Secondary"
+ />
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.checkedB}
+ onChange={this.handleChange('checkedB')}
+ value="checkedB"
+ color="primary"
+ />
+ )}
+ label="Primary"
+ />
+ <FormControlLabel control={<Checkbox value="checkedC" />} label="Uncontrolled" />
+ <FormControlLabel disabled control={<Checkbox value="checkedD" />} label="Disabled" />
+ <FormControlLabel
+ disabled
+ control={<Checkbox checked value="checkedE" />}
+ label="Disabled"
+ />
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.checkedF}
+ onChange={this.handleChange('checkedF')}
+ value="checkedF"
+ indeterminate
+ />
+ )}
+ label="Indeterminate"
+ />
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.checkedG}
+ onChange={this.handleChange('checkedG')}
+ value="checkedG"
+ classes={{
+ root: classes.root,
+ checked: classes.checked,
+ }}
+ />
+ )}
+ label="Custom color"
+ />
+ <FormControlLabel
+ control={
+ <Checkbox icon={<FavoriteBorder />} checkedIcon={<Favorite />} value="checkedH" />
+ }
+ label="Custom icon"
+ />
+ <FormControlLabel
+ control={(
+ <Checkbox
+ className={classes.size}
+ icon={<CheckBoxOutlineBlankIcon className={classes.sizeIcon} />}
+ checkedIcon={<CheckBoxIcon className={classes.sizeIcon} />}
+ value="checkedI"
+ />
+ )}
+ label="Custom size"
+ />
+ </FormGroup>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Checkbox in Form Group</Typography>
+ <Typography className={classes.divider}>FormGroup is a helpful wrapper used to group selection controls components that provides an easier API.</Typography>
+ <div>
+ <FormControl component="fieldset">
+ <FormLabel component="legend">Assign responsibility</FormLabel>
+ <FormGroup>
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.gilad}
+ onChange={this.handleChange('gilad')}
+ value="gilad"
+ />
+ )}
+ label="Gilad Gray"
+ />
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.jason}
+ onChange={this.handleChange('jason')}
+ value="jason"
+ />
+ )}
+ label="Jason Killian"
+ />
+ <FormControlLabel
+ control={(
+ <Checkbox
+ checked={this.state.antoine}
+ onChange={this.handleChange('antoine')}
+ value="antoine"
+ />
+ )}
+ label="Antoine Llorca"
+ />
+ </FormGroup>
+ <FormHelperText>Be careful</FormHelperText>
+ </FormControl>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+Checkboxes.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(Checkboxes);
diff --git a/front/odiparpack/app/containers/Forms/demos/ComplexButtons.js b/front/odiparpack/app/containers/Forms/demos/ComplexButtons.js
new file mode 100644
index 0000000..dbeab99
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/ComplexButtons.js
@@ -0,0 +1,154 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import imgApi from 'ba-api/images';
+
+import { Typography, ButtonBase } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ root: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ minWidth: 300,
+ width: '100%',
+ },
+ image: {
+ position: 'relative',
+ height: 200,
+ [theme.breakpoints.down('xs')]: {
+ width: '100% !important', // Overrides inline-style
+ height: 100,
+ },
+ '&:hover, &$focusVisible': {
+ zIndex: 1,
+ '& $imageBackdrop': {
+ opacity: 0.15,
+ },
+ '& $imageMarked': {
+ opacity: 0,
+ },
+ '& $imageTitle': {
+ border: '4px solid currentColor',
+ },
+ },
+ },
+ focusVisible: {},
+ imageButton: {
+ position: 'absolute',
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ color: theme.palette.common.white,
+ },
+ imageSrc: {
+ position: 'absolute',
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ backgroundSize: 'cover',
+ backgroundPosition: 'center 40%',
+ },
+ imageBackdrop: {
+ position: 'absolute',
+ left: 0,
+ right: 0,
+ top: 0,
+ bottom: 0,
+ backgroundColor: theme.palette.common.black,
+ opacity: 0.4,
+ transition: theme.transitions.create('opacity'),
+ },
+ imageTitle: {
+ position: 'relative',
+ padding: `${theme.spacing(2)}px ${theme.spacing(4)}px ${theme.spacing(1) + 6}px`,
+ },
+ imageMarked: {
+ height: 3,
+ width: 18,
+ backgroundColor: theme.palette.common.white,
+ position: 'absolute',
+ bottom: -2,
+ left: 'calc(50% - 9px)',
+ transition: theme.transitions.create('opacity'),
+ },
+});
+
+const images = [
+ {
+ url: imgApi[0],
+ title: '330x200',
+ width: '40%',
+ id: '0'
+ },
+ {
+ url: imgApi[3],
+ title: '250x200',
+ width: '30%',
+ id: '1'
+ },
+ {
+ url: imgApi[5],
+ title: '250x200',
+ width: '30%',
+ id: '2'
+ },
+];
+
+class ComplexButtons extends PureComponent {
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <div className={classes.root}>
+ {images.map(image => (
+ <ButtonBase
+ focusRipple
+ key={image.id}
+ className={classes.image}
+ focusVisibleClassName={classes.focusVisible}
+ style={{
+ width: image.width,
+ }}
+ >
+ <span
+ className={classes.imageSrc}
+ style={{
+ backgroundImage: `url(${image.url})`,
+ }}
+ />
+ <span className={classes.imageBackdrop} />
+ <span className={classes.imageButton}>
+ <Typography
+ component="span"
+ variant="subtitle1"
+ color="inherit"
+ className={classes.imageTitle}
+ >
+ {image.title}
+ <span className={classes.imageMarked} />
+ </Typography>
+ </span>
+ </ButtonBase>
+ ))}
+ </div>
+ </Fragment>
+ );
+ }
+}
+
+ComplexButtons.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(ComplexButtons);
diff --git a/front/odiparpack/app/containers/Forms/demos/ControlledSelectbox.js b/front/odiparpack/app/containers/Forms/demos/ControlledSelectbox.js
new file mode 100644
index 0000000..8ba1163
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/ControlledSelectbox.js
@@ -0,0 +1,200 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+
+import {
+ Button,
+ Typography,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ Input,
+ InputLabel,
+ MenuItem,
+ FormControl,
+ Select,
+ Grid,
+} from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ container: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ formControl: {
+ margin: theme.spacing(1),
+ minWidth: 120,
+ },
+ button: {
+ display: 'block',
+ marginTop: theme.spacing(2),
+ },
+});
+
+class ControlledSelectbox extends PureComponent {
+ state = {
+ open: false,
+ openRemotely: false,
+ age: '',
+ };
+
+ handleChange = name => event => {
+ this.setState({ [name]: Number(event.target.value) });
+ };
+
+ handleChangeControll = event => {
+ this.setState({ [event.target.name]: event.target.value });
+ };
+
+ handleClickOpen = () => {
+ this.setState({ open: true });
+ };
+
+ handleClickOpenRemot = () => {
+ this.setState({ openRemotely: true });
+ };
+
+ handleClose = () => {
+ this.setState({ open: false });
+ };
+
+ handleOpen = () => {
+ this.setState({ open: true });
+ };
+
+ handleCloseRemot = () => {
+ this.setState({ openRemotely: false });
+ };
+
+ handleOpenRemot = () => {
+ this.setState({ openRemotely: true });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>With a Dialog</Typography>
+ <Typography className={classes.divider}>While its not encouraged by the Material Design specification, you can use a select inside a dialog.</Typography>
+ <div>
+ <Button variant="contained" color="secondary" onClick={this.handleClickOpen}>Open select dialog</Button>
+ <Dialog
+ disableBackdropClick
+ disableEscapeKeyDown
+ open={this.state.open}
+ onClose={this.handleClose}
+ >
+ <DialogTitle>Fill the form</DialogTitle>
+ <DialogContent>
+ <form className={classes.container}>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-native-simple">Age</InputLabel>
+ <Select
+ native
+ value={this.state.age}
+ onChange={this.handleChange('age')}
+ input={<Input id="age-native-simple" />}
+ >
+ <option value="" />
+ <option value={10}>Ten</option>
+ <option value={20}>Twenty</option>
+ <option value={30}>Thirty</option>
+ </Select>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-simple">Age</InputLabel>
+ <Select
+ value={this.state.age}
+ onChange={this.handleChange('age')}
+ input={<Input id="age-simple" />}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value={10}>Ten</MenuItem>
+ <MenuItem value={20}>Twenty</MenuItem>
+ <MenuItem value={30}>Thirty</MenuItem>
+ </Select>
+ </FormControl>
+ </form>
+ </DialogContent>
+ <DialogActions>
+ <Button onClick={this.handleClose} color="primary">
+ Cancel
+ </Button>
+ <Button onClick={this.handleClose} color="primary">
+ Ok
+ </Button>
+ </DialogActions>
+ </Dialog>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Controlled open Select</Typography>
+ <div>
+ <form autoComplete="off">
+ <Button variant="contained" color="secondary" className={classes.button} onClick={this.handleClickOpenRemot}>
+ Open the select
+ </Button>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="controlled-open-select">Age</InputLabel>
+ <Select
+ open={this.state.openRemotely}
+ onClose={this.handleCloseRemot}
+ onOpen={this.handleOpenRemot}
+ value={this.state.age}
+ onChange={this.handleChangeControll}
+ inputProps={{
+ name: 'age',
+ id: 'controlled-open-select',
+ }}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value={10}>Ten</MenuItem>
+ <MenuItem value={20}>Twenty</MenuItem>
+ <MenuItem value={30}>Thirty</MenuItem>
+ </Select>
+ </FormControl>
+ </form>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+ControlledSelectbox.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(ControlledSelectbox);
diff --git a/front/odiparpack/app/containers/Forms/demos/CustomButtons.js b/front/odiparpack/app/containers/Forms/demos/CustomButtons.js
new file mode 100644
index 0000000..f1600a0
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/CustomButtons.js
@@ -0,0 +1,257 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import { withStyles, MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
+import AddIcon from '@material-ui/icons/Add';
+import FileUpload from '@material-ui/icons/CloudUpload';
+import { Link } from 'react-router-dom';
+
+import { purple, green } from '@material-ui/core/colors';
+
+import { Typography, Grid, Button, Fab, IconButton } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ button: {
+ margin: theme.spacing(1),
+ },
+ container: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ margin: {
+ margin: theme.spacing(1),
+ },
+ cssRoot: {
+ color: theme.palette.getContrastText(purple[500]),
+ backgroundColor: purple[500],
+ '&:hover': {
+ backgroundColor: purple[700],
+ },
+ },
+ bootstrapRoot: {
+ boxShadow: 'none',
+ textTransform: 'none',
+ borderRadius: 4,
+ fontSize: 16,
+ padding: '6px 12px',
+ border: '1px solid',
+ backgroundColor: '#007bff',
+ borderColor: '#007bff',
+ '&:hover': {
+ backgroundColor: '#0069d9',
+ borderColor: '#0062cc',
+ },
+ '&:active': {
+ boxShadow: 'none',
+ backgroundColor: '#0062cc',
+ borderColor: '#005cbf',
+ },
+ '&:focus': {
+ boxShadow: '0 0 0 0.2rem rgba(0,123,255,.5)',
+ },
+ },
+ gradientBtn: {
+ background: 'linear-gradient(45deg, #FE6B8B 30%, #FF8E53 90%)',
+ borderRadius: 3,
+ border: 0,
+ color: 'white',
+ height: 48,
+ padding: '0 30px',
+ boxShadow: '0 3px 5px 2px rgba(255, 105, 135, .30)',
+ },
+ label: {
+ textTransform: 'capitalize',
+ },
+ inputUpload: {
+ display: 'none',
+ },
+});
+
+const theme = createMuiTheme({
+ palette: {
+ primary: green,
+ },
+});
+
+const LinkBtn = React.forwardRef(function LinkBtn(props, ref) { // eslint-disable-line
+ return <Link to={props.to} {...props} innerRef={ref} />; // eslint-disable-line
+});
+
+class CustomButtons extends PureComponent {
+ render() {
+ const { classes } = this.props;
+ const MyLink = React.forwardRef((props, ref) => <Link innerRef={ref} to="/app/forms/reduxform" {...props} />); // eslint-disable-line
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="center"
+ justify="flex-start"
+ direction="row"
+ spacing={2}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Sizes</Typography>
+ <Typography className={classes.divider}>
+ Fancy larger or smaller buttons? Use the size or the mini property.
+ </Typography>
+ <div>
+ <div>
+ <Button size="small" className={classes.button}>
+ Small
+ </Button>
+ <Button size="medium" className={classes.button}>
+ Medium
+ </Button>
+ <Button size="large" className={classes.button}>
+ Large
+ </Button>
+ </div>
+ <div>
+ <Button variant="contained" size="small" color="primary" className={classes.button}>
+ Small
+ </Button>
+ <Button variant="contained" size="medium" color="primary" className={classes.button}>
+ Medium
+ </Button>
+ <Button variant="contained" size="large" color="primary" className={classes.button}>
+ Large
+ </Button>
+ </div>
+ <div>
+ <Button variant="outlined" size="small" color="primary" className={classes.button}>
+ Small
+ </Button>
+ <Button variant="outlined" size="medium" color="primary" className={classes.button}>
+ Medium
+ </Button>
+ <Button variant="outlined" size="large" color="primary" className={classes.button}>
+ Large
+ </Button>
+ </div>
+ <div>
+ <Fab size="small" color="secondary" aria-label="add" className={classes.button}>
+ <AddIcon />
+ </Fab>
+ <Fab color="secondary" aria-label="add" className={classes.button}>
+ <AddIcon />
+ </Fab>
+ </div>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Style</Typography>
+ <Typography className={classes.divider}>
+ Here is an example of how you can change the main color of a Button.
+ </Typography>
+ <div>
+ <Button
+ variant="contained"
+ color="primary"
+ className={classNames(classes.margin, classes.cssRoot)}
+ >
+ Custom CSS
+ </Button>
+ <MuiThemeProvider theme={theme}>
+ <Button variant="contained" color="primary" className={classes.margin}>
+ MuiThemeProvider
+ </Button>
+ </MuiThemeProvider>
+ <Button
+ variant="contained"
+ color="primary"
+ disableRipple
+ className={classNames(classes.margin, classes.bootstrapRoot)}
+ >
+ Bootstrap
+ </Button>
+ <Button
+ classes={{
+ root: classNames(classes.gradientBtn, classes.margin), // class name, e.g. `classes-root-x`
+ label: classes.label, // class name, e.g. `classes-label-x`
+ }}
+ >
+ Gradient Style
+ </Button>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Linked Button</Typography>
+ <Typography className={classes.divider}>
+ One common use case is to use the button to trigger a navigation to a new page.
+ </Typography>
+ <div>
+ <Button
+ variant="contained"
+ color="primary"
+ className={classNames(classes.margin, classes.cssRoot)}
+ component={LinkBtn}
+ to="/app/forms/datetimepicker"
+ >
+ Go To Date Time Picker
+ </Button>
+ <Button color="secondary" variant="contained" component={MyLink}> Go To Redux Form </Button>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Upload Button</Typography>
+ <Typography className={classes.divider}>
+ This a sample to trigger input files from button
+ </Typography>
+ <div>
+ <input
+ accept="image/*"
+ className={classes.inputUpload}
+ id="raised-button-file"
+ multiple
+ type="file"
+ />
+ <label htmlFor="raised-button-file">
+ <Button variant="contained" component="span" id="raised-button-file" className={classes.button}>
+ Upload
+ </Button>
+ </label>
+ <input accept="image/*" className={classes.inputUpload} id="icon-button-file" type="file" />
+ <label htmlFor="icon-button-file">
+ <IconButton color="primary" id="uploadBtnIcon" className={classes.button} component="span">
+ <FileUpload />
+ </IconButton>
+ </label>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+CustomButtons.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(CustomButtons);
diff --git a/front/odiparpack/app/containers/Forms/demos/DateInput.js b/front/odiparpack/app/containers/Forms/demos/DateInput.js
new file mode 100644
index 0000000..fc3397c
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/DateInput.js
@@ -0,0 +1,193 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { DatePicker, KeyboardDatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
+import MomentUtils from '@date-io/moment';
+import DateFnsUtils from '@date-io/date-fns';
+import { withStyles } from '@material-ui/core/styles';
+
+import frLocale from 'date-fns/locale/fr';
+import ruLocale from 'date-fns/locale/ru';
+import enLocale from 'date-fns/locale/en-US';
+
+import { MenuItem, Menu, Icon, IconButton, Typography, Grid } from '@material-ui/core';
+
+const localeMap = {
+ en: enLocale,
+ fr: frLocale,
+ ru: ruLocale,
+};
+
+const styles = theme => ({
+ demo: {
+ height: 240,
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ picker: {
+ margin: `${theme.spacing(3)}px 5px`,
+ }
+});
+
+class DateInput extends PureComponent {
+ state = {
+ selectedDate: new Date(),
+ anchorEl: null,
+ currentLocale: 'fr',
+ }
+
+ handleDateChange = (date) => {
+ this.setState({ selectedDate: date });
+ }
+
+ handleMenuOpen = (event) => {
+ event.stopPropagation();
+ this.setState({ anchorEl: event.currentTarget });
+ }
+
+ handleMenuClose = () => {
+ this.setState({ anchorEl: null });
+ };
+
+ selectLocale = (selectedLocale) => {
+ this.setState({
+ currentLocale: selectedLocale,
+ anchorEl: null,
+ });
+ }
+
+ render() {
+ const { selectedDate, currentLocale, anchorEl } = this.state;
+ const { classes } = this.props;
+ const locale = localeMap[currentLocale];
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="center"
+ justify="space-around"
+ direction="row"
+ >
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Basic usage</Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <DatePicker
+ label="Basic example"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ animateYearScrolling={false}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <DatePicker
+ label="Clearable"
+ clearable
+ disableFuture
+ maxDateMessage="Date must be less than today"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ animateYearScrolling={false}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Keyboard Input</Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <KeyboardDatePicker
+ clearable
+ label="Uncontrolled input"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ animateYearScrolling={false}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <KeyboardDatePicker
+ label="Masked input"
+ format="DD/MM/YYYY"
+ placeholder="10/10/2018"
+ mask={[/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/]}
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ animateYearScrolling={false}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Localization</Typography>
+ <div className={classes.picker}>
+ <div className={classes.divider}>
+ <MuiPickersUtilsProvider utils={DateFnsUtils} locale={localeMap[currentLocale]}>
+ <DatePicker
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ InputProps={{
+ endAdornment: (
+ <IconButton
+ aria-label="Select locale"
+ aria-owns={anchorEl ? 'locale-menu' : null}
+ onClick={this.handleMenuOpen}
+ >
+ <Icon> more_vert </Icon>
+ </IconButton>
+ ),
+ }}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+
+ <Menu
+ id="locale-menu"
+ anchorEl={anchorEl}
+ open={Boolean(anchorEl)}
+ onClose={this.handleMenuClose}
+ >
+ {
+ Object.keys(localeMap).map(localeItem => (
+ <MenuItem
+ key={localeItem}
+ selected={localeItem === locale}
+ onClick={() => this.selectLocale(localeItem)}
+ >
+ {localeItem}
+ </MenuItem>
+ ))
+ }
+ </Menu>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+
+DateInput.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(DateInput);
diff --git a/front/odiparpack/app/containers/Forms/demos/DateTimeInput.js b/front/odiparpack/app/containers/Forms/demos/DateTimeInput.js
new file mode 100644
index 0000000..e594013
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/DateTimeInput.js
@@ -0,0 +1,123 @@
+import React, { Fragment, PureComponent } from 'react';
+import { DateTimePicker, KeyboardDateTimePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
+import MomentUtils from '@date-io/moment';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { IconButton, Icon, InputAdornment, Typography, Grid } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ picker: {
+ margin: `${theme.spacing(3)}px 5px`,
+ }
+});
+
+class DateTimeInput extends PureComponent {
+ state = {
+ selectedDate: new Date(),
+ }
+
+ handleDateChange = (date) => {
+ this.setState({ selectedDate: date });
+ }
+
+ render() {
+ const { selectedDate } = this.state;
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Basic usage</Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <DateTimePicker
+ value={selectedDate}
+ disablePast
+ onChange={this.handleDateChange}
+ label="DateTimePicker"
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <DateTimePicker
+ autoOk
+ ampm={false}
+ disableFuture
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ label="24h clock"
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Customization</Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <DateTimePicker
+ autoOk
+ ampm={false}
+ showTabs={false}
+ disableFuture
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ helperText="Hardcoded helper text"
+ leftArrowIcon={<Icon> add_alarm </Icon>}
+ rightArrowIcon={<Icon> snooze </Icon>}
+ InputProps={{
+ endAdornment: (
+ <InputAdornment position="end">
+ <IconButton className={classes.iconBtn}>
+ <Icon>add_alarm</Icon>
+ </IconButton>
+ </InputAdornment>
+ ),
+ }}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <KeyboardDateTimePicker
+ label="Keyboard input"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ format="YYYY/MM/DD hh:mm A"
+ mask={[/\d/, /\d/, /\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, ' ', /\d/, /\d/, ':', /\d/, /\d/, ' ', /a|p/i, 'M']}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+DateTimeInput.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(DateTimeInput);
diff --git a/front/odiparpack/app/containers/Forms/demos/FloatingButtons.js b/front/odiparpack/app/containers/Forms/demos/FloatingButtons.js
new file mode 100644
index 0000000..5fbfa1c
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/FloatingButtons.js
@@ -0,0 +1,185 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import classNames from 'classnames';
+import SwipeableViews from 'react-swipeable-views';
+import AddIcon from '@material-ui/icons/Add';
+import EditIcon from '@material-ui/icons/Create';
+import NavigationIcon from '@material-ui/icons/Navigation';
+import UpIcon from '@material-ui/icons/KeyboardArrowUp';
+import DeleteIcon from '@material-ui/icons/Delete';
+import { green } from '@material-ui/core/colors';
+
+import { Typography, Grid, Fab, AppBar, Tabs, Tab, Zoom, Icon } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ button: {
+ margin: theme.spacing(1),
+ },
+ root: {
+ backgroundColor: theme.palette.background.paper,
+ [theme.breakpoints.up('sm')]: {
+ width: 500,
+ },
+ margin: '0 auto',
+ position: 'relative',
+ minHeight: 200,
+ },
+ fab: {
+ position: 'absolute',
+ bottom: theme.spacing(2),
+ right: theme.spacing(2),
+ },
+ fabGreen: {
+ color: theme.palette.common.white,
+ backgroundColor: green[500],
+ },
+ extendedIcon: {
+ marginRight: theme.spacing(1),
+ },
+});
+
+function TabContainer(props) {
+ const { children, dir } = props;
+
+ return (
+ <Typography component="div" dir={dir} style={{ padding: 8 * 3 }}>
+ {children}
+ </Typography>
+ );
+}
+
+TabContainer.propTypes = {
+ children: PropTypes.node.isRequired,
+ dir: PropTypes.string.isRequired,
+};
+
+class FloatingButtons extends PureComponent {
+ state = {
+ value: 0,
+ };
+
+ handleChange = (event, value) => {
+ this.setState({ value });
+ };
+
+ handleChangeIndex = index => {
+ this.setState({ value: index });
+ };
+
+ render() {
+ const { classes, theme } = this.props;
+ const transitionDuration = {
+ enter: theme.transitions.duration.enteringScreen,
+ exit: theme.transitions.duration.leavingScreen,
+ };
+ const fabs = [
+ {
+ color: 'primary',
+ className: classes.fab,
+ icon: <AddIcon />,
+ },
+ {
+ color: 'secondary',
+ className: classes.fab,
+ icon: <EditIcon />,
+ },
+ {
+ color: 'inherit',
+ className: classNames(classes.fab, classes.fabGreen),
+ icon: <UpIcon />,
+ },
+ ];
+
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="flex-start"
+ direction="row"
+ spacing={2}
+ >
+ <Grid item md={6}>
+ <Typography variant="button" className={classes.divider}>Floating Action Buttons</Typography>
+ <Typography className={classes.divider}>
+ A floating action button represents the primary action in an application.
+ </Typography>
+ <Fab color="primary" aria-label="add" className={classes.button}>
+ <AddIcon />
+ </Fab>
+ <Fab color="secondary" aria-label="edit" className={classes.button}>
+ <Icon>edit_icon</Icon>
+ </Fab>
+ <Fab variant="extended" color="secondary" aria-label="Delete" className={classes.button}>
+ <NavigationIcon className={classes.extendedIcon} />
+ Extended
+ </Fab>
+ <Fab disabled aria-label="delete" className={classes.button}>
+ <DeleteIcon />
+ </Fab>
+ </Grid>
+ <Grid item md={6}>
+ <Typography variant="button" className={classes.divider}>Floating BUtton in Tab</Typography>
+ <Typography className={classes.divider}>
+ A floating action button that spans multiple lateral screens (such as tabbed screens) should briefly disappear, then reappear if its action changes.
+ </Typography>
+ <div className={classes.root}>
+ <AppBar position="static" color="default">
+ <Tabs
+ value={this.state.value}
+ onChange={this.handleChange}
+ indicatorColor="primary"
+ textColor="primary"
+ variant="fullWidth"
+ >
+ <Tab label="Item One" />
+ <Tab label="Item Two" />
+ <Tab label="Item Three" />
+ </Tabs>
+ </AppBar>
+ <SwipeableViews
+ axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}
+ index={this.state.value}
+ onChangeIndex={this.handleChangeIndex}
+ >
+ <TabContainer dir={theme.direction}>Item One</TabContainer>
+ <TabContainer dir={theme.direction}>Item Two</TabContainer>
+ <TabContainer dir={theme.direction}>Item Three</TabContainer>
+ </SwipeableViews>
+ {fabs.map((fab, index) => (
+ <Zoom
+ key={fab.color}
+ in={this.state.value === index}
+ timeout={transitionDuration}
+ style={{
+ transitionDelay: this.state.value === index ? transitionDuration.exit : 0,
+ }}
+ unmountOnExit
+ >
+ <Fab className={fab.className} color={fab.color}>
+ {fab.icon}
+ </Fab>
+ </Zoom>
+ ))}
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+FloatingButtons.propTypes = {
+ classes: PropTypes.object.isRequired,
+ theme: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles, { withTheme: true })(FloatingButtons);
diff --git a/front/odiparpack/app/containers/Forms/demos/FormattedInputs.js b/front/odiparpack/app/containers/Forms/demos/FormattedInputs.js
new file mode 100644
index 0000000..9fbe9cd
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/FormattedInputs.js
@@ -0,0 +1,109 @@
+import React from 'react';
+import MaskedInput from 'react-text-mask';
+import NumberFormat from 'react-number-format';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { Input, InputLabel, TextField, FormControl } from '@material-ui/core';
+
+const styles = theme => ({
+ container: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ formControl: {
+ margin: theme.spacing(3),
+ },
+});
+
+function TextMaskCustom(props) {
+ const { inputRef, ...other } = props;
+
+ return (
+ <MaskedInput
+ {...other}
+ ref={ref => {
+ inputRef(ref ? ref.inputElement : null);
+ }}
+ mask={['(', /[1-9]/, /\d/, /\d/, ')', ' ', /\d/, /\d/, /\d/, '-', /\d/, /\d/, /\d/, /\d/]}
+ placeholderChar={'\u2000'}
+ showMask
+ />
+ );
+}
+
+TextMaskCustom.propTypes = {
+ inputRef: PropTypes.func.isRequired,
+};
+
+function NumberFormatCustom(props) {
+ const { inputRef, onChange, ...other } = props;
+
+ return (
+ <NumberFormat
+ {...other}
+ getInputRef={inputRef}
+ onValueChange={values => {
+ onChange({
+ target: {
+ value: values.value,
+ },
+ });
+ }}
+ thousandSeparator
+ prefix="$"
+ />
+ );
+}
+
+NumberFormatCustom.propTypes = {
+ inputRef: PropTypes.func.isRequired,
+ onChange: PropTypes.func.isRequired,
+};
+
+class FormattedInputs extends React.Component {
+ state = {
+ textmask: '(1  )    -    ',
+ numberformat: '1320',
+ };
+
+ handleChange = name => event => {
+ this.setState({
+ [name]: event.target.value,
+ });
+ };
+
+ render() {
+ const { classes } = this.props;
+ const { textmask, numberformat } = this.state;
+
+ return (
+ <div className={classes.container}>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="formatted-text-mask-input">react-text-mask</InputLabel>
+ <Input
+ value={textmask}
+ onChange={this.handleChange('textmask')}
+ id="formatted-text-mask-input"
+ inputComponent={TextMaskCustom}
+ />
+ </FormControl>
+ <TextField
+ className={classes.formControl}
+ label="react-number-format"
+ value={numberformat}
+ onChange={this.handleChange('numberformat')}
+ id="formatted-numberformat-input"
+ InputProps={{
+ inputComponent: NumberFormatCustom,
+ }}
+ />
+ </div>
+ );
+ }
+}
+
+FormattedInputs.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(FormattedInputs);
diff --git a/front/odiparpack/app/containers/Forms/demos/HighlightSuggest.js b/front/odiparpack/app/containers/Forms/demos/HighlightSuggest.js
new file mode 100644
index 0000000..ee13fd7
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/HighlightSuggest.js
@@ -0,0 +1,198 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import Autosuggest from 'react-autosuggest';
+import match from 'autosuggest-highlight/match';
+import parse from 'autosuggest-highlight/parse';
+import { withStyles } from '@material-ui/core/styles';
+
+import { TextField, Paper, MenuItem } from '@material-ui/core';
+
+const suggestions = [
+ { label: 'Afghanistan' },
+ { label: 'Aland Islands' },
+ { label: 'Albania' },
+ { label: 'Algeria' },
+ { label: 'American Samoa' },
+ { label: 'Andorra' },
+ { label: 'Angola' },
+ { label: 'Anguilla' },
+ { label: 'Antarctica' },
+ { label: 'Antigua and Barbuda' },
+ { label: 'Argentina' },
+ { label: 'Armenia' },
+ { label: 'Aruba' },
+ { label: 'Australia' },
+ { label: 'Austria' },
+ { label: 'Azerbaijan' },
+ { label: 'Bahamas' },
+ { label: 'Bahrain' },
+ { label: 'Bangladesh' },
+ { label: 'Barbados' },
+ { label: 'Belarus' },
+ { label: 'Belgium' },
+ { label: 'Belize' },
+ { label: 'Benin' },
+ { label: 'Bermuda' },
+ { label: 'Bhutan' },
+ { label: 'Bolivia, Plurinational State of' },
+ { label: 'Bonaire, Sint Eustatius and Saba' },
+ { label: 'Bosnia and Herzegovina' },
+ { label: 'Botswana' },
+ { label: 'Bouvet Island' },
+ { label: 'Brazil' },
+ { label: 'British Indian Ocean Territory' },
+ { label: 'Brunei Darussalam' },
+];
+
+function renderInput(inputProps) {
+ const { classes, ref, ...other } = inputProps;
+
+ return (
+ <TextField
+ fullWidth
+ InputProps={{
+ inputRef: ref,
+ classes: {
+ input: classes.input,
+ },
+ ...other,
+ }}
+ />
+ );
+}
+
+function renderSuggestion(suggestion, { query, isHighlighted }) {
+ const matches = match(suggestion.label, query);
+ const parts = parse(suggestion.label, matches);
+
+ return (
+ <MenuItem selected={isHighlighted} component="div">
+ <div>
+ {parts.map((part, index) => (
+ part.highlight ? (
+ <span key={String(index)} style={{ fontWeight: 300 }}>
+ {part.text}
+ </span>
+ ) : (
+ <strong key={String(index)} style={{ fontWeight: 500 }}>
+ {part.text}
+ </strong>
+ )
+ ))}
+ </div>
+ </MenuItem>
+ );
+}
+
+function renderSuggestionsContainer(options) {
+ const { containerProps, children } = options;
+
+ return (
+ <Paper {...containerProps} square>
+ {children}
+ </Paper>
+ );
+}
+
+function getSuggestionValue(suggestion) {
+ return suggestion.label;
+}
+
+function getSuggestions(value) {
+ const inputValue = value.trim().toLowerCase();
+ const inputLength = inputValue.length;
+ let count = 0;
+
+ return inputLength === 0
+ ? [] : suggestions.filter(suggestion => {
+ const keep = count < 5 && suggestion.label.toLowerCase().slice(0, inputLength) === inputValue;
+
+ if (keep) {
+ count += 1;
+ }
+
+ return keep;
+ });
+}
+
+const styles = theme => ({
+ container: {
+ flexGrow: 1,
+ position: 'relative',
+ height: 250,
+ },
+ suggestionsContainerOpen: {
+ position: 'absolute',
+ zIndex: 1,
+ marginTop: theme.spacing(1),
+ left: 0,
+ right: 0,
+ },
+ suggestion: {
+ display: 'block',
+ },
+ suggestionsList: {
+ margin: 0,
+ padding: 0,
+ listStyleType: 'none',
+ },
+});
+
+class HighlightSuggest extends React.Component {
+ state = {
+ value: '',
+ suggestions: [],
+ };
+
+ handleSuggestionsFetchRequested = ({ value }) => {
+ this.setState({
+ suggestions: getSuggestions(value),
+ });
+ };
+
+ handleSuggestionsClearRequested = () => {
+ this.setState({
+ suggestions: [],
+ });
+ };
+
+ handleChange = (event, { newValue }) => {
+ this.setState({
+ value: newValue,
+ });
+ };
+
+ render() {
+ const { classes } = this.props;
+
+ return (
+ <Autosuggest
+ theme={{
+ container: classes.container,
+ suggestionsContainerOpen: classes.suggestionsContainerOpen,
+ suggestionsList: classes.suggestionsList,
+ suggestion: classes.suggestion,
+ }}
+ renderInputComponent={renderInput}
+ suggestions={this.state.suggestions}
+ onSuggestionsFetchRequested={this.handleSuggestionsFetchRequested}
+ onSuggestionsClearRequested={this.handleSuggestionsClearRequested}
+ renderSuggestionsContainer={renderSuggestionsContainer}
+ getSuggestionValue={getSuggestionValue}
+ renderSuggestion={renderSuggestion}
+ inputProps={{
+ classes,
+ placeholder: 'Search a country (start with a)',
+ value: this.state.value,
+ onChange: this.handleChange,
+ }}
+ />
+ );
+ }
+}
+
+HighlightSuggest.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(HighlightSuggest);
diff --git a/front/odiparpack/app/containers/Forms/demos/InputAdornments.js b/front/odiparpack/app/containers/Forms/demos/InputAdornments.js
new file mode 100644
index 0000000..1d6307e
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/InputAdornments.js
@@ -0,0 +1,221 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import { withStyles } from '@material-ui/core/styles';
+import Visibility from '@material-ui/icons/Visibility';
+import VisibilityOff from '@material-ui/icons/VisibilityOff';
+import AccountCircle from '@material-ui/icons/AccountCircle';
+
+import {
+ Typography,
+ Grid,
+ IconButton,
+ Input,
+ InputLabel,
+ InputAdornment,
+ FormControl,
+ FormHelperText,
+ TextField,
+ MenuItem,
+} from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ root: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ margin: {
+ margin: theme.spacing(3),
+ },
+ withoutLabel: {
+ marginTop: theme.spacing(3),
+ },
+ textField: {
+ flexBasis: 200,
+ },
+});
+
+const ranges = [
+ {
+ value: '0-20',
+ label: '0 to 20',
+ },
+ {
+ value: '21-50',
+ label: '21 to 50',
+ },
+ {
+ value: '51-100',
+ label: '51 to 100',
+ },
+];
+
+class InputAdornments extends PureComponent {
+ state = {
+ amount: '',
+ password: '',
+ weight: '',
+ weightRange: '',
+ showPassword: false,
+ };
+
+ handleChange = prop => event => {
+ this.setState({ [prop]: event.target.value });
+ };
+
+ handleMouseDownPassword = event => {
+ event.preventDefault();
+ };
+
+ handleClickShowPassword = () => {
+ this.setState({ showPassword: !this.state.showPassword });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="flex-start"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Input Adornments</Typography>
+ <Typography className={classes.divider}>TextField is composed of smaller components that you can leverage directly to significantly customize your form inputs.</Typography>
+ <div className={classes.root}>
+ <TextField
+ label="With normal TextField"
+ id="simple-start-adornment"
+ className={classNames(classes.margin, classes.textField)}
+ InputProps={{
+ startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
+ }}
+ />
+ <TextField
+ select
+ label="With Select"
+ className={classNames(classes.margin, classes.textField)}
+ value={this.state.weightRange}
+ onChange={this.handleChange('weightRange')}
+ InputProps={{
+ startAdornment: <InputAdornment position="start">Kg</InputAdornment>,
+ }}
+ >
+ {ranges.map(option => (
+ <MenuItem key={option.value} value={option.value}>
+ {option.label}
+ </MenuItem>
+ ))}
+ </TextField>
+ <FormControl fullWidth className={classes.margin}>
+ <InputLabel htmlFor="adornment-amount">Amount</InputLabel>
+ <Input
+ id="adornment-amount"
+ value={this.state.amount}
+ onChange={this.handleChange('amount')}
+ startAdornment={<InputAdornment position="start">$</InputAdornment>}
+ />
+ </FormControl>
+ <FormControl
+ className={classNames(classes.margin, classes.withoutLabel, classes.textField)}
+ aria-describedby="weight-helper-text"
+ >
+ <Input
+ id="adornment-weight"
+ value={this.state.weight}
+ onChange={this.handleChange('weight')}
+ endAdornment={<InputAdornment position="end">Kg</InputAdornment>}
+ inputProps={{
+ 'aria-label': 'Weight',
+ }}
+ />
+ <FormHelperText id="weight-helper-text">Weight</FormHelperText>
+ </FormControl>
+ <FormControl className={classNames(classes.margin, classes.textField)}>
+ <InputLabel htmlFor="adornment-password">Password</InputLabel>
+ <Input
+ id="adornment-password"
+ type={this.state.showPassword ? 'text' : 'password'}
+ value={this.state.password}
+ onChange={this.handleChange('password')}
+ endAdornment={(
+ <InputAdornment position="end">
+ <IconButton
+ aria-label="Toggle password visibility"
+ onClick={this.handleClickShowPassword}
+ onMouseDown={this.handleMouseDownPassword}
+ >
+ {this.state.showPassword ? <VisibilityOff /> : <Visibility />}
+ </IconButton>
+ </InputAdornment>
+ )}
+ />
+ </FormControl>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>With icon</Typography>
+ <Typography className={classes.divider}>Icons can be specified as prepended or appended.</Typography>
+ <FormControl className={classes.margin}>
+ <InputLabel htmlFor="input-with-icon-adornment">With a start adornment</InputLabel>
+ <Input
+ id="input-with-icon-adornment"
+ startAdornment={(
+ <InputAdornment position="start">
+ <AccountCircle />
+ </InputAdornment>
+ )}
+ />
+ </FormControl>
+ <TextField
+ className={classes.margin}
+ id="input-with-icon-textfield"
+ label="TextField"
+ InputProps={{
+ startAdornment: (
+ <InputAdornment position="start">
+ <AccountCircle />
+ </InputAdornment>
+ ),
+ }}
+ />
+ <div className={classes.margin}>
+ <Grid container spacing={1} alignItems="flex-end">
+ <Grid item>
+ <AccountCircle />
+ </Grid>
+ <Grid item>
+ <TextField id="input-with-icon-grid" label="With a grid" />
+ </Grid>
+ </Grid>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+InputAdornments.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(InputAdornments);
diff --git a/front/odiparpack/app/containers/Forms/demos/MultipleSelectbox.js b/front/odiparpack/app/containers/Forms/demos/MultipleSelectbox.js
new file mode 100644
index 0000000..6609147
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/MultipleSelectbox.js
@@ -0,0 +1,165 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+
+import { withStyles } from '@material-ui/core/styles';
+
+import {
+ Input,
+ InputLabel,
+ MenuItem,
+ FormControl,
+ ListItemText,
+ Select,
+ Checkbox,
+ Chip,
+} from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ root: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ formControl: {
+ margin: theme.spacing(1),
+ minWidth: 120,
+ maxWidth: 300,
+ },
+ chips: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ chip: {
+ margin: theme.spacing(0.25),
+ },
+});
+
+const ITEM_HEIGHT = 48;
+const ITEM_PADDING_TOP = 8;
+const MenuProps = {
+ PaperProps: {
+ style: {
+ maxHeight: (ITEM_HEIGHT * 4.5) + ITEM_PADDING_TOP,
+ width: 250,
+ },
+ },
+};
+
+const names = [
+ 'Oliver Hansen',
+ 'Van Henry',
+ 'April Tucker',
+ 'Ralph Hubbard',
+ 'Omar Alexander',
+ 'Carlos Abbott',
+ 'Miriam Wagner',
+ 'Bradley Wilkerson',
+ 'Virginia Andrews',
+ 'Kelly Snyder',
+];
+
+class MultipleSelectbox extends PureComponent {
+ state = {
+ name: [],
+ };
+
+ handleChange = event => {
+ this.setState({ name: event.target.value });
+ };
+
+ render() {
+ const { classes, theme } = this.props;
+ return (
+ <Fragment>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="select-multiple">Name</InputLabel>
+ <Select
+ multiple
+ value={this.state.name}
+ onChange={this.handleChange}
+ input={<Input id="select-multiple" />}
+ MenuProps={MenuProps}
+ >
+ {names.map(name => (
+ <MenuItem
+ key={name}
+ value={name}
+ style={{
+ fontWeight:
+ this.state.name.indexOf(name) === -1
+ ? theme.typography.fontWeightRegular
+ : theme.typography.fontWeightMedium,
+ }}
+ >
+ {name}
+ </MenuItem>
+ ))}
+ </Select>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="select-multiple-checkbox">Tag</InputLabel>
+ <Select
+ multiple
+ value={this.state.name}
+ onChange={this.handleChange}
+ input={<Input id="select-multiple-checkbox" />}
+ renderValue={selected => selected.join(', ')}
+ MenuProps={MenuProps}
+ >
+ {names.map(name => (
+ <MenuItem key={name} value={name}>
+ <Checkbox checked={this.state.name.indexOf(name) > -1} />
+ <ListItemText primary={name} />
+ </MenuItem>
+ ))}
+ </Select>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="select-multiple-chip">Chip</InputLabel>
+ <Select
+ multiple
+ value={this.state.name}
+ onChange={this.handleChange}
+ input={<Input id="select-multiple-chip" />}
+ renderValue={selected => (
+ <div className={classes.chips}>
+ {selected.map(value => <Chip key={value} label={value} className={classes.chip} />)}
+ </div>
+ )}
+ MenuProps={MenuProps}
+ >
+ {names.map(name => (
+ <MenuItem
+ key={name}
+ value={name}
+ style={{
+ fontWeight:
+ this.state.name.indexOf(name) === -1
+ ? theme.typography.fontWeightRegular
+ : theme.typography.fontWeightMedium,
+ }}
+ >
+ {name}
+ </MenuItem>
+ ))}
+ </Select>
+ </FormControl>
+ </Fragment>
+ );
+ }
+}
+
+MultipleSelectbox.propTypes = {
+ classes: PropTypes.object.isRequired,
+ theme: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles, { withTheme: true })(MultipleSelectbox);
diff --git a/front/odiparpack/app/containers/Forms/demos/NativeSelectbox.js b/front/odiparpack/app/containers/Forms/demos/NativeSelectbox.js
new file mode 100644
index 0000000..a0e3c4d
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/NativeSelectbox.js
@@ -0,0 +1,153 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+
+import { withStyles } from '@material-ui/core/styles';
+
+import { Input, InputLabel, FormControl, FormHelperText, Select } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ root: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ formControl: {
+ margin: theme.spacing(1),
+ minWidth: 120,
+ },
+ selectEmpty: {
+ marginTop: theme.spacing(2),
+ },
+});
+
+class NativeSelectbox extends PureComponent {
+ state = {
+ age: '',
+ name: 'hai',
+ };
+
+ handleChange = name => event => {
+ this.setState({ [name]: event.target.value });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-native-simple">Age</InputLabel>
+ <Select
+ native
+ value={this.state.age}
+ onChange={this.handleChange('age')}
+ inputProps={{
+ id: 'age-native-simple',
+ }}
+ >
+ <option value="" />
+ <option value={10}>Ten</option>
+ <option value={20}>Twenty</option>
+ <option value={30}>Thirty</option>
+ </Select>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-native-helper">Age</InputLabel>
+ <Select
+ native
+ value={this.state.age}
+ onChange={this.handleChange('age')}
+ input={<Input id="age-native-helper" />}
+ >
+ <option value="" />
+ <option value={10}>Ten</option>
+ <option value={20}>Twenty</option>
+ <option value={30}>Thirty</option>
+ </Select>
+ <FormHelperText>Some important helper text</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <Select
+ native
+ value={this.state.age}
+ onChange={this.handleChange('age')}
+ className={classes.selectEmpty}
+ >
+ <option value="">None</option>
+ <option value={10}>Ten</option>
+ <option value={20}>Twenty</option>
+ <option value={30}>Thirty</option>
+ </Select>
+ <FormHelperText>Without label</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl} disabled>
+ <InputLabel htmlFor="name-native-disabled">Name</InputLabel>
+ <Select
+ native
+ value={this.state.name}
+ onChange={this.handleChange('name')}
+ input={<Input id="name-native-disabled" />}
+ >
+ <option value="" />
+ <optgroup label="Author">
+ <option value="hai">Hai</option>
+ </optgroup>
+ <optgroup label="Contributors">
+ <option value="olivier">Olivier</option>
+ <option value="kevin">Kevin</option>
+ </optgroup>
+ </Select>
+ <FormHelperText>Disabled</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl} error>
+ <InputLabel htmlFor="name-native-error">Name</InputLabel>
+ <Select
+ native
+ value={this.state.name}
+ onChange={this.handleChange('name')}
+ input={<Input id="name-native-error" />}
+ >
+ <option value="" />
+ <optgroup label="Author">
+ <option value="hai">Hai</option>
+ </optgroup>
+ <optgroup label="Contributors">
+ <option value="olivier">Olivier</option>
+ <option value="kevin">Kevin</option>
+ </optgroup>
+ </Select>
+ <FormHelperText>Error</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="name-input">Name</InputLabel>
+ <Input id="name-input" />
+ <FormHelperText>Alignment with an input</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="uncontrolled-native">Name</InputLabel>
+ <Select native defaultValue={30} input={<Input id="uncontrolled-native" />}>
+ <option value="" />
+ <option value={10}>Ten</option>
+ <option value={20}>Twenty</option>
+ <option value={30}>Thirty</option>
+ </Select>
+ <FormHelperText>Uncontrolled</FormHelperText>
+ </FormControl>
+ </Fragment>
+ );
+ }
+}
+
+NativeSelectbox.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(NativeSelectbox);
diff --git a/front/odiparpack/app/containers/Forms/demos/RadioButton.js b/front/odiparpack/app/containers/Forms/demos/RadioButton.js
new file mode 100644
index 0000000..c378d96
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/RadioButton.js
@@ -0,0 +1,212 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import RadioButtonUncheckedIcon from '@material-ui/icons/RadioButtonUnchecked';
+import RadioButtonCheckedIcon from '@material-ui/icons/RadioButtonChecked';
+import { green } from '@material-ui/core/colors';
+
+import {
+ Radio,
+ RadioGroup,
+ Typography,
+ Grid,
+ FormControl,
+ FormLabel,
+ FormControlLabel,
+ FormHelperText,
+} from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ root: {
+ color: green[600],
+ '&$checked': {
+ color: green[500],
+ },
+ },
+ formControl: {
+ margin: theme.spacing(3),
+ },
+ group: {
+ margin: `${theme.spacing(1)}px 0`,
+ },
+ checked: {},
+ size: {
+ width: 40,
+ height: 40,
+ },
+ sizeIcon: {
+ fontSize: 20,
+ },
+});
+
+class RadioButton extends PureComponent {
+ state = {
+ value: 'female',
+ selectedValue: 'a',
+ };
+
+ handleChange = event => {
+ this.setState({ value: event.target.value });
+ };
+
+ handleChangeOther = event => {
+ this.setState({ selectedValue: event.target.value });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={7}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Basic usage</Typography>
+ <Typography className={classes.divider}>Radio buttons should have the most commonly used option selected by default.</Typography>
+ <div>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <FormControl component="fieldset" required className={classes.formControl}>
+ <FormLabel component="legend">Gender</FormLabel>
+ <RadioGroup
+ aria-label="gender"
+ name="gender1"
+ className={classes.group}
+ value={this.state.value}
+ onChange={this.handleChange}
+ >
+ <FormControlLabel value="female" control={<Radio />} label="Female" />
+ <FormControlLabel value="male" control={<Radio />} label="Male" />
+ <FormControlLabel value="other" control={<Radio />} label="Other" />
+ <FormControlLabel
+ value="disabled"
+ disabled
+ control={<Radio />}
+ label="(Disabled option)"
+ />
+ </RadioGroup>
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <FormControl component="fieldset" required error className={classes.formControl}>
+ <FormLabel component="legend">Gender</FormLabel>
+ <RadioGroup
+ aria-label="gender"
+ name="gender2"
+ className={classes.group}
+ value={this.state.value}
+ onChange={this.handleChange}
+ >
+ <FormControlLabel value="male" control={<Radio color="primary" />} label="Male" />
+ <FormControlLabel value="female" control={<Radio color="primary" />} label="Female" />
+ <FormControlLabel value="other" control={<Radio color="primary" />} label="Other" />
+ <FormControlLabel
+ value="disabled"
+ disabled
+ control={<Radio />}
+ label="(Disabled option)"
+ />
+ </RadioGroup>
+ <FormHelperText>You can display an error</FormHelperText>
+ </FormControl>
+ </Grid>
+ </Grid>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={5}
+ className={classes.demo}
+ >
+ <div>
+ <Typography variant="button" className={classes.divider}>Radio without label</Typography>
+ <Typography className={classes.divider}>Radio can also be used standalone, without the wrapper.</Typography>
+ <Radio
+ checked={this.state.selectedValue === 'a'}
+ onChange={this.handleChangeOther}
+ value="a"
+ name="radio-button-demo"
+ aria-label="A"
+ />
+ <Radio
+ checked={this.state.selectedValue === 'b'}
+ onChange={this.handleChangeOther}
+ value="b"
+ name="radio-button-demo"
+ aria-label="B"
+ />
+ <Radio
+ checked={this.state.selectedValue === 'c'}
+ onChange={this.handleChangeOther}
+ value="c"
+ name="radio-button-demo"
+ aria-label="C"
+ classes={{
+ root: classes.root,
+ checked: classes.checked,
+ }}
+ />
+ <Radio
+ checked={this.state.selectedValue === 'd'}
+ onChange={this.handleChangeOther}
+ value="d"
+ color="default"
+ name="radio-button-demo"
+ aria-label="D"
+ />
+ <Radio
+ checked={this.state.selectedValue === 'e'}
+ onChange={this.handleChangeOther}
+ value="e"
+ color="default"
+ name="radio-button-demo"
+ aria-label="E"
+ className={classes.size}
+ icon={<RadioButtonUncheckedIcon className={classes.sizeIcon} />}
+ checkedIcon={<RadioButtonCheckedIcon className={classes.sizeIcon} />}
+ />
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+RadioButton.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(RadioButton);
diff --git a/front/odiparpack/app/containers/Forms/demos/RangeInput.js b/front/odiparpack/app/containers/Forms/demos/RangeInput.js
new file mode 100644
index 0000000..247050e
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/RangeInput.js
@@ -0,0 +1,92 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import InputRange from 'react-input-range';
+import { withStyles } from '@material-ui/core/styles';
+import 'ba-styles/vendors/react-input-range/react-input-range.css';
+
+import { FormControl, Typography, Grid } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ inputRange: {
+ width: 300,
+ margin: `${theme.spacing(3)}px 5px`,
+ }
+});
+
+class RangeInput extends PureComponent {
+ state = {
+ valueRange: {
+ min: 3,
+ max: 7,
+ },
+ valueRangeLabel: {
+ min: 5,
+ max: 10,
+ },
+ }
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={2}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Range Input Basic</Typography>
+ <FormControl className={classes.formControl}>
+ <div className={classes.inputRange}>
+ <InputRange
+ draggableTrack
+ maxValue={20}
+ minValue={0}
+ onChange={value => this.setState({ valueRange: value })}
+ value={this.state.valueRange}
+ />
+ </div>
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Range with Label</Typography>
+ <FormControl className={classes.formControl}>
+ <div className={classes.inputRange}>
+ <InputRange
+ maxValue={20}
+ minValue={0}
+ formatLabel={value => `${value} kg`}
+ value={this.state.valueRangeLabel}
+ onChange={value => this.setState({ valueRangeLabel: value })}
+ />
+ </div>
+ </FormControl>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+RangeInput.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(RangeInput);
diff --git a/front/odiparpack/app/containers/Forms/demos/RatingCustom.js b/front/odiparpack/app/containers/Forms/demos/RatingCustom.js
new file mode 100644
index 0000000..002548b
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/RatingCustom.js
@@ -0,0 +1,176 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { AddCircle, AddCircleOutline, Remove, ThumbUp } from '@material-ui/icons';
+import { Rating } from 'ba-components';
+
+import { green, red, indigo as blue } from '@material-ui/core/colors';
+
+import { FormControl, Typography, Grid, Chip } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ chip: {
+ margin: theme.spacing(1),
+ fontWeight: 'bold',
+ color: '#FFF',
+ background: red[300]
+ },
+ blue: {
+ color: blue[300]
+ },
+ green: {
+ color: green[500]
+ },
+ red: {
+ color: red[300]
+ },
+ small: {
+ '& button': {
+ width: 72,
+ height: 72,
+ padding: 16
+ },
+ '& svg': {
+ width: 36,
+ height: 36
+ }
+ },
+ medium: {
+ '& button': {
+ width: 96,
+ height: 96,
+ padding: 24
+ },
+ '& svg': {
+ width: 48,
+ height: 48
+ }
+ },
+ large: {
+ '& button': {
+ width: 120,
+ height: 120,
+ padding: 30
+ },
+ '& svg': {
+ width: 60,
+ height: 60
+ }
+ }
+});
+
+class RatingCustom extends PureComponent {
+ state = {
+ rating: 3
+ }
+
+ handleChange = value => {
+ this.setState({ rating: value });
+ }
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={2}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Ratting Custom Icon</Typography>
+ <FormControl className={classes.formControl}>
+ <Rating
+ value={this.state.rating}
+ max={5}
+ onChange={(value) => this.handleChange(value)}
+ iconFilled={<ThumbUp className={classes.blue} />}
+ iconHovered={<ThumbUp className={classes.blue} />}
+ iconNormal={<Remove className={classes.red} />}
+ />
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Show Counter</Typography>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="flex-start"
+ direction="row"
+ >
+ <FormControl className={classes.formControl}>
+ <Rating
+ value={this.state.rating}
+ max={5}
+ onChange={(value) => this.handleChange(value)}
+ iconFilled={<AddCircle className={classes.green} />}
+ iconHovered={<AddCircleOutline className={classes.green} />}
+ iconNormal={<AddCircleOutline className={classes.green} />}
+ tooltipRenderer={(index) => <span>{ index }</span>}
+ tooltipPosition="bottom-center"
+ />
+ </FormControl>
+ <Chip label={this.state.rating} className={classes.chip} />
+ </Grid>
+ </Grid>
+ <Grid
+ item
+ md={12}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Ratting Custom Size</Typography>
+ <FormControl className={classes.formControl}>
+ <div className={classes.small}>
+ <Rating
+ value={this.state.rating}
+ max={5}
+ onChange={(value) => this.handleChange(value)}
+ />
+ </div>
+ <div className={classes.medium}>
+ <Rating
+ value={this.state.rating}
+ max={5}
+ onChange={(value) => this.handleChange(value)}
+ />
+ </div>
+ <div className={classes.large}>
+ <Rating
+ value={this.state.rating}
+ max={5}
+ onChange={(value) => this.handleChange(value)}
+ />
+ </div>
+ </FormControl>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+RatingCustom.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(RatingCustom);
diff --git a/front/odiparpack/app/containers/Forms/demos/RatingNormal.js b/front/odiparpack/app/containers/Forms/demos/RatingNormal.js
new file mode 100644
index 0000000..acfb50d
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/RatingNormal.js
@@ -0,0 +1,92 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { Rating } from 'ba-components';
+
+import { FormControl, Typography, Grid } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+});
+
+class RatingCustom extends PureComponent {
+ state = {
+ rating: 3
+ }
+
+ handleChange = value => {
+ this.setState({ rating: value });
+ }
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={2}
+ >
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Ratting Normal</Typography>
+ <FormControl className={classes.formControl}>
+ <Rating
+ value={this.state.rating}
+ max={5}
+ onChange={(value) => this.handleChange(value)}
+ />
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Read Only</Typography>
+ <FormControl className={classes.formControl}>
+ <Rating
+ value={2}
+ max={5}
+ readOnly
+ />
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Disabled</Typography>
+ <FormControl className={classes.formControl}>
+ <Rating
+ value={4}
+ max={5}
+ disabled
+ />
+ </FormControl>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+RatingCustom.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(RatingCustom);
diff --git a/front/odiparpack/app/containers/Forms/demos/ReduxFormDemo.js b/front/odiparpack/app/containers/Forms/demos/ReduxFormDemo.js
new file mode 100644
index 0000000..32b5d3d
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/ReduxFormDemo.js
@@ -0,0 +1,229 @@
+import React, { Component } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { Field, reduxForm } from 'redux-form/immutable';
+import { bindActionCreators } from 'redux';
+import { connect } from 'react-redux';
+import {
+ CheckboxRedux,
+ SelectRedux,
+ TextFieldRedux,
+ SwitchRedux
+} from 'ba-components/Forms/ReduxFormMUI';
+import { initAction, clearAction } from 'ba-actions/ReduxFormActions';
+
+import {
+ Paper,
+ MenuItem,
+ InputLabel,
+ Grid,
+ Radio,
+ RadioGroup,
+ FormControl,
+ FormLabel,
+ FormControlLabel,
+ Typography,
+ Button,
+} from '@material-ui/core';
+
+const renderRadioGroup = ({ input, ...rest }) => (
+ <RadioGroup
+ {...input}
+ {...rest}
+ valueselected={input.value}
+ onChange={(event, value) => input.onChange(value)}
+ />
+);
+
+// validation functions
+const required = value => (value == null ? 'Required' : undefined);
+const email = value => (
+ value && !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)
+ ? 'Invalid email'
+ : undefined
+);
+
+const styles = theme => ({
+ root: {
+ flexGrow: 1,
+ padding: 30
+ },
+ field: {
+ width: '100%',
+ marginBottom: 20
+ },
+ fieldBasic: {
+ width: '100%',
+ marginBottom: 20,
+ marginTop: 10
+ },
+ inlineWrap: {
+ display: 'flex',
+ flexDirection: 'row'
+ },
+ buttonInit: {
+ margin: theme.spacing(4),
+ textAlign: 'center'
+ },
+});
+
+const initData = {
+ text: 'Sample Text',
+ email: '[email protected]',
+ radio: 'option1',
+ selection: 'option1',
+ onof: true,
+ checkbox: true,
+ textarea: 'This is default text'
+};
+
+class ReduxFormDemo extends Component {
+ render() {
+ const trueBool = true;
+ const {
+ classes,
+ handleSubmit,
+ pristine,
+ reset,
+ submitting,
+ init,
+ clear
+ } = this.props;
+ return (
+ <div>
+ <Grid container spacing={3} alignItems="flex-start" direction="row" justify="center">
+ <Grid item xs={12} md={6}>
+ <Paper className={classes.root}>
+ <Typography variant="h5" component="h3">
+ Simple Form Example
+ </Typography>
+ <Typography component="p">
+ The delay between when you click (Submit) and when the alert dialog pops up is intentional, to simulate server latency.
+ </Typography>
+ <div className={classes.buttonInit}>
+ <Button onClick={() => init(initData)} color="secondary" type="button">
+ Load Sample Data
+ </Button>
+ <Button onClick={() => clear()} type="button">
+ Clear Data
+ </Button>
+ </div>
+ <form onSubmit={handleSubmit}>
+ <div>
+ <Field
+ name="text"
+ component={TextFieldRedux}
+ placeholder="Text Field"
+ label="Text Field"
+ validate={required}
+ required
+ ref={this.saveRef}
+ className={classes.field}
+ />
+ </div>
+ <div>
+ <Field
+ name="email"
+ component={TextFieldRedux}
+ placeholder="Email Field"
+ label="Email"
+ required
+ validate={[required, email]}
+ className={classes.field}
+ />
+ </div>
+ <div className={classes.fieldBasic}>
+ <FormLabel component="label">Choose One Option</FormLabel>
+ <Field name="radio" className={classes.inlineWrap} component={renderRadioGroup}>
+ <FormControlLabel value="option1" control={<Radio />} label="Option 1" />
+ <FormControlLabel value="option2" control={<Radio />} label="Option 2" />
+ </Field>
+ </div>
+ <div>
+ <FormControl className={classes.field}>
+ <InputLabel htmlFor="selection">Selection</InputLabel>
+ <Field
+ name="selection"
+ component={SelectRedux}
+ placeholder="Selection"
+ autoWidth={trueBool}
+ >
+ <MenuItem value="option1">Option One</MenuItem>
+ <MenuItem value="option2">Option Two</MenuItem>
+ <MenuItem value="option3">Option Three</MenuItem>
+ </Field>
+ </FormControl>
+ </div>
+ <div className={classes.fieldBasic}>
+ <FormLabel component="label">Toggle Input</FormLabel>
+ <div className={classes.inlineWrap}>
+ <FormControlLabel control={<Field name="onof" component={SwitchRedux} />} label="On/OF Switch" />
+ <FormControlLabel control={<Field name="checkbox" component={CheckboxRedux} />} label="Checkbox" />
+ </div>
+ </div>
+ <div className={classes.field}>
+ <Field
+ name="textarea"
+ className={classes.field}
+ component={TextFieldRedux}
+ placeholder="Textarea"
+ label="Textarea"
+ multiline={trueBool}
+ rows={4}
+ />
+ </div>
+ <div>
+ <Button variant="contained" color="secondary" type="submit" disabled={submitting}>
+ Submit
+ </Button>
+ <Button
+ type="button"
+ disabled={pristine || submitting}
+ onClick={reset}
+ >
+ Reset
+ </Button>
+ </div>
+ </form>
+ </Paper>
+ </Grid>
+ </Grid>
+ </div>
+ );
+ }
+}
+
+renderRadioGroup.propTypes = {
+ input: PropTypes.object.isRequired,
+};
+
+ReduxFormDemo.propTypes = {
+ classes: PropTypes.object.isRequired,
+ handleSubmit: PropTypes.func.isRequired,
+ reset: PropTypes.func.isRequired,
+ pristine: PropTypes.bool.isRequired,
+ submitting: PropTypes.bool.isRequired,
+ init: PropTypes.func.isRequired,
+ clear: PropTypes.func.isRequired,
+};
+
+const mapDispatchToProps = dispatch => ({
+ init: bindActionCreators(initAction, dispatch),
+ clear: () => dispatch(clearAction),
+});
+
+const ReduxFormMapped = reduxForm({
+ form: 'immutableExample',
+ enableReinitialize: true,
+})(ReduxFormDemo);
+
+const reducer = 'initval';
+const FormInit = connect(
+ state => ({
+ force: state,
+ initialValues: state.getIn([reducer, 'formValues'])
+ }),
+ mapDispatchToProps,
+)(ReduxFormMapped);
+
+export default withStyles(styles)(FormInit);
diff --git a/front/odiparpack/app/containers/Forms/demos/SelectSuggestionTags.js b/front/odiparpack/app/containers/Forms/demos/SelectSuggestionTags.js
new file mode 100644
index 0000000..125fd23
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/SelectSuggestionTags.js
@@ -0,0 +1,379 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import Select from 'react-select';
+import { emphasize, makeStyles, useTheme } from '@material-ui/core/styles';
+import Typography from '@material-ui/core/Typography';
+import NoSsr from '@material-ui/core/NoSsr';
+import TextField from '@material-ui/core/TextField';
+import Paper from '@material-ui/core/Paper';
+import Chip from '@material-ui/core/Chip';
+import MenuItem from '@material-ui/core/MenuItem';
+import CancelIcon from '@material-ui/icons/Cancel';
+
+const suggestions = [
+ { label: 'Afghanistan' },
+ { label: 'Aland Islands' },
+ { label: 'Albania' },
+ { label: 'Algeria' },
+ { label: 'American Samoa' },
+ { label: 'Andorra' },
+ { label: 'Angola' },
+ { label: 'Anguilla' },
+ { label: 'Antarctica' },
+ { label: 'Antigua and Barbuda' },
+ { label: 'Argentina' },
+ { label: 'Armenia' },
+ { label: 'Aruba' },
+ { label: 'Australia' },
+ { label: 'Austria' },
+ { label: 'Azerbaijan' },
+ { label: 'Bahamas' },
+ { label: 'Bahrain' },
+ { label: 'Bangladesh' },
+ { label: 'Barbados' },
+ { label: 'Belarus' },
+ { label: 'Belgium' },
+ { label: 'Belize' },
+ { label: 'Benin' },
+ { label: 'Bermuda' },
+ { label: 'Bhutan' },
+ { label: 'Bolivia, Plurinational State of' },
+ { label: 'Bonaire, Sint Eustatius and Saba' },
+ { label: 'Bosnia and Herzegovina' },
+ { label: 'Botswana' },
+ { label: 'Bouvet Island' },
+ { label: 'Brazil' },
+ { label: 'British Indian Ocean Territory' },
+ { label: 'Brunei Darussalam' },
+].map(suggestion => ({
+ value: suggestion.label,
+ label: suggestion.label,
+}));
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ flexGrow: 1,
+ height: 250,
+ },
+ input: {
+ display: 'flex',
+ padding: 0,
+ height: 'auto',
+ },
+ valueContainer: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ flex: 1,
+ alignItems: 'center',
+ overflow: 'hidden',
+ },
+ chip: {
+ margin: theme.spacing(0.5, 0.25),
+ },
+ chipFocused: {
+ backgroundColor: emphasize(
+ theme.palette.type === 'light' ? theme.palette.grey[300] : theme.palette.grey[700],
+ 0.08,
+ ),
+ },
+ noOptionsMessage: {
+ padding: theme.spacing(1, 2),
+ },
+ singleValue: {
+ fontSize: 16,
+ },
+ placeholder: {
+ position: 'absolute',
+ left: 8,
+ bottom: 6,
+ fontSize: 16,
+ },
+ paper: {
+ position: 'absolute',
+ zIndex: 1,
+ marginTop: theme.spacing(1),
+ left: 0,
+ right: 0,
+ },
+}));
+
+function NoOptionsMessage(props) {
+ const { selectProps, innerProps, children } = props;
+ return (
+ <Typography
+ color="textSecondary"
+ className={selectProps.classes.noOptionsMessage}
+ {...innerProps}
+ >
+ {children}
+ </Typography>
+ );
+}
+
+NoOptionsMessage.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object.isRequired,
+};
+
+NoOptionsMessage.defaultProps = {
+ children: null,
+ innerProps: null
+};
+
+function inputComponent({ inputRef, ...props }) {
+ return <div ref={inputRef} {...props} />;
+}
+
+inputComponent.propTypes = {
+ inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+};
+
+inputComponent.defaultProps = {
+ inputRef: undefined
+};
+
+function Control(props) {
+ const {
+ children,
+ innerProps,
+ innerRef,
+ selectProps: { classes, TextFieldProps },
+ } = props;
+
+ return (
+ <TextField
+ fullWidth
+ InputProps={{
+ inputComponent,
+ inputProps: {
+ className: classes.input,
+ ref: innerRef,
+ children,
+ ...innerProps,
+ },
+ }}
+ {...TextFieldProps}
+ />
+ );
+}
+
+Control.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ selectProps: PropTypes.object.isRequired,
+};
+
+Control.defaultProps = {
+ children: null,
+ innerProps: null,
+ innerRef: undefined
+};
+
+function Option(props) {
+ const {
+ innerRef,
+ isFocused,
+ isSelected,
+ innerProps,
+ children
+ } = props;
+ return (
+ <MenuItem
+ ref={innerRef}
+ selected={isFocused}
+ component="div"
+ style={{
+ fontWeight: isSelected ? 500 : 400,
+ }}
+ {...innerProps}
+ >
+ {children}
+ </MenuItem>
+ );
+}
+
+Option.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ isFocused: PropTypes.bool,
+ isSelected: PropTypes.bool,
+};
+
+Option.defaultProps = {
+ children: null,
+ innerProps: null,
+ innerRef: undefined,
+ isFocused: false,
+ isSelected: false
+};
+
+function Placeholder(props) {
+ const { selectProps, innerProps, children } = props;
+ return (
+ <Typography
+ color="textSecondary"
+ className={selectProps.classes.placeholder}
+ {...innerProps}
+ >
+ {children}
+ </Typography>
+ );
+}
+
+Placeholder.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object.isRequired,
+};
+
+Placeholder.defaultProps = {
+ children: null,
+ innerProps: null,
+};
+
+function SingleValue(props) {
+ const { selectProps, children, innerProps } = props;
+ return (
+ <Typography className={selectProps.classes.singleValue} {...innerProps}>
+ {children}
+ </Typography>
+ );
+}
+
+SingleValue.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object.isRequired,
+};
+
+SingleValue.defaultProps = {
+ children: null,
+ innerProps: null,
+};
+
+function ValueContainer(props) {
+ const { selectProps, children } = props;
+ return <div className={selectProps.classes.valueContainer}>{children}</div>;
+}
+
+ValueContainer.propTypes = {
+ children: PropTypes.node,
+ selectProps: PropTypes.object.isRequired,
+};
+
+ValueContainer.defaultProps = {
+ children: null,
+};
+
+function MultiValue(props) {
+ const {
+ children,
+ selectProps,
+ removeProps,
+ isFocused
+ } = props;
+ return (
+ <Chip
+ tabIndex={-1}
+ label={children}
+ className={classNames(selectProps.classes.chip, {
+ [selectProps.classes.chipFocused]: isFocused,
+ })}
+ onDelete={removeProps.onClick}
+ deleteIcon={<CancelIcon {...removeProps} />}
+ />
+ );
+}
+
+MultiValue.propTypes = {
+ children: PropTypes.node,
+ isFocused: PropTypes.bool,
+ removeProps: PropTypes.object.isRequired,
+ selectProps: PropTypes.object.isRequired,
+};
+
+MultiValue.defaultProps = {
+ children: null,
+ isFocused: false,
+};
+
+function Menu(props) {
+ const { selectProps, innerProps, children } = props;
+ return (
+ <Paper square className={selectProps.classes.paper} {...innerProps}>
+ {children}
+ </Paper>
+ );
+}
+
+Menu.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object,
+};
+
+Menu.defaultProps = {
+ children: null,
+ innerProps: null,
+ selectProps: null,
+};
+
+const components = {
+ Control,
+ Menu,
+ MultiValue,
+ NoOptionsMessage,
+ Option,
+ Placeholder,
+ SingleValue,
+ ValueContainer,
+};
+
+export default function SelectSuggestions() {
+ const classes = useStyles();
+ const theme = useTheme();
+ const [multi, setMulti] = React.useState(null);
+
+ function handleChangeMulti(value) {
+ setMulti(value);
+ }
+
+ const selectStyles = {
+ input: base => ({
+ ...base,
+ color: theme.palette.text.primary,
+ '& input': {
+ font: 'inherit',
+ },
+ }),
+ };
+
+ return (
+ <div className={classes.root}>
+ <NoSsr>
+ <Select
+ classes={classes}
+ styles={selectStyles}
+ inputId="react-select-multiple"
+ TextFieldProps={{
+ label: 'Countries',
+ InputLabelProps: {
+ htmlFor: 'react-select-multiple',
+ shrink: true,
+ },
+ placeholder: 'Select multiple countries',
+ }}
+ options={suggestions}
+ components={components}
+ value={multi}
+ onChange={handleChangeMulti}
+ isMulti
+ />
+ </NoSsr>
+ </div>
+ );
+}
diff --git a/front/odiparpack/app/containers/Forms/demos/SelectSuggestions.js b/front/odiparpack/app/containers/Forms/demos/SelectSuggestions.js
new file mode 100644
index 0000000..2986aff
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/SelectSuggestions.js
@@ -0,0 +1,378 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import Select from 'react-select';
+import { emphasize, makeStyles, useTheme } from '@material-ui/core/styles';
+import Typography from '@material-ui/core/Typography';
+import NoSsr from '@material-ui/core/NoSsr';
+import TextField from '@material-ui/core/TextField';
+import Paper from '@material-ui/core/Paper';
+import Chip from '@material-ui/core/Chip';
+import MenuItem from '@material-ui/core/MenuItem';
+import CancelIcon from '@material-ui/icons/Cancel';
+
+const suggestions = [
+ { label: 'Afghanistan' },
+ { label: 'Aland Islands' },
+ { label: 'Albania' },
+ { label: 'Algeria' },
+ { label: 'American Samoa' },
+ { label: 'Andorra' },
+ { label: 'Angola' },
+ { label: 'Anguilla' },
+ { label: 'Antarctica' },
+ { label: 'Antigua and Barbuda' },
+ { label: 'Argentina' },
+ { label: 'Armenia' },
+ { label: 'Aruba' },
+ { label: 'Australia' },
+ { label: 'Austria' },
+ { label: 'Azerbaijan' },
+ { label: 'Bahamas' },
+ { label: 'Bahrain' },
+ { label: 'Bangladesh' },
+ { label: 'Barbados' },
+ { label: 'Belarus' },
+ { label: 'Belgium' },
+ { label: 'Belize' },
+ { label: 'Benin' },
+ { label: 'Bermuda' },
+ { label: 'Bhutan' },
+ { label: 'Bolivia, Plurinational State of' },
+ { label: 'Bonaire, Sint Eustatius and Saba' },
+ { label: 'Bosnia and Herzegovina' },
+ { label: 'Botswana' },
+ { label: 'Bouvet Island' },
+ { label: 'Brazil' },
+ { label: 'British Indian Ocean Territory' },
+ { label: 'Brunei Darussalam' },
+].map(suggestion => ({
+ value: suggestion.label,
+ label: suggestion.label,
+}));
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ flexGrow: 1,
+ height: 250,
+ },
+ input: {
+ display: 'flex',
+ padding: 0,
+ height: 'auto',
+ },
+ valueContainer: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ flex: 1,
+ alignItems: 'center',
+ overflow: 'hidden',
+ },
+ chip: {
+ margin: theme.spacing(0.5, 0.25),
+ },
+ chipFocused: {
+ backgroundColor: emphasize(
+ theme.palette.type === 'light' ? theme.palette.grey[300] : theme.palette.grey[700],
+ 0.08,
+ ),
+ },
+ noOptionsMessage: {
+ padding: theme.spacing(1, 2),
+ },
+ singleValue: {
+ fontSize: 16,
+ },
+ placeholder: {
+ position: 'absolute',
+ left: 8,
+ bottom: 6,
+ fontSize: 16,
+ },
+ paper: {
+ position: 'absolute',
+ zIndex: 1,
+ marginTop: theme.spacing(1),
+ left: 0,
+ right: 0,
+ },
+}));
+
+function NoOptionsMessage(props) {
+ const { selectProps, innerProps, children } = props;
+ return (
+ <Typography
+ color="textSecondary"
+ className={selectProps.classes.noOptionsMessage}
+ {...innerProps}
+ >
+ {children}
+ </Typography>
+ );
+}
+
+NoOptionsMessage.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object.isRequired,
+};
+
+NoOptionsMessage.defaultProps = {
+ children: null,
+ innerProps: null
+};
+
+function inputComponent({ inputRef, ...props }) {
+ return <div ref={inputRef} {...props} />;
+}
+
+inputComponent.propTypes = {
+ inputRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+};
+
+inputComponent.defaultProps = {
+ inputRef: undefined
+};
+
+function Control(props) {
+ const {
+ children,
+ innerProps,
+ innerRef,
+ selectProps: { classes, TextFieldProps },
+ } = props;
+
+ return (
+ <TextField
+ fullWidth
+ InputProps={{
+ inputComponent,
+ inputProps: {
+ className: classes.input,
+ ref: innerRef,
+ children,
+ ...innerProps,
+ },
+ }}
+ {...TextFieldProps}
+ />
+ );
+}
+
+Control.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ selectProps: PropTypes.object.isRequired,
+};
+
+Control.defaultProps = {
+ children: null,
+ innerProps: null,
+ innerRef: undefined
+};
+
+function Option(props) {
+ const {
+ innerRef,
+ isFocused,
+ isSelected,
+ innerProps,
+ children
+ } = props;
+ return (
+ <MenuItem
+ ref={innerRef}
+ selected={isFocused}
+ component="div"
+ style={{
+ fontWeight: isSelected ? 500 : 400,
+ }}
+ {...innerProps}
+ >
+ {children}
+ </MenuItem>
+ );
+}
+
+Option.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ innerRef: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
+ isFocused: PropTypes.bool,
+ isSelected: PropTypes.bool,
+};
+
+Option.defaultProps = {
+ children: null,
+ innerProps: null,
+ innerRef: undefined,
+ isFocused: false,
+ isSelected: false
+};
+
+function Placeholder(props) {
+ const { selectProps, innerProps, children } = props;
+ return (
+ <Typography
+ color="textSecondary"
+ className={selectProps.classes.placeholder}
+ {...innerProps}
+ >
+ {children}
+ </Typography>
+ );
+}
+
+Placeholder.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object.isRequired,
+};
+
+Placeholder.defaultProps = {
+ children: null,
+ innerProps: null,
+};
+
+function SingleValue(props) {
+ const { selectProps, children, innerProps } = props;
+ return (
+ <Typography className={selectProps.classes.singleValue} {...innerProps}>
+ {children}
+ </Typography>
+ );
+}
+
+SingleValue.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object.isRequired,
+};
+
+SingleValue.defaultProps = {
+ children: null,
+ innerProps: null,
+};
+
+function ValueContainer(props) {
+ const { selectProps, children } = props;
+ return <div className={selectProps.classes.valueContainer}>{children}</div>;
+}
+
+ValueContainer.propTypes = {
+ children: PropTypes.node,
+ selectProps: PropTypes.object.isRequired,
+};
+
+ValueContainer.defaultProps = {
+ children: null,
+};
+
+function MultiValue(props) {
+ const {
+ children,
+ selectProps,
+ removeProps,
+ isFocused
+ } = props;
+ return (
+ <Chip
+ tabIndex={-1}
+ label={children}
+ className={classNames(selectProps.classes.chip, {
+ [selectProps.classes.chipFocused]: isFocused,
+ })}
+ onDelete={removeProps.onClick}
+ deleteIcon={<CancelIcon {...removeProps} />}
+ />
+ );
+}
+
+MultiValue.propTypes = {
+ children: PropTypes.node,
+ isFocused: PropTypes.bool,
+ removeProps: PropTypes.object.isRequired,
+ selectProps: PropTypes.object.isRequired,
+};
+
+MultiValue.defaultProps = {
+ children: null,
+ isFocused: false,
+};
+
+function Menu(props) {
+ const { selectProps, innerProps, children } = props;
+ return (
+ <Paper square className={selectProps.classes.paper} {...innerProps}>
+ {children}
+ </Paper>
+ );
+}
+
+Menu.propTypes = {
+ children: PropTypes.node,
+ innerProps: PropTypes.object,
+ selectProps: PropTypes.object,
+};
+
+Menu.defaultProps = {
+ children: null,
+ innerProps: null,
+ selectProps: null,
+};
+
+const components = {
+ Control,
+ Menu,
+ MultiValue,
+ NoOptionsMessage,
+ Option,
+ Placeholder,
+ SingleValue,
+ ValueContainer,
+};
+
+export default function SelectSuggestions() {
+ const classes = useStyles();
+ const theme = useTheme();
+ const [single, setSingle] = React.useState(null);
+
+ function handleChangeSingle(value) {
+ setSingle(value);
+ }
+
+ const selectStyles = {
+ input: base => ({
+ ...base,
+ color: theme.palette.text.primary,
+ '& input': {
+ font: 'inherit',
+ },
+ }),
+ };
+
+ return (
+ <div className={classes.root}>
+ <NoSsr>
+ <Select
+ classes={classes}
+ styles={selectStyles}
+ inputId="react-select-single"
+ TextFieldProps={{
+ label: 'Country',
+ InputLabelProps: {
+ htmlFor: 'react-select-single',
+ shrink: true,
+ },
+ placeholder: 'Search a country (start with a)',
+ }}
+ options={suggestions}
+ components={components}
+ value={single}
+ onChange={handleChangeSingle}
+ />
+ </NoSsr>
+ </div>
+ );
+}
diff --git a/front/odiparpack/app/containers/Forms/demos/SimpleSelectbox.js b/front/odiparpack/app/containers/Forms/demos/SimpleSelectbox.js
new file mode 100644
index 0000000..eb7bd0a
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/SimpleSelectbox.js
@@ -0,0 +1,180 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+
+import { withStyles } from '@material-ui/core/styles';
+
+import { Input, InputLabel, MenuItem, FormControl, FormHelperText, Select } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ root: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ formControl: {
+ margin: theme.spacing(1),
+ minWidth: 120,
+ },
+ selectEmpty: {
+ marginTop: theme.spacing(2),
+ },
+});
+
+class SimpleSelectbox extends PureComponent {
+ state = {
+ age: '',
+ name: 'hai',
+ };
+
+ handleChange = event => {
+ this.setState({ [event.target.name]: event.target.value });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <form className={classes.root} autoComplete="off">
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-simple2">Age</InputLabel>
+ <Select
+ value={this.state.age}
+ onChange={this.handleChange}
+ inputProps={{
+ name: 'age',
+ id: 'age-simple2',
+ }}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value={10}>Ten</MenuItem>
+ <MenuItem value={20}>Twenty</MenuItem>
+ <MenuItem value={30}>Thirty</MenuItem>
+ </Select>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-helper">Age</InputLabel>
+ <Select
+ value={this.state.age}
+ onChange={this.handleChange}
+ input={<Input name="age" id="age-helper" />}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value={10}>Ten</MenuItem>
+ <MenuItem value={20}>Twenty</MenuItem>
+ <MenuItem value={30}>Thirty</MenuItem>
+ </Select>
+ <FormHelperText>Some important helper text</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <Select
+ value={this.state.age}
+ onChange={this.handleChange}
+ displayEmpty
+ name="age"
+ className={classes.selectEmpty}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value={10}>Ten</MenuItem>
+ <MenuItem value={20}>Twenty</MenuItem>
+ <MenuItem value={30}>Thirty</MenuItem>
+ </Select>
+ <FormHelperText>Without label</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl} disabled>
+ <InputLabel htmlFor="name-disabled">Name</InputLabel>
+ <Select
+ value={this.state.name}
+ onChange={this.handleChange}
+ input={<Input name="name" id="name-disabled" />}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value="hai">Hai</MenuItem>
+ <MenuItem value="olivier">Olivier</MenuItem>
+ <MenuItem value="kevin">Kevin</MenuItem>
+ </Select>
+ <FormHelperText>Disabled</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl} error>
+ <InputLabel htmlFor="name-error">Name</InputLabel>
+ <Select
+ value={this.state.name}
+ onChange={this.handleChange}
+ name="name"
+ renderValue={value => `⚠️ - ${value}`}
+ input={<Input id="name-error" />}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value="hai">Hai</MenuItem>
+ <MenuItem value="olivier">Olivier</MenuItem>
+ <MenuItem value="kevin">Kevin</MenuItem>
+ </Select>
+ <FormHelperText>Error</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="name-input">Name</InputLabel>
+ <Input id="name-input" />
+ <FormHelperText>Alignment with an input</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="name-readonly">Name</InputLabel>
+ <Select
+ value={this.state.name}
+ onChange={this.handleChange}
+ input={<Input name="name" id="name-readonly" readOnly />}
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value="hai">Hai</MenuItem>
+ <MenuItem value="olivier">Olivier</MenuItem>
+ <MenuItem value="kevin">Kevin</MenuItem>
+ </Select>
+ <FormHelperText>Read only</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="age-simple3">Age</InputLabel>
+ <Select
+ value={this.state.age}
+ onChange={this.handleChange}
+ input={<Input name="age" id="age-simple3" />}
+ autoWidth
+ >
+ <MenuItem value="">
+ <em>None</em>
+ </MenuItem>
+ <MenuItem value={10}>Ten</MenuItem>
+ <MenuItem value={20}>Twenty</MenuItem>
+ <MenuItem value={30}>Thirty</MenuItem>
+ </Select>
+ <FormHelperText>Auto width</FormHelperText>
+ </FormControl>
+ </form>
+ </Fragment>
+ );
+ }
+}
+
+SimpleSelectbox.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(SimpleSelectbox);
diff --git a/front/odiparpack/app/containers/Forms/demos/SliderInput.js b/front/odiparpack/app/containers/Forms/demos/SliderInput.js
new file mode 100644
index 0000000..d0513ed
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/SliderInput.js
@@ -0,0 +1,104 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import InputRange from 'react-input-range';
+import { withStyles } from '@material-ui/core/styles';
+import 'ba-styles/vendors/react-input-range/react-input-range.css';
+
+import { FormControl, Typography, Grid } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ inputRange: {
+ width: 200,
+ margin: `${theme.spacing(3)}px 5px`,
+ }
+});
+
+class SliderInput extends PureComponent {
+ state = {
+ value: 10,
+ valueDisabled: 5,
+ valueDecimal: 16,
+ }
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={2}
+ >
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Slider Input Basic</Typography>
+ <FormControl className={classes.formControl}>
+ <div className={classes.inputRange}>
+ <InputRange
+ maxValue={20}
+ minValue={0}
+ value={this.state.value}
+ onChange={value => this.setState({ value })}
+ />
+ </div>
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Slider Input Disabled</Typography>
+ <FormControl className={classes.formControl}>
+ <div className={classes.inputRange}>
+ <InputRange
+ maxValue={20}
+ minValue={0}
+ disabled
+ value={this.state.valueDisabled}
+ onChange={value => this.setState({ valueDisabled: value })}
+ />
+ </div>
+ </FormControl>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Formated Value</Typography>
+ <FormControl className={classes.formControl}>
+ <div className={classes.inputRange}>
+ <InputRange
+ maxValue={20}
+ minValue={0}
+ formatLabel={value => value.toFixed(2)}
+ value={this.state.valueDecimal}
+ onChange={value => this.setState({ valueDecimal: value })}
+ />
+ </div>
+ </FormControl>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+SliderInput.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(SliderInput);
diff --git a/front/odiparpack/app/containers/Forms/demos/StandardButtons.js b/front/odiparpack/app/containers/Forms/demos/StandardButtons.js
new file mode 100644
index 0000000..d88c004
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/StandardButtons.js
@@ -0,0 +1,223 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import { withStyles } from '@material-ui/core/styles';
+import DeleteIcon from '@material-ui/icons/Delete';
+import AddShoppingCartIcon from '@material-ui/icons/AddShoppingCart';
+import PhotoCamera from '@material-ui/icons/PhotoCamera';
+import FileUpload from '@material-ui/icons/CloudUpload';
+import KeyboardVoice from '@material-ui/icons/KeyboardVoice';
+import Save from '@material-ui/icons/Save';
+
+import { Button, Typography, Grid, Icon, IconButton } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ button: {
+ margin: theme.spacing(1),
+ },
+ inputUpload: {
+ display: 'none',
+ },
+ leftIcon: {
+ marginRight: theme.spacing(1),
+ },
+ rightIcon: {
+ marginLeft: theme.spacing(1),
+ },
+ iconSmall: {
+ fontSize: 20,
+ },
+});
+
+function doSomething(event) {
+ alert(event.currentTarget.getAttribute('data-something'));
+}
+
+class StandardButtons extends PureComponent {
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="center"
+ justify="flex-start"
+ direction="row"
+ spacing={2}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Flat Button</Typography>
+ <Typography className={classes.divider}>
+ Flat buttons are text-only buttons. They may be used in dialogs, toolbars, or inline. They do not lift, but fill with color on press.
+ </Typography>
+ <Button className={classes.button}>Default</Button>
+ <Button color="primary" className={classes.button}>
+ Primary
+ </Button>
+ <Button color="secondary" className={classes.button}>
+ Secondary
+ </Button>
+ <Button disabled className={classes.button}>
+ Disabled
+ </Button>
+ <Button href="#flat-buttons" className={classes.button}>
+ Link
+ </Button>
+ <Button disabled href="/" className={classes.button}>
+ Link disabled
+ </Button>
+ <Button className={classes.button} onClick={doSomething} data-something="here I am">
+ Does something
+ </Button>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Raised Button</Typography>
+ <Typography className={classes.divider}>
+ Raised buttons are rectangular-shaped buttons. They may be used inline. They lift and display ink reactions on press.
+ </Typography>
+ <Button variant="contained" className={classes.button}>
+ Default
+ </Button>
+ <Button variant="contained" color="primary" className={classes.button}>
+ Primary
+ </Button>
+ <Button variant="contained" color="secondary" className={classes.button}>
+ Secondary
+ </Button>
+ <Button variant="contained" color="secondary" disabled className={classes.button}>
+ Disabled
+ </Button>
+ <input
+ accept="image/*"
+ className={classes.inputUpload}
+ id="raised-button-file"
+ multiple
+ type="file"
+ />
+ <label htmlFor="raised-button-file">
+ <Button variant="contained" component="span" className={classes.button}>
+ Upload
+ </Button>
+ </label>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Outline Button</Typography>
+ <Button variant="outlined" className={classes.button}>
+ Default
+ </Button>
+ <Button variant="outlined" color="primary" className={classes.button}>
+ Primary
+ </Button>
+ <Button variant="outlined" color="secondary" className={classes.button}>
+ Secondary
+ </Button>
+ <Button variant="outlined" disabled className={classes.button}>
+ Disabled
+ </Button>
+ <Button variant="outlined" href="#outlined-buttons" className={classes.button}>
+ Link
+ </Button>
+ <input
+ accept="image/*"
+ className={classes.inputUpload}
+ id="outlined-button-file"
+ multiple
+ type="file"
+ />
+ <label htmlFor="outlined-button-file">
+ <Button variant="outlined" component="span" className={classes.button}>
+ Upload
+ </Button>
+ </label>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Icon Button</Typography>
+ <Typography className={classes.divider}>
+ Icon buttons are commonly found in app bars and toolbars.
+ </Typography>
+ <IconButton className={classes.button} aria-label="Delete">
+ <DeleteIcon />
+ </IconButton>
+ <IconButton className={classes.button} aria-label="Delete" disabled color="primary">
+ <DeleteIcon />
+ </IconButton>
+ <IconButton color="secondary" className={classes.button} aria-label="Add an alarm">
+ <Icon>alarm</Icon>
+ </IconButton>
+ <IconButton color="primary" className={classes.button} aria-label="Add to shopping cart">
+ <AddShoppingCartIcon />
+ </IconButton>
+ <input accept="image/*" className={classes.inputUpload} id="icon-button-file" type="file" />
+ <label htmlFor="icon-button-file">
+ <IconButton color="primary" className={classes.button} component="span">
+ <PhotoCamera />
+ </IconButton>
+ </label>
+ </Grid>
+ <Grid
+ item
+ md={12}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Icon Raised Button</Typography>
+ <Typography className={classes.divider}>
+ Icon buttons are commonly found in app bars and toolbars.
+ </Typography>
+ <Button className={classes.button} variant="contained" color="secondary">
+ Delete
+ <DeleteIcon className={classes.rightIcon} />
+ </Button>
+ <Button className={classes.button} variant="contained" color="primary">
+ Send
+ <Icon className={classes.rightIcon}>send</Icon>
+ </Button>
+ <Button className={classes.button} variant="contained" color="default">
+ Upload
+ <FileUpload className={classes.rightIcon} />
+ </Button>
+ <Button className={classes.button} variant="contained" disabled color="secondary">
+ <KeyboardVoice className={classes.leftIcon} />
+ Talk
+ </Button>
+ <Button className={classes.button} variant="contained" size="small">
+ <Save className={classNames(classes.leftIcon, classes.iconSmall)} />
+ Save
+ </Button>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+StandardButtons.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(StandardButtons);
diff --git a/front/odiparpack/app/containers/Forms/demos/SwitchesInput.js b/front/odiparpack/app/containers/Forms/demos/SwitchesInput.js
new file mode 100644
index 0000000..3c10803
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/SwitchesInput.js
@@ -0,0 +1,210 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { green } from '@material-ui/core/colors';
+
+import {
+ Switch,
+ Typography,
+ Grid,
+ FormControl,
+ FormLabel,
+ FormControlLabel,
+ FormGroup,
+ FormHelperText,
+} from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ field: {
+ margin: `${theme.spacing(3)}px 5px`,
+ },
+ formControl: {
+ margin: theme.spacing(3),
+ },
+ group: {
+ margin: `${theme.spacing(1)}px 0`,
+ },
+ switchBase: {
+ color: green[50],
+ '&$checked': {
+ color: green[500],
+ '& + $bar': {
+ backgroundColor: green[500],
+ },
+ },
+ },
+ bar: {},
+ checked: {},
+ size: {
+ width: 40,
+ height: 40,
+ },
+ sizeIcon: {
+ fontSize: 20,
+ },
+});
+
+class RadioButton extends PureComponent {
+ state = {
+ checkedA: true,
+ checkedB: true,
+ checkedF: true,
+ gilad: true,
+ jason: false,
+ antoine: true,
+ };
+
+ handleChange = name => event => {
+ this.setState({ [name]: event.target.checked });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={3}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Basic usage</Typography>
+ <div>
+ <Switch
+ checked={this.state.checkedA}
+ onChange={this.handleChange('checkedA')}
+ value="checkedA"
+ />
+ <Switch
+ checked={this.state.checkedB}
+ onChange={this.handleChange('checkedB')}
+ value="checkedB"
+ color="primary"
+ />
+ <Switch value="checkedC" />
+ <Switch disabled value="checkedD" />
+ <Switch disabled checked value="checkedE" />
+ <Switch defaultChecked value="checkedF" color="default" />
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={4}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Switch with label</Typography>
+ <Typography className={classes.divider}>Switch can also be used with a label description thanks to the FormControlLabel component.</Typography>
+ <div>
+ <FormGroup row>
+ <FormControlLabel
+ control={(
+ <Switch
+ checked={this.state.checkedA}
+ onChange={this.handleChange('checkedA')}
+ value="checkedA"
+ />
+ )}
+ label="Secondary"
+ />
+ <FormControlLabel
+ control={(
+ <Switch
+ checked={this.state.checkedB}
+ onChange={this.handleChange('checkedB')}
+ value="checkedB"
+ color="primary"
+ />
+ )}
+ label="Primary"
+ />
+ <FormControlLabel control={<Switch value="checkedC" />} label="Uncontrolled" />
+ <FormControlLabel disabled control={<Switch value="checkedD" />} label="Disabled" />
+ <FormControlLabel disabled control={<Switch checked value="checkedE" />} label="Disabled" />
+ <FormControlLabel
+ control={(
+ <Switch
+ checked={this.state.checkedF}
+ onChange={this.handleChange('checkedF')}
+ value="checkedF"
+ classes={{
+ switchBase: classes.switchBase,
+ checked: classes.checked,
+ track: classes.bar,
+ }}
+ />
+ )}
+ label="Custom color"
+ />
+ </FormGroup>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={5}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Switch in Form Group</Typography>
+ <Typography className={classes.divider}>FormGroup is a helpful wrapper used to group selection controls components that provides an easier API. However, we encourage you to use a Checkbox instead.</Typography>
+ <div>
+ <FormControl component="fieldset">
+ <FormLabel component="legend">Assign responsibility</FormLabel>
+ <FormGroup>
+ <FormControlLabel
+ control={(
+ <Switch
+ checked={this.state.gilad}
+ onChange={this.handleChange('gilad')}
+ value="gilad"
+ />
+ )}
+ label="Gilad Gray"
+ />
+ <FormControlLabel
+ control={(
+ <Switch
+ checked={this.state.jason}
+ onChange={this.handleChange('jason')}
+ value="jason"
+ />
+ )}
+ label="Jason Killian"
+ />
+ <FormControlLabel
+ control={(
+ <Switch
+ checked={this.state.antoine}
+ onChange={this.handleChange('antoine')}
+ value="antoine"
+ />
+ )}
+ label="Antoine Llorca"
+ />
+ </FormGroup>
+ <FormHelperText>Be careful</FormHelperText>
+ </FormControl>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+RadioButton.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(RadioButton);
diff --git a/front/odiparpack/app/containers/Forms/demos/TagSuggestions.js b/front/odiparpack/app/containers/Forms/demos/TagSuggestions.js
new file mode 100644
index 0000000..1648fc3
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/TagSuggestions.js
@@ -0,0 +1,249 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import keycode from 'keycode';
+import Downshift from 'downshift';
+import { withStyles } from '@material-ui/core/styles';
+import { TextField, Paper, MenuItem, Chip } from '@material-ui/core';
+
+const suggestions = [
+ { label: 'Afghanistan' },
+ { label: 'Aland Islands' },
+ { label: 'Albania' },
+ { label: 'Algeria' },
+ { label: 'American Samoa' },
+ { label: 'Andorra' },
+ { label: 'Angola' },
+ { label: 'Anguilla' },
+ { label: 'Antarctica' },
+ { label: 'Antigua and Barbuda' },
+ { label: 'Argentina' },
+ { label: 'Armenia' },
+ { label: 'Aruba' },
+ { label: 'Australia' },
+ { label: 'Austria' },
+ { label: 'Azerbaijan' },
+ { label: 'Bahamas' },
+ { label: 'Bahrain' },
+ { label: 'Bangladesh' },
+ { label: 'Barbados' },
+ { label: 'Belarus' },
+ { label: 'Belgium' },
+ { label: 'Belize' },
+ { label: 'Benin' },
+ { label: 'Bermuda' },
+ { label: 'Bhutan' },
+ { label: 'Bolivia, Plurinational State of' },
+ { label: 'Bonaire, Sint Eustatius and Saba' },
+ { label: 'Bosnia and Herzegovina' },
+ { label: 'Botswana' },
+ { label: 'Bouvet Island' },
+ { label: 'Brazil' },
+ { label: 'British Indian Ocean Territory' },
+ { label: 'Brunei Darussalam' },
+];
+
+function renderInput(inputProps) {
+ const {
+ InputProps,
+ classes,
+ ref,
+ ...other
+ } = inputProps;
+
+ return (
+ <TextField
+ InputProps={{
+ inputRef: ref,
+ classes: {
+ root: classes.inputRoot,
+ },
+ ...InputProps,
+ }}
+ {...other}
+ />
+ );
+}
+
+function renderSuggestion({
+ suggestion,
+ index,
+ itemProps,
+ highlightedIndex,
+ selectedItem
+}) {
+ const isHighlighted = highlightedIndex === index;
+ const isSelected = (selectedItem || '').indexOf(suggestion.label) > -1;
+
+ return (
+ <MenuItem
+ {...itemProps}
+ key={suggestion.label}
+ selected={isHighlighted}
+ component="div"
+ style={{
+ fontWeight: isSelected ? 500 : 400,
+ }}
+ >
+ {suggestion.label}
+ </MenuItem>
+ );
+}
+
+renderSuggestion.propTypes = {
+ highlightedIndex: PropTypes.number.isRequired,
+ index: PropTypes.number.isRequired,
+ itemProps: PropTypes.object.isRequired,
+ selectedItem: PropTypes.string.isRequired,
+ suggestion: PropTypes.shape({ label: PropTypes.string }).isRequired,
+};
+
+function getSuggestions(inputValue) {
+ let count = 0;
+
+ return suggestions.filter(suggestion => {
+ const keep = (!inputValue || suggestion.label.toLowerCase().indexOf(inputValue.toLowerCase()) !== -1)
+ && count < 5;
+
+ if (keep) {
+ count += 1;
+ }
+
+ return keep;
+ });
+}
+
+class DownshiftMultiple extends React.Component {
+ state = {
+ inputValue: '',
+ selectedItem: [],
+ };
+
+ handleKeyDown = event => {
+ const { inputValue, selectedItem } = this.state;
+ if (selectedItem.length && !inputValue.length && keycode(event) === 'backspace') {
+ this.setState({
+ selectedItem: selectedItem.slice(0, selectedItem.length - 1),
+ });
+ }
+ };
+
+ handleInputChange = event => {
+ this.setState({ inputValue: event.target.value });
+ };
+
+ handleChange = item => {
+ let { selectedItem } = this.state;
+
+ if (selectedItem.indexOf(item) === -1) {
+ selectedItem = [...selectedItem, item];
+ }
+
+ this.setState({
+ inputValue: '',
+ selectedItem,
+ });
+ };
+
+ handleDelete = item => () => {
+ const selectedItem = [...this.state.selectedItem];
+ selectedItem.splice(selectedItem.indexOf(item), 1);
+
+ this.setState({ selectedItem });
+ };
+
+ render() {
+ const { classes } = this.props;
+ const { inputValue, selectedItem } = this.state;
+
+ return (
+ <Downshift inputValue={inputValue} onChange={this.handleChange} selectedItem={selectedItem}>
+ {({
+ getInputProps,
+ getItemProps,
+ isOpen,
+ inputValue: inputValue2,
+ selectedItem: selectedItem2,
+ highlightedIndex,
+ }) => (
+ <div className={classes.container}>
+ {renderInput({
+ fullWidth: true,
+ classes,
+ InputProps: getInputProps({
+ startAdornment: selectedItem.map(item => (
+ <Chip
+ key={item}
+ tabIndex={-1}
+ label={item}
+ className={classes.chip}
+ onDelete={this.handleDelete(item)}
+ />
+ )),
+ onChange: this.handleInputChange,
+ onKeyDown: this.handleKeyDown,
+ placeholder: 'Select multiple countries',
+ id: 'integration-downshift-multiple',
+ }),
+ })}
+ {isOpen ? (
+ <Paper className={classes.paper} square>
+ {getSuggestions(inputValue2).map((suggestion, index) => renderSuggestion({
+ suggestion,
+ index,
+ itemProps: getItemProps({ item: suggestion.label }),
+ highlightedIndex,
+ selectedItem: selectedItem2,
+ }),
+ )}
+ </Paper>
+ ) : null}
+ </div>
+ )}
+ </Downshift>
+ );
+ }
+}
+
+DownshiftMultiple.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+const styles = theme => ({
+ root: {
+ flexGrow: 1,
+ height: 100,
+ },
+ container: {
+ flexGrow: 1,
+ position: 'relative',
+ },
+ paper: {
+ position: 'absolute',
+ zIndex: 1,
+ marginTop: theme.spacing(1),
+ left: 0,
+ right: 0,
+ },
+ chip: {
+ margin: `${theme.spacing(0.5)}px ${theme.spacing(0.25)}px`,
+ },
+ inputRoot: {
+ flexWrap: 'wrap',
+ },
+});
+
+function TagSuggestions(props) {
+ const { classes } = props;
+
+ return (
+ <div className={classes.root}>
+ <DownshiftMultiple classes={classes} />
+ </div>
+ );
+}
+
+TagSuggestions.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(TagSuggestions);
diff --git a/front/odiparpack/app/containers/Forms/demos/TextFields.js b/front/odiparpack/app/containers/Forms/demos/TextFields.js
new file mode 100644
index 0000000..b408284
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/TextFields.js
@@ -0,0 +1,124 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { Typography, Grid, Input, InputLabel, FormControl, FormHelperText } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ input: {
+ margin: theme.spacing(3),
+ },
+ container: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ formControl: {
+ margin: theme.spacing(3),
+ },
+});
+
+class TextFields extends PureComponent {
+ state = {
+ name: 'Composed TextField',
+ };
+
+ handleChange = event => {
+ this.setState({ name: event.target.value });
+ };
+
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="flex-start"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Textfield Components</Typography>
+ <Typography className={classes.divider}>TextField is composed of smaller components that you can leverage directly to significantly customize your form inputs.</Typography>
+ <div className={classes.container}>
+ <FormControl className={classes.formControl}>
+ <InputLabel htmlFor="name-simple">Name</InputLabel>
+ <Input id="name-simple" value={this.state.name} onChange={this.handleChange} />
+ </FormControl>
+ <FormControl className={classes.formControl} aria-describedby="name-helper-text">
+ <InputLabel htmlFor="name-helper">Name</InputLabel>
+ <Input id="name-helper" value={this.state.name} onChange={this.handleChange} />
+ <FormHelperText id="name-helper-text">Some important helper text</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl} disabled>
+ <InputLabel htmlFor="name-disabled">Name</InputLabel>
+ <Input id="name-disabled" value={this.state.name} onChange={this.handleChange} />
+ <FormHelperText>Disabled</FormHelperText>
+ </FormControl>
+ <FormControl className={classes.formControl} error aria-describedby="name-error-text">
+ <InputLabel htmlFor="name-error">Name</InputLabel>
+ <Input id="name-error" value={this.state.name} onChange={this.handleChange} />
+ <FormHelperText id="name-error-text">Error</FormHelperText>
+ </FormControl>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Input State</Typography>
+ <div className={classes.container}>
+ <Input
+ defaultValue="Hello world"
+ className={classes.input}
+ inputProps={{
+ 'aria-label': 'Description',
+ }}
+ />
+ <Input
+ placeholder="Placeholder"
+ className={classes.input}
+ inputProps={{
+ 'aria-label': 'Description',
+ }}
+ />
+ <Input
+ value="Disabled"
+ className={classes.input}
+ disabled
+ inputProps={{
+ 'aria-label': 'Description',
+ }}
+ />
+ <Input
+ defaultValue="Error"
+ className={classes.input}
+ error
+ inputProps={{
+ 'aria-label': 'Description',
+ }}
+ />
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+TextFields.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(TextFields);
diff --git a/front/odiparpack/app/containers/Forms/demos/TextFieldsLayout.js b/front/odiparpack/app/containers/Forms/demos/TextFieldsLayout.js
new file mode 100644
index 0000000..27809f4
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/TextFieldsLayout.js
@@ -0,0 +1,174 @@
+import React, { Fragment, PureComponent } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles, MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
+import { purple, green } from '@material-ui/core/colors';
+
+import { Typography, Grid, Input, InputLabel, TextField, FormControl } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ lineHeight: '24px'
+ },
+ input: {
+ margin: theme.spacing(3),
+ },
+ margin: {
+ margin: theme.spacing(1),
+ },
+ container: {
+ display: 'flex',
+ flexWrap: 'wrap',
+ },
+ textField: {
+ margin: `${theme.spacing(2)}px ${theme.spacing(1)}px`,
+ width: 200,
+ },
+ cssLabel: {
+ '&$cssFocused': {
+ color: purple[500],
+ },
+ },
+ cssFocused: {},
+ cssUnderline: {
+ '&:after': {
+ backgroundColor: purple[500],
+ },
+ },
+ bootstrapRoot: {
+ padding: 0,
+ 'label + &': {
+ marginTop: theme.spacing(3),
+ },
+ },
+ bootstrapInput: {
+ borderRadius: 4,
+ backgroundColor: theme.palette.common.white,
+ border: '1px solid #ced4da',
+ fontSize: 16,
+ padding: '10px 12px',
+ width: 'calc(100% - 24px)',
+ transition: theme.transitions.create(['border-color', 'box-shadow']),
+ '&:focus': {
+ borderColor: '#80bdff',
+ boxShadow: '0 0 0 0.2rem rgba(0,123,255,.25)',
+ },
+ },
+ bootstrapFormLabel: {
+ fontSize: 18,
+ },
+});
+
+const theme = createMuiTheme({
+ palette: {
+ primary: green,
+ },
+});
+
+class TextFields extends PureComponent {
+ render() {
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="flex-start"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={12}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Layout</Typography>
+ <Typography className={classes.divider}>TextField, FormControl allow the specification of margin to alter the vertical spacing of inputs. Using none (default) will not apply margins to the FormControl, whereas dense and normal will as well as alter other styles to meet the specification.</Typography>
+ <div className={classes.container}>
+ <TextField
+ label="None"
+ id="margin-none"
+ defaultValue="Default Value"
+ className={classes.textField}
+ helperText="Some important text"
+ />
+ <TextField
+ label="Dense"
+ id="margin-dense"
+ defaultValue="Default Value"
+ className={classes.textField}
+ helperText="Some important text"
+ margin="dense"
+ />
+ <TextField
+ label="Normal"
+ id="margin-normal"
+ defaultValue="Default Value"
+ className={classes.textField}
+ helperText="Some important text"
+ margin="normal"
+ />
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={12}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Customized Designs</Typography>
+ <Typography className={classes.divider}>Here is an example of how you can change the main color of an Input.</Typography>
+ <div className={classes.container}>
+ <FormControl className={classes.margin}>
+ <InputLabel
+ htmlFor="custom-css-input"
+ >
+ Custom CSS
+ </InputLabel>
+ <Input
+ classes={{
+ underline: classes.cssUnderline,
+ }}
+ id="custom-css-input"
+ />
+ </FormControl>
+ <MuiThemeProvider theme={theme}>
+ <TextField
+ className={classes.margin}
+ label="MuiThemeProvider"
+ id="mui-theme-provider-input"
+ />
+ </MuiThemeProvider>
+ <TextField
+ className={classes.divider}
+ defaultValue="react-bootstrap"
+ label="Bootstrap"
+ id="bootstrap-input"
+ InputProps={{
+ disableUnderline: true,
+ classes: {
+ root: classes.bootstrapRoot,
+ input: classes.bootstrapInput,
+ },
+ }}
+ InputLabelProps={{
+ shrink: true,
+ className: classes.bootstrapFormLabel,
+ }}
+ />
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+TextFields.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(TextFields);
diff --git a/front/odiparpack/app/containers/Forms/demos/TimeInput.js b/front/odiparpack/app/containers/Forms/demos/TimeInput.js
new file mode 100644
index 0000000..d8ed35b
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/TimeInput.js
@@ -0,0 +1,124 @@
+import React, { Fragment, PureComponent } from 'react';
+import { TimePicker, KeyboardDatePicker, MuiPickersUtilsProvider } from '@material-ui/pickers';
+import MomentUtils from '@date-io/moment';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import { Typography, Grid, InputAdornment, Icon, IconButton } from '@material-ui/core';
+
+const styles = theme => ({
+ demo: {
+ height: 'auto',
+ },
+ divider: {
+ display: 'block',
+ margin: `${theme.spacing(3)}px 0`,
+ },
+ picker: {
+ margin: `${theme.spacing(3)}px 5px`,
+ }
+});
+
+class TimeInput extends PureComponent {
+ state = {
+ selectedDate: new Date(),
+ }
+
+ handleDateChange = (date) => {
+ this.setState({ selectedDate: date });
+ }
+
+ render() {
+ const { selectedDate } = this.state;
+ const { classes } = this.props;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Basic usage</Typography>
+ <Typography className={classes.divider}>
+ A time picker should adjusts to a user’s preferred time setting, i.e. the 12-hour or 24-hour format.
+ </Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <div className="picker">
+ <TimePicker
+ label="12 hours"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ />
+ </div>
+ </MuiPickersUtilsProvider>
+ </div>
+
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <TimePicker
+ clearable
+ ampm={false}
+ label="24 hours"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ </Grid>
+ <Grid
+ item
+ md={6}
+ className={classes.demo}
+ >
+ <Typography variant="button" className={classes.divider}>Keyboard Input</Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <KeyboardDatePicker
+ label="Masked timepicker"
+ mask={[/\d/, /\d/, ':', /\d/, /\d/, ' ', /a|p/i, 'M']}
+ placeholder="08:00 AM"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ <Typography variant="button" className={classes.divider}>Custom Icon</Typography>
+ <div className={classes.picker}>
+ <MuiPickersUtilsProvider utils={MomentUtils}>
+ <TimePicker
+ label="Masked timepicker"
+ mask={[/\d/, /\d/, ':', /\d/, /\d/, ' ', /a|p/i, 'M']}
+ placeholder="08:00 AM"
+ value={selectedDate}
+ onChange={this.handleDateChange}
+ InputProps={{
+ endAdornment: (
+ <InputAdornment position="end">
+ <IconButton>
+ <Icon>access_time</Icon>
+ </IconButton>
+ </InputAdornment>
+ ),
+ }}
+ />
+ </MuiPickersUtilsProvider>
+ </div>
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+TimeInput.propTypes = {
+ classes: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles)(TimeInput);
diff --git a/front/odiparpack/app/containers/Forms/demos/UploadInputAll.js b/front/odiparpack/app/containers/Forms/demos/UploadInputAll.js
new file mode 100644
index 0000000..22ae742
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/UploadInputAll.js
@@ -0,0 +1,31 @@
+import React, { Fragment } from 'react';
+import { MaterialDropZone } from 'ba-components';
+
+class UploadInputAll extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ files: [],
+ };
+ }
+
+ render() {
+ const { files } = this.state;
+ return (
+ <Fragment>
+ <div>
+ <MaterialDropZone
+ files={files}
+ showPreviews
+ maxSize={5000000}
+ filesLimit={5}
+ text="Drag and drop file(s) here or click"
+ />
+ </div>
+ </Fragment>
+ );
+ }
+}
+
+export default UploadInputAll;
diff --git a/front/odiparpack/app/containers/Forms/demos/UploadInputBtn.js b/front/odiparpack/app/containers/Forms/demos/UploadInputBtn.js
new file mode 100644
index 0000000..959ee85
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/UploadInputBtn.js
@@ -0,0 +1,32 @@
+import React, { Fragment } from 'react';
+import { MaterialDropZone } from 'ba-components';
+
+class UploadInputBtn extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ files: [],
+ };
+ }
+
+ render() {
+ const { files } = this.state;
+ return (
+ <Fragment>
+ <div>
+ <MaterialDropZone
+ files={files}
+ showPreviews
+ maxSize={5000000}
+ filesLimit={5}
+ text="Drag and drop file(s) here or click button bellow"
+ showButton
+ />
+ </div>
+ </Fragment>
+ );
+ }
+}
+
+export default UploadInputBtn;
diff --git a/front/odiparpack/app/containers/Forms/demos/UploadInputImg.js b/front/odiparpack/app/containers/Forms/demos/UploadInputImg.js
new file mode 100644
index 0000000..3600f37
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/UploadInputImg.js
@@ -0,0 +1,32 @@
+import React, { Fragment } from 'react';
+import { MaterialDropZone } from 'ba-components';
+
+class UploadInputImg extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ files: [],
+ };
+ }
+
+ render() {
+ const { files } = this.state;
+ return (
+ <Fragment>
+ <div>
+ <MaterialDropZone
+ acceptedFiles={['image/jpeg', 'image/png', 'image/bmp']}
+ files={files}
+ showPreviews
+ maxSize={5000000}
+ filesLimit={5}
+ text="Drag and drop image(s) here or click"
+ />
+ </div>
+ </Fragment>
+ );
+ }
+}
+
+export default UploadInputImg;
diff --git a/front/odiparpack/app/containers/Forms/demos/Wysiwyg.js b/front/odiparpack/app/containers/Forms/demos/Wysiwyg.js
new file mode 100644
index 0000000..61c64a8
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/Wysiwyg.js
@@ -0,0 +1,91 @@
+import React, { Fragment, PureComponent } from 'react';
+import { convertFromRaw, EditorState, convertToRaw } from 'draft-js';
+import { Editor } from 'react-draft-wysiwyg';
+import draftToHtml from 'draftjs-to-html';
+import draftToMarkdown from 'draftjs-to-markdown';
+import EditorStyle from 'ba-styles/TextEditor.scss';
+import 'ba-styles/vendors/react-draft-wysiwyg/react-draft-wysiwyg.css';
+
+import { Grid, Typography } from '@material-ui/core';
+
+const content = {
+ blocks: [{
+ key: '637gr',
+ text: 'Lorem ipsum dolor sit amet 😀',
+ type: 'unstyled',
+ depth: 0,
+ inlineStyleRanges: [],
+ entityRanges: [],
+ data: {}
+ }],
+ entityMap: {}
+};
+
+class Wysiwyg extends PureComponent {
+ constructor(props) {
+ super(props);
+ const contentBlock = convertFromRaw(content);
+ if (contentBlock) {
+ const editorState = EditorState.createWithContent(contentBlock);
+ this.state = {
+ editorState,
+ };
+ }
+ }
+
+ onEditorStateChange = editorState => {
+ this.setState({
+ editorState,
+ });
+ };
+
+ render() {
+ const { editorState } = this.state;
+ return (
+ <Fragment>
+ <Grid
+ container
+ alignItems="flex-start"
+ justify="space-around"
+ direction="row"
+ spacing={3}
+ >
+ <Grid item xs={12}>
+ <Editor
+ editorState={editorState}
+ editorClassName={EditorStyle.TextEditor}
+ toolbarClassName={EditorStyle.ToolbarEditor}
+ onEditorStateChange={this.onEditorStateChange}
+ />
+ </Grid>
+ <Grid item md={4} xs={12}>
+ <Typography variant="button">JSON Result :</Typography>
+ <textarea
+ className={EditorStyle.textPreview}
+ disabled
+ value={JSON.stringify(editorState, null, 4)}
+ />
+ </Grid>
+ <Grid item md={4} xs={12}>
+ <Typography variant="button">HTML Result :</Typography>
+ <textarea
+ className={EditorStyle.textPreview}
+ disabled
+ value={draftToHtml(convertToRaw(editorState.getCurrentContent()))}
+ />
+ </Grid>
+ <Grid item md={4} xs={12}>
+ <Typography variant="button">Markdown Result :</Typography>
+ <textarea
+ className={EditorStyle.textPreview}
+ disabled
+ value={editorState && draftToMarkdown(convertToRaw(editorState.getCurrentContent()))}
+ />
+ </Grid>
+ </Grid>
+ </Fragment>
+ );
+ }
+}
+
+export default Wysiwyg;
diff --git a/front/odiparpack/app/containers/Forms/demos/index.js b/front/odiparpack/app/containers/Forms/demos/index.js
new file mode 100644
index 0000000..8ae709e
--- /dev/null
+++ b/front/odiparpack/app/containers/Forms/demos/index.js
@@ -0,0 +1,44 @@
+// Redux Form
+export ReduxFormDemo from './ReduxFormDemo';
+// Date Time Picker
+export DateInput from './DateInput';
+export TimeInput from './TimeInput';
+export DateTimeInput from './DateTimeInput';
+// Checkbox and Radio
+export Checkboxes from './Checkboxes';
+export RadioButton from './RadioButton';
+// Switches
+export SwitchesInput from './SwitchesInput';
+// Selectbox
+export SimpleSelectbox from './SimpleSelectbox';
+export NativeSelectbox from './NativeSelectbox';
+export MultipleSelectbox from './MultipleSelectbox';
+export ControlledSelectbox from './ControlledSelectbox';
+// Ratting
+export RatingNormal from './RatingNormal';
+export RatingCustom from './RatingCustom';
+// Slide Range
+export SliderInput from './SliderInput';
+export RangeInput from './RangeInput';
+// Buttons
+export StandardButtons from './StandardButtons';
+export FloatingButtons from './FloatingButtons';
+export CustomButtons from './CustomButtons';
+export ComplexButtons from './ComplexButtons';
+// Textfield
+export TextFields from './TextFields';
+export TextFieldsLayout from './TextFieldsLayout';
+export InputAdornments from './InputAdornments';
+export FormattedInputs from './FormattedInputs';
+// Autocomplete
+export AutoSuggest from './AutoSuggest';
+export TagSuggestions from './TagSuggestions';
+export SelectSuggestions from './SelectSuggestions';
+export SelectSuggestionTags from './SelectSuggestionTags';
+export HighlightSuggest from './HighlightSuggest';
+// Text Editor
+export Wysiwyg from './Wysiwyg';
+// Uploader
+export UploadInputAll from './UploadInputAll';
+export UploadInputImg from './UploadInputImg';
+export UploadInputBtn from './UploadInputBtn';