diff options
Diffstat (limited to 'front/odiparpack/app/containers/UiElements')
124 files changed, 11689 insertions, 0 deletions
diff --git a/front/odiparpack/app/containers/UiElements/Accordion.js b/front/odiparpack/app/containers/UiElements/Accordion.js new file mode 100644 index 0000000..dd354d3 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Accordion.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { SimpleAccordion, AdvancedAccordion, ControlledAccordion } from './demos'; + +class Accordion extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Accordion/'; + 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="Accordion" desc="Accordion is MUI Expansion Panels contain creation flows and allow lightweight editing of an element."> + <div> + <SimpleAccordion /> + <SourceReader componentName={docSrc + 'SimpleAccordion.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Secondary heading and Columns" desc="Multiple columns can be used to structure the content, and a helper text may be added to the panel to assist the user."> + <div> + <AdvancedAccordion /> + <SourceReader componentName={docSrc + 'AdvancedAccordion.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Controlled Accordion" desc="Extend the default panel behavior to create an accordion with the ExpansionPanel component."> + <div> + <ControlledAccordion /> + <SourceReader componentName={docSrc + 'ControlledAccordion.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Accordion; diff --git a/front/odiparpack/app/containers/UiElements/Avatars.js b/front/odiparpack/app/containers/UiElements/Avatars.js new file mode 100644 index 0000000..3ccbaaa --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Avatars.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { AvatarsDemo, AvatarsPractice } from './demos'; + +class Avatars extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Avatars/'; + 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="Avatars" desc="Avatars are found throughout material design with uses in everything from tables to dialog menus."> + <div> + <AvatarsDemo /> + <SourceReader componentName={docSrc + 'AvatarsDemo.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Implemented Avatars" desc="Some examples of components, using an image Avatar, SVG Icon Avatar, Letter and (string) Avatar."> + <div> + <AvatarsPractice /> + <SourceReader componentName={docSrc + 'AvatarsPractice.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Avatars; diff --git a/front/odiparpack/app/containers/UiElements/Badges.js b/front/odiparpack/app/containers/UiElements/Badges.js new file mode 100644 index 0000000..ff4783d --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Badges.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { CommonBadges, VariantBadges } from './demos'; + +class Badges extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Badges/'; + 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="Common Badges" desc="Badge generates a small badge to the top-right of its child(ren)."> + <div> + <CommonBadges /> + <SourceReader componentName={docSrc + 'CommonBadges.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Variant Badges" desc="Examples of badges with icon and in tab, using primary and secondary colors. The badge is applied to its children."> + <div> + <VariantBadges /> + <SourceReader componentName={docSrc + 'VariantBadges.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Badges; diff --git a/front/odiparpack/app/containers/UiElements/Breadcrumbs.js b/front/odiparpack/app/containers/UiElements/Breadcrumbs.js new file mode 100644 index 0000000..daaa24f --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Breadcrumbs.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { ClassicBreadcrumbs, PaperBreadcrumbs } from './demos'; + +class BreadCrumbs extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Breadcrumbs/'; + 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="Classic Breadcrumb" desc="Breadcrumb is one of navigation component. With this User can jump to parent, children or grand-children page as long in a single inheritance.This example is designed with classic style separator"> + <div> + <ClassicBreadcrumbs /> + <SourceReader componentName={docSrc + 'ClassicBreadcrumbs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Paper Breadcrumb" desc=""> + <div> + <PaperBreadcrumbs /> + <SourceReader componentName={docSrc + 'PaperBreadcrumbs.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default BreadCrumbs; diff --git a/front/odiparpack/app/containers/UiElements/Cards.js b/front/odiparpack/app/containers/UiElements/Cards.js new file mode 100644 index 0000000..7865b9d --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Cards.js @@ -0,0 +1,63 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { + StandardCards, + ControlCards, + PaperSheet, + SocialCards, + EcommerceCards +} from './demos'; + +class Cards extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Cards/'; + 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="Paper" desc="In material design, the physical properties of paper are translated to the screen."> + <div> + <PaperSheet /> + <SourceReader componentName={docSrc + 'PaperSheet.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Standard Cards" desc="A card is a sheet of material that serves as an entry point to more detailed information."> + <div> + <StandardCards /> + <SourceReader componentName={docSrc + 'StandardCards.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Control Cards" desc="Supplemental actions within the card are explicitly called out using icons, text, and UI controls."> + <div> + <ControlCards /> + <SourceReader componentName={docSrc + 'ControlCards.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Social Cards" desc="A Customized material-ui card that contain profile elements"> + <div> + <SocialCards /> + <SourceReader componentName={docSrc + 'SocialCards.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Ecommerce Cards" desc="A Customized material-ui card that contain product information"> + <div> + <EcommerceCards /> + <SourceReader componentName={docSrc + 'EcommerceCards.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Cards; diff --git a/front/odiparpack/app/containers/UiElements/DialogModal.js b/front/odiparpack/app/containers/UiElements/DialogModal.js new file mode 100644 index 0000000..6e26609 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/DialogModal.js @@ -0,0 +1,97 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { Grid } from '@material-ui/core'; +import { + ModalDemo, + AlertDialog, + SelectDialog, + SelectRadioDialog, + FormDialog, + FullScreenDialog, + ImagePopup, + ScrollDialog +} from './demos'; + +class DialogModal extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/DialogModal/'; + 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="Modals" desc="The modal component provides a solid foundation for creating dialogs, popovers, lightboxes, or whatever else."> + <div> + <ModalDemo /> + <SourceReader componentName={docSrc + 'ModalDemo.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Image Popup" desc="A flexible lightbox component for displaying images. It's also can handle zoom and panning of images. Mobile friendly, with pinch to zoom and swipe"> + <div> + <ImagePopup /> + <SourceReader componentName={docSrc + 'ImagePopup.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Alerts" desc="Alerts are urgent interruptions, requiring acknowledgement, that inform the user about a situation."> + <div> + <AlertDialog /> + <SourceReader componentName={docSrc + 'AlertDialog.js'} /> + </div> + </PapperBlock> + <Grid container spacing={2}> + <Grid item md={6}> + <PapperBlock title="Selection Dialog" desc="Choosing an option immediately commits the option and closes the menu"> + <div> + <SelectDialog /> + <SourceReader componentName={docSrc + 'SelectDialog.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6}> + <PapperBlock title="Selection Radio Dialog" desc="In this example, users can listen to multiple ringtones but only make a final selection upon touching “OK.”"> + <div> + <SelectRadioDialog /> + <SourceReader componentName={docSrc + 'SelectRadioDialog.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + <PapperBlock title="Form dialogs" desc="Form dialogs allow users to fill out form fields within a dialog."> + <div> + <FormDialog /> + <SourceReader componentName={docSrc + 'FormDialog.js'} /> + </div> + </PapperBlock> + <Grid container spacing={2}> + <Grid item md={6} xs={12}> + <PapperBlock title="Full Screen (Responsive)" desc="You may make a Dialog responsively full screen the dialog using withMobileDialog. By default, withMobileDialog()(Dialog) responsively full screens at or below the sm screen size."> + <div> + <FullScreenDialog /> + <SourceReader componentName={docSrc + 'FullScreenDialog.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6} xs={12}> + <PapperBlock title="Scrolling dialog" desc="When dialogs become too long for the user’s viewport or device, they scroll."> + <div> + <ScrollDialog /> + <SourceReader componentName={docSrc + 'ScrollDialog.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + </div> + ); + } +} + +export default DialogModal; diff --git a/front/odiparpack/app/containers/UiElements/Dividers.js b/front/odiparpack/app/containers/UiElements/Dividers.js new file mode 100644 index 0000000..34c66a9 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Dividers.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { CommonDividers, SpecialDividers } from './demos'; + +class Dividers extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Dividers/'; + 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="Common Dividers" desc="Some variant divider style base on hr tag"> + <div> + <CommonDividers /> + <SourceReader componentName={docSrc + 'CommonDividers.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Special Dividers" desc="Sometime the divider is more than a line. With this You can add text or decoration at the edges"> + <div> + <SpecialDividers /> + <SourceReader componentName={docSrc + 'SpecialDividers.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Dividers; diff --git a/front/odiparpack/app/containers/UiElements/DrawerMenu.js b/front/odiparpack/app/containers/UiElements/DrawerMenu.js new file mode 100644 index 0000000..dfffbc8 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/DrawerMenu.js @@ -0,0 +1,104 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { Grid } from '@material-ui/core'; +import { + TemporaryDrawer, + SwipeDrawer, + PermanentDrawer, + PersistentDrawer, + MiniDrawer, + BasicMenu, + DropdownMenu, + StyledMenu, + MenuTransition +} from './demos'; + +class DrawerMenu extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/DrawerMenu/'; + 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> + <Grid container spacing={2}> + <Grid item md={6}> + <PapperBlock title="Temporary drawer" desc="Temporary navigation drawers can toggle open or closed. Closed by default, the drawer opens temporarily above all other content until a section is selected."> + <div> + <TemporaryDrawer /> + <SourceReader componentName={docSrc + 'TemporaryDrawer.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6}> + <PapperBlock title="Swipeable Temporary drawer" desc="You can make the drawer swipeable with the SwipeableDrawer component."> + <div> + <SwipeDrawer /> + <SourceReader componentName={docSrc + 'SwipeDrawer.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + <PapperBlock title="Permanent drawer" desc="Permanent navigation drawers are always visible and pinned to the left edge, at the same elevation as the content or background. They cannot be closed."> + <div> + <PermanentDrawer /> + <SourceReader componentName={docSrc + 'PermanentDrawer.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Persistent drawer" desc="Persistent navigation drawers can toggle open or closed. The drawer sits on the same surface elevation as the content. It is closed by default and opens by selecting the menu icon, and stays open until closed by the user."> + <div> + <PersistentDrawer /> + <SourceReader componentName={docSrc + 'PersistentDrawer.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Mini variant drawer" desc="In this variation, the persistent navigation drawer changes its width. Its resting state is as a mini-drawer at the same elevation as the content, clipped by the app bar."> + <div> + <MiniDrawer /> + <SourceReader componentName={docSrc + 'MiniDrawer.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Basic Menu" desc="Basic menus open over the anchor element by default (this option can be changed via props). When close to a screen edge, simple menus vertically realign to make all menu items are completely visible."> + <div> + <BasicMenu /> + <SourceReader componentName={docSrc + 'BasicMenu.js'} /> + </div> + </PapperBlock> + <Grid container spacing={2}> + <Grid item md={6}> + <PapperBlock title="Selected menus" desc="If used for item selection, when opened, simple menus attempt to vertically align the currently selected menu item with the anchor element."> + <div> + <DropdownMenu /> + <SourceReader componentName={docSrc + 'DropdownMenu.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6}> + <PapperBlock title="Styled Menu" desc="The MenuItem is a wrapper around ListItem with some additional styles."> + <div> + <StyledMenu /> + <SourceReader componentName={docSrc + 'StyledMenu.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + <PapperBlock title="Transition" desc="Use a different transition altogether."> + <div> + <MenuTransition /> + <SourceReader componentName={docSrc + 'MenuTransition.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default DrawerMenu; diff --git a/front/odiparpack/app/containers/UiElements/IconGallery/DetailIcon.js b/front/odiparpack/app/containers/UiElements/IconGallery/DetailIcon.js new file mode 100644 index 0000000..e19c17a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/IconGallery/DetailIcon.js @@ -0,0 +1,149 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light'; +import jsx from 'react-syntax-highlighter/languages/prism/jsx'; +import themeSource from 'react-syntax-highlighter/styles/prism/prism'; +import { withStyles } from '@material-ui/core/styles'; + +import { + Typography, + Button, + Icon, + Divider, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Slide, +} from '@material-ui/core'; + +const Transition = React.forwardRef(function Transition(props, ref) { // eslint-disable-line + return <Slide direction="up" ref={ref} {...props} />; +}); + +const humanize = (str, space) => { + let string = str; + if (str === '3d_rotation') { + string = 'three_d_rotation'; + } + const frags = string.split('_'); + for (let i = 0; i < frags.length; i += 1) { + frags[i] = frags[i].charAt(0).toUpperCase() + frags[i].slice(1); + } + + if (space) { + return frags.join(' '); + } + return frags.join(''); +}; + +const styles = theme => ({ + code: { + fontSize: 12, + padding: '5px !important' + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, + bigIcon: { + textAlign: 'center', + marginBottom: 30, + '& span': { + fontSize: 128 + } + }, + title: { + marginBottom: 40, + fontSize: 22, + paddingBottom: 20, + position: 'relative', + fontWeight: 500, + color: theme.palette.grey[700], + textTransform: 'uppercase', + '&:after': { + content: '""', + display: 'block', + position: 'absolute', + bottom: 0, + left: 24, + width: 40, + borderBottom: `5px solid ${theme.palette.primary.main}` + } + }, +}); + +class DetailIcon extends React.Component { + render() { + registerLanguage('jsx', jsx); + const { + isOpenDetail, + iconName, + iconCode, + closeDetail + } = this.props; + const { classes } = this.props; + const linkCode = '<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />'; + const fontCode = '<Icon>' + iconName + '</Icon>'; + const importCode = 'import ' + humanize(iconName, false) + " from '@material-ui/icons/" + humanize(iconName, false) + "';"; + const importIconCode = "import Icon from '@material-ui/core/Icon';"; + const svgCode = '<' + humanize(iconName, false) + ' />'; + return ( + <Dialog + open={isOpenDetail} + TransitionComponent={Transition} + keepMounted + maxWidth="md" + onClose={closeDetail} + aria-labelledby="alert-dialog-slide-title" + aria-describedby="alert-dialog-slide-description" + > + <DialogTitle id="alert-dialog-slide-title" className={classes.title}> + {humanize(iconName, true)} + {' '} +( + {iconCode} +) + </DialogTitle> + <DialogContent> + <div className={classes.bigIcon}> + <Icon className={classes.icon}>{iconName}</Icon> + </div> + <Typography variant="subtitle1" gutterBottom>Use with Font Icons</Typography> + <SyntaxHighlighter className={classes.code} language="jsx" style={themeSource}> + {linkCode} + </SyntaxHighlighter> + <SyntaxHighlighter className={classes.code} language="jsx" style={themeSource}> + {importIconCode} + </SyntaxHighlighter> + <SyntaxHighlighter className={classes.code} language="jsx" style={themeSource}> + {fontCode} + </SyntaxHighlighter> + <Divider className={classes.divider} /> + <Typography variant="subtitle1" gutterBottom>Use with SVG Material icons</Typography> + <SyntaxHighlighter className={classes.code} language="jsx" style={themeSource}> + {importCode} + </SyntaxHighlighter> + <SyntaxHighlighter className={classes.code} language="jsx" style={themeSource}> + {svgCode} + </SyntaxHighlighter> + </DialogContent> + <DialogActions> + <Button onClick={closeDetail} color="primary"> + Close + </Button> + </DialogActions> + </Dialog> + ); + } +} + +DetailIcon.propTypes = { + classes: PropTypes.object.isRequired, + isOpenDetail: PropTypes.bool.isRequired, + closeDetail: PropTypes.func.isRequired, + iconName: PropTypes.string.isRequired, + iconCode: PropTypes.string.isRequired, +}; + +export default withStyles(styles)(DetailIcon); diff --git a/front/odiparpack/app/containers/UiElements/IconGallery/SearchIcons.js b/front/odiparpack/app/containers/UiElements/IconGallery/SearchIcons.js new file mode 100644 index 0000000..c046362 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/IconGallery/SearchIcons.js @@ -0,0 +1,54 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import SearchIcon from '@material-ui/icons/Search'; + +import { IconButton, Input, InputAdornment, FormControl } from '@material-ui/core'; + +const styles = theme => ({ + search: { + display: 'block', + background: '#fff', + marginBottom: 10, + paddingTop: 5, + boxShadow: theme.shadows[2], + '& > div': { + width: '100%', + }, + '& input': { + padding: '10px 8px' + } + } +}); + +class SearchIcons extends React.Component { + render() { + const { filterText, classes, handleSearch } = this.props; + return ( + <FormControl fullWidth className={classes.search}> + <Input + id="search_filter" + type="text" + placeholder="Search more than 900 icons" + value={filterText} + onChange={handleSearch} + endAdornment={( + <InputAdornment position="end"> + <IconButton aria-label="Search filter"> + <SearchIcon /> + </IconButton> + </InputAdornment> + )} + /> + </FormControl> + ); + } +} + +SearchIcons.propTypes = { + classes: PropTypes.object.isRequired, + filterText: PropTypes.string.isRequired, + handleSearch: PropTypes.func.isRequired, +}; + +export default withStyles(styles)(SearchIcons); diff --git a/front/odiparpack/app/containers/UiElements/Icons.js b/front/odiparpack/app/containers/UiElements/Icons.js new file mode 100644 index 0000000..f207d29 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Icons.js @@ -0,0 +1,158 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import PropTypes from 'prop-types'; +import Axios from 'axios'; +import { withStyles } from '@material-ui/core/styles'; +import { PapperBlock } from 'ba-components'; +import { Typography, IconButton, Icon, LinearProgress } from '@material-ui/core'; +import DetailIcon from './IconGallery/DetailIcon'; +import SearchIcons from './IconGallery/SearchIcons'; +const url = '/api/icons?src='; + +const styles = theme => ({ + hide: { + display: 'none' + }, + iconsList: { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-between', + [theme.breakpoints.down('xs')]: { + justifyContent: 'center', + }, + overflow: 'auto', + maxHeight: 1000, + position: 'relative' + }, + iconWrap: { + position: 'relative', + width: 120, + margin: 20, + [theme.breakpoints.down('xs')]: { + margin: 10, + }, + textAlign: 'center' + }, + btn: { + display: 'block', + textAlign: 'center', + margin: '0 auto', + }, + icon: { + fontSize: 48, + }, + preloader: { + width: '100%' + }, +}); + +class Icons extends React.Component { + state = { + raws: [], + loading: false, + openDetail: false, + iconName: '', + iconCode: '', + filterText: '' + }; + + componentDidMount = () => { + const name = 'material-icon-cheat.txt'; + this.setState({ loading: true }, () => { + Axios.get(url + name) + .then(response => response.data.records[0].source) + .then(data => { + const namesAndCodes = data.split('\n'); + const icons = namesAndCodes.map(nameAndCode => { + const parts = nameAndCode.split(' '); + return { + name: parts[0], + code: parts[1] + }; + }); + return icons; + }) + .then(icons => { + this.setState({ + raws: icons, + loading: false + }); + }); + }); + } + + handleOpenDetail = (name, code) => { + this.setState({ + openDetail: true, + iconName: name, + iconCode: code, + }); + }; + + handleCloseDetail = () => { + this.setState({ openDetail: false }); + }; + + handleSearch = (event) => { + event.persist(); + // Show result base on keyword + this.setState({ filterText: event.target.value.toLowerCase() }); + } + + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const { + raws, + loading, + openDetail, + iconName, + iconCode, + filterText + } = this.state; + const { classes } = this.props; + 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="Material Icons" desc="Material icons are delightful, beautifully crafted symbols for common actions and items. System icons are designed to be simple, modern, friendly, and sometimes quirky. Each icon is reduced to its minimal form, expressing essential characteristics."> + <div> + {loading + && <LinearProgress color="secondary" className={classes.preloader} /> + } + <SearchIcons filterText={filterText} handleSearch={(event) => this.handleSearch(event)} /> + <div className={classes.iconsList}> + {raws.map((raw, index) => { + if (raw.name.toLowerCase().indexOf(filterText) === -1) { + return false; + } + return ( + <div className={classes.iconWrap} key={index.toString()}> + <IconButton title="Click to see detail" onClick={() => this.handleOpenDetail(raw.name, raw.code)} className={classes.btn}> + <Icon className={classes.icon}>{raw.name}</Icon> + </IconButton> + <Typography gutterBottom noWrap>{raw.name}</Typography> + </div> + ); + })} + <DetailIcon closeDetail={this.handleCloseDetail} isOpenDetail={openDetail} iconName={iconName} iconCode={iconCode} /> + </div> + </div> + </PapperBlock> + </div> + ); + } +} + +Icons.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(Icons); diff --git a/front/odiparpack/app/containers/UiElements/ImageGrid.js b/front/odiparpack/app/containers/UiElements/ImageGrid.js new file mode 100644 index 0000000..a95fd50 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/ImageGrid.js @@ -0,0 +1,51 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { ImageGridList, TitlebarGridList, AdvancedGridList, SingleLineGridList } from './demos'; + +class ImageGrid extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/ImageGrid/'; + 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="Image-only Grid list" desc="A simple example of a scrollable image GridList"> + <div> + <ImageGridList /> + <SourceReader componentName={docSrc + 'ImageGridList.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Grid list with titlebars" desc="This example demonstrates the use of the GridListTileBar to add an overlay to each GridListTile."> + <div> + <TitlebarGridList /> + <SourceReader componentName={docSrc + 'TitlebarGridList.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Advanced Grid list" desc="This example demonstrates featured tiles, using the rows and cols props to adjust the size of the tile, and the padding prop to adjust the spacing."> + <div> + <AdvancedGridList /> + <SourceReader componentName={docSrc + 'AdvancedGridList.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Single line Grid list" desc="This example demonstrates a horizontal scrollable single-line grid list of images."> + <div> + <SingleLineGridList /> + <SourceReader componentName={docSrc + 'SingleLineGridList.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default ImageGrid; diff --git a/front/odiparpack/app/containers/UiElements/List.js b/front/odiparpack/app/containers/UiElements/List.js new file mode 100644 index 0000000..665cd08 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/List.js @@ -0,0 +1,63 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { + ListBasic, + ListMenu, + PinnedList, + ListControl, + ListInteractive +} from './demos'; + +class List extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/List/'; + 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="List Basic" desc="The divider renders as a <hr> by default. You can save rendering this DOM element by using the divider property on the ListItem component."> + <div> + <ListBasic /> + <SourceReader componentName={docSrc + 'ListBasic.js'} /> + </div> + </PapperBlock> + <PapperBlock title="List Menu" desc="Lists are made up of a continuous column of rows. Each row contains a tile. Primary actions fill the tile, and supplemental actions are represented by icons and text."> + <div> + <ListMenu /> + <SourceReader componentName={docSrc + 'ListMenu.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Pinned Subheader List" desc="Upon scrolling, subheaders remain pinned to the top of the screen until pushed off screen by the next subheader."> + <div> + <PinnedList /> + <SourceReader componentName={docSrc + 'PinnedList.js'} /> + </div> + </PapperBlock> + <PapperBlock title="List Controls" desc="The checkbox is the primary action and the state indicator for the list item. The comment button is a secondary action and a separate target."> + <div> + <ListControl /> + <SourceReader componentName={docSrc + 'ListControl.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Interactive" desc="Below is an interactive demo that lets you explore the visual results of the different settings:"> + <div> + <ListInteractive /> + <SourceReader componentName={docSrc + 'ListInteractive.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default List; diff --git a/front/odiparpack/app/containers/UiElements/Notification.js b/front/odiparpack/app/containers/UiElements/Notification.js new file mode 100644 index 0000000..b00f24e --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Notification.js @@ -0,0 +1,56 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { Grid } from '@material-ui/core'; +import { SimpleNotif, StyledNotif, TransitionNotif, MobileNotif } from './demos'; + +class Notification extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Notification/'; + 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="Snackbars/Notification" desc="Snackbars provide brief feedback about an operation through a message - typically at the bottom of the screen."> + <div> + <SimpleNotif /> + <SourceReader componentName={docSrc + 'SimpleNotif.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Styled Notification" desc="Some snackbars with varying message style. And some snackbars with varying message length."> + <div> + <StyledNotif /> + <SourceReader componentName={docSrc + 'StyledNotif.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Mobile Notification" desc="Move the floating action button vertically to accommodate the snackbar height."> + <div> + <Grid container justify="center"> + <Grid item md={4} xs={12}> + <MobileNotif /> + </Grid> + </Grid> + <SourceReader componentName={docSrc + 'MobileNotif.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Transition" desc="Per Google's guidelines, when a second snackbar is triggered while the first is displayed, the first should start the contraction motion downwards before the second one animates upwards."> + <div> + <TransitionNotif /> + <SourceReader componentName={docSrc + 'TransitionNotif.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Notification; diff --git a/front/odiparpack/app/containers/UiElements/Paginations.js b/front/odiparpack/app/containers/UiElements/Paginations.js new file mode 100644 index 0000000..7f6fa47 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Paginations.js @@ -0,0 +1,45 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { TbPagination, TbPaginationCustom, GeneralPagination } from './demos'; + +class Paginations extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Pagination/'; + 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="Table Pagination" desc="The Action property of the TablePagination component allows the implementation of custom actions."> + <div> + <TbPagination /> + <SourceReader componentName={docSrc + 'TbPagination.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Table Pagination Custom" desc="The Action property of the TablePagination component allows the implementation of custom actions."> + <div> + <TbPaginationCustom /> + <SourceReader componentName={docSrc + 'TbPaginationCustom.js'} /> + </div> + </PapperBlock> + <PapperBlock title="General Pagination" desc="React.js pagination component based on ultimate-pagination. It's implemented as a higher-order component that allows easy integration of react-ultimate-pagination with different CSS frameworks or approaches."> + <div> + <GeneralPagination /> + <SourceReader componentName={docSrc + 'GeneralPagination.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Paginations; diff --git a/front/odiparpack/app/containers/UiElements/PopoverTooltip.js b/front/odiparpack/app/containers/UiElements/PopoverTooltip.js new file mode 100644 index 0000000..508129b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/PopoverTooltip.js @@ -0,0 +1,95 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { Grid } from '@material-ui/core'; +import { + SimpleTooltips, + PositionedTooltips, + SimplePopover, + PopoverPlayground, + DelayTooltips, + TransitionsTooltips, + TriggersTooltips, + CustomizedTooltips +} from './demos'; + +class PopoverTooltip extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/PopoverTooltip/'; + 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 Tooltips" desc="The tooltips are text labels that appear when the user hovers over, focuses on, or touches an element."> + <div> + <SimpleTooltips /> + <SourceReader componentName={docSrc + 'SimpleTooltips.js'} /> + </div> + </PapperBlock> + <PapperBlock overflowX title="Positioned Tooltips" desc="The Tooltip has 12 placements choice. They don’t have directional arrows; instead, they rely on motion emanating from the source to convey direction."> + <div> + <PositionedTooltips /> + <SourceReader componentName={docSrc + 'PositionedTooltips.js'} /> + </div> + </PapperBlock> + <Grid container spacing={2}> + <Grid item md={6} xs={12}> + <PapperBlock title="Triggers Tooltips" desc="You can define the types of events that cause a tooltip to show."> + <div> + <TriggersTooltips /> + <SourceReader componentName={docSrc + 'TriggersTooltips.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6} xs={12}> + <PapperBlock title="Delay Tooltip" desc="A delay in showing or hiding the tooltip can be added also"> + <div> + <DelayTooltips /> + <SourceReader componentName={docSrc + 'DelayTooltips.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6} xs={12}> + <PapperBlock title="Transitions Tooltips" desc="Tooltips with different transition."> + <div> + <TransitionsTooltips /> + <SourceReader componentName={docSrc + 'TransitionsTooltips.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6} xs={12}> + <PapperBlock title="Customized Tooltips" desc="The tooltip with customized css style"> + <div> + <CustomizedTooltips /> + <SourceReader componentName={docSrc + 'CustomizedTooltips.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + <PapperBlock title="Simple Popover" desc="A Popover can be used to display some content on top of another."> + <div> + <SimplePopover /> + <SourceReader componentName={docSrc + 'SimplePopover.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Popover playground" desc="Use the radio buttons to adjust the anchorOrigin and transformOrigin positions. You can also set the anchorReference to anchorPosition or anchorEl."> + <div> + <PopoverPlayground /> + <SourceReader componentName={docSrc + 'PopoverPlayground.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default PopoverTooltip; diff --git a/front/odiparpack/app/containers/UiElements/Progress.js b/front/odiparpack/app/containers/UiElements/Progress.js new file mode 100644 index 0000000..669da02 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Progress.js @@ -0,0 +1,126 @@ +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 { + CircularStatic, + CircularIndeterminate, + CircularDeterminate, + CircularIntegration, + LinearStatic, + LinearIndeterminate, + LinearDeterminate, + LinearBuffer, + LinearQuery, + ProgressDelay +} from './demos'; + +const styles = ({ + root: { + flexGrow: 1, + } +}); + +class Progress extends React.Component { + render() { + const { classes } = this.props; + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Progress/'; + 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={6} xs={12}> + <PapperBlock title="Circular Static" desc="Progress and activity indicators are visual indications of an app loading content."> + <div> + <CircularStatic /> + <SourceReader componentName={docSrc + 'CircularStatic.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Circular Determinate" desc="Indicators display how long an operation will take."> + <div> + <CircularDeterminate /> + <SourceReader componentName={docSrc + 'CircularDeterminate.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6} xs={12}> + <PapperBlock title="Circular Indeterminate" desc="Indicators visualize an unspecified wait time."> + <div> + <CircularIndeterminate /> + <SourceReader componentName={docSrc + 'CircularIndeterminate.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Circular Integration" desc="Visual indicator should be used to represent each type of operation."> + <div> + <CircularIntegration /> + <SourceReader componentName={docSrc + 'CircularIntegration.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + <PapperBlock title="Linear Static" desc=""> + <div> + <LinearStatic /> + <SourceReader componentName={docSrc + 'LinearStatic.js'} /> + </div> + </PapperBlock> + <Grid container spacing={3}> + <Grid item md={6} xs={12}> + <PapperBlock title="Linear Determinate" desc=""> + <div> + <LinearDeterminate /> + <SourceReader componentName={docSrc + 'LinearDeterminate.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Linear Buffer" desc=""> + <div> + <LinearBuffer /> + <SourceReader componentName={docSrc + 'LinearBuffer.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Linear Query" desc=""> + <div> + <LinearQuery /> + <SourceReader componentName={docSrc + 'LinearQuery.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6} xs={12}> + <PapperBlock title="Linear Indeterminate" desc=""> + <div> + <LinearIndeterminate /> + <SourceReader componentName={docSrc + 'LinearIndeterminate.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Progress Delay Appearance" desc="There are 3 important limits to know around response time. The ripple effect of the ButtonBase component ensures that the user feels that the system is reacting instantaneously."> + <div> + <ProgressDelay /> + <SourceReader componentName={docSrc + 'ProgressDelay.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + </div> + </div> + ); + } +} + +Progress.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(Progress); diff --git a/front/odiparpack/app/containers/UiElements/SliderCarousel.js b/front/odiparpack/app/containers/UiElements/SliderCarousel.js new file mode 100644 index 0000000..b624774 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/SliderCarousel.js @@ -0,0 +1,77 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { + SingleCarousel, + MultipleCarousel, + AutoplayCarousel, + ThumbnailCarousel, + VerticalCarousel, + CustomCarousel, + AnimatedSlider +} from './demos'; + +class SliderCarousel extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/SliderCaraousel/'; + 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="Animated Slider" desc="A Slider/Carousel component for React supporting custom css animations."> + <div> + <AnimatedSlider /> + <SourceReader componentName={docSrc + 'AnimatedSlider.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Simple Slider" desc="React slick is a carousel component built with React. It is a react port of slick carousel"> + <div> + <SingleCarousel /> + <SourceReader componentName={docSrc + 'SingleCarousel.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Carousel" desc=""> + <div> + <MultipleCarousel /> + <SourceReader componentName={docSrc + 'MultipleCarousel.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Autoplay Carousel" desc=""> + <div> + <AutoplayCarousel /> + <SourceReader componentName={docSrc + 'AutoplayCarousel.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Carousel with Thumbnail Pagination" desc=""> + <div> + <ThumbnailCarousel /> + <SourceReader componentName={docSrc + 'ThumbnailCarousel.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Vertical Carousel" desc=""> + <div> + <VerticalCarousel /> + <SourceReader componentName={docSrc + 'VerticalCarousel.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Custom Navigation Carousel" desc=""> + <div> + <CustomCarousel /> + <SourceReader componentName={docSrc + 'CustomCarousel.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default SliderCarousel; diff --git a/front/odiparpack/app/containers/UiElements/Steppers.js b/front/odiparpack/app/containers/UiElements/Steppers.js new file mode 100644 index 0000000..358f641 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Steppers.js @@ -0,0 +1,70 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { + HorizontalLinear, + HorizontalNonLinear, + StepperError, + VerticalStepper, + MobileSteppers, + StepperCarousel +} from './demos'; + +class Steppers extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Steppers/'; + 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="Horizontal Linear" desc="The Stepper can be controlled by passing the current step index (zero-based) as the activeStep property."> + <div> + <HorizontalLinear /> + <SourceReader componentName={docSrc + 'HorizontalLinear.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Horizontal Non-linear" desc="Non-linear steppers allow users to enter a multi-step flow at any point."> + <div> + <HorizontalNonLinear /> + <SourceReader componentName={docSrc + 'HorizontalNonLinear.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Horizontal Non Linear - Error Step" desc=""> + <div> + <StepperError /> + <SourceReader componentName={docSrc + 'StepperError.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Vertical Stepper" desc=""> + <div> + <VerticalStepper /> + <SourceReader componentName={docSrc + 'VerticalStepper.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Mobile Stepper" desc="Use a progress bar or dots when there are many steps, or if there are steps that need to be inserted during the process (based on responses to earlier steps)."> + <div> + <MobileSteppers /> + <SourceReader componentName={docSrc + 'MobileSteppers.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Carousel Stepper" desc="This is essentially a back/next button positioned correctly. You must implement the textual description yourself, however, an example is provided below for reference."> + <div> + <StepperCarousel /> + <SourceReader componentName={docSrc + 'StepperCarousel.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Steppers; diff --git a/front/odiparpack/app/containers/UiElements/Tabs.js b/front/odiparpack/app/containers/UiElements/Tabs.js new file mode 100644 index 0000000..0782462 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Tabs.js @@ -0,0 +1,120 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { withStyles } from '@material-ui/core/styles'; +import PropTypes from 'prop-types'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { Grid } from '@material-ui/core'; +import { + SimpleTabs, + LongTextTabs, + FixedTabs, + CenteredTabs, + IconTabs, + ScrollTabs, + ScrollIconTabs, + DisabledTab, + CustomTabs, + BottomNav +} from './demos'; + +const styles = ({ + root: { + flexGrow: 1, + } +}); + +class Tabs extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const { classes } = this.props; + const docSrc = 'containers/UiElements/demos/Tabs/'; + 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}> + <PapperBlock title="Simple Tabs" desc="A simple example with no frills."> + <div> + <SimpleTabs /> + <SourceReader componentName={docSrc + 'SimpleTabs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Wrapped Labels" desc="Long labels will automatically wrap on tabs. If the label is too long for the tab, it will overflow and the text will not be visible."> + <div> + <LongTextTabs /> + <SourceReader componentName={docSrc + 'LongTextTabs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Fixed Tabs" desc="Fixed tabs should be used with a limited number of tabs and when consistent placement will aid muscle memory."> + <div> + <FixedTabs /> + <SourceReader componentName={docSrc + 'FixedTabs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Centered" desc="The centered property should be used for larger views."> + <div> + <CenteredTabs /> + <SourceReader componentName={docSrc + 'CenteredTabs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Icon Tabs" desc="Tab labels may be either all icons or all text."> + <div> + <IconTabs /> + <SourceReader componentName={docSrc + 'IconTabs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Scrollable Tabs" desc="Left and right scroll buttons will automatically be presented on desktop and hidden on mobile. (based on viewport width)"> + <div> + <ScrollTabs /> + <SourceReader componentName={docSrc + 'ScrollTabs.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Scrollable Icon Tabs" desc=""> + <div> + <ScrollIconTabs /> + <SourceReader componentName={docSrc + 'ScrollIconTabs.js'} /> + </div> + </PapperBlock> + <Grid container spacing={3}> + <Grid item md={6}> + <PapperBlock title="Disabled Tab" desc="Tab may be disabled by setting disabled property."> + <div> + <DisabledTab /> + <SourceReader componentName={docSrc + 'DisabledTab.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={6}> + <PapperBlock title="Customized Tabs" desc="If you have been reading the overrides documentation page but you are not confident jumping in, here's an example of how you can change the main color of the Tabs."> + <div> + <CustomTabs /> + <SourceReader componentName={docSrc + 'CustomTabs.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + <PapperBlock title="Bottom Navigation" desc="Bottom navigation bars make it easy to explore and switch between top-level views in a single tap."> + <div> + <BottomNav /> + <SourceReader componentName={docSrc + 'BottomNav.js'} /> + </div> + </PapperBlock> + </div> + </div> + ); + } +} + +Tabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(Tabs); diff --git a/front/odiparpack/app/containers/UiElements/Tags.js b/front/odiparpack/app/containers/UiElements/Tags.js new file mode 100644 index 0000000..e8a5571 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Tags.js @@ -0,0 +1,39 @@ +import React from 'react'; +import { Helmet } from 'react-helmet'; +import brand from 'ba-api/brand'; +import { SourceReader, PapperBlock } from 'ba-components'; +import { BasicTags, ArrayTags } from './demos'; + +class Tags extends React.Component { + render() { + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Tags/'; + 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="Basic Tags" desc="Tags represent complex entities in small blocks, such as a contact."> + <div> + <BasicTags /> + <SourceReader componentName={docSrc + 'BasicTags.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Array Tags" desc="An example of rendering multiple Tags from an array of values. "> + <div> + <ArrayTags /> + <SourceReader componentName={docSrc + 'ArrayTags.js'} /> + </div> + </PapperBlock> + </div> + ); + } +} + +export default Tags; diff --git a/front/odiparpack/app/containers/UiElements/Typography.js b/front/odiparpack/app/containers/UiElements/Typography.js new file mode 100644 index 0000000..e1a88ba --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/Typography.js @@ -0,0 +1,92 @@ +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 { + GeneralTypo, + Heading, + ListTypo, + AlignTypo, + ColouredTypo, + QuotesDemo +} from './demos'; + +const styles = ({ + root: { + flexGrow: 1, + } +}); + +class Typography extends React.Component { + render() { + const { classes } = this.props; + const title = brand.name + ' - UI Elements'; + const description = brand.desc; + const docSrc = 'containers/UiElements/demos/Typography/'; + 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={7} xs={12}> + <PapperBlock title="Genereal Typo" desc="The Roboto font will not be automatically loaded by Material-UI. The developer is responsible for loading all fonts used in their application. Roboto Font has a few easy ways to get started."> + <div> + <GeneralTypo /> + <SourceReader componentName={docSrc + 'GeneralTypo.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Text Alignment" desc=""> + <div> + <AlignTypo /> + <SourceReader componentName={docSrc + 'AlignTypo.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Coloured Text" desc=""> + <div> + <ColouredTypo /> + <SourceReader componentName={docSrc + 'ColouredTypo.js'} /> + </div> + </PapperBlock> + </Grid> + <Grid item md={5} xs={12}> + <PapperBlock title="Fuente - Roboto" desc=""> + <div> + <Heading /> + {/* <SourceReader componentName={docSrc + 'Heading.js'} /> */} + </div> + </PapperBlock> + <PapperBlock title="List" desc=""> + <div> + <ListTypo /> + <SourceReader componentName={docSrc + 'ListTypo.js'} /> + </div> + </PapperBlock> + <PapperBlock title="Quotes" desc=""> + <div> + <QuotesDemo /> + <SourceReader componentName={docSrc + 'QuotesDemo.js'} /> + </div> + </PapperBlock> + </Grid> + </Grid> + </div> + </div> + ); + } +} + +Typography.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(Typography); diff --git a/front/odiparpack/app/containers/UiElements/demos/Accordion/AdvancedAccordion.js b/front/odiparpack/app/containers/UiElements/demos/Accordion/AdvancedAccordion.js new file mode 100644 index 0000000..87cd84e --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Accordion/AdvancedAccordion.js @@ -0,0 +1,97 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import classNames from 'classnames'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; + +import { + ExpansionPanel, + ExpansionPanelDetails, + ExpansionPanelSummary, + ExpansionPanelActions, + Typography, + Chip, + Button, + Divider, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + }, + heading: { + fontSize: theme.typography.pxToRem(15), + }, + secondaryHeading: { + fontSize: theme.typography.pxToRem(15), + color: theme.palette.text.secondary, + }, + icon: { + verticalAlign: 'bottom', + height: 20, + width: 20, + }, + details: { + alignItems: 'center', + }, + column: { + flexBasis: '33.33%', + }, + helper: { + borderLeft: `2px solid ${theme.palette.divider}`, + padding: `${theme.spacing(1)}px ${theme.spacing(2)}px`, + }, + link: { + color: theme.palette.secondary.main, + textDecoration: 'none', + '&:hover': { + textDecoration: 'underline', + }, + }, +}); + +function AdvancedAccordion(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <ExpansionPanel defaultExpanded> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <div className={classes.column}> + <Typography className={classes.heading}>Location</Typography> + </div> + <div className={classes.column}> + <Typography className={classes.secondaryHeading}>Select trip destination</Typography> + </div> + </ExpansionPanelSummary> + <ExpansionPanelDetails className={classes.details}> + <div className={classes.column} /> + <div className={classes.column}> + <Chip label="Barbados" className={classes.chip} onDelete={() => {}} /> + </div> + <div className={classNames(classes.column, classes.helper)}> + <Typography variant="caption"> + Select your destination of choice + <br /> + <a href="#sub-labels-and-columns" className={classes.link}> + Learn more + </a> + </Typography> + </div> + </ExpansionPanelDetails> + <Divider /> + <ExpansionPanelActions> + <Button size="small">Cancel</Button> + <Button size="small" color="secondary"> + Save + </Button> + </ExpansionPanelActions> + </ExpansionPanel> + </div> + ); +} + +AdvancedAccordion.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AdvancedAccordion); diff --git a/front/odiparpack/app/containers/UiElements/demos/Accordion/ControlledAccordion.js b/front/odiparpack/app/containers/UiElements/demos/Accordion/ControlledAccordion.js new file mode 100644 index 0000000..6bcc2c8 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Accordion/ControlledAccordion.js @@ -0,0 +1,100 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; + +import { ExpansionPanel, ExpansionPanelSummary, ExpansionPanelDetails, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + }, + heading: { + fontSize: theme.typography.pxToRem(15), + flexBasis: '33.33%', + flexShrink: 0, + }, + secondaryHeading: { + fontSize: theme.typography.pxToRem(15), + color: theme.palette.text.secondary, + }, +}); + +class ControlledAccordion extends React.Component { + state = { + expanded: null, + }; + + handleChange = panel => (event, expanded) => { + this.setState({ + expanded: expanded ? panel : false, + }); + }; + + render() { + const { classes } = this.props; + const { expanded } = this.state; + + return ( + <div className={classes.root}> + <ExpansionPanel expanded={expanded === 'panel1'} onChange={this.handleChange('panel1')}> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>General settings</Typography> + <Typography className={classes.secondaryHeading}>I am an expansion panel</Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails> + <Typography> + Nulla facilisi. Phasellus sollicitudin nulla et quam mattis feugiat. Aliquam eget + maximus est, id dignissim quam. + </Typography> + </ExpansionPanelDetails> + </ExpansionPanel> + <ExpansionPanel expanded={expanded === 'panel2'} onChange={this.handleChange('panel2')}> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>Users</Typography> + <Typography className={classes.secondaryHeading}> + You are currently not an owner + </Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails> + <Typography> + Donec placerat, lectus sed mattis semper, neque lectus feugiat lectus, varius pulvinar + diam eros in elit. Pellentesque convallis laoreet laoreet. + </Typography> + </ExpansionPanelDetails> + </ExpansionPanel> + <ExpansionPanel expanded={expanded === 'panel3'} onChange={this.handleChange('panel3')}> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>Advanced settings</Typography> + <Typography className={classes.secondaryHeading}> + Filtering has been entirely disabled for whole web server + </Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails> + <Typography> + Nunc vitae orci ultricies, auctor nunc in, volutpat nisl. Integer sit amet egestas + eros, vitae egestas augue. Duis vel est augue. + </Typography> + </ExpansionPanelDetails> + </ExpansionPanel> + <ExpansionPanel expanded={expanded === 'panel4'} onChange={this.handleChange('panel4')}> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>Personal data</Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails> + <Typography> + Nunc vitae orci ultricies, auctor nunc in, volutpat nisl. Integer sit amet egestas + eros, vitae egestas augue. Duis vel est augue. + </Typography> + </ExpansionPanelDetails> + </ExpansionPanel> + </div> + ); + } +} + +ControlledAccordion.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ControlledAccordion); diff --git a/front/odiparpack/app/containers/UiElements/demos/Accordion/SimpleAccordion.js b/front/odiparpack/app/containers/UiElements/demos/Accordion/SimpleAccordion.js new file mode 100644 index 0000000..a88f772 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Accordion/SimpleAccordion.js @@ -0,0 +1,57 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; + +import { ExpansionPanel, ExpansionPanelDetails, ExpansionPanelSummary, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + }, + heading: { + fontSize: theme.typography.pxToRem(15), + fontWeight: theme.typography.fontWeightRegular, + }, +}); + +function SimpleAccordion(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <ExpansionPanel> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>Expansion Panel 1</Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails> + <Typography> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, + sit amet blandit leo lobortis eget. + </Typography> + </ExpansionPanelDetails> + </ExpansionPanel> + <ExpansionPanel> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>Expansion Panel 2</Typography> + </ExpansionPanelSummary> + <ExpansionPanelDetails> + <Typography> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse malesuada lacus ex, + sit amet blandit leo lobortis eget. + </Typography> + </ExpansionPanelDetails> + </ExpansionPanel> + <ExpansionPanel disabled> + <ExpansionPanelSummary expandIcon={<ExpandMoreIcon />}> + <Typography className={classes.heading}>Disabled Expansion Panel</Typography> + </ExpansionPanelSummary> + </ExpansionPanel> + </div> + ); +} + +SimpleAccordion.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SimpleAccordion); diff --git a/front/odiparpack/app/containers/UiElements/demos/Avatars/AvatarsDemo.js b/front/odiparpack/app/containers/UiElements/demos/Avatars/AvatarsDemo.js new file mode 100644 index 0000000..e21391e --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Avatars/AvatarsDemo.js @@ -0,0 +1,112 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import FolderIcon from '@material-ui/icons/Folder'; +import PageviewIcon from '@material-ui/icons/Pageview'; +import AssignmentIcon from '@material-ui/icons/Assignment'; +import avatarApi from 'ba-api/avatars'; + +import { pink, green, deepOrange, deepPurple } from '@material-ui/core/colors'; + +import { Typography, Avatar, Grid } from '@material-ui/core'; + +const styles = ({ + row: { + display: 'flex', + justifyContent: 'flex-start', + }, + avatar: { + margin: 10, + }, + bigAvatar: { + width: 60, + height: 60, + }, + pinkAvatar: { + margin: 10, + color: '#fff', + backgroundColor: pink[500], + }, + greenAvatar: { + margin: 10, + color: '#fff', + backgroundColor: green[500], + }, + orangeAvatar: { + margin: 10, + color: '#fff', + backgroundColor: deepOrange[500], + }, + purpleAvatar: { + margin: 10, + color: '#fff', + backgroundColor: deepPurple[500], + }, +}); + +class AvatarsDemo extends PureComponent { + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid + item + md={4} + > + <Typography variant="button" className={classes.divider}>Image Avatars</Typography> + <div className={classes.row}> + <Avatar alt="Remy Sharp" src={avatarApi[7]} className={classes.avatar} /> + <Avatar + alt="Adelle Charles" + src={avatarApi[5]} + className={classNames(classes.avatar, classes.bigAvatar)} + /> + </div> + </Grid> + <Grid + item + md={4} + > + <Typography variant="button" className={classes.divider}>Icon Avatars</Typography> + <div className={classes.row}> + <Avatar className={classes.avatar}> + <FolderIcon /> + </Avatar> + <Avatar className={classes.pinkAvatar}> + <PageviewIcon /> + </Avatar> + <Avatar className={classes.greenAvatar}> + <AssignmentIcon /> + </Avatar> + </div> + </Grid> + <Grid + item + md={4} + > + <Typography variant="button" className={classes.divider}>Icon Avatars</Typography> + <div className={classes.row}> + <Avatar className={classes.avatar}>H</Avatar> + <Avatar className={classes.orangeAvatar}>N</Avatar> + <Avatar className={classes.purpleAvatar}>OP</Avatar> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +AvatarsDemo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AvatarsDemo); diff --git a/front/odiparpack/app/containers/UiElements/demos/Avatars/AvatarsPractice.js b/front/odiparpack/app/containers/UiElements/demos/Avatars/AvatarsPractice.js new file mode 100644 index 0000000..a95b702 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Avatars/AvatarsPractice.js @@ -0,0 +1,212 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import ImageIcon from '@material-ui/icons/Image'; +import FavoriteIcon from '@material-ui/icons/Favorite'; +import WorkIcon from '@material-ui/icons/Work'; +import BeachAccessIcon from '@material-ui/icons/BeachAccess'; +import ShareIcon from '@material-ui/icons/Share'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import FaceIcon from '@material-ui/icons/Face'; +import imgApi from 'ba-api/images'; + +import { red, green, amber } from '@material-ui/core/colors'; + +import { + Typography, + Card, + CardHeader, + CardMedia, + CardContent, + CardActions, + IconButton, + Avatar, + List, + ListItem, + ListItemText, + ListItemAvatar, + Grid, + Chip, + Divider, +} from '@material-ui/core'; + +const styles = theme => ({ + row: { + display: 'flex', + justifyContent: 'flex-start', + }, + chip: { + margin: theme.spacing(1), + }, + card: { + maxWidth: 400, + }, + media: { + height: 0, + paddingTop: '56.25%', // 16:9 + }, + actions: { + display: 'flex', + }, + expand: { + transform: 'rotate(0deg)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shortest, + }), + marginLeft: 'auto', + }, + expandOpen: { + transform: 'rotate(180deg)', + }, + root: { + width: '100%', + maxWidth: 360, + backgroundColor: theme.palette.background.paper, + }, + avatarRed: { + backgroundColor: red[500], + }, + avatarGreen: { + backgroundColor: green[500], + }, + avatarAmber: { + backgroundColor: amber[500], + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +function handleDelete() { + alert('You clicked the delete icon.'); // eslint-disable-line no-alert +} + +function handleClick() { + alert('You clicked the Chip.'); // eslint-disable-line no-alert +} + +class AvatarsDemo extends PureComponent { + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Avatars in Tag(Chip)</Typography> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={1} + > + <Chip + avatar={<Avatar>MB</Avatar>} + label="Clickable Chip" + onClick={handleClick} + className={classes.chip} + /> + <Chip + avatar={<Avatar src="/images/pp_boy.svg" />} + label="Deletable Chip" + onDelete={handleDelete} + className={classes.chip} + /> + <Chip + avatar={( + <Avatar> + <FaceIcon /> + </Avatar> + )} + label="Clickable Deletable Chip" + onClick={handleClick} + onDelete={handleDelete} + className={classes.chip} + /> + </Grid> + <Divider className={classes.divider} /> + <Typography variant="button" className={classes.divider}>Avatars in List Menu</Typography> + <div className={classes.root}> + <List> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarRed}> + <ImageIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Photos" secondary="Jan 9, 2014" /> + </ListItem> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarGreen}> + <WorkIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Work" secondary="Jan 7, 2014" /> + </ListItem> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarAmber}> + <BeachAccessIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Vacation" secondary="July 20, 2014" /> + </ListItem> + </List> + </div> + </Grid> + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Avatars in Social Media</Typography> + <div> + <Card className={classes.card}> + <CardHeader + avatar={ + <Avatar src="/images/pp_girl.svg" /> + } + action={( + <IconButton> + <MoreVertIcon /> + </IconButton> + )} + title="Aliquam nec ex aliquet" + subheader="September 14, 2018" + /> + <CardMedia + className={classes.media} + image={imgApi[7]} + title="Image" + /> + <CardContent> + <Typography component="p"> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sed urna in justo euismod condimentum. + </Typography> + </CardContent> + <CardActions className={classes.actions}> + <IconButton aria-label="Add to favorites"> + <FavoriteIcon /> + </IconButton> + <IconButton aria-label="Share"> + <ShareIcon /> + </IconButton> + </CardActions> + </Card> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +AvatarsDemo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AvatarsDemo); diff --git a/front/odiparpack/app/containers/UiElements/demos/Badges/CommonBadges.js b/front/odiparpack/app/containers/UiElements/demos/Badges/CommonBadges.js new file mode 100644 index 0000000..b9dca43 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Badges/CommonBadges.js @@ -0,0 +1,121 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles, MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles'; +import { pink, teal } from '@material-ui/core/colors'; + +import { Badge, Typography, Grid, Button } from '@material-ui/core'; + +const styles = theme => ({ + demo: { + height: 'auto', + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, + alone: { + position: 'relative', + margin: 20 + }, + field: { + margin: '10px', + position: 'relative' + }, + cssRoot: { + '& span': { + backgroundColor: pink[700], + color: theme.palette.getContrastText(pink[500]), + }, + }, +}); + +const theme = createMuiTheme({ + palette: { + primary: teal, + secondary: pink + }, +}); + +class CommonBadges extends PureComponent { + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid + item + md={6} + > + <Typography variant="button" className={classes.divider}>Button Badges</Typography> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={3} + > + <div className={classes.field}> + <Badge color="primary" badgeContent={4} className={classes.margin}> + <Button variant="contained">Button</Button> + </Badge> + </div> + <div className={classes.field}> + <Badge color="secondary" badgeContent={4} className={classes.margin}> + <Button variant="contained" color="primary">Button</Button> + </Badge> + </div> + <div className={classes.field}> + <Badge color="primary" badgeContent={4} className={classes.margin}> + <Button variant="contained" color="secondary">Button</Button> + </Badge> + </div> + <div className={classes.field}> + <MuiThemeProvider theme={theme}> + <Badge color="primary" badgeContent={4} className={classes.margin}> + <Button variant="contained" color="secondary">Button</Button> + </Badge> + </MuiThemeProvider> + </div> + </Grid> + </Grid> + <Grid + item + md={6} + > + <Typography variant="button" className={classes.divider}>Text Badges</Typography> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={5} + > + <div className={classes.field}> + <Badge color="primary" badgeContent={4} className={classes.margin}> + <Typography className={classes.padding}>Badge Text</Typography> + </Badge> + </div> + <div className={classes.field}> + <Badge color="secondary" badgeContent={4} className={classes.margin}> + <Typography variant="button" className={classes.padding}>Badges Bold Text</Typography> + </Badge> + </div> + </Grid> + </Grid> + </Grid> + </Fragment> + ); + } +} + +CommonBadges.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CommonBadges); diff --git a/front/odiparpack/app/containers/UiElements/demos/Badges/VariantBadges.js b/front/odiparpack/app/containers/UiElements/demos/Badges/VariantBadges.js new file mode 100644 index 0000000..8dcc485 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Badges/VariantBadges.js @@ -0,0 +1,117 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import classNames from 'classnames'; +import MailIcon from '@material-ui/icons/Mail'; +import { LimitedBadges } from 'ba-components'; + +import { Badge, Typography, Grid, IconButton, AppBar, Tabs, Tab } from '@material-ui/core'; + +const styles = theme => ({ + demo: { + height: 'auto', + }, + divider: { + margin: `${theme.spacing(3)}px 0`, + }, + alone: { + position: 'relative', + margin: 20 + }, + field: { + margin: '10px', + position: 'relative' + }, + margin: { + margin: theme.spacing(2), + }, + padding: { + padding: `0 ${theme.spacing(2)}px`, + }, + autoscale: { + '& span': { + width: 'auto', + padding: 2 + } + } +}); + +class CommonBadges extends PureComponent { + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid + item + md={3} + > + <Typography variant="button" className={classes.divider}>Icon Badges</Typography> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + > + <div className={classes.field}> + <Badge className={classes.margin} badgeContent={4} color="secondary"> + <MailIcon /> + </Badge> + </div> + <div className={classes.field}> + <IconButton> + <Badge badgeContent={10} color="primary"> + <MailIcon /> + </Badge> + </IconButton> + </div> + <div className={classes.field}> + <LimitedBadges className={classes.margin} value={300} limit={99} color="secondary"> + <MailIcon /> + </LimitedBadges> + </div> + <div className={classNames(classes.padding, classes.autoscale)}> + <IconButton> + <LimitedBadges className={classes.margin} value={3000} limit={999} color="primary"> + <MailIcon /> + </LimitedBadges> + </IconButton> + </div> + </Grid> + </Grid> + <Grid + item + md={7} + > + <Typography variant="button" className={classes.divider}>Tab Badges</Typography> + <AppBar position="static"> + <Tabs value={0}> + <Tab + label={( + <Badge className={classes.padding} color="secondary" badgeContent={4}> + Item One + </Badge> + )} + /> + <Tab label="Item Two" /> + <Tab label="Item Three" /> + </Tabs> + </AppBar> + </Grid> + </Grid> + </Fragment> + ); + } +} + +CommonBadges.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CommonBadges); diff --git a/front/odiparpack/app/containers/UiElements/demos/Breadcrumbs/ClassicBreadcrumbs.js b/front/odiparpack/app/containers/UiElements/demos/Breadcrumbs/ClassicBreadcrumbs.js new file mode 100644 index 0000000..786a07b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Breadcrumbs/ClassicBreadcrumbs.js @@ -0,0 +1,83 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { BreadCrumb } from 'ba-components'; + +import { Typography, Grid } from '@material-ui/core'; + +const styles = theme => ({ + demo: { + height: 'auto', + }, + divider: { + margin: `${theme.spacing(3)}px 0`, + }, + field: { + margin: '10px', + position: 'relative' + }, +}); + +class ClassicBreadcrumbs extends PureComponent { + render() { + const { classes } = this.props; + const location = { pathname: '/grand-parent/parent/children' }; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid + item + md={4} + container + alignItems="center" + justify="center" + direction="column" + > + <Typography variant="button" className={classes.divider}>Arrow Separator</Typography> + <div className={classes.field}> + <BreadCrumb theme="dark" separator=" › " location={location} /> + </div> + </Grid> + <Grid + item + md={4} + container + alignItems="center" + justify="center" + direction="column" + > + <Typography variant="button" className={classes.divider}>Slash Separator</Typography> + <div className={classes.field}> + <BreadCrumb theme="dark" separator=" / " location={location} /> + </div> + </Grid> + <Grid + item + md={4} + container + alignItems="center" + justify="center" + direction="column" + > + <Typography variant="button" className={classes.divider}>Greater Than Separator</Typography> + <div className={classes.field}> + <BreadCrumb theme="dark" separator=" > " location={location} /> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +ClassicBreadcrumbs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ClassicBreadcrumbs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Breadcrumbs/PaperBreadcrumbs.js b/front/odiparpack/app/containers/UiElements/demos/Breadcrumbs/PaperBreadcrumbs.js new file mode 100644 index 0000000..70effb0 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Breadcrumbs/PaperBreadcrumbs.js @@ -0,0 +1,97 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { BreadCrumb } from 'ba-components'; + +import { Typography, Grid, Paper } from '@material-ui/core'; + +const styles = theme => ({ + demo: { + height: 'auto', + }, + divider: { + margin: `${theme.spacing(3)}px 0`, + }, + alone: { + position: 'relative', + margin: 20 + }, + field: { + margin: '10px', + position: 'relative' + }, + paper: { + padding: '5px 10px 1px', + borderRadius: 5 + } +}); + +class ClassicBreadcrumbs extends PureComponent { + render() { + const { classes } = this.props; + const location = { pathname: '/grand-parent/parent/children' }; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={1} + > + <Grid + item + md={6} + container + alignItems="center" + justify="center" + direction="column" + > + <Typography variant="button" className={classes.divider}>Arrow Separator</Typography> + <div className={classes.field}> + <Paper className={classes.paper}> + <BreadCrumb theme="dark" separator=" › " location={location} /> + </Paper> + </div> + </Grid> + <Grid + item + md={6} + container + alignItems="center" + justify="center" + direction="column" + > + <Typography variant="button" className={classes.divider}>Slash Separator</Typography> + <div className={classes.field}> + <Paper className={classes.paper}> + <BreadCrumb theme="dark" separator=" / " location={location} /> + </Paper> + </div> + </Grid> + <Grid + item + md={12} + container + alignItems="center" + justify="center" + direction="column" + > + <Typography variant="button" className={classes.divider}>Greater Than Separator</Typography> + <div className={classes.field}> + <Paper className={classes.paper}> + <BreadCrumb theme="dark" separator=" > " location={location} /> + </Paper> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +ClassicBreadcrumbs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ClassicBreadcrumbs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Cards/ControlCards.js b/front/odiparpack/app/containers/UiElements/demos/Cards/ControlCards.js new file mode 100644 index 0000000..1ddc92b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Cards/ControlCards.js @@ -0,0 +1,204 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import classnames from 'classnames'; +import FavoriteIcon from '@material-ui/icons/Favorite'; +import ShareIcon from '@material-ui/icons/Share'; +import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; +import imgApi from 'ba-api/images'; +import { PlayerCard, VideoCard } from 'ba-components'; +import { red } from '@material-ui/core/colors'; + +import { + Typography, + Grid, + Card, + CardHeader, + CardMedia, + CardContent, + CardActions, + IconButton, + Collapse, + Avatar, +} from '@material-ui/core'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, + card: { + display: 'flex', + justifyContent: 'space-between' + }, + details: { + display: 'flex', + flexDirection: 'column', + }, + content: { + flex: '1 0 auto', + }, + cover: { + width: 150, + height: 150, + }, + controls: { + display: 'flex', + alignItems: 'center', + paddingLeft: theme.spacing(1), + paddingBottom: theme.spacing(1), + }, + playIcon: { + height: 38, + width: 38, + }, + cardSocmed: { + maxWidth: 400, + }, + media: { + height: 0, + paddingTop: '56.25%', // 16:9 + }, + actions: { + display: 'flex', + }, + expand: { + transform: 'rotate(0deg)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.shortest, + }), + marginLeft: 'auto', + }, + expandOpen: { + transform: 'rotate(180deg)', + }, + avatar: { + backgroundColor: red[500], + }, +}); + +class ControlCard extends React.Component { + state = { expanded: false }; + + handleExpandClick = () => { + this.setState({ expanded: !this.state.expanded }); + }; + + render() { + const { classes } = this.props; + + return ( + <Grid + container + alignItems="center" + justify="flex-start" + spacing={2} + > + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>UI Controls</Typography> + <div> + <PlayerCard + title="Live From Space" + artist="Mac Miller" + cover={imgApi[32]} + /> + </div> + </Grid> + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Video Thumb</Typography> + <VideoCard + title="Live From Space" + cover={imgApi[42]} + date="September 14, 2016" + /> + </Grid> + <Grid item md={12} container alignItems="center" direction="column"> + <Typography variant="button" className={classes.divider}>Complex Interaction</Typography> + <div> + <Card className={classes.cardSocmed}> + <CardHeader + avatar={( + <Avatar aria-label="Recipe" className={classes.avatar}> + R + </Avatar> + )} + action={( + <IconButton> + <MoreVertIcon /> + </IconButton> + )} + title="Shrimp and Chorizo Paella" + subheader="September 14, 2016" + /> + <CardMedia + className={classes.media} + image={imgApi[3]} + title="Contemplative Reptile" + /> + <CardContent> + <Typography component="p"> + This impressive paella is a perfect party dish and a fun meal to cook together with + your guests. Add 1 cup of frozen peas along with the mussels, if you like. + </Typography> + </CardContent> + <CardActions className={classes.actions}> + <IconButton aria-label="Add to favorites"> + <FavoriteIcon /> + </IconButton> + <IconButton aria-label="Share"> + <ShareIcon /> + </IconButton> + <IconButton + className={classnames(classes.expand, { + [classes.expandOpen]: this.state.expanded, + })} + onClick={this.handleExpandClick} + aria-expanded={this.state.expanded} + aria-label="Show more" + > + <ExpandMoreIcon /> + </IconButton> + </CardActions> + <Collapse in={this.state.expanded} timeout="auto" unmountOnExit> + <CardContent> + <Typography paragraph variant="body1"> + Method: + </Typography> + <Typography paragraph> + Heat 1/2 cup of the broth in a pot until simmering, add saffron and set aside for 10 + minutes. + </Typography> + <Typography paragraph> + Heat oil in a (14- to 16-inch) paella pan or a large, deep skillet over medium-high + heat. Add chicken, shrimp and chorizo, and cook, stirring occasionally until lightly + browned, 6 to 8 minutes. Transfer shrimp to a large plate and set aside, leaving + chicken and chorizo in the pan. Add pimentón, bay leaves, garlic, tomatoes, onion, + salt and pepper, and cook, stirring often until thickened and fragrant, about 10 + minutes. Add saffron broth and remaining 4 1/2 cups chicken broth; bring to a boil. + </Typography> + <Typography paragraph> + Add rice and stir very gently to distribute. Top with artichokes and peppers, and + cook without stirring, until most of the liquid is absorbed, 15 to 18 minutes. + Reduce heat to medium-low, add reserved shrimp and mussels, tucking them down into + the rice, and cook again without stirring, until mussels have opened and rice is + just tender, 5 to 7 minutes more. (Discard any mussels that don’t open.) + </Typography> + <Typography> + Set aside off of the heat to let rest for 10 minutes, and then serve. + </Typography> + </CardContent> + </Collapse> + </Card> + </div> + </Grid> + </Grid> + ); + } +} + +ControlCard.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ControlCard); diff --git a/front/odiparpack/app/containers/UiElements/demos/Cards/EcommerceCards.js b/front/odiparpack/app/containers/UiElements/demos/Cards/EcommerceCards.js new file mode 100644 index 0000000..6a5a275 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Cards/EcommerceCards.js @@ -0,0 +1,92 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgApi from 'ba-api/images'; +import { ProductCard } from 'ba-components'; + +import { Typography, Grid } from '@material-ui/core'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, +}); + +class EcommerceCard extends React.Component { + render() { + const { classes } = this.props; + return ( + <Grid + container + alignItems="flex-start" + justify="center" + direction="row" + spacing={2} + > + <Grid item md={4}> + <Typography variant="button" className={classes.divider}>Product Card</Typography> + <ProductCard + thumbnail={imgApi[21]} + name="Lorem ipsum dolor sit amet" + desc="Sed imperdiet enim ligula, vitae viverra justo porta vel. Duis eget felis bibendum, pretium mi sed, placerat ante." + ratting={5} + price={30} + /> + </Grid> + <Grid item md={4}> + <Typography variant="button" className={classes.divider}>Product with discount</Typography> + <ProductCard + discount="10%" + thumbnail={imgApi[22]} + name="Cras convallis lacus orci" + desc="Phasellus ante massa, aliquam non ante at" + ratting={3} + price={18} + prevPrice={20} + /> + </Grid> + <Grid item md={4}> + <Typography variant="button" className={classes.divider}>Sold Out Product</Typography> + <ProductCard + soldout + thumbnail={imgApi[23]} + name="Lorem ipsum dolor sit amet" + desc="Sed imperdiet enim ligula, vitae viverra justo porta vel. Duis eget felis bibendum, pretium mi sed, placerat ante." + ratting={4} + price={44} + /> + </Grid> + <Grid item md={12}> + <Typography variant="button" className={classes.divider}>List Mode</Typography> + <ProductCard + discount="10%" + thumbnail={imgApi[24]} + name="Lorem ipsum dolor sit amet" + desc="Sed imperdiet enim ligula, vitae viverra justo porta vel. Duis eget felis bibendum, pretium mi sed, placerat ante." + ratting={5} + price={30} + prevPrice={20} + list + /> + </Grid> + <Grid item md={12}> + <ProductCard + thumbnail={imgApi[25]} + name="Lorem ipsum dolor sit amet" + desc="Sed imperdiet enim ligula, vitae viverra justo porta vel. Duis eget felis bibendum, pretium mi sed, placerat ante." + ratting={0} + price={20} + list + /> + </Grid> + </Grid> + ); + } +} + +EcommerceCard.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(EcommerceCard); diff --git a/front/odiparpack/app/containers/UiElements/demos/Cards/PaperSheet.js b/front/odiparpack/app/containers/UiElements/demos/Cards/PaperSheet.js new file mode 100644 index 0000000..2867e38 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Cards/PaperSheet.js @@ -0,0 +1,34 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Paper, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: theme.mixins.gutters({ + paddingTop: 16, + paddingBottom: 16, + marginTop: theme.spacing(3), + }), +}); + +function PaperSheet(props) { + const { classes } = props; + return ( + <div> + <Paper className={classes.root} elevation={4}> + <Typography variant="h5" component="h3"> + This is a sheet of paper. + </Typography> + <Typography component="p"> + Paper can be used to build surface or other elements for your application. + </Typography> + </Paper> + </div> + ); +} + +PaperSheet.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(PaperSheet); diff --git a/front/odiparpack/app/containers/UiElements/demos/Cards/SocialCards.js b/front/odiparpack/app/containers/UiElements/demos/Cards/SocialCards.js new file mode 100644 index 0000000..7208926 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Cards/SocialCards.js @@ -0,0 +1,75 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgApi from 'ba-api/images'; +import avatarApi from 'ba-api/avatars'; +import { ProfileCard, PostCard } from 'ba-components'; + +import { Typography, Grid } from '@material-ui/core'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, +}); + +class StandardCard extends React.Component { + render() { + const { classes } = this.props; + + return ( + <Grid + container + alignItems="flex-start" + justify="center" + direction="row" + spacing={2} + > + <Grid item md={4}> + <Typography variant="button" className={classes.divider}>Profile Card</Typography> + <ProfileCard + cover={imgApi[42]} + avatar={avatarApi[6]} + name="John Doe" + title="UX designer" + connection={10} + btnText="Connect" + isVerified + /> + </Grid> + <Grid item md={4}> + <Typography variant="button" className={classes.divider}>Post Card</Typography> + <PostCard + liked={1} + shared={20} + commented={15} + date="Sept, 25 2018" + content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sed urna in justo euismod condimentum." + image={imgApi[11]} + avatar={avatarApi[10]} + name="Jim Doe" + /> + </Grid> + <Grid item md={4}> + <Typography variant="button" className={classes.divider}>Post Card (Without Image)</Typography> + <PostCard + liked={90} + shared={10} + commented={22} + date="Sept, 15 2018" + content="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sed urna in justo euismod condimentum." + avatar={avatarApi[2]} + name="Jane Doe" + /> + </Grid> + </Grid> + ); + } +} + +StandardCard.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(StandardCard); diff --git a/front/odiparpack/app/containers/UiElements/demos/Cards/StandardCards.js b/front/odiparpack/app/containers/UiElements/demos/Cards/StandardCards.js new file mode 100644 index 0000000..37fdf39 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Cards/StandardCards.js @@ -0,0 +1,120 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import dummy from 'ba-api/dummyContents'; +import imgApi from 'ba-api/images'; +import { GeneralCard, NewsCard, Quote, IdentityCard } from 'ba-components'; + +import { Typography, Grid } from '@material-ui/core'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, + card: { + minWidth: 275, + }, + bullet: { + display: 'inline-block', + margin: '0 2px', + transform: 'scale(0.8)', + }, + title: { + marginBottom: 16, + fontSize: 14, + }, + pos: { + marginBottom: 12, + }, + cardMedia: { + maxWidth: 345, + }, + media: { + height: 0, + paddingTop: '56.25%', // 16:9 + }, +}); + +class StandardCard extends React.Component { + render() { + const { classes } = this.props; + const bull = <span className={classes.bullet}>•</span>; + + return ( + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Simple Card</Typography> + <div> + <GeneralCard liked={1} shared={20} commented={15}> + <Typography className={classes.title} color="textSecondary"> + Word of the Day + </Typography> + <Typography variant="h5" component="h2"> + be + {bull} +nev + {bull} +o + {bull} +lent + </Typography> + <Typography className={classes.pos} color="textSecondary"> + adjective + </Typography> + <Typography component="p"> + well meaning and kindly. + <br /> + {'"a benevolent smile"'} + </Typography> + </GeneralCard> + </div> + <Typography variant="button" className={classes.divider}>Media</Typography> + <div> + <NewsCard + image={imgApi[8]} + title="Contemplative Reptile" + > + <Typography gutterBottom variant="h5" component="h2"> + Lorem ipsum + </Typography> + <Typography component="p"> + Aliquam venenatis magna et odio lobortis maximus. Nullam in tortor ligula. Proin maximus risus nunc + </Typography> + </NewsCard> + </div> + </Grid> + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Quoted Card</Typography> + <div> + <GeneralCard liked={1} shared={20} commented={15}> + <Quote align="left" content="Imagine all the people living life in peace. You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us, and the world will be as one." footnote="John Lennon" /> + </GeneralCard> + </div> + <div> + <Typography variant="button" className={classes.divider}>Identity Card</Typography> + <IdentityCard + title="Contact and Address Card" + name={dummy.user.name} + avatar={dummy.user.avatar} + phone="(+8543201213)" + address="Town Hall Building no.45 Block C - ABC Street" + /> + </div> + </Grid> + </Grid> + ); + } +} + +StandardCard.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(StandardCard); diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/AlertDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/AlertDialog.js new file mode 100644 index 0000000..68f099a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/AlertDialog.js @@ -0,0 +1,127 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; + +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + Grid, + Typography, + Slide, +} from '@material-ui/core'; + +const styles = theme => ({ + title: { + display: 'block', + margin: `${theme.spacing(4)}px 0 ${theme.spacing(2)}px`, + }, +}); + +const Transition = React.forwardRef(function Transition(props, ref) { // eslint-disable-line + return <Slide direction="up" ref={ref} {...props} />; +}); + +class AlertDialog extends React.Component { // eslint-disable-line + state = { + open: false, + openSlide: false, + }; + + handleClickOpen = () => { + this.setState({ open: true }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + handleClickOpenSlide = () => { + this.setState({ openSlide: true }); + }; + + handleCloseSlide = () => { + this.setState({ openSlide: false }); + }; + + render() { + const { classes } = this.props; + return ( + <div> + <Grid container spacing={2}> + <Grid item md={6}> + <Typography variant="button" className={classes.title}> + Fade Transition + </Typography> + <Button color="secondary" onClick={this.handleClickOpen}>Open alert dialog</Button> + <Dialog + open={this.state.open} + onClose={this.handleClose} + aria-labelledby="alert-dialog-title" + aria-describedby="alert-dialog-description" + > + <DialogTitle id="alert-dialog-title"> + {"Use Google's location service?"} + </DialogTitle> + <DialogContent> + <DialogContentText id="alert-dialog-description"> + Let Google help apps determine location. This means sending anonymous location data to + Google, even when no apps are running. + </DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={this.handleClose} color="primary"> + Disagree + </Button> + <Button onClick={this.handleClose} color="primary" autoFocus> + Agree + </Button> + </DialogActions> + </Dialog> + </Grid> + <Grid item md={6}> + <Typography variant="button" className={classes.title}> + Slide Transition + </Typography> + <Button onClick={this.handleClickOpenSlide} color="primary">Slide in alert dialog</Button> + <Dialog + open={this.state.openSlide} + TransitionComponent={Transition} + keepMounted + onClose={this.handleCloseSlide} + aria-labelledby="alert-dialog-slide-title" + aria-describedby="alert-dialog-slide-description" + > + <DialogTitle id="alert-dialog-slide-title"> + {"Use Google's location service?"} + </DialogTitle> + <DialogContent> + <DialogContentText id="alert-dialog-slide-description"> + Let Google help apps determine location. This means sending anonymous location data to + Google, even when no apps are running. + </DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={this.handleClose} color="primary"> + Disagree + </Button> + <Button onClick={this.handleClose} color="primary"> + Agree + </Button> + </DialogActions> + </Dialog> + </Grid> + </Grid> + </div> + ); + } +} + +AlertDialog.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AlertDialog); diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/ConfirmationDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ConfirmationDialog.js new file mode 100644 index 0000000..1f49788 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ConfirmationDialog.js @@ -0,0 +1,111 @@ +import React from 'react'; +import PropTypes from 'prop-types'; + +import { + Button, + DialogTitle, + DialogContent, + DialogActions, + Dialog, + Radio, + RadioGroup, + FormControlLabel, +} from '@material-ui/core'; + +const options = [ + 'None', + 'Atria', + 'Callisto', + 'Dione', + 'Ganymede', + 'Hangouts Call', + 'Luna', + 'Oberon', + 'Phobos', + 'Pyxis', + 'Sedna', + 'Titania', + 'Triton', + 'Umbriel', +]; + +class ConfirmationDialog extends React.Component { + constructor(props, context) { + super(props, context); + + this.state.value = this.props.value; + } + + state = {}; + + componentWillReceiveProps(nextProps) { + if (nextProps.value !== this.props.value) { + this.setState({ value: nextProps.value }); + } + } + + radioGroup = null; + + handleEntering = () => { + this.radioGroup.focus(); + }; + + handleCancel = () => { + this.props.onClose(this.props.value); + }; + + handleOk = () => { + this.props.onClose(this.state.value); + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { value, ...other } = this.props; + + return ( + <Dialog + disableBackdropClick + disableEscapeKeyDown + maxWidth="xs" + onEntering={this.handleEntering} + aria-labelledby="confirmation-dialog-title" + {...other} + > + <DialogTitle id="confirmation-dialog-title">Phone Ringtone</DialogTitle> + <DialogContent> + <RadioGroup + ref={node => { + this.radioGroup = node; + }} + aria-label="ringtone" + name="ringtone" + value={this.state.value} + onChange={this.handleChange} + > + {options.map(option => ( + <FormControlLabel value={option} key={option} control={<Radio />} label={option} /> + ))} + </RadioGroup> + </DialogContent> + <DialogActions> + <Button onClick={this.handleCancel} color="primary"> + Cancel + </Button> + <Button onClick={this.handleOk} color="primary"> + Ok + </Button> + </DialogActions> + </Dialog> + ); + } +} + +ConfirmationDialog.propTypes = { + onClose: PropTypes.func.isRequired, + value: PropTypes.string.isRequired, +}; + +export default ConfirmationDialog; diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/FormDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/FormDialog.js new file mode 100644 index 0000000..58bf1aa --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/FormDialog.js @@ -0,0 +1,65 @@ +import React from 'react'; + +import { + Button, + TextField, + Grid, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, +} from '@material-ui/core'; + +export default class FormDialog extends React.Component { + state = { + open: false, + }; + + handleClickOpen = () => { + this.setState({ open: true }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + render() { + return ( + <div> + <Grid container justify="center" direction="column"> + <Button variant="contained" color="secondary" onClick={this.handleClickOpen}>Open form dialog</Button> + <Dialog + open={this.state.open} + onClose={this.handleClose} + aria-labelledby="form-dialog-title" + > + <DialogTitle id="form-dialog-title">Subscribe</DialogTitle> + <DialogContent> + <DialogContentText> + To subscribe to this website, please enter your email address here. We will send + updates occasionally. + </DialogContentText> + <TextField + autoFocus + margin="dense" + id="name" + label="Email Address" + type="email" + fullWidth + /> + </DialogContent> + <DialogActions> + <Button onClick={this.handleClose} color="primary"> + Cancel + </Button> + <Button onClick={this.handleClose} color="primary"> + Subscribe + </Button> + </DialogActions> + </Dialog> + </Grid> + </div> + ); + } +} diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/FullScreenDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/FullScreenDialog.js new file mode 100644 index 0000000..935ed4d --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/FullScreenDialog.js @@ -0,0 +1,134 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import CloseIcon from '@material-ui/icons/Close'; + +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, + List, + ListItem, + ListItemText, + Divider, + Grid, + AppBar, + Toolbar, + IconButton, + Typography, + Slide, +} from '@material-ui/core'; + +const styles = { + appBar: { + position: 'relative', + }, + flex: { + flex: 1, + }, +}; + +const Transition = React.forwardRef(function Transition(props, ref) { // eslint-disable-line + return <Slide direction="up" ref={ref} {...props} />; +}); + +class FullScreenDialog extends React.Component { // eslint-disable-line + state = { + open: false, + open2: false, + }; + + handleClickOpen = () => { + this.setState({ open: true }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + handleClickOpen2 = () => { + this.setState({ open2: true }); + }; + + handleClose2 = () => { + this.setState({ open2: false }); + }; + + render() { + const { classes } = this.props; + return ( + <div> + <Grid container spacing={2}> + <Grid item container alignItems="center" justify="center" md={6}> + <Button variant="contained" color="primary" onClick={this.handleClickOpen}>Open full-screen dialog</Button> + <Dialog + fullScreen + open={this.state.open} + onClose={this.handleClose} + TransitionComponent={Transition} + > + <AppBar className={classes.appBar}> + <Toolbar> + <IconButton color="inherit" onClick={this.handleClose} aria-label="Close"> + <CloseIcon /> + </IconButton> + <Typography variant="h6" color="inherit" className={classes.flex}> + Sound + </Typography> + <Button color="inherit" onClick={this.handleClose}> + save + </Button> + </Toolbar> + </AppBar> + <List> + <ListItem button> + <ListItemText primary="Phone ringtone" secondary="Titania" /> + </ListItem> + <Divider /> + <ListItem button> + <ListItemText primary="Default notification ringtone" secondary="Tethys" /> + </ListItem> + </List> + </Dialog> + </Grid> + <Grid item container alignItems="center" justify="center" md={6}> + <Button variant="contained" color="secondary" onClick={this.handleClickOpen2}>Open responsive dialog</Button> + <Dialog + fullScreen + open={this.state.open2} + onClose={this.handleClose} + aria-labelledby="responsive-dialog-title" + > + <DialogTitle id="responsive-dialog-title"> + {'Use location service?'} + </DialogTitle> + <DialogContent> + <DialogContentText> + Let Google help apps determine location. This means sending anonymous location data to + Google, even when no apps are running. + </DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={this.handleClose2} color="primary"> + Disagree + </Button> + <Button onClick={this.handleClose2} color="primary" autoFocus> + Agree + </Button> + </DialogActions> + </Dialog> + </Grid> + </Grid> + </div> + ); + } +} + +FullScreenDialog.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(FullScreenDialog); diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/ImagePopup.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ImagePopup.js new file mode 100644 index 0000000..169c5ec --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ImagePopup.js @@ -0,0 +1,51 @@ +import React, { Component } from 'react'; +import 'ba-styles/vendors/image-lightbox/image-lightbox.css'; +import images from 'ba-api/imgData'; +import { ImageLightbox } from 'ba-components'; + +import { Button, Grid } from '@material-ui/core'; + +export default class ImagePopup extends Component { + constructor(props) { + super(props); + + this.state = { + photoIndex: 0, + isOpen: false, + }; + } + + render() { + const { photoIndex, isOpen } = this.state; + + return ( + <Grid + container + alignItems="center" + justify="center" + direction="column" + > + <Button variant="contained" color="secondary" onClick={() => this.setState({ isOpen: true })}> + Open Image Lightbox + </Button> + + {isOpen && ( + <ImageLightbox + mainSrc={images[photoIndex].img} + nextSrc={images[(photoIndex + 1) % images.length].img} + prevSrc={images[(photoIndex + (images.length - 1)) % images.length].img} + onCloseRequest={() => this.setState({ isOpen: false })} + onMovePrevRequest={() => this.setState({ + photoIndex: (photoIndex + (images.length - 1)) % images.length, + }) + } + onMoveNextRequest={() => this.setState({ + photoIndex: (photoIndex + 1) % images.length, + }) + } + /> + )} + </Grid> + ); + } +} diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/ModalDemo.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ModalDemo.js new file mode 100644 index 0000000..c18a5e1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ModalDemo.js @@ -0,0 +1,73 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Typography, Modal, Button, Grid } from '@material-ui/core'; + +function getModalStyle() { + return { + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + }; +} + +const styles = theme => ({ + paper: { + position: 'absolute', + width: theme.spacing(50), + backgroundColor: theme.palette.background.paper, + boxShadow: theme.shadows[5], + padding: theme.spacing(4), + }, +}); + +class ModalDemo extends React.Component { + state = { + open: false, + }; + + handleOpen = () => { + this.setState({ open: true }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + render() { + const { classes } = this.props; + + return ( + <Grid + container + alignItems="center" + justify="center" + direction="column" + > + <Typography gutterBottom>Click to get the full Modal experience!</Typography> + <Button variant="contained" color="secondary" onClick={this.handleOpen}>Open Modal</Button> + <Modal + aria-labelledby="simple-modal-title" + aria-describedby="simple-modal-description" + open={this.state.open} + onClose={this.handleClose} + > + <div style={getModalStyle()} className={classes.paper}> + <Typography variant="h6" id="modal-title"> + Text in a modal + </Typography> + <Typography variant="subtitle1" id="simple-modal-description"> + Duis mollis, est non commodo luctus, nisi erat porttitor ligula. + </Typography> + </div> + </Modal> + </Grid> + ); + } +} + +ModalDemo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ModalDemo); diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/ScrollDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ScrollDialog.js new file mode 100644 index 0000000..b7f2b74 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/ScrollDialog.js @@ -0,0 +1,93 @@ +import React from 'react'; + +import { + Button, + Dialog, + DialogActions, + DialogContent, + DialogContentText, + DialogTitle, +} from '@material-ui/core'; + +class ScrollDialog extends React.Component { + state = { + open: false, + scroll: 'paper', + }; + + handleClickOpen = scroll => () => { + this.setState({ open: true, scroll }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + render() { + return ( + <div> + <Button variant="contained" color="secondary" onClick={this.handleClickOpen('paper')}>scroll=paper</Button> + + <Button variant="contained" color="secondary" onClick={this.handleClickOpen('body')}>scroll=body</Button> + <Dialog + open={this.state.open} + onClose={this.handleClose} + scroll={this.state.scroll} + aria-labelledby="scroll-dialog-title" + > + <DialogTitle id="scroll-dialog-title">Subscribe</DialogTitle> + <DialogContent> + <DialogContentText> + Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac + facilisis in, egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum + at eros. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus + sagittis lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum + nulla sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur + et. Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras + mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, + egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla + sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis + consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, + egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla + sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis + consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, + egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla + sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis + consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, + egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla + sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. Cras mattis + consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, + egestas eget quam. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. + Praesent commodo cursus magna, vel scelerisque nisl consectetur et. Vivamus sagittis + lacus vel augue laoreet rutrum faucibus dolor auctor. Aenean lacinia bibendum nulla + sed consectetur. Praesent commodo cursus magna, vel scelerisque nisl consectetur et. + Donec sed odio dui. Donec ullamcorper nulla non metus auctor fringilla. + </DialogContentText> + </DialogContent> + <DialogActions> + <Button onClick={this.handleClose} color="primary"> + Cancel + </Button> + <Button onClick={this.handleClose} color="primary"> + Subscribe + </Button> + </DialogActions> + </Dialog> + </div> + ); + } +} + +export default ScrollDialog; diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/SelectDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/SelectDialog.js new file mode 100644 index 0000000..f75b1be --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/SelectDialog.js @@ -0,0 +1,120 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import PersonIcon from '@material-ui/icons/Person'; +import AddIcon from '@material-ui/icons/Add'; +import { blue } from '@material-ui/core/colors'; + +import { + Button, + Avatar, + List, + ListItem, + ListItemText, + ListItemAvatar, + Dialog, + DialogTitle, + Typography, + Grid, +} from '@material-ui/core'; + +const emails = ['[email protected]', '[email protected]']; +const styles = ({ + avatar: { + backgroundColor: blue[100], + color: blue[600], + }, +}); + +const SimpleDialog = props => { + const { + classes, + onClose, + selectedValue, + ...other + } = props; + + function handleClose() { + props.onClose(this.props.selectedValue); + } + + function handleListItemClick(value) { + props.onClose(value); + } + + return ( + <Dialog onClose={() => handleClose()} aria-labelledby="simple-dialog-title" {...other}> + <DialogTitle id="simple-dialog-title">Set backup account</DialogTitle> + <div> + <List> + {emails.map(email => ( + <ListItem button onClick={() => handleListItemClick(email)} key={email}> + <ListItemAvatar> + <Avatar className={classes.avatar}> + <PersonIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary={email} /> + </ListItem> + ))} + <ListItem button onClick={() => handleListItemClick('addAccount')}> + <ListItemAvatar> + <Avatar> + <AddIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="add account" /> + </ListItem> + </List> + </div> + </Dialog> + ); +}; + +SimpleDialog.propTypes = { + classes: PropTypes.object.isRequired, + onClose: PropTypes.func.isRequired, + selectedValue: PropTypes.string.isRequired, +}; + +const SimpleDialogWrapped = withStyles(styles)(SimpleDialog); + +class SelectDialog extends React.Component { + state = { + open: false, + selectedValue: emails[1], + }; + + handleClickOpen = () => { + this.setState({ + open: true, + }); + }; + + handleClose = value => { + this.setState({ selectedValue: value, open: false }); + }; + + render() { + return ( + <div> + <Grid container justify="center" direction="column"> + <Typography variant="subtitle1"> +Selected: + <strong>{this.state.selectedValue}</strong> + </Typography> + <br /> + <Button variant="contained" color="primary" onClick={this.handleClickOpen}>Open simple dialog</Button> + <SimpleDialogWrapped + selectedValue={this.state.selectedValue} + open={this.state.open} + onClose={this.handleClose} + /> + </Grid> + </div> + ); + } +} + + +export default SelectDialog; diff --git a/front/odiparpack/app/containers/UiElements/demos/DialogModal/SelectRadioDialog.js b/front/odiparpack/app/containers/UiElements/demos/DialogModal/SelectRadioDialog.js new file mode 100644 index 0000000..ff30bd4 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DialogModal/SelectRadioDialog.js @@ -0,0 +1,68 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { List, ListItem, ListItemText } from '@material-ui/core'; +import ConfirmationDialog from './ConfirmationDialog'; + + +const styles = theme => ({ + root: { + width: '100%', + maxWidth: 360, + backgroundColor: theme.palette.background.paper, + }, + dialog: { + width: '80%', + maxHeight: 435, + }, +}); + +class SelectRadioDialog extends React.Component { + state = { + open: false, + value: 'Dione', + }; + + button = undefined; + + handleClickListItem = () => { + this.setState({ open: true }); + }; + + handleClose = value => { + this.setState({ value, open: false }); + }; + + render() { + const { classes } = this.props; + return ( + <div className={classes.root}> + <List> + <ListItem + button + aria-haspopup="true" + aria-controls="ringtone-menu" + aria-label="Phone ringtone" + onClick={this.handleClickListItem} + > + <ListItemText primary="Phone ringtone" secondary={this.state.value} /> + </ListItem> + <ConfirmationDialog + classes={{ + paper: classes.dialog, + }} + open={this.state.open} + onClose={this.handleClose} + value={this.state.value} + /> + </List> + </div> + ); + } +} + +SelectRadioDialog.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SelectRadioDialog); diff --git a/front/odiparpack/app/containers/UiElements/demos/Dividers/CommonDividers.js b/front/odiparpack/app/containers/UiElements/demos/Dividers/CommonDividers.js new file mode 100644 index 0000000..db67c0f --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Dividers/CommonDividers.js @@ -0,0 +1,29 @@ +import React, { Fragment, PureComponent } from 'react'; +import Type from 'ba-styles/Typography.scss'; +import { + GradientDivider, + DashDivider, + ShadowDivider, + InsetDivider, +} from 'ba-components/Divider'; + +import { Typography } from '@material-ui/core'; + +class CommonDivider extends PureComponent { + render() { + return ( + <Fragment> + <Typography variant="button" className={Type.textCenter}>Gradient Divider</Typography> + <GradientDivider /> + <Typography variant="button" className={Type.textCenter}>Dash Divider</Typography> + <DashDivider /> + <Typography variant="button" className={Type.textCenter}>Shadow Divider</Typography> + <ShadowDivider /> + <Typography variant="button" className={Type.textCenter}>Inset Divider</Typography> + <InsetDivider /> + </Fragment> + ); + } +} + +export default CommonDivider; diff --git a/front/odiparpack/app/containers/UiElements/demos/Dividers/SpecialDividers.js b/front/odiparpack/app/containers/UiElements/demos/Dividers/SpecialDividers.js new file mode 100644 index 0000000..d857e06 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Dividers/SpecialDividers.js @@ -0,0 +1,23 @@ +import React, { Fragment, PureComponent } from 'react'; +import Type from 'ba-styles/Typography.scss'; +import { + FlairedEdgesDivider, + ContentDivider, +} from 'ba-components/Divider'; + +import { Typography } from '@material-ui/core'; + +class CommonDivider extends PureComponent { + render() { + return ( + <Fragment> + <Typography variant="button" className={Type.textCenter}>Flaired Edges Divider</Typography> + <FlairedEdgesDivider /> + <Typography variant="button" className={Type.textCenter}>Content Text Divider</Typography> + <ContentDivider content="OR" /> + </Fragment> + ); + } +} + +export default CommonDivider; diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/BasicMenu.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/BasicMenu.js new file mode 100644 index 0000000..24039db --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/BasicMenu.js @@ -0,0 +1,74 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; + +import { Button, Menu, MenuItem, MenuList, Grid, Paper } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + }, + paper: { + marginRight: theme.spacing(2), + }, + popperClose: { + pointerEvents: 'none', + }, +}); + +class BasicMenu extends React.Component { + state = { + anchorEl: null, + }; + + handleClick = event => { + this.setState({ anchorEl: event.currentTarget }); + }; + + handleClose = () => { + this.setState({ anchorEl: null }); + }; + + render() { + const { anchorEl } = this.state; + const { classes } = this.props; + return ( + <Grid container spacing={2}> + <Grid item md={6}> + <Paper className={classes.paper}> + <MenuList> + <MenuItem>Profile</MenuItem> + <MenuItem>My account</MenuItem> + <MenuItem>Logout</MenuItem> + </MenuList> + </Paper> + </Grid> + <Grid item md={6}> + <Button + aria-owns={anchorEl ? 'simple-menu' : null} + aria-haspopup="true" + onClick={this.handleClick} + > + Open Menu + </Button> + <Menu + id="simple-menu" + anchorEl={anchorEl} + open={Boolean(anchorEl)} + onClose={this.handleClose} + > + <MenuItem onClick={this.handleClose}>Profile</MenuItem> + <MenuItem onClick={this.handleClose}>My account</MenuItem> + <MenuItem onClick={this.handleClose}>Logout</MenuItem> + </Menu> + </Grid> + </Grid> + ); + } +} + +BasicMenu.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(BasicMenu); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/DropdownMenu.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/DropdownMenu.js new file mode 100644 index 0000000..0e5bce7 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/DropdownMenu.js @@ -0,0 +1,148 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import MoreVertIcon from '@material-ui/icons/MoreVert'; + +import { IconButton, List, ListItem, ListItemText, Menu, MenuItem, Grid } from '@material-ui/core'; + +const styles = { + root: { + width: '100%', + }, +}; + +const options = [ + 'Show some love to Material-UI', + 'Show all notification content', + 'Hide sensitive notification content', + 'Hide all notification content', +]; + +const optionsOpt = [ + 'None', + 'Atria', + 'Callisto', + 'Dione', + 'Ganymede', + 'Hangouts Call', + 'Luna', + 'Oberon', + 'Phobos', + 'Pyxis', + 'Sedna', + 'Titania', + 'Triton', + 'Umbriel', +]; + +const ITEM_HEIGHT = 48; + +class DropdownMenu extends React.Component { + state = { + anchorEl: null, + anchorElOpt: null, + selectedIndex: 1, + }; + + button = undefined; + + handleClickListItem = event => { + this.setState({ anchorEl: event.currentTarget }); + }; + + handleMenuItemClick = (event, index) => { + this.setState({ selectedIndex: index, anchorEl: null }); + }; + + handleClose = () => { + this.setState({ anchorEl: null }); + }; + + handleClickOpt = event => { + this.setState({ anchorElOpt: event.currentTarget }); + }; + + handleCloseOpt = () => { + this.setState({ anchorElOpt: null }); + }; + + + render() { + const { classes } = this.props; + const { anchorEl, anchorElOpt } = this.state; + + return ( + <div className={classes.root}> + <Grid container spacing={2}> + <Grid item md={8}> + <List component="nav"> + <ListItem + button + aria-haspopup="true" + aria-controls="lock-menu" + aria-label="When device is locked" + onClick={this.handleClickListItem} + > + <ListItemText + primary="When device is locked" + secondary={options[this.state.selectedIndex]} + /> + </ListItem> + </List> + <Menu + id="lock-menu" + anchorEl={anchorEl} + open={Boolean(anchorEl)} + onClose={this.handleClose} + > + {options.map((option, index) => ( + <MenuItem + key={option} + disabled={index === 0} + selected={index === this.state.selectedIndex} + onClick={event => this.handleMenuItemClick(event, index)} + > + {option} + </MenuItem> + ))} + </Menu> + </Grid> + <Grid item md={4}> + <IconButton + aria-label="More" + aria-owns={anchorEl ? 'long-menu' : null} + aria-haspopup="true" + onClick={this.handleClickOpt} + > + <MoreVertIcon /> + </IconButton> + <Menu + id="long-menu" + anchorEl={anchorElOpt} + open={Boolean(anchorElOpt)} + onClose={this.handleCloseOpt} + PaperProps={{ + style: { + maxHeight: ITEM_HEIGHT * 4.5, + width: 200, + }, + }} + > + {optionsOpt.map(option => ( + <MenuItem key={option} selected={option === 'Pyxis'} onClick={this.handleCloseOpt}> + {option} + </MenuItem> + ))} + </Menu> + </Grid> + </Grid> + </div> + ); + } +} + +DropdownMenu.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(DropdownMenu); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/MenuTransition.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/MenuTransition.js new file mode 100644 index 0000000..e8cfbc6 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/MenuTransition.js @@ -0,0 +1,108 @@ +import React from 'react'; +import Button from '@material-ui/core/Button'; +import Menu from '@material-ui/core/Menu'; +import MenuItem from '@material-ui/core/MenuItem'; +import Grow from '@material-ui/core/Grow'; +import Fade from '@material-ui/core/Fade'; +import Zoom from '@material-ui/core/Zoom'; +import Grid from '@material-ui/core/Grid'; + + +class MenuTransition extends React.Component { + state = { + anchorFade: null, + anchorGrow: null, + anchorCollapse: null, + anchorZoom: null, + }; + + handleClick = (event, type) => { + this.setState({ [type]: event.currentTarget }); + }; + + handleClose = type => { + this.setState({ [type]: null }); + }; + + handleToggle = type => { + // eslint-disable-next-line + this.setState({ [type]: !this.state[type] }); + }; + + render() { + const { + anchorFade, + anchorGrow, + anchorZoom + } = this.state; + + return ( + <Grid container spacing={2}> + <Grid item md={4}> + <Button + aria-owns={anchorFade ? 'fade-menu' : null} + aria-haspopup="true" + onClick={(e) => this.handleClick(e, 'anchorFade')} + > + Open with fade transition + </Button> + <Menu + id="fade-menu" + anchorEl={anchorFade} + open={Boolean(anchorFade)} + onClose={() => this.handleClose('anchorFade')} + TransitionComponent={Fade} + > + <MenuItem onClick={() => this.handleClose('anchorFade')}>Profile</MenuItem> + <MenuItem onClick={() => this.handleClose('anchorFade')}>My account</MenuItem> + <MenuItem onClick={() => this.handleClose('anchorFade')}>Logout</MenuItem> + </Menu> + </Grid> + <Grid item md={4}> + <Button + aria-owns={anchorGrow ? 'grow-menu' : null} + aria-haspopup="true" + onClick={(e) => this.handleClick(e, 'anchorGrow')} + > + Open with grow transition + </Button> + <Menu + id="grow-menu" + anchorEl={anchorGrow} + open={Boolean(anchorGrow)} + onClose={() => this.handleClose('anchorGrow')} + TransitionComponent={Grow} + > + <MenuItem onClick={() => this.handleClose('anchorGrow')}>Profile</MenuItem> + <MenuItem onClick={() => this.handleClose('anchorGrow')}>My account</MenuItem> + <MenuItem onClick={() => this.handleClose('anchorGrow')}>Logout</MenuItem> + </Menu> + </Grid> + <Grid item md={4}> + <div style={{ position: 'relative' }}> + <Button + aria-owns={anchorZoom ? 'zoom-menu' : null} + aria-haspopup="true" + onClick={(e) => this.handleClick(e, 'anchorZoom')} + > + Open with zoom transition + </Button> + <Menu + id="zoom-menu" + anchorEl={anchorZoom} + open={Boolean(anchorZoom)} + onClose={() => this.handleClose('anchorZoom')} + TransitionComponent={Zoom} + > + <MenuItem onClick={() => this.handleClose('anchorZoom')}>Profile</MenuItem> + <MenuItem onClick={() => this.handleClose('anchorZoom')}>My account</MenuItem> + <MenuItem onClick={() => this.handleClose('anchorZoom')}>Logout</MenuItem> + </Menu> + </div> + </Grid> + </Grid> + ); + } +} + +export default MenuTransition; diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/MiniDrawer.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/MiniDrawer.js new file mode 100644 index 0000000..4a07e14 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/MiniDrawer.js @@ -0,0 +1,235 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import classNames from 'classnames'; +import MenuIcon from '@material-ui/icons/Menu'; +import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; +import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import { + Drawer, + AppBar, + Toolbar, + List, + Typography, + MenuItem, + Divider, + TextField, + IconButton, +} from '@material-ui/core'; +import { mailFolderListItems, otherMailFolderListItems } from './menuData'; + + +const drawerWidth = 240; + +const styles = theme => ({ + root: { + flexGrow: 1, + }, + appFrame: { + height: 430, + zIndex: 1, + overflow: 'hidden', + position: 'relative', + display: 'flex', + width: '100%', + }, + appBar: { + zIndex: theme.zIndex.drawer + 1, + padding: '0 24px', + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + }, + appBarShift: { + marginLeft: drawerWidth, + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['width', 'margin'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + 'appBarShift-left': { + marginLeft: drawerWidth, + }, + 'appBarShift-right': { + marginRight: drawerWidth, + }, + menuButton: { + marginLeft: 3, + marginRight: 3, + }, + hide: { + display: 'none', + }, + drawerPaper: { + position: 'relative', + whiteSpace: 'nowrap', + width: drawerWidth, + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.enteringScreen, + }), + }, + drawerPaperClose: { + overflowX: 'hidden', + transition: theme.transitions.create('width', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + width: theme.spacing(7), + [theme.breakpoints.up('sm')]: { + width: theme.spacing(9), + }, + }, + toolbar: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + padding: '0 8px', + ...theme.mixins.toolbar, + }, + content: { + flexGrow: 1, + backgroundColor: theme.palette.background.default, + padding: theme.spacing(3), + }, + 'content-left': { + marginLeft: -drawerWidth, + }, + 'content-right': { + marginRight: -drawerWidth, + }, + contentShift: { + transition: theme.transitions.create('margin', { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + }, + 'contentShift-left': { + marginLeft: 0, + }, + 'contentShift-right': { + marginRight: 0, + }, + title: { + flex: 1, + } +}); + +class MiniDrawer extends React.Component { + state = { + open: false, + anchor: 'left', + }; + + handleDrawerOpen = () => { + this.setState({ open: true }); + }; + + handleDrawerClose = () => { + this.setState({ open: false }); + }; + + handleChangeAnchor = event => { + this.setState({ + anchor: event.target.value, + }); + }; + + render() { + const { classes, theme } = this.props; + const { anchor, open } = this.state; + const drawer = ( + <Drawer + variant="permanent" + classes={{ + paper: classNames(classes.drawerPaper, !open && classes.drawerPaperClose), + }} + open={open} + > + <div className={classes.toolbar}> + <IconButton onClick={this.handleDrawerClose}> + {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />} + </IconButton> + </div> + <Divider /> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </Drawer> + ); + + const menuBtn = ( + <IconButton + color="inherit" + aria-label="open drawer" + onClick={this.handleDrawerOpen} + className={classNames(classes.menuButton, open && classes.hide)} + > + <MenuIcon /> + </IconButton> + ); + + let before = null; + let after = null; + let beforeBtn = null; + let afterBtn = null; + + if (anchor === 'left') { + before = drawer; + beforeBtn = menuBtn; + } else { + after = drawer; + afterBtn = menuBtn; + } + + return ( + <div className={classes.root}> + <TextField + id="persistent-anchor" + select + label="Anchor" + value={anchor} + onChange={this.handleChangeAnchor} + margin="normal" + > + <MenuItem value="left">left</MenuItem> + <MenuItem value="right">right</MenuItem> + </TextField> + <div className={classes.appFrame}> + <AppBar + position="absolute" + className={classNames(classes.appBar, { + [classes.appBarShift]: open, + [classes[`appBarShift-${anchor}`]]: open, + })} + > + <Toolbar disableGutters> + {beforeBtn} + <Typography className={classes.title} variant="h6" color="inherit" noWrap> + Mini variant drawer + </Typography> + {afterBtn} + </Toolbar> + </AppBar> + {before} + <main className={classes.content}> + <div className={classes.toolbar} /> + <Typography noWrap> + {'You think water moves fast? You should see ice.'} + </Typography> + </main> + {after} + </div> + </div> + ); + } +} + +MiniDrawer.propTypes = { + classes: PropTypes.object.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default withStyles(styles, { withTheme: true })(MiniDrawer); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/PermanentDrawer.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/PermanentDrawer.js new file mode 100644 index 0000000..9538873 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/PermanentDrawer.js @@ -0,0 +1,126 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import { Drawer, AppBar, Toolbar, List, MenuItem, TextField, Typography, Divider } from '@material-ui/core'; +import { mailFolderListItems, otherMailFolderListItems } from './menuData'; + + +const drawerWidth = 240; + +const styles = theme => ({ + root: { + flexGrow: 1, + }, + appFrame: { + height: 430, + zIndex: 1, + overflow: 'hidden', + position: 'relative', + display: 'flex', + width: '100%', + }, + appBar: { + width: `calc(100% - ${drawerWidth}px)`, + }, + 'appBar-left': { + marginLeft: drawerWidth, + }, + 'appBar-right': { + marginRight: drawerWidth, + }, + drawerPaper: { + position: 'relative', + width: drawerWidth, + }, + toolbar: theme.mixins.toolbar, + content: { + flexGrow: 1, + backgroundColor: theme.palette.background.default, + padding: theme.spacing(3), + }, +}); + +class PermanentDrawer extends React.Component { + state = { + anchor: 'left', + }; + + handleChange = event => { + this.setState({ + anchor: event.target.value, + }); + }; + + render() { + const { classes } = this.props; + const { anchor } = this.state; + + const drawer = ( + <Drawer + variant="permanent" + classes={{ + paper: classes.drawerPaper, + }} + anchor={anchor} + > + <div className={classes.toolbar} /> + <Divider /> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </Drawer> + ); + + let before = null; + let after = null; + + if (anchor === 'left') { + before = drawer; + } else { + after = drawer; + } + + return ( + <div className={classes.root}> + <TextField + id="permanent-anchor" + select + label="Anchor" + value={anchor} + onChange={this.handleChange} + margin="normal" + > + <MenuItem value="left">left</MenuItem> + <MenuItem value="right">right</MenuItem> + </TextField> + <div className={classes.appFrame}> + <AppBar + position="absolute" + className={classNames(classes.appBar, classes[`appBar-${anchor}`])} + > + <Toolbar> + <Typography variant="h6" color="inherit" noWrap> + Permanent drawer + </Typography> + </Toolbar> + </AppBar> + {before} + <main className={classes.content}> + <div className={classes.toolbar} /> + <Typography> + {'You think water moves fast? You should see ice.'} + </Typography> + </main> + {after} + </div> + </div> + ); + } +} + +PermanentDrawer.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(PermanentDrawer); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/PersistentDrawer.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/PersistentDrawer.js new file mode 100644 index 0000000..cd529d5 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/PersistentDrawer.js @@ -0,0 +1,228 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import classNames from 'classnames'; +import MenuIcon from '@material-ui/icons/Menu'; +import ChevronLeftIcon from '@material-ui/icons/ChevronLeft'; +import ChevronRightIcon from '@material-ui/icons/ChevronRight'; +import { + Drawer, + AppBar, + Toolbar, + List, + MenuItem, + Typography, + TextField, + Divider, + IconButton, +} from '@material-ui/core'; +import { mailFolderListItems, otherMailFolderListItems } from './menuData'; + + +const drawerWidth = 240; + +const styles = theme => ({ + root: { + flexGrow: 1, + }, + appFrame: { + height: 430, + zIndex: 1, + overflow: 'hidden', + position: 'relative', + display: 'flex', + width: '100%', + }, + appBar: { + position: 'absolute', + padding: '0 24px', + transition: theme.transitions.create(['margin', 'width'], { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + }, + appBarShift: { + width: `calc(100% - ${drawerWidth}px)`, + transition: theme.transitions.create(['margin', 'width'], { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + }, + 'appBarShift-left': { + marginLeft: drawerWidth, + }, + 'appBarShift-right': { + marginRight: drawerWidth, + }, + menuButton: { + marginLeft: 3, + marginRight: 3, + }, + hide: { + display: 'none', + }, + drawerPaper: { + position: 'relative', + width: drawerWidth, + }, + drawerHeader: { + display: 'flex', + alignItems: 'center', + justifyContent: 'flex-end', + padding: '0 8px', + ...theme.mixins.toolbar, + }, + content: { + flexGrow: 1, + backgroundColor: theme.palette.background.default, + padding: theme.spacing(3), + transition: theme.transitions.create('margin', { + easing: theme.transitions.easing.sharp, + duration: theme.transitions.duration.leavingScreen, + }), + }, + 'content-left': { + marginLeft: -drawerWidth, + }, + 'content-right': { + marginRight: -drawerWidth, + }, + contentShift: { + transition: theme.transitions.create('margin', { + easing: theme.transitions.easing.easeOut, + duration: theme.transitions.duration.enteringScreen, + }), + }, + 'contentShift-left': { + marginLeft: 0, + }, + 'contentShift-right': { + marginRight: 0, + }, + title: { + flex: 1, + } +}); + +class PersistentDrawer extends React.Component { + state = { + open: false, + anchor: 'left', + }; + + handleDrawerOpen = () => { + this.setState({ open: true }); + }; + + handleDrawerClose = () => { + this.setState({ open: false }); + }; + + handleChangeAnchor = event => { + this.setState({ + anchor: event.target.value, + }); + }; + + render() { + const { classes, theme } = this.props; + const { anchor, open } = this.state; + + const drawer = ( + <Drawer + variant="persistent" + anchor={anchor} + open={open} + classes={{ + paper: classes.drawerPaper, + }} + > + <div className={classes.drawerHeader}> + <IconButton onClick={this.handleDrawerClose}> + {theme.direction === 'rtl' ? <ChevronRightIcon /> : <ChevronLeftIcon />} + </IconButton> + </div> + <Divider /> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </Drawer> + ); + + const menuBtn = ( + <IconButton + color="inherit" + aria-label="open drawer" + onClick={this.handleDrawerOpen} + className={classNames(classes.menuButton, open && classes.hide)} + > + <MenuIcon /> + </IconButton> + ); + + let before = null; + let after = null; + let beforeBtn = null; + let afterBtn = null; + + if (anchor === 'left') { + before = drawer; + beforeBtn = menuBtn; + } else { + after = drawer; + afterBtn = menuBtn; + } + + return ( + <div className={classes.root}> + <TextField + id="persistent-anchor" + select + label="Anchor" + value={anchor} + onChange={this.handleChangeAnchor} + margin="normal" + > + <MenuItem value="left">left</MenuItem> + <MenuItem value="right">right</MenuItem> + </TextField> + <div className={classes.appFrame}> + <AppBar + className={classNames(classes.appBar, { + [classes.appBarShift]: open, + [classes[`appBarShift-${anchor}`]]: open, + })} + > + <Toolbar disableGutters> + {beforeBtn} + <Typography className={classes.title} variant="h6" color="inherit" noWrap> + Persistent drawer + </Typography> + {afterBtn} + </Toolbar> + </AppBar> + {before} + <main + className={classNames(classes.content, classes[`content-${anchor}`], { + [classes.contentShift]: open, + [classes[`contentShift-${anchor}`]]: open, + })} + > + <div className={classes.drawerHeader} /> + <Typography> + {'You think water moves fast? You should see ice.'} + </Typography> + </main> + {after} + </div> + </div> + ); + } +} + +PersistentDrawer.propTypes = { + classes: PropTypes.object.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default withStyles(styles, { withTheme: true })(PersistentDrawer); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/StyledMenu.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/StyledMenu.js new file mode 100644 index 0000000..ed6ac4a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/StyledMenu.js @@ -0,0 +1,60 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import InboxIcon from '@material-ui/icons/MoveToInbox'; +import DraftsIcon from '@material-ui/icons/Drafts'; +import SendIcon from '@material-ui/icons/Send'; + +import { MenuList, MenuItem, Paper, ListItemIcon, ListItemText } from '@material-ui/core'; + +const styles = theme => ({ + menu: { + maxWidth: 400, + margin: '20 auto' + }, + menuItem: { + '&:focus': { + backgroundColor: theme.palette.primary.main, + '& $primary, & $icon': { + color: theme.palette.common.white, + }, + }, + }, + primary: {}, + icon: {}, +}); + +function StyledMenu(props) { + const { classes } = props; + + return ( + <Paper className={classes.menu}> + <MenuList> + <MenuItem className={classes.menuItem}> + <ListItemIcon className={classes.icon}> + <SendIcon /> + </ListItemIcon> + <ListItemText classes={{ primary: classes.primary }} variant="inset" primary="Sent mail" /> + </MenuItem> + <MenuItem className={classes.menuItem}> + <ListItemIcon className={classes.icon}> + <DraftsIcon /> + </ListItemIcon> + <ListItemText classes={{ primary: classes.primary }} variant="inset" primary="Drafts" /> + </MenuItem> + <MenuItem className={classes.menuItem}> + <ListItemIcon className={classes.icon}> + <InboxIcon /> + </ListItemIcon> + <ListItemText classes={{ primary: classes.primary }} variant="inset" primary="Inbox" /> + </MenuItem> + </MenuList> + </Paper> + ); +} + +StyledMenu.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(StyledMenu); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/SwipeDrawer.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/SwipeDrawer.js new file mode 100644 index 0000000..a91feb5 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/SwipeDrawer.js @@ -0,0 +1,124 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { SwipeableDrawer, Button, List, Divider, Grid } from '@material-ui/core'; +import { mailFolderListItems, otherMailFolderListItems } from './menuData'; + + +const styles = { + list: { + width: 250, + }, + fullList: { + width: 'auto', + }, +}; + +class SwipeDrawer extends React.Component { + state = { + top: false, + left: false, + bottom: false, + right: false, + }; + + toggleDrawer = (side, open) => () => { + this.setState({ + [side]: open, + }); + }; + + render() { + const { classes } = this.props; + + const sideList = ( + <div className={classes.list}> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </div> + ); + + const fullList = ( + <div className={classes.fullList}> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </div> + ); + + return ( + <Grid container justify="center" direction="row"> + <Button onClick={this.toggleDrawer('left', true)}>Open Left</Button> + <Button onClick={this.toggleDrawer('right', true)}>Open Right</Button> + <Button onClick={this.toggleDrawer('top', true)}>Open Top</Button> + <Button onClick={this.toggleDrawer('bottom', true)}>Open Bottom</Button> + <SwipeableDrawer + open={this.state.left} + onClose={this.toggleDrawer('left', false)} + onOpen={this.toggleDrawer('left', true)} + > + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('left', false)} + onKeyDown={this.toggleDrawer('left', false)} + > + {sideList} + </div> + </SwipeableDrawer> + <SwipeableDrawer + anchor="top" + open={this.state.top} + onClose={this.toggleDrawer('top', false)} + onOpen={this.toggleDrawer('top', true)} + > + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('top', false)} + onKeyDown={this.toggleDrawer('top', false)} + > + {fullList} + </div> + </SwipeableDrawer> + <SwipeableDrawer + anchor="bottom" + open={this.state.bottom} + onClose={this.toggleDrawer('bottom', false)} + onOpen={this.toggleDrawer('bottom', true)} + > + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('bottom', false)} + onKeyDown={this.toggleDrawer('bottom', false)} + > + {fullList} + </div> + </SwipeableDrawer> + <SwipeableDrawer + anchor="right" + open={this.state.right} + onClose={this.toggleDrawer('right', false)} + onOpen={this.toggleDrawer('right', true)} + > + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('right', false)} + onKeyDown={this.toggleDrawer('right', false)} + > + {sideList} + </div> + </SwipeableDrawer> + </Grid> + ); + } +} + +SwipeDrawer.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SwipeDrawer); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/TemporaryDrawer.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/TemporaryDrawer.js new file mode 100644 index 0000000..6af2a24 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/TemporaryDrawer.js @@ -0,0 +1,109 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Drawer, Button, List, Divider, Grid } from '@material-ui/core'; +import { mailFolderListItems, otherMailFolderListItems } from './menuData'; + + +const styles = { + list: { + width: 250, + }, + fullList: { + width: 'auto', + }, +}; + +class TemporaryDrawer extends React.Component { + state = { + top: false, + left: false, + bottom: false, + right: false, + }; + + toggleDrawer = (side, open) => () => { + this.setState({ + [side]: open, + }); + }; + + render() { + const { classes } = this.props; + + const sideList = ( + <div className={classes.list}> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </div> + ); + + const fullList = ( + <div className={classes.fullList}> + <List>{mailFolderListItems}</List> + <Divider /> + <List>{otherMailFolderListItems}</List> + </div> + ); + + return ( + <Grid container justify="center" direction="row"> + <Button onClick={this.toggleDrawer('left', true)}>Open Left</Button> + <Button onClick={this.toggleDrawer('right', true)}>Open Right</Button> + <Button onClick={this.toggleDrawer('top', true)}>Open Top</Button> + <Button onClick={this.toggleDrawer('bottom', true)}>Open Bottom</Button> + <Drawer open={this.state.left} onClose={this.toggleDrawer('left', false)}> + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('left', false)} + onKeyDown={this.toggleDrawer('left', false)} + > + {sideList} + </div> + </Drawer> + <Drawer anchor="top" open={this.state.top} onClose={this.toggleDrawer('top', false)}> + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('top', false)} + onKeyDown={this.toggleDrawer('top', false)} + > + {fullList} + </div> + </Drawer> + <Drawer + anchor="bottom" + open={this.state.bottom} + onClose={this.toggleDrawer('bottom', false)} + > + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('bottom', false)} + onKeyDown={this.toggleDrawer('bottom', false)} + > + {fullList} + </div> + </Drawer> + <Drawer anchor="right" open={this.state.right} onClose={this.toggleDrawer('right', false)}> + <div + tabIndex={0} + role="button" + onClick={this.toggleDrawer('right', false)} + onKeyDown={this.toggleDrawer('right', false)} + > + {sideList} + </div> + </Drawer> + </Grid> + ); + } +} + +TemporaryDrawer.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(TemporaryDrawer); diff --git a/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/menuData.js b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/menuData.js new file mode 100644 index 0000000..cd2d653 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/DrawerMenu/menuData.js @@ -0,0 +1,64 @@ +// This file is shared across the demos. + +import React from 'react'; +import InboxIcon from '@material-ui/icons/MoveToInbox'; +import DraftsIcon from '@material-ui/icons/Drafts'; +import StarIcon from '@material-ui/icons/Star'; +import SendIcon from '@material-ui/icons/Send'; +import MailIcon from '@material-ui/icons/Mail'; +import DeleteIcon from '@material-ui/icons/Delete'; +import ReportIcon from '@material-ui/icons/Report'; + +import { ListItem, ListItemIcon, ListItemText } from '@material-ui/core'; + +export const mailFolderListItems = ( + <div> + <ListItem button> + <ListItemIcon> + <InboxIcon /> + </ListItemIcon> + <ListItemText primary="Inbox" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <StarIcon /> + </ListItemIcon> + <ListItemText primary="Starred" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <SendIcon /> + </ListItemIcon> + <ListItemText primary="Send mail" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <DraftsIcon /> + </ListItemIcon> + <ListItemText primary="Drafts" /> + </ListItem> + </div> +); + +export const otherMailFolderListItems = ( + <div> + <ListItem button> + <ListItemIcon> + <MailIcon /> + </ListItemIcon> + <ListItemText primary="All mail" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <DeleteIcon /> + </ListItemIcon> + <ListItemText primary="Trash" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <ReportIcon /> + </ListItemIcon> + <ListItemText primary="Spam" /> + </ListItem> + </div> +); diff --git a/front/odiparpack/app/containers/UiElements/demos/ImageGrid/AdvancedGridList.js b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/AdvancedGridList.js new file mode 100644 index 0000000..5d11f0d --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/AdvancedGridList.js @@ -0,0 +1,85 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import StarBorderIcon from '@material-ui/icons/StarBorder'; +import imgData from 'ba-api/imgData'; + +import { GridList, GridListTile, GridListTileBar, IconButton } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-around', + overflow: 'hidden', + backgroundColor: theme.palette.background.paper, + }, + gridList: { + width: 500, + height: 450, + // Promote the list into his own layer on Chrome. This cost memory but helps keeping high FPS. + transform: 'translateZ(0)', + }, + titleBar: { + background: + 'linear-gradient(to bottom, rgba(0,0,0,0.7) 0%, ' + + 'rgba(0,0,0,0.3) 70%, rgba(0,0,0,0) 100%)', + }, + icon: { + color: 'white', + }, + img: { + maxWidth: 'none' + } +}); + +/** + * The example data is structured as follows: + * + * import image from 'path/to/image.jpg'; + * [etc...] + * + * const tileData = [ + * { + * img: image, + * title: 'Image', + * author: 'author', + * featured: true, + * }, + * { + * [etc...] + * }, + * ]; + */ +function AdvancedGridList(props) { + const { classes } = props; + + return ( + <div className={classes.root}> + <GridList cellHeight={200} spacing={1} className={classes.gridList}> + {imgData.map((tile, index) => ( + <GridListTile key={index.toString()} cols={tile.featured ? 2 : 1} rows={tile.featured ? 2 : 1}> + <img src={tile.img} className={classes.img} alt={tile.title} /> + <GridListTileBar + title={tile.title} + titlePosition="top" + actionIcon={( + <IconButton className={classes.icon}> + <StarBorderIcon /> + </IconButton> + )} + actionPosition="left" + className={classes.titleBar} + /> + </GridListTile> + ))} + </GridList> + </div> + ); +} + +AdvancedGridList.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AdvancedGridList); diff --git a/front/odiparpack/app/containers/UiElements/demos/ImageGrid/ImageGridList.js b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/ImageGridList.js new file mode 100644 index 0000000..ce785ac --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/ImageGridList.js @@ -0,0 +1,66 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgData from 'ba-api/imgData'; + +import { GridList, GridListTile } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-around', + overflow: 'hidden', + backgroundColor: theme.palette.background.paper, + }, + gridList: { + width: 500, + height: 450, + }, + subheader: { + width: '100%', + }, + img: { + maxWidth: 'none' + } +}); + +/** + * The example data is structured as follows: + * + * import image from 'path/to/image.jpg'; + * [etc...] + * + * const tileData = [ + * { + * img: image, + * title: 'Image', + * author: 'author', + * cols: 2, + * }, + * { + * [etc...] + * }, + * ]; + */ +function ImageGridList(props) { + const { classes } = props; + + return ( + <div className={classes.root}> + <GridList cellHeight={160} className={classes.gridList} cols={3}> + {imgData.map((tile, index) => ( + <GridListTile key={index.toString()} cols={tile.cols || 1}> + <img src={tile.img} className={classes.img} alt={tile.title} /> + </GridListTile> + ))} + </GridList> + </div> + ); +} + +ImageGridList.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ImageGridList); diff --git a/front/odiparpack/app/containers/UiElements/demos/ImageGrid/SingleLineGridList.js b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/SingleLineGridList.js new file mode 100644 index 0000000..ac30e6f --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/SingleLineGridList.js @@ -0,0 +1,83 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import StarBorderIcon from '@material-ui/icons/StarBorder'; +import imgData from 'ba-api/imgData'; + +import { GridList, GridListTile, GridListTileBar, IconButton } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-around', + overflow: 'hidden', + backgroundColor: theme.palette.background.paper, + }, + gridList: { + flexWrap: 'nowrap', + // Promote the list into his own layer on Chrome. This cost memory but helps keeping high FPS. + transform: 'translateZ(0)', + }, + title: { + color: theme.palette.primary.light, + }, + titleBar: { + background: + 'linear-gradient(to top, rgba(0,0,0,0.7) 0%, rgba(0,0,0,0.3) 70%, rgba(0,0,0,0) 100%)', + }, + img: { + maxWidth: 'none' + } +}); + +/** + * The example data is structured as follows: + * + * import image from 'path/to/image.jpg'; + * [etc...] + * + * const tileData = [ + * { + * img: image, + * title: 'Image', + * author: 'author', + * }, + * { + * [etc...] + * }, + * ]; + */ +function SingleLineGridList(props) { + const { classes } = props; + + return ( + <div className={classes.root}> + <GridList className={classes.gridList} cols={2.5}> + {imgData.map((tile, index) => ( + <GridListTile key={index.toString()}> + <img src={tile.img} alt={tile.title} className={classes.img} /> + <GridListTileBar + title={tile.title} + classes={{ + root: classes.titleBar, + title: classes.title, + }} + actionIcon={( + <IconButton> + <StarBorderIcon className={classes.title} /> + </IconButton> + )} + /> + </GridListTile> + ))} + </GridList> + </div> + ); +} + +SingleLineGridList.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SingleLineGridList); diff --git a/front/odiparpack/app/containers/UiElements/demos/ImageGrid/TitlebarGridList.js b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/TitlebarGridList.js new file mode 100644 index 0000000..41f8d1a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/ImageGrid/TitlebarGridList.js @@ -0,0 +1,89 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import InfoIcon from '@material-ui/icons/Info'; +import imgData from 'ba-api/imgData'; + +import { + GridList, + GridListTile, + GridListTileBar, + ListSubheader as Subheader, + IconButton, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + flexWrap: 'wrap', + justifyContent: 'space-around', + overflow: 'hidden', + backgroundColor: theme.palette.background.paper, + }, + gridList: { + width: 500, + height: 450, + }, + icon: { + color: 'rgba(255, 255, 255, 0.54)', + }, + img: { + maxWidth: 'none' + } +}); + +/** + * The example data is structured as follows: + * + * import image from 'path/to/image.jpg'; + * [etc...] + * + * const tileData = [ + * { + * img: image, + * title: 'Image', + * author: 'author', + * }, + * { + * [etc...] + * }, + * ]; + */ +function TitlebarGridList(props) { + const { classes } = props; + + return ( + <div className={classes.root}> + <GridList cellHeight={180} className={classes.gridList}> + <GridListTile key="Subheader" cols={2} style={{ height: 'auto' }}> + <Subheader component="div">December</Subheader> + </GridListTile> + {imgData.map((tile, index) => ( + <GridListTile key={index.toString()}> + <img src={tile.img} className={classes.img} alt={tile.title} /> + <GridListTileBar + title={tile.title} + subtitle={( + <span> +by: + {tile.author} + </span> + )} + actionIcon={( + <IconButton className={classes.icon}> + <InfoIcon /> + </IconButton> + )} + /> + </GridListTile> + ))} + </GridList> + </div> + ); +} + +TitlebarGridList.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(TitlebarGridList); diff --git a/front/odiparpack/app/containers/UiElements/demos/List/ListBasic.js b/front/odiparpack/app/containers/UiElements/demos/List/ListBasic.js new file mode 100644 index 0000000..ba4f13a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/List/ListBasic.js @@ -0,0 +1,116 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +// import classNames from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import ImageIcon from '@material-ui/icons/Image'; +import WorkIcon from '@material-ui/icons/Work'; +import BeachAccessIcon from '@material-ui/icons/BeachAccess'; + +import { red, green, amber } from '@material-ui/core/colors'; + +import { + Typography, Grid, List, + ListItem, ListItemText, ListItemAvatar, + Avatar, Divider +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + maxWidth: '360px', + backgroundColor: theme.palette.background.paper, + margin: 10 + }, + avatarRed: { + backgroundColor: red[500], + }, + avatarGreen: { + backgroundColor: green[500], + }, + avatarAmber: { + backgroundColor: amber[500], + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +class ListBasic extends PureComponent { + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Simple List Divider</Typography> + <div className={classes.root}> + <List component="nav"> + <ListItem button> + <ListItemText primary="Inbox" /> + </ListItem> + <Divider /> + <ListItem button divider> + <ListItemText primary="Drafts" /> + </ListItem> + <ListItem button> + <ListItemText primary="Trash" /> + </ListItem> + <Divider light /> + <ListItem button> + <ListItemText primary="Spam" /> + </ListItem> + </List> + </div> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Inset Divider</Typography> + <div className={classes.root}> + <List> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarRed}> + <ImageIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Photos" secondary="Jan 9, 2014" /> + </ListItem> + <li> + <Divider variant="inset" /> + </li> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarGreen}> + <WorkIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Work" secondary="Jan 7, 2014" /> + </ListItem> + <Divider variant="inset" component="li" /> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarAmber}> + <BeachAccessIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Vacation" secondary="July 20, 2014" /> + </ListItem> + </List> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +ListBasic.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ListBasic); diff --git a/front/odiparpack/app/containers/UiElements/demos/List/ListControl.js b/front/odiparpack/app/containers/UiElements/demos/List/ListControl.js new file mode 100644 index 0000000..2743d4b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/List/ListControl.js @@ -0,0 +1,159 @@ +import React, { Fragment } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import CommentIcon from '@material-ui/icons/Comment'; +import WifiIcon from '@material-ui/icons/Wifi'; +import BluetoothIcon from '@material-ui/icons/Bluetooth'; + +import { + List, + ListItem, + ListItemIcon, + ListItemSecondaryAction, + ListItemText, + ListSubheader, + ListItemAvatar, + Checkbox, + Switch, + IconButton, + Grid, + Typography, + Avatar, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + maxWidth: 360, + backgroundColor: theme.palette.background.paper, + margin: 10 + }, +}); + +class ListControl extends React.Component { + state = { + checked: [0], + checked2: [1], + checked3: ['wifi'], + }; + + handleToggle = value => () => { + const { checked } = this.state; + const currentIndex = checked.indexOf(value); + const newChecked = [...checked]; + + if (currentIndex === -1) { + newChecked.push(value); + } else { + newChecked.splice(currentIndex, 1); + } + + this.setState({ + checked: newChecked, + checked2: newChecked, + checked3: newChecked, + }); + }; + + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={4} xs={12}> + <Typography variant="button" className={classes.divider}>Checkbox</Typography> + <div className={classes.root}> + <List> + {[0, 1, 2, 3].map(value => ( + <ListItem + key={value} + role={undefined} + dense + button + onClick={this.handleToggle(value)} + className={classes.listItem} + > + <Checkbox + checked={this.state.checked.indexOf(value) !== -1} + tabIndex={-1} + disableRipple + /> + <ListItemText primary={`Line item ${value + 1}`} /> + <ListItemSecondaryAction> + <IconButton aria-label="Comments"> + <CommentIcon /> + </IconButton> + </ListItemSecondaryAction> + </ListItem> + ))} + </List> + </div> + </Grid> + <Grid item md={4} xs={12}> + <Typography variant="button" className={classes.divider}>Checkbox</Typography> + <div className={classes.root}> + <List> + {[0, 1, 2, 3].map(value => ( + <ListItem key={value} dense button className={classes.listItem}> + <ListItemAvatar> + <Avatar alt="Remy Sharp" src="/images/pp_boy.svg" /> + </ListItemAvatar> + <ListItemText primary={`Line item ${value + 1}`} /> + <ListItemSecondaryAction> + <Checkbox + onChange={this.handleToggle(value)} + checked={this.state.checked2.indexOf(value) !== -1} + /> + </ListItemSecondaryAction> + </ListItem> + ))} + </List> + </div> + </Grid> + <Grid item md={4} xs={12}> + <Typography variant="button" className={classes.divider}>Switch</Typography> + <div className={classes.root}> + <List subheader={<ListSubheader>Settings</ListSubheader>}> + <ListItem> + <ListItemIcon> + <WifiIcon /> + </ListItemIcon> + <ListItemText primary="Wi-Fi" /> + <ListItemSecondaryAction> + <Switch + onChange={this.handleToggle('wifi')} + checked={this.state.checked3.indexOf('wifi') !== -1} + /> + </ListItemSecondaryAction> + </ListItem> + <ListItem> + <ListItemIcon> + <BluetoothIcon /> + </ListItemIcon> + <ListItemText primary="Bluetooth" /> + <ListItemSecondaryAction> + <Switch + onChange={this.handleToggle('bluetooth')} + checked={this.state.checked3.indexOf('bluetooth') !== -1} + /> + </ListItemSecondaryAction> + </ListItem> + </List> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +ListControl.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ListControl); diff --git a/front/odiparpack/app/containers/UiElements/demos/List/ListInteractive.js b/front/odiparpack/app/containers/UiElements/demos/List/ListInteractive.js new file mode 100644 index 0000000..f8d3fa8 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/List/ListInteractive.js @@ -0,0 +1,183 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import FolderIcon from '@material-ui/icons/Folder'; +import DeleteIcon from '@material-ui/icons/Delete'; +import { cyan } from '@material-ui/core/colors'; + +import { + List, + ListItem, + ListItemAvatar, + ListItemIcon, + ListItemSecondaryAction, + ListItemText, + Avatar, + IconButton, + FormGroup, + FormControlLabel, + Checkbox, + Grid, + Typography, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + flexGrow: 1, + maxWidth: 752, + }, + demo: { + backgroundColor: theme.palette.background.paper, + }, + title: { + margin: `${theme.spacing(4)}px 0 ${theme.spacing(2)}px`, + }, + iconCyan: { + color: cyan[300] + }, + avatarCyan: { + background: cyan[300] + } +}); + +function generate(element) { + return [0, 1, 2].map(value => React.cloneElement(element, { + key: value, + }), + ); +} + +class ListInteractive extends React.Component { + state = { + dense: false, + secondary: false, + }; + + render() { + const { classes } = this.props; + const { dense, secondary } = this.state; + + return ( + <div className={classes.root}> + <FormGroup row> + <FormControlLabel + control={( + <Checkbox + checked={dense} + onChange={(event, checked) => this.setState({ dense: checked })} + value="dense" + /> + )} + label="Enable dense" + /> + <FormControlLabel + control={( + <Checkbox + checked={secondary} + onChange={(event, checked) => this.setState({ secondary: checked })} + value="secondary" + /> + )} + label="Enable secondary text" + /> + </FormGroup> + <Grid container spacing={2}> + <Grid item xs={12} md={6}> + <Typography variant="button" className={classes.title}> + Text only + </Typography> + <div className={classes.demo}> + <List dense={dense}> + {generate( + <ListItem> + <ListItemText + primary="Single-line item" + secondary={secondary ? 'Secondary text' : null} + /> + </ListItem>, + )} + </List> + </div> + </Grid> + <Grid item xs={12} md={6}> + <Typography variant="button" className={classes.title}> + Icon with text + </Typography> + <div className={classes.demo}> + <List dense={dense}> + {generate( + <ListItem> + <ListItemIcon> + <FolderIcon className={classes.iconCyan} /> + </ListItemIcon> + <ListItemText + primary="Single-line item" + secondary={secondary ? 'Secondary text' : null} + /> + </ListItem>, + )} + </List> + </div> + </Grid> + </Grid> + <Grid container spacing={2}> + <Grid item xs={12} md={6}> + <Typography variant="button" className={classes.title}> + Avatar with text + </Typography> + <div className={classes.demo}> + <List dense={dense}> + {generate( + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarCyan}> + <FolderIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText + primary="Single-line item" + secondary={secondary ? 'Secondary text' : null} + /> + </ListItem>, + )} + </List> + </div> + </Grid> + <Grid item xs={12} md={6}> + <Typography variant="button" className={classes.title}> + Avatar with text and icon + </Typography> + <div className={classes.demo}> + <List dense={dense}> + {generate( + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarCyan}> + <FolderIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText + primary="Single-line item" + secondary={secondary ? 'Secondary text' : null} + /> + <ListItemSecondaryAction> + <IconButton aria-label="Delete"> + <DeleteIcon /> + </IconButton> + </ListItemSecondaryAction> + </ListItem>, + )} + </List> + </div> + </Grid> + </Grid> + </div> + ); + } +} + +ListInteractive.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ListInteractive); diff --git a/front/odiparpack/app/containers/UiElements/demos/List/ListMenu.js b/front/odiparpack/app/containers/UiElements/demos/List/ListMenu.js new file mode 100644 index 0000000..f796f76 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/List/ListMenu.js @@ -0,0 +1,204 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import StarIcon from '@material-ui/icons/Star'; +import ImageIcon from '@material-ui/icons/Image'; +import WorkIcon from '@material-ui/icons/Work'; +import BeachAccessIcon from '@material-ui/icons/BeachAccess'; +import InboxIcon from '@material-ui/icons/Inbox'; +import DraftsIcon from '@material-ui/icons/Drafts'; +import SendIcon from '@material-ui/icons/Send'; +import ExpandLess from '@material-ui/icons/ExpandLess'; +import ExpandMore from '@material-ui/icons/ExpandMore'; +import StarBorder from '@material-ui/icons/StarBorder'; +import { red, green, amber, lightBlue, pink, teal } from '@material-ui/core/colors'; + +import { + Typography, + Grid, + List, + ListItem, + ListItemIcon, + ListItemText, + ListSubheader, + ListItemAvatar, + Divider, + Avatar, + Collapse, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + maxWidth: '360px', + backgroundColor: theme.palette.background.paper, + margin: 10 + }, + nested: { + paddingLeft: theme.spacing(4), + }, + avatarRed: { + backgroundColor: red[500], + }, + avatarGreen: { + backgroundColor: green[500], + }, + avatarAmber: { + backgroundColor: amber[500], + }, + iconBlue: { + color: lightBlue[500] + }, + iconPink: { + color: pink[500] + }, + iconAmber: { + color: amber[500] + }, + iconTeal: { + color: teal[500] + }, +}); + +class ListMenu extends PureComponent { + state = { open: true }; + + handleClick = () => { + this.setState({ open: !this.state.open }); + }; + + render() { + const { classes } = this.props; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Menu List</Typography> + <div className={classes.root}> + <List component="nav"> + <ListItem button> + <ListItemIcon> + <InboxIcon className={classes.iconPink} /> + </ListItemIcon> + <ListItemText primary="Inbox" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <DraftsIcon className={classes.iconBlue} /> + </ListItemIcon> + <ListItemText primary="Drafts" /> + </ListItem> + </List> + <Divider /> + <List component="nav"> + <ListItem button> + <ListItemText primary="Trash" /> + </ListItem> + <ListItem button component="a" href="#simple-list"> + <ListItemText primary="Spam" /> + </ListItem> + </List> + </div> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Folder List</Typography> + <div className={classes.root}> + <List> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarRed}> + <ImageIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Photos" secondary="Jan 9, 2014" /> + </ListItem> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarGreen}> + <WorkIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Work" secondary="Jan 7, 2014" /> + </ListItem> + <ListItem> + <ListItemAvatar> + <Avatar className={classes.avatarAmber}> + <BeachAccessIcon /> + </Avatar> + </ListItemAvatar> + <ListItemText primary="Vacation" secondary="July 20, 2014" /> + </ListItem> + </List> + </div> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Inset List</Typography> + <div className={classes.root}> + <List component="nav"> + <ListItem button> + <ListItemIcon> + <StarIcon className={classes.iconAmber} /> + </ListItemIcon> + <ListItemText variant="inset" primary="Chelsea Otakan" /> + </ListItem> + <ListItem button> + <ListItemText variant="inset" primary="Eric Hoffman" /> + </ListItem> + </List> + </div> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Nested List</Typography> + <div className={classes.root}> + <List + component="nav" + subheader={<ListSubheader component="div">Nested List Items</ListSubheader>} + > + <ListItem button> + <ListItemIcon> + <SendIcon className={classes.iconTeal} /> + </ListItemIcon> + <ListItemText variant="inset" primary="Sent mail" /> + </ListItem> + <ListItem button> + <ListItemIcon> + <DraftsIcon className={classes.iconBlue} /> + </ListItemIcon> + <ListItemText variant="inset" primary="Drafts" /> + </ListItem> + <ListItem button onClick={this.handleClick}> + <ListItemIcon> + <InboxIcon className={classes.iconPink} /> + </ListItemIcon> + <ListItemText variant="inset" primary="Inbox" /> + {this.state.open ? <ExpandLess /> : <ExpandMore />} + </ListItem> + <Collapse in={this.state.open} timeout="auto" unmountOnExit> + <List component="div" disablePadding> + <ListItem button className={classes.nested}> + <ListItemIcon> + <StarBorder className={classes.iconAmber} /> + </ListItemIcon> + <ListItemText variant="inset" primary="Starred" /> + </ListItem> + </List> + </Collapse> + </List> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +ListMenu.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ListMenu); diff --git a/front/odiparpack/app/containers/UiElements/demos/List/PinnedList.js b/front/odiparpack/app/containers/UiElements/demos/List/PinnedList.js new file mode 100644 index 0000000..e770fd0 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/List/PinnedList.js @@ -0,0 +1,62 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Grid, ListSubheader, List, ListItem, ListItemText } from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + maxWidth: 360, + backgroundColor: theme.palette.background.paper, + position: 'relative', + overflow: 'auto', + maxHeight: 300, + }, + listSection: { + backgroundColor: 'inherit', + }, + ul: { + backgroundColor: 'inherit', + padding: 0, + }, + head: { + backgroundColor: theme.palette.secondary.light, + lineHeight: '30px', + height: 30, + textTransform: 'uppercase' + } +}); + +function PinnedList(props) { + const { classes } = props; + + return ( + <Grid + container + alignItems="center" + justify="center" + direction="row" + > + <List className={classes.root} subheader={<li />}> + {[0, 1, 2, 3, 4].map(sectionId => ( + <li key={`section-${sectionId}`} className={classes.listSection}> + <ul className={classes.ul}> + <ListSubheader className={classes.head}>{`I'm sticky ${sectionId}`}</ListSubheader> + {[0, 1, 2].map(item => ( + <ListItem key={`item-${sectionId}-${item}`}> + <ListItemText primary={`Item ${item}`} /> + </ListItem> + ))} + </ul> + </li> + ))} + </List> + </Grid> + ); +} + +PinnedList.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(PinnedList); diff --git a/front/odiparpack/app/containers/UiElements/demos/Notification/MobileNotif.js b/front/odiparpack/app/containers/UiElements/demos/Notification/MobileNotif.js new file mode 100644 index 0000000..60cdbbd --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Notification/MobileNotif.js @@ -0,0 +1,116 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import MenuIcon from '@material-ui/icons/Menu'; +import AddIcon from '@material-ui/icons/Add'; +import { AppBar, Toolbar, IconButton, Typography, Button, Fab, Snackbar } from '@material-ui/core'; + +const styles = theme => ({ + root: { + position: 'relative', + overflow: 'hidden', + }, + appFrame: { + width: '100%', + height: 360, + backgroundColor: theme.palette.background.paper, + }, + menuButton: { + marginLeft: -12, + marginRight: 20, + }, + button: { + marginBottom: theme.spacing(1), + }, + fab: { + position: 'absolute', + bottom: theme.spacing(2), + right: theme.spacing(2), + }, + fabMoveUp: { + transform: 'translate3d(0, -46px, 0)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.enteringScreen, + easing: theme.transitions.easing.easeOut, + }), + }, + fabMoveDown: { + transform: 'translate3d(0, 0, 0)', + transition: theme.transitions.create('transform', { + duration: theme.transitions.duration.leavingScreen, + easing: theme.transitions.easing.sharp, + }), + }, + snackbar: { + position: 'absolute', + }, + snackbarContent: { + width: '100%', + }, +}); + +class MobileNotif extends React.Component { + state = { + open: false, + }; + + handleClick = () => { + this.setState({ open: true }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + render() { + const { classes } = this.props; + const { open } = this.state; + const fabClassName = classNames(classes.fab, open ? classes.fabMoveUp : classes.fabMoveDown); + + return ( + <div className={classes.root}> + <Button className={classes.button} variant="outlined" color="primary" onClick={this.handleClick}> + Open snackbar + </Button> + <div className={classes.appFrame}> + <AppBar position="static" color="primary"> + <Toolbar> + <IconButton className={classes.menuButton} color="inherit" aria-label="Menu"> + <MenuIcon /> + </IconButton> + <Typography variant="h6" color="inherit"> + Out of my way! + </Typography> + </Toolbar> + </AppBar> + <Fab color="secondary" className={fabClassName}> + <AddIcon /> + </Fab> + <Snackbar + open={open} + autoHideDuration={4000} + onClose={this.handleClose} + ContentProps={{ + 'aria-describedby': 'snackbar-fab-message-id', + className: classes.snackbarContent, + }} + message={<span id="snackbar-fab-message-id">Archived</span>} + action={( + <Button color="inherit" size="small" onClick={this.handleClose}> + Undo + </Button> + )} + className={classes.snackbar} + /> + </div> + </div> + ); + } +} + +MobileNotif.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(MobileNotif); diff --git a/front/odiparpack/app/containers/UiElements/demos/Notification/SimpleNotif.js b/front/odiparpack/app/containers/UiElements/demos/Notification/SimpleNotif.js new file mode 100644 index 0000000..0b068b5 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Notification/SimpleNotif.js @@ -0,0 +1,132 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import CloseIcon from '@material-ui/icons/Close'; +import { Typography, Button, Snackbar, IconButton, Grid } from '@material-ui/core'; + +const styles = theme => ({ + close: { + width: theme.spacing(4) + }, + divider: { + margin: `${theme.spacing(3)}px 0`, + }, + button: { + margin: theme.spacing(1) + } +}); + +class SimpleNotif extends React.Component { + state = { + open: false, + open2: false, + vertical: 'bottom', + horizontal: 'left', + }; + + handleClick = () => { + this.setState({ open: true }); + }; + + handleClose = (event, reason) => { + if (reason === 'clickaway') { + return; + } + + this.setState({ open: false }); + }; + + handleClick2 = state => () => { + this.setState({ open2: true, ...state }); + }; + + handleClose2 = () => { + this.setState({ open2: false }); + }; + + render() { + const { classes } = this.props; + const { vertical, horizontal, open2 } = this.state; + return ( + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Simple Notification</Typography> + <div> + <Button variant="contained" onClick={this.handleClick}>Open simple snackbar</Button> + <Snackbar + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', + }} + open={this.state.open} + autoHideDuration={6000} + onClose={this.handleClose} + ContentProps={{ + 'aria-describedby': 'message-id', + }} + message={<span id="message-id">Note archived</span>} + action={[ + <Button key="undo" color="secondary" size="small" onClick={this.handleClose}> + UNDO + </Button>, + <IconButton + key="close" + aria-label="Close" + color="inherit" + className={classes.close} + onClick={this.handleClose} + > + <CloseIcon /> + </IconButton>, + ]} + /> + </div> + </Grid> + <Grid item md={6}> + <Typography variant="button" className={classes.divider}>Positioning</Typography> + <div> + <Button className={classes.button} variant="contained" onClick={this.handleClick2({ vertical: 'top', horizontal: 'center' })}> + Top-Center + </Button> + <Button className={classes.button} variant="contained" onClick={this.handleClick2({ vertical: 'top', horizontal: 'right' })}> + Top-Right + </Button> + <Button className={classes.button} variant="contained" onClick={this.handleClick2({ vertical: 'bottom', horizontal: 'right' })}> + Bottom-Right + </Button> + <Button className={classes.button} variant="contained" onClick={this.handleClick2({ vertical: 'bottom', horizontal: 'center' })}> + Bottom-Center + </Button> + <Button className={classes.button} variant="contained" onClick={this.handleClick2({ vertical: 'bottom', horizontal: 'left' })}> + Bottom-Left + </Button> + <Button className={classes.button} variant="contained" onClick={this.handleClick2({ vertical: 'top', horizontal: 'left' })}> + Top-Left + </Button> + <Snackbar + anchorOrigin={{ vertical, horizontal }} + open={open2} + onClose={this.handleClose2} + ContentProps={{ + 'aria-describedby': 'message-id', + }} + message={<span id="message-id">I love snacks</span>} + /> + </div> + </Grid> + </Grid> + ); + } +} + +SimpleNotif.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SimpleNotif); diff --git a/front/odiparpack/app/containers/UiElements/demos/Notification/StyledNotif.js b/front/odiparpack/app/containers/UiElements/demos/Notification/StyledNotif.js new file mode 100644 index 0000000..2ad8dba --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Notification/StyledNotif.js @@ -0,0 +1,198 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import classNames from 'classnames'; +import CheckCircleOutlinedIcon from '@material-ui/icons/CheckCircleOutlined'; +import ErrorOutlineOutlinedIcon from '@material-ui/icons/ErrorOutlineOutlined'; +import InfoOutlinedIcon from '@material-ui/icons/InfoOutlined'; +import CloseIcon from '@material-ui/icons/Close'; +import ReportProblemOutlinedIcon from '@material-ui/icons/ReportProblemOutlined'; +import messageStyles from 'ba-styles/Messages.scss'; + +import { Typography, Button, IconButton, Snackbar, SnackbarContent, Grid } from '@material-ui/core'; + +const variantIcon = { + success: CheckCircleOutlinedIcon, + warning: ReportProblemOutlinedIcon, + error: ErrorOutlineOutlinedIcon, + info: InfoOutlinedIcon, +}; + +const styles1 = theme => ({ + success: { + backgroundColor: '#b6f8c4', + }, + error: { + backgroundColor: '#faabab', + }, + info: { + backgroundColor: '#b2e7f5', + }, + warning: { + backgroundColor: '#f5ea9f', + }, + icon: { + fontSize: 20, + color: 'black' + }, + iconVariant: { + opacity: 0.9, + marginRight: theme.spacing(1), + }, + message: { + display: 'flex', + alignItems: 'center', + color: 'black' + }, +}); + +function MySnackbarContent(props) { + const { + classes, + className, + message, + onClose, + variant, + ...other + } = props; + const Icon = variantIcon[variant]; + + return ( + <SnackbarContent + className={classNames(classes[variant], className)} + aria-describedby="client-snackbar" + message={( + <span id="client-snackbar" className={classes.message}> + <Icon className={classNames(classes.icon, classes.iconVariant)} /> + {message} + </span> + )} + action={[ + <IconButton + key="close" + aria-label="Close" + color="inherit" + className={classes.close} + onClick={onClose} + > + <CloseIcon className={classes.icon} /> + </IconButton>, + ]} + {...other} + /> + ); +} + +MySnackbarContent.propTypes = { + classes: PropTypes.object.isRequired, + className: PropTypes.string.isRequired, + message: PropTypes.node.isRequired, + onClose: PropTypes.func, + variant: PropTypes.oneOf(['success', 'warning', 'error', 'info']).isRequired, +}; + +MySnackbarContent.defaultProps = { + onClose: () => {} +}; + +const MySnackbarContentWrapper = withStyles(styles1)(MySnackbarContent); + +const styles = theme => ({ + snackbar: { + margin: theme.spacing(1), + }, + divider: { + margin: `${theme.spacing(3)}px 0`, + }, + margin: { + margin: theme.spacing(1) + } +}); + +const action = ( + <Button color="secondary" size="small"> + Action + </Button> +); + +class StyledNotif extends React.Component { + state = { + openStyle: false, + }; + + handleClickStyle = () => { + this.setState({ openStyle: true }); + }; + + handleCloseStyle = (event, reason) => { + if (reason === 'clickaway') { + return; + } + this.setState({ openStyle: false }); + }; + + render() { + const { classes } = this.props; + return ( + <Grid container alignItems="flex-start" justify="center" direction="row" spacing={2}> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Default Styled Notification</Typography> + <Button className={classes.margin} variant="outlined" color="primary" onClick={this.handleClickStyle}> + Open success snackbar + </Button> + <Snackbar + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', + }} + open={this.state.openStyle} + autoHideDuration={6000} + onClose={this.handleCloseStyle} + > + <MySnackbarContentWrapper + onClose={this.handleCloseStyle} + variant="success" + message="This is a success message!" + /> + </Snackbar> + <MySnackbarContentWrapper + variant="error" + className={classes.margin} + message="This is an error message!" + /> + <MySnackbarContentWrapper + variant="warning" + className={classes.margin} + message="This is a warning message!" + /> + <MySnackbarContentWrapper + variant="info" + className={classes.margin} + message="This is an information message!" + /> + <MySnackbarContentWrapper + variant="success" + className={classes.margin} + message="This is a success message!" + /> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Custom Styled Notification with CSS</Typography> + <div> + <SnackbarContent className={classes.snackbar} message="Notification default" action={action} /> + <SnackbarContent className={classNames(classes.snackbar, messageStyles.bgInfo)} message="Notification Info" action={action} /> + <SnackbarContent className={classNames(classes.snackbar, messageStyles.bgSuccess)} message="Success Notification Message" /> + <SnackbarContent className={classNames(classes.snackbar, messageStyles.bgWarning)} message="I love candy. I love cookies. I love cupcakes." action={action} /> + <SnackbarContent className={classNames(classes.snackbar, messageStyles.bgError)} message="I love cheesecake. I love chocolate." action={action} /> + </div> + </Grid> + </Grid> + ); + } +} + +StyledNotif.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(StyledNotif); diff --git a/front/odiparpack/app/containers/UiElements/demos/Notification/TransitionNotif.js b/front/odiparpack/app/containers/UiElements/demos/Notification/TransitionNotif.js new file mode 100644 index 0000000..6ac8df5 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Notification/TransitionNotif.js @@ -0,0 +1,203 @@ +import React, { Fragment, PureComponent } from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import CloseIcon from '@material-ui/icons/Close'; + +import { Typography, Button, Grid, Snackbar, Slide, Fade, IconButton } from '@material-ui/core'; + +const styles = theme => ({ + row: { + display: 'flex', + justifyContent: 'flex-start', + }, + close: { + width: theme.spacing(4) + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + }, + button: { + margin: theme.spacing(1) + } +}); + +function TransitionLeft(props) { + return <Slide {...props} direction="left" />; +} + +function TransitionUp(props) { + return <Slide {...props} direction="up" />; +} + +function TransitionRight(props) { + return <Slide {...props} direction="right" />; +} + +function TransitionDown(props) { + return <Slide {...props} direction="down" />; +} + +class TransitionNotif extends PureComponent { + state = { + open: false, + open2: false, + open3: false, + transition: null, + messageInfo: {}, + }; + + queue = []; + + handleClickQueue = message => () => { + this.queue.push({ + message, + key: new Date().getTime(), + }); + + if (this.state.open3) { + // immediately begin dismissing current message + // to start showing new one + this.setState({ open3: false }); + } else { + this.processQueue(); + } + }; + + processQueue = () => { + if (this.queue.length > 0) { + this.setState({ + messageInfo: this.queue.shift(), + open3: true, + }); + } + }; + + handleCloseQueue = (event, reason) => { + if (reason === 'clickaway') { + return; + } + this.setState({ open3: false }); + }; + + handleExited = () => { + this.processQueue(); + }; + + handleClick = transition => () => { + this.setState({ open: true, transition }); + }; + + handleClose = () => { + this.setState({ open: false }); + }; + + handleClick2 = () => { + this.setState({ open2: true }); + }; + + handleClose2 = () => { + this.setState({ open2: false }); + }; + + render() { + const { classes } = this.props; + const { message, key } = this.state.messageInfo; + return ( + <Fragment> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid + item + md={4} + > + <Typography variant="button" className={classes.divider}>Transition</Typography> + <div> + <Button variant="contained" className={classes.button} onClick={this.handleClick(TransitionLeft)}>Right</Button> + <Button variant="contained" className={classes.button} onClick={this.handleClick(TransitionUp)}>Up</Button> + <Button variant="contained" className={classes.button} onClick={this.handleClick(TransitionRight)}>Left</Button> + <Button variant="contained" className={classes.button} onClick={this.handleClick(TransitionDown)}>Down</Button> + <Snackbar + open={this.state.open} + onClose={this.handleClose} + TransitionComponent={this.state.transition} + ContentProps={{ + 'aria-describedby': 'message-id', + }} + message={<span>I love snacks</span>} + /> + </div> + </Grid> + <Grid + item + md={4} + > + <Typography variant="button" className={classes.divider}>Change Transition</Typography> + <div> + <Button variant="contained" className={classes.button} onClick={this.handleClick2}>Open with Fade Transition</Button> + <Snackbar + open={this.state.open2} + onClose={this.handleClose2} + TransitionComponent={Fade} + ContentProps={{ + 'aria-describedby': 'message-id', + }} + message={<span>I love snacks</span>} + /> + </div> + </Grid> + <Grid + item + md={4} + > + <Typography variant="button" className={classes.divider}>Consecutive Snackbars</Typography> + <div> + <Button variant="contained" className={classes.button} onClick={this.handleClickQueue('message a')}>Show message A</Button> + <Button variant="contained" className={classes.button} onClick={this.handleClickQueue('message b')}>Show message B</Button> + <Snackbar + key={key} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'left', + }} + open={this.state.open3} + autoHideDuration={6000} + onClose={this.handleCloseQueue} + onExited={this.handleExited} + ContentProps={{ + 'aria-describedby': 'message-id', + }} + message={<span>{message}</span>} + action={[ + <Button key="undo" color="secondary" size="small" onClick={this.handleClose2}> + UNDO + </Button>, + <IconButton + key="close" + aria-label="Close" + color="inherit" + className={classes.close} + onClick={this.handleCloseQueue} + > + <CloseIcon /> + </IconButton> + ]} + /> + </div> + </Grid> + </Grid> + </Fragment> + ); + } +} + +TransitionNotif.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(TransitionNotif); diff --git a/front/odiparpack/app/containers/UiElements/demos/Pagination/GeneralPagination.js b/front/odiparpack/app/containers/UiElements/demos/Pagination/GeneralPagination.js new file mode 100644 index 0000000..884be0a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Pagination/GeneralPagination.js @@ -0,0 +1,136 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Pagination } from 'ba-components'; +import { Paper } from '@material-ui/core'; + +const styles = theme => ({ + paper: theme.mixins.gutters({ + paddingTop: 16, + paddingBottom: 16, + marginTop: theme.spacing(3), + }), +}); + +class GeneralPagination extends React.Component { + constructor() { + super(); + this.state = { + page: 1, + content: [ + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', + 'Suspendisse sed urna in justo euismod condimentum', + 'Fusce placerat enim et odio molestie sagittis.', + 'Vestibulum dignissim orci vitae eros rutrum euismod.', + 'Vestibulum tempor, sem et molestie egestas, dui tortor laoreet tellus, id rhoncus mauris neque malesuada augue.', + 'Duis tristique metus magna, lobortis aliquam risus euismod sit amet.', + 'Suspendisse porttitor velit nisl, feugiat tincidunt nisl mattis ut.', + 'Nulla lobortis nunc vitae nisi semper semper.', + 'Sed mi neque, convallis at ipsum at, blandit pretium enim.', + 'Nunc quis sem quis velit tincidunt congue a sit amet ante.', + 'In hac habitasse platea dictumst.', + 'In mi nulla, fringilla vestibulum finibus et, vehicula non leo. Vivamus et luctus mauris.', + 'Maecenas nisl libero, tincidunt id odio id, feugiat vulputate quam. Vestibulum feugiat rhoncus metus.', + 'In non erat et ipsum molestie porta sit amet ut felis.', + 'Vestibulum a massa vestibulum, gravida odio id, fringilla ipsum.', + 'Ut sed eros finibus, placerat orci id, dapibus mauris.', + 'Proin varius, tortor faucibus tempor pharetra, nunc mi consectetur enim, nec posuere ante magna vitae quam.', + 'Cras convallis lacus orci, tristique tincidunt magna consequat in.', + 'Vestibulum consequat hendrerit lacus. In id nisi id neque venenatis molestie.', + 'Quisque lacinia purus ut libero facilisis, at vulputate sem maximus.', + 'Pellentesque ac bibendum tortor, vel blandit nulla.', + 'Nulla eget lobortis lacus.', + 'Aliquam venenatis magna et odio lobortis maximus.', + 'Nullam in tortor ligula.', + 'Proin maximus risus nunc, eu aliquam nibh tempus a.', + 'Interdum et malesuada fames ac ante ipsum primis in faucibus.', + ], + contentsPerPage: 3 + }; + this.onPageChange = this.onPageChange.bind(this); + this.onPrev = this.onPrev.bind(this); + this.onNext = this.onNext.bind(this); + this.onGoFirst = this.onGoFirst.bind(this); + this.onGoLast = this.onGoLast.bind(this); + } + + onPageChange(page) { + this.setState({ page }); + } + + onPrev() { + if (this.state.page > 1) { + this.setState({ page: this.state.page -= 1 }); + } else { + this.setState({ page: 1 }); + } + } + + onNext(totalPages) { + if (this.state.page < totalPages) { + this.setState({ page: this.state.page += 1 }); + } else { + this.setState({ page: totalPages }); + } + } + + onGoFirst() { + this.setState({ page: 1 }); + } + + onGoLast(totalPages) { + this.setState({ page: totalPages }); + } + + render() { + const { classes } = this.props; + const { page, content, contentsPerPage } = this.state; + + // Logic for displaying current todos + const indexOfLastTodo = page * contentsPerPage; + const indexOfFirstTodo = indexOfLastTodo - contentsPerPage; + const currentContent = content.slice(indexOfFirstTodo, indexOfLastTodo); + + const renderContent = currentContent.map((ctn, index) => ( + <p key={index.toString()}>{ctn}</p> + )); + + // Logic for displaying page numbers + const pageNumbers = []; + for (let i = 1; i <= Math.ceil(content.length / contentsPerPage); i += 1) { + pageNumbers.push(i); + } + + return ( + <div className={classes.root}> + <Paper className={classes.paper}> + <h3> +We are in page + {page} + </h3> + <article> + {renderContent} + </article> + </Paper> + <Pagination + curpage={page} + totpages={pageNumbers.length} + boundaryPagesRange={1} + onChange={this.onPageChange} + siblingPagesRange={1} + hideEllipsis={false} + onPrev={this.onPrev} + onNext={() => this.onNext(pageNumbers.length)} + onGoFirst={this.onGoFirst} + onGoLast={() => this.onGoLast(pageNumbers.length)} + /> + </div> + ); + } +} + +GeneralPagination.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(GeneralPagination); diff --git a/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPagination.js b/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPagination.js new file mode 100644 index 0000000..d1a0214 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPagination.js @@ -0,0 +1,110 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Table, TableBody, TableCell, TableFooter, TablePagination, TableRow, Paper } from '@material-ui/core'; + +let counter = 0; +function createData(name, calories, fat) { + counter += 1; + return { + id: counter, + name, + calories, + fat + }; +} + +const styles = theme => ({ + root: { + width: '100%', + marginTop: theme.spacing(3), + }, + table: { + minWidth: 500, + }, + tableWrapper: { + overflowX: 'auto', + }, +}); + +class TbPagination extends React.Component { + constructor(props, context) { + super(props, context); + + this.state = { + data: [ + createData('Cupcake', 305, 3.7), + createData('Donut', 452, 25.0), + createData('Eclair', 262, 16.0), + createData('Frozen yoghurt', 159, 6.0), + createData('Gingerbread', 356, 16.0), + createData('Honeycomb', 408, 3.2), + createData('Ice cream sandwich', 237, 9.0), + createData('Jelly Bean', 375, 0.0), + createData('KitKat', 518, 26.0), + createData('Lollipop', 392, 0.2), + createData('Marshmallow', 318, 0), + createData('Nougat', 360, 19.0), + createData('Oreo', 437, 18.0), + ].sort((a, b) => (a.calories < b.calories ? -1 : 1)), + page: 0, + rowsPerPage: 5, + }; + } + + handleChangePage = (event, page) => { + this.setState({ page }); + }; + + handleChangeRowsPerPage = event => { + this.setState({ rowsPerPage: event.target.value }); + }; + + render() { + const { classes } = this.props; + const { data, rowsPerPage, page } = this.state; + const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - (page * rowsPerPage)); + + return ( + <Paper className={classes.root}> + <div className={classes.tableWrapper}> + <Table className={classes.table}> + <TableBody> + {data.slice(page * rowsPerPage, (page * rowsPerPage) + rowsPerPage).map(n => ( + <TableRow key={n.id}> + <TableCell>{n.name}</TableCell> + <TableCell align="right">{n.calories}</TableCell> + <TableCell align="right">{n.fat}</TableCell> + </TableRow> + ))} + {emptyRows > 0 && ( + <TableRow style={{ height: 48 * emptyRows }}> + <TableCell colSpan={6} /> + </TableRow> + )} + </TableBody> + <TableFooter> + <TableRow> + <TablePagination + colSpan={3} + rowsPerPageOptions={[5, 10, 25]} + count={data.length} + rowsPerPage={rowsPerPage} + page={page} + onChangePage={this.handleChangePage} + onChangeRowsPerPage={this.handleChangeRowsPerPage} + /> + </TableRow> + </TableFooter> + </Table> + </div> + </Paper> + ); + } +} + +TbPagination.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(TbPagination); diff --git a/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPaginationActions.js b/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPaginationActions.js new file mode 100644 index 0000000..3f56fa0 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPaginationActions.js @@ -0,0 +1,93 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import FirstPageIcon from '@material-ui/icons/FirstPage'; +import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; +import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; +import LastPageIcon from '@material-ui/icons/LastPage'; +import { IconButton } from '@material-ui/core'; + +const actionsStyles = theme => ({ + root: { + flexShrink: 0, + color: theme.palette.text.secondary, + marginLeft: theme.spacing(2.5), + }, +}); + +class TbPaginationActions extends React.Component { + handleFirstPageButtonClick = event => { + this.props.onChangePage(event, 0); + }; + + handleBackButtonClick = event => { + this.props.onChangePage(event, this.props.page - 1); + }; + + handleNextButtonClick = event => { + this.props.onChangePage(event, this.props.page + 1); + }; + + handleLastPageButtonClick = event => { + this.props.onChangePage( + event, + Math.max(0, Math.ceil(this.props.count / this.props.rowsPerPage) - 1), + ); + }; + + render() { + const { + classes, + count, + page, + rowsPerPage, + theme + } = this.props; + + return ( + <div className={classes.root}> + <IconButton + onClick={this.handleFirstPageButtonClick} + disabled={page === 0} + aria-label="First Page" + > + {theme.direction === 'rtl' ? <LastPageIcon /> : <FirstPageIcon />} + </IconButton> + <IconButton + onClick={this.handleBackButtonClick} + disabled={page === 0} + aria-label="Previous Page" + > + {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />} + </IconButton> + <IconButton + onClick={this.handleNextButtonClick} + disabled={page >= Math.ceil(count / rowsPerPage) - 1} + aria-label="Next Page" + > + {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />} + </IconButton> + <IconButton + onClick={this.handleLastPageButtonClick} + disabled={page >= Math.ceil(count / rowsPerPage) - 1} + aria-label="Last Page" + > + {theme.direction === 'rtl' ? <FirstPageIcon /> : <LastPageIcon />} + </IconButton> + </div> + ); + } +} + +TbPaginationActions.propTypes = { + classes: PropTypes.object.isRequired, + count: PropTypes.number.isRequired, + onChangePage: PropTypes.func.isRequired, + page: PropTypes.number.isRequired, + rowsPerPage: PropTypes.number.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default withStyles(actionsStyles, { withTheme: true })( + TbPaginationActions, +); diff --git a/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPaginationCustom.js b/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPaginationCustom.js new file mode 100644 index 0000000..49494dc --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Pagination/TbPaginationCustom.js @@ -0,0 +1,115 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Table, TableBody, TableCell, TablePagination, TableRow, TableFooter, Paper } from '@material-ui/core'; +import TbPaginationActions from './TbPaginationActions'; + + +let counter = 0; +function createData(name, calories, fat) { + counter += 1; + return { + id: counter, + name, + calories, + fat + }; +} + +const styles = theme => ({ + root: { + width: '100%', + marginTop: theme.spacing(3), + }, + table: { + minWidth: 500, + }, + tableWrapper: { + overflowX: 'auto', + }, +}); + +class TbPaginationCustom extends React.Component { + constructor(props, context) { + super(props, context); + + this.state = { + data: [ + createData('Cupcake', 305, 3.7), + createData('Donut', 452, 25.0), + createData('Eclair', 262, 16.0), + createData('Frozen yoghurt', 159, 6.0), + createData('Gingerbread', 356, 16.0), + createData('Honeycomb', 408, 3.2), + createData('Ice cream sandwich', 237, 9.0), + createData('Jelly Bean', 375, 0.0), + createData('KitKat', 518, 26.0), + createData('Lollipop', 392, 0.2), + createData('Marshmallow', 318, 0), + createData('Nougat', 360, 19.0), + createData('Oreo', 437, 18.0), + ].sort((a, b) => (a.calories < b.calories ? -1 : 1)), + page: 0, + rowsPerPage: 5, + }; + } + + handleChangePage = (event, page) => { + this.setState({ page }); + }; + + handleChangeRowsPerPage = event => { + this.setState({ rowsPerPage: event.target.value }); + }; + + render() { + const { classes } = this.props; + const { data, rowsPerPage, page } = this.state; + const emptyRows = rowsPerPage - Math.min(rowsPerPage, data.length - (page * rowsPerPage)); + + return ( + <Paper className={classes.root}> + <div className={classes.tableWrapper}> + <Table className={classes.table}> + <TableBody> + {data.slice(page * rowsPerPage, (page * rowsPerPage) + rowsPerPage).map(n => ( + <TableRow key={n.id}> + <TableCell component="th" scope="row"> + {n.name} + </TableCell> + <TableCell align="right">{n.calories}</TableCell> + <TableCell align="right">{n.fat}</TableCell> + </TableRow> + ))} + {emptyRows > 0 && ( + <TableRow style={{ height: 48 * emptyRows }}> + <TableCell colSpan={6} /> + </TableRow> + )} + </TableBody> + <TableFooter> + <TableRow> + <TablePagination + rowsPerPageOptions={[5, 10, 25]} + colSpan={3} + count={data.length} + rowsPerPage={rowsPerPage} + page={page} + onChangePage={this.handleChangePage} + onChangeRowsPerPage={this.handleChangeRowsPerPage} + ActionsComponent={TbPaginationActions} + /> + </TableRow> + </TableFooter> + </Table> + </div> + </Paper> + ); + } +} + +TbPaginationCustom.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(TbPaginationCustom); diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/CustomizedTooltips.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/CustomizedTooltips.js new file mode 100644 index 0000000..f0f9111 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/CustomizedTooltips.js @@ -0,0 +1,125 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Button, Tooltip } from '@material-ui/core'; + +const styles = theme => ({ + lightTooltip: { + background: theme.palette.common.white, + color: theme.palette.text.primary, + boxShadow: theme.shadows[1], + fontSize: 11, + }, + arrowPopper: { + '&[x-placement*="bottom"] $arrowArrow': { + top: 0, + left: 0, + marginTop: '-0.9em', + width: '3em', + height: '1em', + '&::before': { + borderWidth: '0 1em 1em 1em', + borderColor: `transparent transparent ${theme.palette.grey[700]} transparent`, + }, + }, + '&[x-placement*="top"] $arrowArrow': { + bottom: 0, + left: 0, + marginBottom: '-0.9em', + width: '3em', + height: '1em', + '&::before': { + borderWidth: '1em 1em 0 1em', + borderColor: `${theme.palette.grey[700]} transparent transparent transparent`, + }, + }, + '&[x-placement*="right"] $arrowArrow': { + left: 0, + marginLeft: '-0.9em', + height: '3em', + width: '1em', + '&::before': { + borderWidth: '1em 1em 1em 0', + borderColor: `transparent ${theme.palette.grey[700]} transparent transparent`, + }, + }, + '&[x-placement*="left"] $arrowArrow': { + right: 0, + marginRight: '-0.9em', + height: '3em', + width: '1em', + '&::before': { + borderWidth: '1em 0 1em 1em', + borderColor: `transparent transparent transparent ${theme.palette.grey[700]}`, + }, + }, + }, + arrowArrow: { + position: 'absolute', + fontSize: 7, + width: '3em', + height: '3em', + '&::before': { + content: '""', + margin: 'auto', + display: 'block', + width: 0, + height: 0, + borderStyle: 'solid', + }, + }, +}); + +class CustomizedTooltips extends React.Component { + state = { + arrowRef: null, + }; + + handleArrowRef = node => { + this.setState({ + arrowRef: node, + }); + }; + + render() { + const { classes } = this.props; + + return ( + <div> + <Tooltip title="Add"> + <Button>Default</Button> + </Tooltip> + <Tooltip title="Add" classes={{ tooltip: classes.lightTooltip }}> + <Button>Light</Button> + </Tooltip> + <Tooltip + title={( + <React.Fragment> + Add + <span className={classes.arrowArrow} ref={this.handleArrowRef} /> + </React.Fragment> + )} + classes={{ popper: classes.arrowPopper }} + PopperProps={{ + popperOptions: { + modifiers: { + arrow: { + enabled: Boolean(this.state.arrowRef), + element: this.state.arrowRef, + }, + }, + }, + }} + > + <Button>Arrow</Button> + </Tooltip> + </div> + ); + } +} + +CustomizedTooltips.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CustomizedTooltips); diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/DelayTooltips.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/DelayTooltips.js new file mode 100644 index 0000000..786dd4f --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/DelayTooltips.js @@ -0,0 +1,12 @@ +import React from 'react'; +import { Button, Tooltip } from '@material-ui/core'; + +function DelayTooltips() { + return ( + <Tooltip title="Add" enterDelay={500} leaveDelay={200}> + <Button>[500ms, 200ms]</Button> + </Tooltip> + ); +} + +export default DelayTooltips; diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/PopoverPlayground.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/PopoverPlayground.js new file mode 100644 index 0000000..7878df1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/PopoverPlayground.js @@ -0,0 +1,340 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light'; +import jsx from 'react-syntax-highlighter/languages/prism/jsx'; +import themeSource from 'react-syntax-highlighter/styles/prism/prism'; +import { green } from '@material-ui/core/colors'; + +import { + FormControl, + FormLabel, + FormControlLabel, + Radio, + RadioGroup, + Grid, + Typography, + Button, + Popover, + Input, + InputLabel, +} from '@material-ui/core'; + +const styles = theme => ({ + buttonWrapper: { + position: 'relative', + marginBottom: theme.spacing(4), + }, + anchor: { + backgroundColor: green[500], + width: 10, + height: 10, + borderRadius: '50%', + position: 'absolute', + }, + radioAnchor: { + color: green[600], + '&$checked': { + color: green[500], + }, + }, + checked: {}, + typography: { + margin: theme.spacing(2), + }, +}); + +const inlineStyles = { + anchorVertical: { + top: { + top: -5, + }, + center: { + top: 'calc(50% - 5px)', + }, + bottom: { + bottom: -5, + }, + }, + anchorHorizontal: { + left: { + left: -5, + }, + center: { + left: 'calc(50% - 5px)', + }, + right: { + right: -5, + }, + }, +}; + +class PopoverPlayground extends React.Component { + state = { + open: false, + anchorOriginVertical: 'top', + anchorOriginHorizontal: 'left', + transformOriginVertical: 'top', + transformOriginHorizontal: 'left', + positionTop: 200, // Just so the popover can be spotted more easily + positionLeft: 400, // Same as above + anchorReference: 'anchorEl', + }; + + handleChange = key => (event, value) => { + this.setState({ + [key]: value, + }); + }; + + handleNumberInputChange = key => event => { + this.setState({ + [key]: parseInt(event.target.value, 10), + }); + }; + + handleClickButton = () => { + this.setState({ + open: true, + }); + }; + + handleClose = () => { + this.setState({ + open: false, + }); + }; + + anchorEl = null; + + render() { + const { classes } = this.props; + registerLanguage('jsx', jsx); + const { + open, + anchorOriginVertical, + anchorOriginHorizontal, + transformOriginVertical, + transformOriginHorizontal, + positionTop, + positionLeft, + anchorReference, + } = this.state; + + let mode = ''; + + if (anchorReference === 'anchorPosition') { + mode = ` + anchorReference="${anchorReference}" + anchorPosition={{ top: ${positionTop}, left: ${positionLeft} }}`; + } + + const code = ` +<Popover ${mode} + anchorOrigin={{ + vertical: '${anchorOriginVertical}', + horizontal: '${anchorOriginHorizontal}', + }} + transformOrigin={{ + vertical: '${transformOriginVertical}', + horizontal: '${transformOriginHorizontal}', + }} +> +`; + + const radioAnchorClasses = { root: classes.radioAnchor, checked: classes.checked }; + + return ( + <div> + <Grid container justify="center" spacing={0}> + <Grid item className={classes.buttonWrapper}> + <Button + buttonRef={node => { + this.anchorEl = node; + }} + variant="contained" + onClick={this.handleClickButton} + > + Open Popover + </Button> + {anchorReference === 'anchorEl' && ( + <div + className={classes.anchor} + style={{ + ...inlineStyles.anchorVertical[anchorOriginVertical], + ...inlineStyles.anchorHorizontal[anchorOriginHorizontal], + }} + /> + )} + </Grid> + </Grid> + <Popover + open={open} + anchorEl={this.anchorEl} + anchorReference={anchorReference} + anchorPosition={{ top: positionTop, left: positionLeft }} + onClose={this.handleClose} + anchorOrigin={{ + vertical: anchorOriginVertical, + horizontal: anchorOriginHorizontal, + }} + transformOrigin={{ + vertical: transformOriginVertical, + horizontal: transformOriginHorizontal, + }} + > + <Typography className={classes.typography}>The content of the Popover.</Typography> + </Popover> + <Grid container spacing={2}> + <Grid item xs={12} sm={6}> + <FormControl component="fieldset"> + <FormLabel component="legend">anchorReference</FormLabel> + <RadioGroup + row + aria-label="anchorReference" + name="anchorReference" + value={this.state.anchorReference} + onChange={this.handleChange('anchorReference')} + > + <FormControlLabel value="anchorEl" control={<Radio />} label="anchorEl" /> + <FormControlLabel + value="anchorPosition" + control={<Radio />} + label="anchorPosition" + /> + </RadioGroup> + </FormControl> + </Grid> + <Grid item xs={12} sm={6}> + <FormControl className={classes.formControl}> + <InputLabel htmlFor="position-top">anchorPosition.top</InputLabel> + <Input + id="position-top" + type="number" + value={this.state.positionTop} + onChange={this.handleNumberInputChange('positionTop')} + /> + </FormControl> + + <FormControl className={classes.formControl}> + <InputLabel htmlFor="position-left">anchorPosition.left</InputLabel> + <Input + id="position-left" + type="number" + value={this.state.positionLeft} + onChange={this.handleNumberInputChange('positionLeft')} + /> + </FormControl> + </Grid> + <Grid item xs={12} sm={6}> + <FormControl component="fieldset"> + <FormLabel component="legend">anchorOrigin.vertical</FormLabel> + <RadioGroup + aria-label="anchorOriginVertical" + name="anchorOriginVertical" + value={this.state.anchorOriginVertical} + onChange={this.handleChange('anchorOriginVertical')} + > + <FormControlLabel + value="top" + control={<Radio classes={radioAnchorClasses} />} + label="Top" + /> + <FormControlLabel + value="center" + control={<Radio classes={radioAnchorClasses} />} + label="Center" + /> + <FormControlLabel + value="bottom" + control={<Radio classes={radioAnchorClasses} />} + label="Bottom" + /> + </RadioGroup> + </FormControl> + </Grid> + <Grid item xs={12} sm={6}> + <FormControl component="fieldset"> + <FormLabel component="legend">transformOrigin.vertical</FormLabel> + <RadioGroup + aria-label="transformOriginVertical" + name="transformOriginVertical" + value={this.state.transformOriginVertical} + onChange={this.handleChange('transformOriginVertical')} + > + <FormControlLabel value="top" control={<Radio color="primary" />} label="Top" /> + <FormControlLabel + value="center" + control={<Radio color="primary" />} + label="Center" + /> + <FormControlLabel + value="bottom" + control={<Radio color="primary" />} + label="Bottom" + /> + </RadioGroup> + </FormControl> + </Grid> + <Grid item xs={12} sm={6}> + <FormControl component="fieldset"> + <FormLabel component="legend">anchorOrigin.horizontal</FormLabel> + <RadioGroup + row + aria-label="anchorOriginHorizontal" + name="anchorOriginHorizontal" + value={this.state.anchorOriginHorizontal} + onChange={this.handleChange('anchorOriginHorizontal')} + > + <FormControlLabel + value="left" + control={<Radio classes={radioAnchorClasses} />} + label="Left" + /> + <FormControlLabel + value="center" + control={<Radio classes={radioAnchorClasses} />} + label="Center" + /> + <FormControlLabel + value="right" + control={<Radio classes={radioAnchorClasses} />} + label="Right" + /> + </RadioGroup> + </FormControl> + </Grid> + <Grid item xs={12} sm={6}> + <FormControl component="fieldset"> + <FormLabel component="legend">transformOrigin.horizontal</FormLabel> + <RadioGroup + row + aria-label="transformOriginHorizontal" + name="transformOriginHorizontal" + value={this.state.transformOriginHorizontal} + onChange={this.handleChange('transformOriginHorizontal')} + > + <FormControlLabel value="left" control={<Radio color="primary" />} label="Left" /> + <FormControlLabel + value="center" + control={<Radio color="primary" />} + label="Center" + /> + <FormControlLabel value="right" control={<Radio color="primary" />} label="Right" /> + </RadioGroup> + </FormControl> + </Grid> + </Grid> + <SyntaxHighlighter language="jsx" style={themeSource} showLineNumbers="true"> + {code} + </SyntaxHighlighter> + </div> + ); + } +} + +PopoverPlayground.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(PopoverPlayground); diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/PositionedTooltips.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/PositionedTooltips.js new file mode 100644 index 0000000..336d932 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/PositionedTooltips.js @@ -0,0 +1,83 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Grid, Button, Tooltip } from '@material-ui/core'; + +const styles = { + root: { + width: 500, + margin: '0 auto' + }, +}; + +function PositionedTooltips(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <Grid container justify="center"> + <Grid item> + <Tooltip id="tooltip-top-start" title="Add" placement="top-start"> + <Button>top-start</Button> + </Tooltip> + <Tooltip id="tooltip-top" title="Add" placement="top"> + <Button>top</Button> + </Tooltip> + <Tooltip id="tooltip-top-end" title="Add" placement="top-end"> + <Button>top-end</Button> + </Tooltip> + </Grid> + </Grid> + <Grid container justify="center"> + <Grid item xs={6}> + <Tooltip id="tooltip-left-start" title="Add" placement="left-start"> + <Button>left-start</Button> + </Tooltip> + <br /> + <Tooltip id="tooltip-left" title="Add" placement="left"> + <Button>left</Button> + </Tooltip> + <br /> + <Tooltip id="tooltip-left-end" title="Add" placement="left-end"> + <Button>left-end</Button> + </Tooltip> + </Grid> + <Grid item container xs={6} alignItems="flex-end" direction="column" spacing={0}> + <Grid item> + <Tooltip id="tooltip-right-start" title="Add" placement="right-start"> + <Button>right-start</Button> + </Tooltip> + </Grid> + <Grid item> + <Tooltip id="tooltip-right" title="Add" placement="right"> + <Button>right</Button> + </Tooltip> + </Grid> + <Grid item> + <Tooltip id="tooltip-right-end" title="Add" placement="right-end"> + <Button>right-end</Button> + </Tooltip> + </Grid> + </Grid> + </Grid> + <Grid container justify="center"> + <Grid item> + <Tooltip id="tooltip-bottom-start" title="Add" placement="bottom-start"> + <Button>bottom-start</Button> + </Tooltip> + <Tooltip id="tooltip-bottom" title="Add" placement="bottom"> + <Button>bottom</Button> + </Tooltip> + <Tooltip id="tooltip-bottom-end" title="Add" placement="bottom-end"> + <Button>bottom-end</Button> + </Tooltip> + </Grid> + </Grid> + </div> + ); +} + +PositionedTooltips.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(PositionedTooltips); diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/SimplePopover.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/SimplePopover.js new file mode 100644 index 0000000..23d2462 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/SimplePopover.js @@ -0,0 +1,79 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Button, Popover, Typography, Grid } from '@material-ui/core'; + +const styles = theme => ({ + typography: { + margin: theme.spacing(2), + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + textAlign: 'center' + }, + button: { + margin: theme.spacing(1), + }, +}); + +class SimplePopover extends React.Component { + state = { + anchorEl: null, + }; + + handleClick = event => { + this.setState({ + anchorEl: event.currentTarget, + }); + }; + + handleClose = () => { + this.setState({ + anchorEl: null, + }); + }; + + render() { + const { classes } = this.props; + const { anchorEl } = this.state; + return ( + <div> + <Grid + container + alignItems="center" + justify="center" + direction="row" + spacing={2} + > + <Grid item md={6}> + <Button className={classes.button} variant="contained" onClick={this.handleClick}> + Open Simple Popover + </Button> + <Popover + open={Boolean(anchorEl)} + anchorEl={anchorEl} + onClose={this.handleClose} + anchorOrigin={{ + vertical: 'bottom', + horizontal: 'center', + }} + transformOrigin={{ + vertical: 'top', + horizontal: 'center', + }} + > + <Typography className={classes.typography}>The content of the Popover.</Typography> + </Popover> + </Grid> + </Grid> + </div> + ); + } +} + +SimplePopover.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SimplePopover); diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/SimpleTooltips.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/SimpleTooltips.js new file mode 100644 index 0000000..0714e6c --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/SimpleTooltips.js @@ -0,0 +1,116 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import AddIcon from '@material-ui/icons/Add'; +import DeleteIcon from '@material-ui/icons/Delete'; +import { Fab, IconButton, Tooltip, Typography, Grid } from '@material-ui/core'; + +const styles = theme => ({ + fab: { + margin: theme.spacing(2), + }, + fixed: { + position: 'fixed', + bottom: theme.spacing(2), + right: theme.spacing(3), + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + textAlign: 'center' + }, +}); + +class SimpleTooltips extends React.Component { + state = { + open: false, + }; + + handleTooltipClose = () => { + this.setState({ open: false }); + }; + + handleTooltipOpen = () => { + this.setState({ open: true }); + }; + + render() { + const { classes } = this.props; + return ( + <div> + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid + item + md={6} + > + <Typography variant="button" className={classes.divider}>Simple Tooltips</Typography> + <Grid + container + alignItems="center" + justify="center" + direction="row" + spacing={2} + > + <Tooltip title="Delete"> + <IconButton aria-label="Delete"> + <DeleteIcon /> + </IconButton> + </Tooltip> + <Tooltip title="Add"> + <Fab color="primary" aria-label="Add" className={classes.fab}> + <AddIcon /> + </Fab> + </Tooltip> + <br /> + <br /> + <Tooltip title="FAB 'position: absolute;'"> + <Fab color="secondary" className={classes.fixed}> + <AddIcon /> + </Fab> + </Tooltip> + </Grid> + </Grid> + <Grid + item + md={6} + > + <Typography variant="button" className={classes.divider}>Delayed Tooltips</Typography> + <Grid + container + alignItems="center" + justify="center" + direction="row" + spacing={2} + > + <Tooltip + enterDelay={300} + leaveDelay={300} + onClose={this.handleTooltipClose} + onOpen={this.handleTooltipOpen} + open={this.state.open} + placement="bottom" + title="Delete" + > + <IconButton aria-label="Delete"> + <DeleteIcon /> + </IconButton> + </Tooltip> + </Grid> + </Grid> + </Grid> + </div> + ); + } +} + +SimpleTooltips.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SimpleTooltips); diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/TransitionsTooltips.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/TransitionsTooltips.js new file mode 100644 index 0000000..7b8adc1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/TransitionsTooltips.js @@ -0,0 +1,20 @@ +import React from 'react'; +import { Button, Tooltip, Fade, Zoom } from '@material-ui/core'; + +function TransitionsTooltips() { + return ( + <div> + <Tooltip title="Add"> + <Button>Grow</Button> + </Tooltip> + <Tooltip TransitionComponent={Fade} TransitionProps={{ timeout: 600 }} title="Add"> + <Button>Fade</Button> + </Tooltip> + <Tooltip TransitionComponent={Zoom} title="Add"> + <Button>Zoom</Button> + </Tooltip> + </div> + ); +} + +export default TransitionsTooltips; diff --git a/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/TriggersTooltips.js b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/TriggersTooltips.js new file mode 100644 index 0000000..bd4db5b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/PopoverTooltip/TriggersTooltips.js @@ -0,0 +1,61 @@ +import React from 'react'; +import { Grid, Button, Tooltip, ClickAwayListener } from '@material-ui/core'; + +class TriggersTooltips extends React.Component { + state = { + open: false, + }; + + handleTooltipClose = () => { + this.setState({ open: false }); + }; + + handleTooltipOpen = () => { + this.setState({ open: true }); + }; + + render() { + return ( + <div> + <Grid container justify="center"> + <Grid item> + <Tooltip disableFocusListener title="Add"> + <Button>Hover or touch</Button> + </Tooltip> + </Grid> + <Grid item> + <Tooltip disableHoverListener title="Add"> + <Button>Focus or touch</Button> + </Tooltip> + </Grid> + <Grid item> + <Tooltip disableFocusListener disableTouchListener title="Add"> + <Button>Hover</Button> + </Tooltip> + </Grid> + <Grid item> + <ClickAwayListener onClickAway={this.handleTooltipClose}> + <div> + <Tooltip + PopperProps={{ + disablePortal: true, + }} + onClose={this.handleTooltipClose} + open={this.state.open} + disableFocusListener + disableHoverListener + disableTouchListener + title="Add" + > + <Button onClick={this.handleTooltipOpen}>Click</Button> + </Tooltip> + </div> + </ClickAwayListener> + </Grid> + </Grid> + </div> + ); + } +} + +export default TriggersTooltips; diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/CircularDeterminate.js b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularDeterminate.js new file mode 100644 index 0000000..0b1312b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularDeterminate.js @@ -0,0 +1,69 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { CircularProgress } from '@material-ui/core'; + +const styles = theme => ({ + progress: { + margin: theme.spacing(2), + }, +}); + +class CircularDeterminate extends React.Component { + state = { + completed: 0, + }; + + componentDidMount() { + this.timer = setInterval(this.progress, 20); + } + + componentWillUnmount() { + clearInterval(this.timer); + } + + timer; + + progress = () => { + const { completed } = this.state; + this.setState({ completed: completed === 100 ? 0 : completed + 1 }); + }; + + render() { + const { classes } = this.props; + return ( + <div> + <CircularProgress + className={classes.progress} + variant="determinate" + value={this.state.completed} + /> + <CircularProgress + className={classes.progress} + variant="determinate" + size={50} + value={this.state.completed} + /> + <CircularProgress + className={classes.progress} + color="secondary" + variant="determinate" + value={this.state.completed} + /> + <CircularProgress + className={classes.progress} + color="secondary" + variant="determinate" + size={50} + value={this.state.completed} + /> + </div> + ); + } +} + +CircularDeterminate.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CircularDeterminate); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/CircularIndeterminate.js b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularIndeterminate.js new file mode 100644 index 0000000..cc37de8 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularIndeterminate.js @@ -0,0 +1,29 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { purple } from '@material-ui/core/colors'; +import { CircularProgress } from '@material-ui/core'; + +const styles = theme => ({ + progress: { + margin: theme.spacing(2), + }, +}); + +function CircularIndeterminate(props) { + const { classes } = props; + return ( + <div> + <CircularProgress className={classes.progress} /> + <CircularProgress className={classes.progress} size={50} /> + <CircularProgress className={classes.progress} color="secondary" /> + <CircularProgress className={classes.progress} style={{ color: purple[500] }} thickness={7} /> + </div> + ); +} + +CircularIndeterminate.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CircularIndeterminate); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/CircularIntegration.js b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularIntegration.js new file mode 100644 index 0000000..ff19f5c --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularIntegration.js @@ -0,0 +1,114 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import CheckIcon from '@material-ui/icons/Check'; +import SaveIcon from '@material-ui/icons/Save'; +import { green } from '@material-ui/core/colors'; + +import { CircularProgress, Button, Fab } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + alignItems: 'center', + }, + wrapper: { + margin: theme.spacing(1), + position: 'relative', + }, + buttonSuccess: { + backgroundColor: green[500], + '&:hover': { + backgroundColor: green[700], + }, + }, + fabProgress: { + color: green[500], + position: 'absolute', + top: -6, + left: -6, + zIndex: 1, + }, + buttonProgress: { + color: green[500], + position: 'absolute', + top: '50%', + left: '50%', + marginTop: -12, + marginLeft: -12, + }, +}); + +class CircularIntegration extends React.Component { + state = { + loading: false, + success: false, + }; + + componentWillUnmount() { + clearTimeout(this.timer); + } + + handleButtonClick = () => { + if (!this.state.loading) { + this.setState( + { + success: false, + loading: true, + }, + () => { + this.timer = setTimeout(() => { + this.setState({ + loading: false, + success: true, + }); + }, 2000); + }, + ); + } + }; + + timer = undefined; + + render() { + const { loading, success } = this.state; + const { classes } = this.props; + const buttonClassname = classNames({ + [classes.buttonSuccess]: success, + }); + + return ( + <div className={classes.root}> + <div className={classes.wrapper}> + <Fab + color="primary" + className={buttonClassname} + onClick={this.handleButtonClick} + > + {success ? <CheckIcon /> : <SaveIcon />} + </Fab> + {loading && <CircularProgress size={68} className={classes.fabProgress} />} + </div> + <div className={classes.wrapper}> + <Button + variant="contained" + color="primary" + className={buttonClassname} + disabled={loading} + onClick={this.handleButtonClick} + > + Accept terms + </Button> + {loading && <CircularProgress size={24} className={classes.buttonProgress} />} + </div> + </div> + ); + } +} + +CircularIntegration.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CircularIntegration); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/CircularStatic.js b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularStatic.js new file mode 100644 index 0000000..bfa931a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/CircularStatic.js @@ -0,0 +1,29 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { CircularProgress } from '@material-ui/core'; + +const styles = theme => ({ + progress: { + margin: theme.spacing(2), + }, +}); + +function CircularStatic(props) { + const { classes } = props; + return ( + <div> + <CircularProgress className={classes.progress} variant="static" value={5} /> + <CircularProgress className={classes.progress} variant="static" value={25} /> + <CircularProgress className={classes.progress} variant="static" value={50} /> + <CircularProgress className={classes.progress} variant="static" value={75} /> + <CircularProgress className={classes.progress} variant="static" value={100} /> + </div> + ); +} + +CircularStatic.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CircularStatic); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/LinearBuffer.js b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearBuffer.js new file mode 100644 index 0000000..44bca71 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearBuffer.js @@ -0,0 +1,56 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { LinearProgress } from '@material-ui/core'; + +const styles = { + root: { + flexGrow: 1, + }, +}; + +class LinearBuffer extends React.Component { + state = { + completed: 0, + buffer: 10, + }; + + componentDidMount() { + this.timer = setInterval(this.progress, 500); + } + + componentWillUnmount() { + clearInterval(this.timer); + } + + timer = null; + + progress = () => { + const { completed } = this.state; + if (completed > 100) { + this.setState({ completed: 0, buffer: 10 }); + } else { + const diff = Math.random() * 10; + const diff2 = Math.random() * 10; + this.setState({ completed: completed + diff, buffer: completed + diff + diff2 }); + } + }; + + render() { + const { classes } = this.props; + const { completed, buffer } = this.state; + return ( + <div className={classes.root}> + <LinearProgress variant="buffer" value={completed} valueBuffer={buffer} /> + <br /> + <LinearProgress color="secondary" variant="buffer" value={completed} valueBuffer={buffer} /> + </div> + ); + } +} + +LinearBuffer.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(LinearBuffer); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/LinearDeterminate.js b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearDeterminate.js new file mode 100644 index 0000000..08c718d --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearDeterminate.js @@ -0,0 +1,53 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { LinearProgress } from '@material-ui/core'; + +const styles = { + root: { + flexGrow: 1, + }, +}; + +class LinearDeterminate extends React.Component { + state = { + completed: 0, + }; + + componentDidMount() { + this.timer = setInterval(this.progress, 500); + } + + componentWillUnmount() { + clearInterval(this.timer); + } + + timer = null; + + progress = () => { + const { completed } = this.state; + if (completed === 100) { + this.setState({ completed: 0 }); + } else { + const diff = Math.random() * 10; + this.setState({ completed: Math.min(completed + diff, 100) }); + } + }; + + render() { + const { classes } = this.props; + return ( + <div className={classes.root}> + <LinearProgress variant="determinate" value={this.state.completed} /> + <br /> + <LinearProgress color="secondary" variant="determinate" value={this.state.completed} /> + </div> + ); + } +} + +LinearDeterminate.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(LinearDeterminate); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/LinearIndeterminate.js b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearIndeterminate.js new file mode 100644 index 0000000..de5071a --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearIndeterminate.js @@ -0,0 +1,27 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { LinearProgress } from '@material-ui/core'; + +const styles = { + root: { + flexGrow: 1, + }, +}; + +function LinearIndeterminate(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <LinearProgress /> + <br /> + <LinearProgress color="secondary" /> + </div> + ); +} + +LinearIndeterminate.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(LinearIndeterminate); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/LinearQuery.js b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearQuery.js new file mode 100644 index 0000000..6e51da7 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearQuery.js @@ -0,0 +1,27 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { LinearProgress } from '@material-ui/core'; + +const styles = { + root: { + flexGrow: 1, + }, +}; + +function LinearQuery(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <LinearProgress variant="query" /> + <br /> + <LinearProgress color="secondary" variant="query" /> + </div> + ); +} + +LinearQuery.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(LinearQuery); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/LinearStatic.js b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearStatic.js new file mode 100644 index 0000000..55ad2a1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/LinearStatic.js @@ -0,0 +1,27 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { LinearProgress } from '@material-ui/core'; + +const styles = { + root: { + flexGrow: 1, + }, +}; + +function LinearIndeterminate(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <LinearProgress variant="determinate" value={20} /> + <br /> + <LinearProgress variant="determinate" value={60} color="secondary" /> + </div> + ); +} + +LinearIndeterminate.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(LinearIndeterminate); diff --git a/front/odiparpack/app/containers/UiElements/demos/Progress/ProgressDelay.js b/front/odiparpack/app/containers/UiElements/demos/Progress/ProgressDelay.js new file mode 100644 index 0000000..6417795 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Progress/ProgressDelay.js @@ -0,0 +1,105 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Fade, Button, CircularProgress, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + }, + button: { + margin: theme.spacing(2), + }, + placeholder: { + height: 40, + }, +}); + +class ProgressDelay extends React.Component { + state = { + loading: false, + query: 'idle', + }; + + componentWillUnmount() { + clearTimeout(this.timer); + } + + timer = null; + + handleClickLoading = () => { + this.setState({ + loading: !this.state.loading, + }); + }; + + handleClickQuery = () => { + clearTimeout(this.timer); + + if (this.state.query !== 'idle') { + this.setState({ + query: 'idle', + }); + return; + } + + this.setState({ + query: 'progress', + }); + this.timer = setTimeout(() => { + this.setState({ + query: 'success', + }); + }, 2e3); + }; + + render() { + const { classes } = this.props; + const { loading, query } = this.state; + + return ( + <div className={classes.root}> + <div className={classes.placeholder}> + <Fade + in={loading} + style={{ + transitionDelay: loading ? '800ms' : '0ms', + }} + unmountOnExit + > + <CircularProgress /> + </Fade> + </div> + <Button onClick={this.handleClickLoading} className={classes.button}> + {loading ? 'Stop loading' : 'Loading'} + </Button> + <div className={classes.placeholder}> + {query === 'success' ? ( + <Typography>Success!</Typography> + ) : ( + <Fade + in={query === 'progress'} + style={{ + transitionDelay: query === 'progress' ? '800ms' : '0ms', + }} + unmountOnExit + > + <CircularProgress /> + </Fade> + )} + </div> + <Button onClick={this.handleClickQuery} className={classes.button}> + {query !== 'idle' ? 'Reset' : 'Simulate a load'} + </Button> + </div> + ); + } +} + +ProgressDelay.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ProgressDelay); diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/AnimatedSlider.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/AnimatedSlider.js new file mode 100644 index 0000000..57fb5e4 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/AnimatedSlider.js @@ -0,0 +1,72 @@ +import React from 'react'; +import Type from 'ba-styles/Typography.scss'; +import Slider from 'react-animated-slider'; +import imgApi from 'ba-api/images'; +import avatarApi from 'ba-api/avatars'; +import 'ba-styles/vendors/react-animated-slider/react-animated-slider.css'; + +import { Button, Typography, Hidden } from '@material-ui/core'; + +const content = [ + { + title: 'Vulputate Mollis Ultricies Fermentum Parturient', + description: + 'Aenean eu leo quam. Pellentesque ornare sem lacinia quam venenatis vestibulum. Fusce dapibus, tellus ac cursus commodo, tortor mauris condimentum nibh, ut fermentum massa justo sit amet risus. Cras justo odio, dapibus ac facilisis.', + button: 'Read More', + image: imgApi[38], + user: 'Luanda Gjokaj', + userProfile: avatarApi[1] + }, + { + title: 'Tortor Dapibus Commodo Aenean Quam', + description: + 'Nullam id dolor id nibh ultricies vehicula ut id elit. Cras mattis consectetur purus sit amet fermentum. Morbi leo risus, porta ac consectetur ac, vestibulum at eros. Donec sed odio dui.', + button: 'Discover', + image: imgApi[2], + user: 'Erich Behrens', + userProfile: avatarApi[8] + }, + { + title: 'Phasellus volutpat metus', + description: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras mattis consectetur purus sit amet fermentum. Cras justo odio, dapibus ac facilisis in, egestas eget quam. Duis mollis, est non commodo luctus, nisi erat porttitor ligula.', + button: 'Buy now', + image: imgApi[28], + user: 'Bruno Vizovskyy', + userProfile: avatarApi[10] + } +]; + +const AnimatedSlider = () => ( + <div> + <Slider className="slider-wrapper"> + {content.map((item, index) => ( + <div + key={index.toString()} + className="slider-content" + style={{ background: `url('${item.image}') no-repeat center center` }} + > + <div className="inner"> + <Typography variant="h4" component="h1" className={Type.light} gutterBottom>{item.title}</Typography> + <Hidden mdDown> + <p>{item.description}</p> + </Hidden> + <Button variant="contained" color="primary"> + {item.button} + </Button> + </div> + <section> + <img src={item.userProfile} alt={item.user} /> + <span> + Posted by + {' '} + <strong>{item.user}</strong> + </span> + </section> + </div> + ))} + </Slider> + </div> +); + +export default AnimatedSlider; diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/AutoplayCarousel.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/AutoplayCarousel.js new file mode 100644 index 0000000..59c11ef --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/AutoplayCarousel.js @@ -0,0 +1,52 @@ +import React from 'react'; +import Slider from 'react-slick'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgData from 'ba-api/imgData'; +import 'ba-styles/vendors/slick-carousel/slick-carousel.css'; +import 'ba-styles/vendors/slick-carousel/slick.css'; +import 'ba-styles/vendors/slick-carousel/slick-theme.css'; + +const styles = ({ + item: { + textAlign: 'center', + '& img': { + margin: '10px auto' + } + } +}); + +class AutoplayCarousel extends React.Component { + render() { + const { classes } = this.props; + const settings = { + dots: true, + infinite: true, + centerMode: false, + speed: 500, + autoplaySpeed: 2000, + pauseOnHover: true, + autoplay: true, + slidesToShow: 3, + slidesToScroll: 1, + cssEase: 'ease-out' + }; + return ( + <div className="container"> + <Slider {...settings}> + {imgData.map((item, index) => ( + <div key={index.toString()} className={classes.item}> + <img src={item.img} alt={item.title} /> + </div> + ))} + </Slider> + </div> + ); + } +} + +AutoplayCarousel.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AutoplayCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/CustomCarousel.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/CustomCarousel.js new file mode 100644 index 0000000..a558d8e --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/CustomCarousel.js @@ -0,0 +1,93 @@ +import React from 'react'; +import Slider from 'react-slick'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import ArrowForward from '@material-ui/icons/ArrowForward'; +import ArrowBack from '@material-ui/icons/ArrowBack'; +import imgData from 'ba-api/imgData'; +import 'ba-styles/vendors/slick-carousel/slick-carousel.css'; +import 'ba-styles/vendors/slick-carousel/slick.css'; +import 'ba-styles/vendors/slick-carousel/slick-theme.css'; +import { IconButton } from '@material-ui/core'; + +function SampleNextArrow(props) { + const { onClick } = props; + return ( + <IconButton + className="nav-next" + onClick={onClick} + > + <ArrowForward /> + </IconButton> + ); +} + +SampleNextArrow.propTypes = { + onClick: PropTypes.func, +}; + +SampleNextArrow.defaultProps = { + onClick: undefined, +}; + +function SamplePrevArrow(props) { + const { onClick } = props; + return ( + <IconButton + className="nav-prev" + onClick={onClick} + > + <ArrowBack /> + </IconButton> + ); +} + +SamplePrevArrow.propTypes = { + onClick: PropTypes.func, +}; + +SamplePrevArrow.defaultProps = { + onClick: undefined, +}; + +const styles = ({ + item: { + textAlign: 'center', + '& img': { + margin: '10px auto' + } + } +}); + +class CustomCarousel extends React.Component { + render() { + const { classes } = this.props; + const settings = { + dots: true, + infinite: true, + centerMode: true, + speed: 500, + slidesToShow: 3, + slidesToScroll: 1, + nextArrow: <SampleNextArrow />, + prevArrow: <SamplePrevArrow /> + }; + return ( + <div className="container custom-arrow"> + <Slider {...settings}> + {imgData.map((item, index) => ( + <div key={index.toString()} className={classes.item}> + <img src={item.img} alt={item.title} /> + </div> + ))} + </Slider> + </div> + ); + } +} + +CustomCarousel.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CustomCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/MultipleCarousel.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/MultipleCarousel.js new file mode 100644 index 0000000..c8ff743 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/MultipleCarousel.js @@ -0,0 +1,48 @@ +import React from 'react'; +import Slider from 'react-slick'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgData from 'ba-api/imgData'; +import 'ba-styles/vendors/slick-carousel/slick-carousel.css'; +import 'ba-styles/vendors/slick-carousel/slick.css'; +import 'ba-styles/vendors/slick-carousel/slick-theme.css'; + +const styles = ({ + item: { + textAlign: 'center', + '& img': { + margin: '10px auto' + } + } +}); + +class MultipleCarousel extends React.Component { + render() { + const { classes } = this.props; + const settings = { + dots: true, + infinite: true, + centerMode: true, + speed: 500, + slidesToShow: 3, + slidesToScroll: 1 + }; + return ( + <div className="container"> + <Slider {...settings}> + {imgData.map((item, index) => ( + <div key={index.toString()} className={classes.item}> + <img src={item.img} alt={item.title} /> + </div> + ))} + </Slider> + </div> + ); + } +} + +MultipleCarousel.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(MultipleCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/SingleCarousel.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/SingleCarousel.js new file mode 100644 index 0000000..76158f7 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/SingleCarousel.js @@ -0,0 +1,80 @@ +import React from 'react'; +import Slider from 'react-slick'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgData from 'ba-api/imgData'; +import 'ba-styles/vendors/slick-carousel/slick-carousel.css'; +import 'ba-styles/vendors/slick-carousel/slick.css'; +import 'ba-styles/vendors/slick-carousel/slick-theme.css'; + +import { FormControl, MenuItem, InputLabel, Select } from '@material-ui/core'; + +const styles = ({ + root: { + display: 'flex', + flexDirection: 'column', + justifyContent: 'center' + }, + formControl: { + width: '50%', + margin: '0 auto' + }, + item: { + textAlign: 'center', + '& img': { + margin: '10px auto' + } + } +}); + +class SingleCarousel extends React.Component { + state = { + transition: 'slide' + } + + handleChange = event => { + this.setState({ [event.target.name]: event.target.value }); + }; + + render() { + const { classes } = this.props; + const { transition } = this.state; + const settings = { + dots: true, + fade: this.state.transition === 'fade', + }; + return ( + <div className={classes.root}> + <FormControl className={classes.formControl}> + <InputLabel htmlFor="age-simple">Carousel Transition</InputLabel> + <Select + value={transition} + onChange={this.handleChange} + inputProps={{ + name: 'transition', + id: 'transition-single-carousel', + }} + > + <MenuItem value="slide">Slide</MenuItem> + <MenuItem value="fade">Fade</MenuItem> + </Select> + </FormControl> + <div className="container"> + <Slider {...settings}> + {imgData.map((item, index) => ( + <div key={index.toString()} className={classes.item}> + <img src={item.img} alt={item.title} /> + </div> + ))} + </Slider> + </div> + </div> + ); + } +} + +SingleCarousel.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SingleCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/ThumbnailCarousel.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/ThumbnailCarousel.js new file mode 100644 index 0000000..9860b55 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/ThumbnailCarousel.js @@ -0,0 +1,90 @@ +import React from 'react'; +import Slider from 'react-slick'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import 'ba-styles/vendors/slick-carousel/slick-carousel.css'; +import 'ba-styles/vendors/slick-carousel/slick.css'; +import 'ba-styles/vendors/slick-carousel/slick-theme.css'; +import imgData from 'ba-api/imgData'; + +import { FormControl, MenuItem, InputLabel, Select } from '@material-ui/core'; + +const styles = ({ + root: { + display: 'flex', + flexDirection: 'column', + justifyContent: 'center' + }, + formControl: { + width: '50%', + margin: '0 auto' + }, + item: { + textAlign: 'center', + '& img': { + margin: '10px auto' + } + } +}); + +const getThumb = imgData.map(a => a.thumb); + +class ThumbnailCarousel extends React.Component { + state = { + transition: 'slide' + } + + handleChange = event => { + this.setState({ [event.target.name]: event.target.value }); + }; + + render() { + const { classes } = this.props; + const { transition } = this.state; + const settings = { + customPaging: (i) => ( + <a> + <img src={getThumb[i]} alt="thumb" /> + </a> + ), + infinite: true, + dots: true, + slidesToShow: 1, + slidesToScroll: 1, + fade: this.state.transition === 'fade', + }; + return ( + <div className={classes.root}> + <FormControl className={classes.formControl}> + <InputLabel htmlFor="age-simple">Carousel Transition</InputLabel> + <Select + value={transition} + onChange={this.handleChange} + inputProps={{ + name: 'transition', + id: 'transition-single-carousel', + }} + > + <MenuItem value="slide">Slide</MenuItem> + <MenuItem value="fade">Fade</MenuItem> + </Select> + </FormControl> + <div className="container thumb-nav custom-nav"> + <Slider {...settings}> + {imgData.map((item, index) => ( + <div key={index.toString()} className={classes.item}> + <img src={item.img} alt={item.title} /> + </div> + ))} + </Slider> + </div> + </div> + ); + } +} + +ThumbnailCarousel.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ThumbnailCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/VerticalCarousel.js b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/VerticalCarousel.js new file mode 100644 index 0000000..36dd7c3 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/SliderCaraousel/VerticalCarousel.js @@ -0,0 +1,48 @@ +import React from 'react'; +import Slider from 'react-slick'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import imgData from 'ba-api/imgData'; +import 'ba-styles/vendors/slick-carousel/slick-carousel.css'; +import 'ba-styles/vendors/slick-carousel/slick.css'; +import 'ba-styles/vendors/slick-carousel/slick-theme.css'; + +const styles = ({ + item: { + textAlign: 'center', + '& img': { + margin: '10px auto' + } + } +}); + +class VerticalCarousel extends React.Component { + render() { + const { classes } = this.props; + const settings = { + infinite: true, + slidesToShow: 2, + slidesToScroll: 1, + vertical: true, + verticalSwiping: true, + swipeToSlide: true, + }; + return ( + <div className="container"> + <Slider {...settings}> + {imgData.map((item, index) => ( + <div key={index.toString()} className={classes.item}> + <img src={item.img} alt={item.title} /> + </div> + ))} + </Slider> + </div> + ); + } +} + +VerticalCarousel.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(VerticalCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/Steppers/HorizontalLinear.js b/front/odiparpack/app/containers/UiElements/demos/Steppers/HorizontalLinear.js new file mode 100644 index 0000000..db47ee1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Steppers/HorizontalLinear.js @@ -0,0 +1,196 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Type from 'ba-styles/Typography.scss'; + +import { + Stepper, + Step, + StepLabel, + Button, + Typography, + FormGroup, + FormControlLabel, + Switch, + Divider, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + }, + button: { + marginRight: theme.spacing(1), + }, + instructions: { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, +}); + +function getSteps() { + return ['Select campaign settings', 'Create an ad group', 'Create an ad']; +} + +function getStepContent(step) { + switch (step) { + case 0: + return 'Select campaign settings...'; + case 1: + return 'What is an ad group anyways?'; + case 2: + return 'This is the bit I really care about!'; + default: + return 'Unknown step'; + } +} + +class HorizontalLinear extends React.Component { + static propTypes = { + classes: PropTypes.object.isRequired, + }; + + state = { + activeStep: 0, + altLabel: false, + skipped: new Set(), + }; + + isStepOptional = step => (step === 1); + + isStepSkipped(step) { + return this.state.skipped.has(step); + } + + handleNext = () => { + const { activeStep } = this.state; + let { skipped } = this.state; + if (this.isStepSkipped(activeStep)) { + skipped = new Set(skipped.values()); + skipped.delete(activeStep); + } + this.setState({ + activeStep: activeStep + 1, + skipped, + }); + }; + + handleBack = () => { + const { activeStep } = this.state; + this.setState({ + activeStep: activeStep - 1, + }); + }; + + handleSkip = () => { + const { activeStep } = this.state; + if (!this.isStepOptional(activeStep)) { + // You probably want to guard against something like this, + // it should never occur unless someone's actively trying to break something. + throw new Error("You can't skip a step that isn't optional."); + } + const skipped = new Set(this.state.skipped.values()); + skipped.add(activeStep); + this.setState({ + activeStep: this.state.activeStep + 1, + skipped, + }); + }; + + handleReset = () => { + this.setState({ + activeStep: 0, + }); + }; + + handleChange = name => event => { + this.setState({ [name]: event.target.checked }); + }; + + render() { + const { classes } = this.props; + const steps = getSteps(); + const { activeStep, altLabel } = this.state; + + return ( + <div className={classes.root}> + <FormGroup row> + <FormControlLabel + control={( + <Switch + checked={altLabel} + onChange={this.handleChange('altLabel')} + value="altLabel" + /> + )} + label="Alternative Design" + /> + </FormGroup> + <Divider /> + <Stepper activeStep={activeStep} alternativeLabel={altLabel}> + {steps.map((label, index) => { + const props = {}; + const labelProps = {}; + if (this.isStepOptional(index)) { + labelProps.optional = <Typography className={altLabel ? Type.textCenter : ''} variant="caption">Optional</Typography>; + } + if (this.isStepSkipped(index)) { + props.completed = false; + } + return ( + <Step key={label} {...props}> + <StepLabel {...labelProps}>{label}</StepLabel> + </Step> + ); + })} + </Stepper> + <Divider /> + <div> + {activeStep === steps.length ? ( + <div> + <Typography className={classes.instructions}> + All steps completed - you"re finished + </Typography> + <Button onClick={this.handleReset} className={classes.button}> + Reset + </Button> + </div> + ) : ( + <div> + <Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography> + <div> + <Button + disabled={activeStep === 0} + onClick={this.handleBack} + className={classes.button} + > + Back + </Button> + {this.isStepOptional(activeStep) && ( + <Button + variant="contained" + color="primary" + onClick={this.handleSkip} + className={classes.button} + > + Skip + </Button> + )} + <Button + variant="contained" + color="primary" + onClick={this.handleNext} + className={classes.button} + > + {activeStep === steps.length - 1 ? 'Finish' : 'Next'} + </Button> + </div> + </div> + )} + </div> + </div> + ); + } +} + +export default withStyles(styles)(HorizontalLinear); diff --git a/front/odiparpack/app/containers/UiElements/demos/Steppers/HorizontalNonLinear.js b/front/odiparpack/app/containers/UiElements/demos/Steppers/HorizontalNonLinear.js new file mode 100644 index 0000000..3c72df3 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Steppers/HorizontalNonLinear.js @@ -0,0 +1,213 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; + +import { + Stepper, + Step, + StepButton, + Button, + Divider, + FormGroup, + FormControlLabel, + Switch, + Typography, +} from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + }, + button: { + marginRight: theme.spacing(1), + }, + completed: { + display: 'inline-block', + }, + instructions: { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, + stepItem: { + whiteSpace: 'inherit' + } +}); + +function getSteps() { + return ['Select campaign settings', 'Create an ad group', 'Create an ad']; +} + +function getStepContent(step) { + switch (step) { + case 0: + return 'Step 1: Select campaign settings...'; + case 1: + return 'Step 2: What is an ad group anyways?'; + case 2: + return 'Step 3: This is the bit I really care about!'; + default: + return 'Unknown step'; + } +} + +class HorizontalNonLinear extends React.Component { + state = { + activeStep: 0, + altLabel: false, + completed: {}, + }; + + completedSteps() { + return Object.keys(this.state.completed).length; + } + + totalSteps = () => ( + getSteps().length + ); + + isLastStep() { + return this.state.activeStep === this.totalSteps() - 1; + } + + allStepsCompleted() { + return this.completedSteps() === this.totalSteps(); + } + + handleNext = () => { + let activeStep; + + if (this.isLastStep() && !this.allStepsCompleted()) { + // It's the last step, but not all steps have been completed, + // find the first step that has been completed + const steps = getSteps(); + activeStep = steps.findIndex((step, i) => !(i in this.state.completed)); + } else { + activeStep = this.state.activeStep + 1; + } + this.setState({ + activeStep, + }); + }; + + handleBack = () => { + const { activeStep } = this.state; + this.setState({ + activeStep: activeStep - 1, + }); + }; + + handleStep = step => () => { + this.setState({ + activeStep: step, + }); + }; + + handleComplete = () => { + const { completed } = this.state; + completed[this.state.activeStep] = true; + this.setState({ + completed, + }); + this.handleNext(); + }; + + handleReset = () => { + this.setState({ + activeStep: 0, + completed: {}, + }); + }; + + handleChange = name => event => { + this.setState({ [name]: event.target.checked }); + }; + + render() { + const { classes } = this.props; + const steps = getSteps(); + const { activeStep, altLabel } = this.state; + + return ( + <div className={classes.root}> + <FormGroup row> + <FormControlLabel + control={( + <Switch + checked={altLabel} + onChange={this.handleChange('altLabel')} + value="altLabel" + /> + )} + label="Alternative Design" + /> + </FormGroup> + <Divider /> + <Stepper nonLinear activeStep={activeStep} alternativeLabel={altLabel}> + {steps.map((label, index) => ( + <Step key={label}> + <StepButton + className={classes.stepItem} + onClick={this.handleStep(index)} + completed={this.state.completed[index]} + > + {label} + </StepButton> + </Step> + ))} + </Stepper> + <Divider /> + <div> + {this.allStepsCompleted() ? ( + <div> + <Typography className={classes.instructions}> + All steps completed - you"re finished + </Typography> + <Button onClick={this.handleReset}>Reset</Button> + </div> + ) : ( + <div> + <Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography> + <div> + <Button + disabled={activeStep === 0} + onClick={this.handleBack} + className={classes.button} + > + Back + </Button> + <Button + variant="contained" + color="primary" + onClick={this.handleNext} + className={classes.button} + > + Next + </Button> + {activeStep !== steps.length + && (this.state.completed[this.state.activeStep] ? ( + <Typography variant="caption" className={classes.completed}> + Step + {' '} + {activeStep + 1} + {' '} +already completed + </Typography> + ) : ( + <Button variant="contained" color="primary" onClick={this.handleComplete}> + {this.completedSteps() === this.totalSteps() - 1 ? 'Finish' : 'Complete Step'} + </Button> + ))} + </div> + </div> + )} + </div> + </div> + ); + } +} + +HorizontalNonLinear.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(HorizontalNonLinear); diff --git a/front/odiparpack/app/containers/UiElements/demos/Steppers/MobileSteppers.js b/front/odiparpack/app/containers/UiElements/demos/Steppers/MobileSteppers.js new file mode 100644 index 0000000..c9d7cf1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Steppers/MobileSteppers.js @@ -0,0 +1,116 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; +import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; + +import { MobileStepper, Button, Grid, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + [theme.breakpoints.up('sm')]: { + width: 400, + margin: '0 auto' + }, + flexGrow: 1, + }, + title: { + textAlign: 'center', + margin: `${theme.spacing(4)}px 0 ${theme.spacing(2)}px`, + }, +}); + +class MobileSteppers extends React.Component { + state = { + activeStepDots: 0, + activeStepLine: 0, + }; + + handleNextDots = () => { + this.setState({ + activeStepDots: this.state.activeStepDots + 1, + }); + }; + + handleBackDots = () => { + this.setState({ + activeStepDots: this.state.activeStepDots - 1, + }); + }; + + handleNextLine = () => { + this.setState({ + activeStepLine: this.state.activeStepLine + 1, + }); + }; + + handleBackLine = () => { + this.setState({ + activeStepLine: this.state.activeStepLine - 1, + }); + }; + + render() { + const { classes, theme } = this.props; + + return ( + <Grid container spacing={2}> + <Grid item container justify="center" direction="column" md={6}> + <Typography variant="button" className={classes.title}> + Mobile Stepper - Dots + </Typography> + <MobileStepper + variant="dots" + steps={6} + position="static" + activeStep={this.state.activeStepDots} + className={classes.root} + nextButton={( + <Button size="small" onClick={this.handleNextDots} disabled={this.state.activeStepDots === 5}> + Next + {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />} + </Button> + )} + backButton={( + <Button size="small" onClick={this.handleBackDots} disabled={this.state.activeStepDots === 0}> + {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />} + Back + </Button> + )} + /> + </Grid> + <Grid item container justify="center" direction="column" md={6}> + <Typography variant="button" className={classes.title}> + Mobile Stepper - Progress + </Typography> + <MobileStepper + variant="progress" + steps={6} + position="static" + activeStep={this.state.activeStepLine} + className={classes.root} + nextButton={( + <Button size="small" onClick={this.handleNextLine} disabled={this.state.activeStepLine === 5}> + Next + {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />} + </Button> + )} + backButton={( + <Button size="small" onClick={this.handleBackLine} disabled={this.state.activeStepLine === 0}> + {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />} + Back + </Button> + )} + /> + </Grid> + </Grid> + ); + } +} + +MobileSteppers.propTypes = { + classes: PropTypes.object.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default withStyles(styles, { withTheme: true })(MobileSteppers); diff --git a/front/odiparpack/app/containers/UiElements/demos/Steppers/StepperCarousel.js b/front/odiparpack/app/containers/UiElements/demos/Steppers/StepperCarousel.js new file mode 100644 index 0000000..0f127b3 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Steppers/StepperCarousel.js @@ -0,0 +1,187 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import KeyboardArrowLeft from '@material-ui/icons/KeyboardArrowLeft'; +import KeyboardArrowRight from '@material-ui/icons/KeyboardArrowRight'; +import SwipeableViews from 'react-swipeable-views'; +import imgApi from 'ba-api/images'; + +import { MobileStepper, Paper, Typography, Button, Grid } from '@material-ui/core'; + +const tutorialSteps = [ + { + label: 'How to be happy :)', + imgPath: imgApi[45], + }, + { + label: '1. Work with something that you like, like…', + imgPath: imgApi[33], + }, + { + label: '2. Keep your friends close to you and hangout with them', + imgPath: imgApi[14], + }, + { + label: '3. Travel everytime that you have a chance', + imgPath: imgApi[9], + }, + { + label: '4. And contribute to Material-UI :D', + imgPath: imgApi[44], + }, +]; + +const styles = theme => ({ + root: { + [theme.breakpoints.up('sm')]: { + width: 400, + }, + flexGrow: 1, + }, + header: { + textAlign: 'center', + height: 50, + paddingLeft: theme.spacing(4), + marginBottom: 20, + backgroundColor: theme.palette.background.default, + }, + img: { + height: 255, + maxWidth: 400, + overflow: 'hidden', + width: '100%', + margin: '0 auto' + }, + figure: { + maxWidth: 400, + overflow: 'hidden', + margin: '0 auto' + }, + mobileStepper: { + [theme.breakpoints.up('sm')]: { + width: 400, + }, + margin: '0 auto', + textAlign: 'center' + } +}); + +class StepperCarousel extends React.Component { + state = { + activeStep: 0, + activeStepSwipe: 0, + }; + + handleNext = () => { + this.setState(prevState => ({ + activeStep: prevState.activeStep + 1, + })); + }; + + handleBack = () => { + this.setState(prevState => ({ + activeStep: prevState.activeStep - 1, + })); + }; + + handleNextSwipe = () => { + this.setState(prevState => ({ + activeStepSwipe: prevState.activeStepSwipe + 1, + })); + }; + + handleBackSwipe = () => { + this.setState(prevState => ({ + activeStepSwipe: prevState.activeStepSwipe - 1, + })); + }; + + handleStepChangeSwipe = activeStepSwipe => { + this.setState({ activeStepSwipe }); + }; + + render() { + const { classes, theme } = this.props; + const { activeStep, activeStepSwipe } = this.state; + + const maxSteps = tutorialSteps.length; + const maxStepsSwipe = tutorialSteps.length; + + return ( + <Grid container spacing={2}> + <Grid item container justify="center" direction="column" md={6}> + <Paper square elevation={0} className={classes.header}> + <Typography>{tutorialSteps[activeStep].label}</Typography> + </Paper> + <img + className={classes.img} + src={tutorialSteps[activeStep].imgPath} + alt={tutorialSteps[activeStep].label} + /> + <MobileStepper + variant="text" + steps={maxSteps} + position="static" + activeStep={activeStep} + className={classes.mobileStepper} + nextButton={( + <Button size="small" onClick={this.handleNext} disabled={activeStep === maxSteps - 1}> + Next + {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />} + </Button> + )} + backButton={( + <Button size="small" onClick={this.handleBack} disabled={activeStep === 0}> + {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />} + Back + </Button> + )} + /> + </Grid> + <Grid item container justify="center" direction="column" md={6}> + <Paper square elevation={0} className={classes.header}> + <Typography>{tutorialSteps[activeStepSwipe].label}</Typography> + </Paper> + <SwipeableViews + axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'} + index={this.state.activeStepSwipe} + onChangeIndex={this.handleStepChangeSwipe} + enableMouseEvents + > + {tutorialSteps.map((step, index) => ( + <div className={classes.figure} key={index.toString()}> + <img key={step.label} className={classes.img} src={step.imgPath} alt={step.label} /> + </div> + ))} + </SwipeableViews> + <MobileStepper + variant="text" + steps={maxStepsSwipe} + position="static" + activeStep={activeStepSwipe} + className={classes.mobileStepper} + nextButton={( + <Button size="small" onClick={this.handleNextSwipe} disabled={activeStepSwipe === maxStepsSwipe - 1}> + Next + {theme.direction === 'rtl' ? <KeyboardArrowLeft /> : <KeyboardArrowRight />} + </Button> + )} + backButton={( + <Button size="small" onClick={this.handleBackSwipe} disabled={activeStepSwipe === 0}> + {theme.direction === 'rtl' ? <KeyboardArrowRight /> : <KeyboardArrowLeft />} + Back + </Button> + )} + /> + </Grid> + </Grid> + ); + } +} + +StepperCarousel.propTypes = { + classes: PropTypes.object.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default withStyles(styles, { withTheme: true })(StepperCarousel); diff --git a/front/odiparpack/app/containers/UiElements/demos/Steppers/StepperError.js b/front/odiparpack/app/containers/UiElements/demos/Steppers/StepperError.js new file mode 100644 index 0000000..85630a1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Steppers/StepperError.js @@ -0,0 +1,178 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Stepper, Step, StepLabel, Button, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '100%', + }, + button: { + marginRight: theme.spacing(1), + }, + instructions: { + marginTop: theme.spacing(1), + marginBottom: theme.spacing(1), + }, +}); + +function getSteps() { + return ['Select campaign settings', 'Create an ad group', 'Create an ad']; +} + +function getStepContent(step) { + switch (step) { + case 0: + return 'Select campaign settings...'; + case 1: + return 'What is an ad group anyways?'; + case 2: + return 'This is the bit I really care about!'; + default: + return 'Unknown step'; + } +} + +class StepperError extends React.Component { + static propTypes = { + classes: PropTypes.object.isRequired, + }; + + state = { + activeStep: 0, + skipped: new Set(), + }; + + isStepOptional = step => ( + step === 1 + ); + + isStepSkipped(step) { + return this.state.skipped.has(step); + } + + isStepFailed = step => ( + step === 1 + ); + + handleNext = () => { + const { activeStep } = this.state; + let { skipped } = this.state; + if (this.isStepSkipped(activeStep)) { + skipped = new Set(skipped.values()); + skipped.delete(activeStep); + } + this.setState({ + activeStep: activeStep + 1, + skipped, + }); + }; + + handleBack = () => { + const { activeStep } = this.state; + this.setState({ + activeStep: activeStep - 1, + }); + }; + + handleSkip = () => { + const { activeStep } = this.state; + if (!this.isStepOptional(activeStep)) { + // You probably want to guard against something like this, + // it should never occur unless someone's actively trying to break something. + throw new Error("You can't skip a step that isn't optional."); + } + const skipped = new Set(this.state.skipped.values()); + skipped.add(activeStep); + this.setState({ + activeStep: this.state.activeStep + 1, + skipped, + }); + }; + + handleReset = () => { + this.setState({ + activeStep: 0, + }); + }; + + render() { + const { classes } = this.props; + const steps = getSteps(); + const { activeStep } = this.state; + + return ( + <div className={classes.root}> + <Stepper activeStep={activeStep}> + {steps.map((label, index) => { + const props = {}; + const labelProps = {}; + if (this.isStepOptional(index)) { + labelProps.optional = ( + <Typography variant="caption" color="error"> + Alert message + </Typography> + ); + } + if (this.isStepFailed(index)) { + labelProps.error = true; + } + if (this.isStepSkipped(index)) { + props.completed = false; + } + return ( + <Step key={label} {...props}> + <StepLabel {...labelProps}>{label}</StepLabel> + </Step> + ); + })} + </Stepper> + <div> + {activeStep === steps.length ? ( + <div> + <Typography className={classes.instructions}> + All steps completed - you"re finished + </Typography> + <Button onClick={this.handleReset} className={classes.button}> + Reset + </Button> + </div> + ) : ( + <div> + <Typography className={classes.instructions}>{getStepContent(activeStep)}</Typography> + <div> + <Button + disabled={activeStep === 0} + onClick={this.handleBack} + className={classes.button} + > + Back + </Button> + {this.isStepOptional(activeStep) && ( + <Button + variant="contained" + color="primary" + onClick={this.handleSkip} + className={classes.button} + > + Skip + </Button> + )} + <Button + variant="contained" + color="primary" + onClick={this.handleNext} + className={classes.button} + > + {activeStep === steps.length - 1 ? 'Finish' : 'Next'} + </Button> + </div> + </div> + )} + </div> + </div> + ); + } +} + +export default withStyles(styles)(StepperError); diff --git a/front/odiparpack/app/containers/UiElements/demos/Steppers/VerticalStepper.js b/front/odiparpack/app/containers/UiElements/demos/Steppers/VerticalStepper.js new file mode 100644 index 0000000..5a2314b --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Steppers/VerticalStepper.js @@ -0,0 +1,120 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Stepper, Step, StepLabel, StepContent, Button, Paper, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: '90%', + }, + button: { + marginTop: theme.spacing(1), + marginRight: theme.spacing(1), + }, + actionsContainer: { + marginBottom: theme.spacing(2), + }, + resetContainer: { + padding: theme.spacing(3), + }, +}); + +function getSteps() { + return ['Select campaign settings', 'Create an ad group', 'Create an ad']; +} + +function getStepContent(step) { + switch (step) { + case 0: + return `For each ad campaign that you create, you can control how much + you're willing to spend on clicks and conversions, which networks + and geographical locations you want your ads to show on, and more.`; + case 1: + return 'An ad group contains one or more ads which target a shared set of keywords.'; + case 2: + return `Try out different ad text to see what brings in the most customers, + and learn how to enhance your ads using features like ad extensions. + If you run into any problems with your ads, find out how to tell if + they're running and how to resolve approval issues.`; + default: + return 'Unknown step'; + } +} + +class VerticalStepper extends React.Component { + state = { + activeStep: 0, + }; + + handleNext = () => { + this.setState({ + activeStep: this.state.activeStep + 1, + }); + }; + + handleBack = () => { + this.setState({ + activeStep: this.state.activeStep - 1, + }); + }; + + handleReset = () => { + this.setState({ + activeStep: 0, + }); + }; + + render() { + const { classes } = this.props; + const steps = getSteps(); + const { activeStep } = this.state; + + return ( + <div className={classes.root}> + <Stepper activeStep={activeStep} orientation="vertical"> + {steps.map((label, index) => ( + <Step key={label}> + <StepLabel>{label}</StepLabel> + <StepContent> + <Typography>{getStepContent(index)}</Typography> + <div className={classes.actionsContainer}> + <div> + <Button + disabled={activeStep === 0} + onClick={this.handleBack} + className={classes.button} + > + Back + </Button> + <Button + variant="contained" + color="primary" + onClick={this.handleNext} + className={classes.button} + > + {activeStep === steps.length - 1 ? 'Finish' : 'Next'} + </Button> + </div> + </div> + </StepContent> + </Step> + ))} + </Stepper> + {activeStep === steps.length && ( + <Paper square elevation={0} className={classes.resetContainer}> + <Typography>All steps completed - you"re finished</Typography> + <Button onClick={this.handleReset} className={classes.button}> + Reset + </Button> + </Paper> + )} + </div> + ); + } +} + +VerticalStepper.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(VerticalStepper); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/BottomNav.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/BottomNav.js new file mode 100644 index 0000000..f3aa033 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/BottomNav.js @@ -0,0 +1,82 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import RestoreIcon from '@material-ui/icons/Restore'; +import FavoriteIcon from '@material-ui/icons/Favorite'; +import LocationOnIcon from '@material-ui/icons/LocationOn'; + +import { Typography, Grid, BottomNavigation, BottomNavigationAction, Icon } from '@material-ui/core'; + +const styles = theme => ({ + root: { + width: 'auto', + }, + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +class BottomNav extends React.Component { + state = { + value: 0, + value2: 'recents', + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + handleChange2 = (event, value2) => { + this.setState({ value2 }); + }; + + + render() { + const { classes } = this.props; + const { value, value2 } = this.state; + + return ( + <Grid + container + alignItems="flex-start" + justify="flex-start" + direction="row" + spacing={2} + > + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>With Label</Typography> + <div> + <BottomNavigation + value={value} + onChange={this.handleChange} + showLabels + className={classes.root} + > + <BottomNavigationAction label="Recents" icon={<RestoreIcon />} /> + <BottomNavigationAction label="Favorites" icon={<FavoriteIcon />} /> + <BottomNavigationAction label="Nearby" icon={<LocationOnIcon />} /> + </BottomNavigation> + </div> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" className={classes.divider}>Without Label</Typography> + <div> + <BottomNavigation value={value2} onChange={this.handleChange2} className={classes.root}> + <BottomNavigationAction label="Recents" value="recents" icon={<RestoreIcon />} /> + <BottomNavigationAction label="Favorites" value="favorites" icon={<FavoriteIcon />} /> + <BottomNavigationAction label="Nearby" value="nearby" icon={<LocationOnIcon />} /> + <BottomNavigationAction label="Folder" value="folder" icon={<Icon>folder</Icon>} /> + </BottomNavigation> + </div> + </Grid> + </Grid> + ); + } +} + +BottomNav.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(BottomNav); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/CenteredTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/CenteredTabs.js new file mode 100644 index 0000000..00a285e --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/CenteredTabs.js @@ -0,0 +1,46 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Paper, Tabs, Tab } from '@material-ui/core'; + +const styles = { + root: { + flexGrow: 1, + }, +}; + +class CenteredTabs extends React.Component { + state = { + value: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { classes } = this.props; + + return ( + <Paper className={classes.root}> + <Tabs + value={this.state.value} + onChange={this.handleChange} + indicatorColor="primary" + textColor="primary" + centered + > + <Tab label="Item One" /> + <Tab label="Item Two" /> + <Tab label="Item Three" /> + </Tabs> + </Paper> + ); + } +} + +CenteredTabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CenteredTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/CustomTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/CustomTabs.js new file mode 100644 index 0000000..96fd136 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/CustomTabs.js @@ -0,0 +1,101 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Tabs, Tab, Typography } from '@material-ui/core'; + +const styles = theme => ({ + root: { + flexGrow: 1, + backgroundColor: theme.palette.background.paper, + }, + tabsRoot: { + borderBottom: '1px solid #e8e8e8', + }, + tabsIndicator: { + backgroundColor: '#1890ff', + }, + tabRoot: { + textTransform: 'initial', + minWidth: 64, + [theme.breakpoints.up('sm')]: { + minWidth: 72, + }, + fontWeight: theme.typography.fontWeightRegular, + marginRight: theme.spacing(4), + fontFamily: [ + '-apple-system', + 'BlinkMacSystemFont', + '"Segoe UI"', + 'Roboto', + '"Helvetica Neue"', + 'Arial', + 'sans-serif', + '"Apple Color Emoji"', + '"Segoe UI Emoji"', + '"Segoe UI Symbol"', + ].join(','), + '&:hover': { + color: '#40a9ff', + opacity: 1, + }, + '&$tabSelected': { + color: '#1890ff', + fontWeight: theme.typography.fontWeightMedium, + }, + '&:focus': { + color: '#40a9ff', + }, + }, + tabSelected: {}, + typography: { + padding: theme.spacing(3), + }, +}); + +class CustomTabs extends React.Component { + state = { + value: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { classes } = this.props; + const { value } = this.state; + + return ( + <div className={classes.root}> + <Tabs + value={value} + onChange={this.handleChange} + classes={{ root: classes.tabsRoot, indicator: classes.tabsIndicator }} + > + <Tab + disableRipple + classes={{ root: classes.tabRoot, selected: classes.tabSelected }} + label="Tab 1" + /> + <Tab + disableRipple + classes={{ root: classes.tabRoot, selected: classes.tabSelected }} + label="Tab 2" + /> + <Tab + disableRipple + classes={{ root: classes.tabRoot, selected: classes.tabSelected }} + label="Tab 3" + /> + </Tabs> + <Typography className={classes.typography}>powered by Material-UI</Typography> + </div> + ); + } +} + +CustomTabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(CustomTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/DisabledTab.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/DisabledTab.js new file mode 100644 index 0000000..17808a1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/DisabledTab.js @@ -0,0 +1,31 @@ +import React from 'react'; +import { Paper, Tabs, Tab } from '@material-ui/core'; + +class DisabledTab extends React.Component { + state = { + value: 2, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + return ( + <Paper> + <Tabs + value={this.state.value} + indicatorColor="primary" + textColor="primary" + onChange={this.handleChange} + > + <Tab label="Active" /> + <Tab label="Disabled" disabled /> + <Tab label="Active" /> + </Tabs> + </Paper> + ); + } +} + +export default DisabledTab; diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/FixedTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/FixedTabs.js new file mode 100644 index 0000000..f64240f --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/FixedTabs.js @@ -0,0 +1,80 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import SwipeableViews from 'react-swipeable-views'; +import { AppBar, Tabs, Tab, Typography } from '@material-ui/core'; + +function TabContainer({ children, dir }) { + return ( + <Typography component="div" dir={dir} style={{ padding: 8 * 3 }}> + {children} + </Typography> + ); +} + +TabContainer.propTypes = { + children: PropTypes.node.isRequired, + dir: PropTypes.string.isRequired, +}; + +const styles = theme => ({ + root: { + backgroundColor: theme.palette.background.paper, + [theme.breakpoints.up('sm')]: { + width: 500, + }, + margin: '10px auto' + }, +}); + +class FixedTabs extends React.Component { + state = { + value: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + handleChangeIndex = index => { + this.setState({ value: index }); + }; + + render() { + const { classes, theme } = this.props; + + return ( + <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> + </div> + ); + } +} + +FixedTabs.propTypes = { + classes: PropTypes.object.isRequired, + theme: PropTypes.object.isRequired, +}; + +export default withStyles(styles, { withTheme: true })(FixedTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/IconTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/IconTabs.js new file mode 100644 index 0000000..ff97d16 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/IconTabs.js @@ -0,0 +1,61 @@ +import React from 'react'; +import PhoneIcon from '@material-ui/icons/Phone'; +import FavoriteIcon from '@material-ui/icons/Favorite'; +import PersonPinIcon from '@material-ui/icons/PersonPin'; +import { Paper, Grid, Tabs, Tab, Typography } from '@material-ui/core'; + +export default class IconTabs extends React.Component { + state = { + value: 0, + value2: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + handleChange2 = (event, value2) => { + this.setState({ value2 }); + }; + + render() { + return ( + <div> + <Grid container spacing={3}> + <Grid item md={6} xs={12}> + <Typography variant="button" gutterBottom>Without Text</Typography> + <Paper> + <Tabs + value={this.state.value2} + onChange={this.handleChange2} + variant="fullWidth" + indicatorColor="primary" + textColor="primary" + > + <Tab icon={<PhoneIcon />} /> + <Tab icon={<FavoriteIcon />} /> + <Tab icon={<PersonPinIcon />} /> + </Tabs> + </Paper> + </Grid> + <Grid item md={6} xs={12}> + <Typography variant="button" gutterBottom>With Text</Typography> + <Paper> + <Tabs + value={this.state.value} + onChange={this.handleChange} + variant="fullWidth" + indicatorColor="secondary" + textColor="secondary" + > + <Tab icon={<PhoneIcon />} label="RECENTS" /> + <Tab icon={<FavoriteIcon />} label="FAVORITES" /> + <Tab icon={<PersonPinIcon />} label="NEARBY" /> + </Tabs> + </Paper> + </Grid> + </Grid> + </div> + ); + } +} diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/LongTextTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/LongTextTabs.js new file mode 100644 index 0000000..724ac03 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/LongTextTabs.js @@ -0,0 +1,59 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { AppBar, Tabs, Tab, Typography } from '@material-ui/core'; + +function TabContainer(props) { + return ( + <Typography component="div" style={{ padding: 8 * 3 }}> + {props.children} + </Typography> + ); +} + +TabContainer.propTypes = { + children: PropTypes.node.isRequired, +}; + +const styles = theme => ({ + root: { + flexGrow: 1, + backgroundColor: theme.palette.background.paper, + }, +}); + +class LongTextTabs extends React.Component { + state = { + value: 'one', + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { classes } = this.props; + const { value } = this.state; + + return ( + <div className={classes.root}> + <AppBar position="static"> + <Tabs value={value} onChange={this.handleChange}> + <Tab value="one" label="New Arrivals in the Longest Text of Nonfiction" /> + <Tab value="two" label="Item Two" /> + <Tab value="three" label="Item Three" /> + </Tabs> + </AppBar> + {value === 'one' && <TabContainer>Item One</TabContainer>} + {value === 'two' && <TabContainer>Item Two</TabContainer>} + {value === 'three' && <TabContainer>Item Three</TabContainer>} + </div> + ); + } +} + +LongTextTabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(LongTextTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/ScrollIconTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/ScrollIconTabs.js new file mode 100644 index 0000000..98f52d2 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/ScrollIconTabs.js @@ -0,0 +1,82 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import PhoneIcon from '@material-ui/icons/Phone'; +import FavoriteIcon from '@material-ui/icons/Favorite'; +import PersonPinIcon from '@material-ui/icons/PersonPin'; +import HelpIcon from '@material-ui/icons/Help'; +import ShoppingBasket from '@material-ui/icons/ShoppingBasket'; +import ThumbDown from '@material-ui/icons/ThumbDown'; +import ThumbUp from '@material-ui/icons/ThumbUp'; +import { AppBar, Tabs, Tab, Typography } from '@material-ui/core'; + +function TabContainer(props) { + return ( + <Typography component="div" style={{ padding: 8 * 3 }}> + {props.children} + </Typography> + ); +} + +TabContainer.propTypes = { + children: PropTypes.node.isRequired, +}; + +const styles = theme => ({ + root: { + flexGrow: 1, + width: '100%', + backgroundColor: theme.palette.background.paper, + }, +}); + +class ScrollIconTabs extends React.Component { + state = { + value: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { classes } = this.props; + const { value } = this.state; + + return ( + <div className={classes.root}> + <AppBar position="static" color="default"> + <Tabs + value={value} + onChange={this.handleChange} + variant="scrollable" + scrollButtons="on" + indicatorColor="primary" + textColor="secondary" + > + <Tab label="Item One" icon={<PhoneIcon />} /> + <Tab label="Item Two" icon={<FavoriteIcon />} /> + <Tab label="Item Three" icon={<PersonPinIcon />} /> + <Tab label="Item Four" icon={<HelpIcon />} /> + <Tab label="Item Five" icon={<ShoppingBasket />} /> + <Tab label="Item Six" icon={<ThumbDown />} /> + <Tab label="Item Seven" icon={<ThumbUp />} /> + </Tabs> + </AppBar> + {value === 0 && <TabContainer>Item One</TabContainer>} + {value === 1 && <TabContainer>Item Two</TabContainer>} + {value === 2 && <TabContainer>Item Three</TabContainer>} + {value === 3 && <TabContainer>Item Four</TabContainer>} + {value === 4 && <TabContainer>Item Five</TabContainer>} + {value === 5 && <TabContainer>Item Six</TabContainer>} + {value === 6 && <TabContainer>Item Seven</TabContainer>} + </div> + ); + } +} + +ScrollIconTabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ScrollIconTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/ScrollTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/ScrollTabs.js new file mode 100644 index 0000000..f7f9477 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/ScrollTabs.js @@ -0,0 +1,75 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { AppBar, Tabs, Tab, Typography } from '@material-ui/core'; + +function TabContainer(props) { + return ( + <Typography component="div" style={{ padding: 8 * 3 }}> + {props.children} + </Typography> + ); +} + +TabContainer.propTypes = { + children: PropTypes.node.isRequired, +}; + +const styles = theme => ({ + root: { + flexGrow: 1, + width: '100%', + backgroundColor: theme.palette.background.paper, + }, +}); + +class ScrollTabs extends React.Component { + state = { + value: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { classes } = this.props; + const { value } = this.state; + + return ( + <div className={classes.root}> + <AppBar position="static" color="default"> + <Tabs + value={value} + onChange={this.handleChange} + indicatorColor="secondary" + textColor="secondary" + variant="scrollable" + scrollButtons="auto" + > + <Tab label="Item One" /> + <Tab label="Item Two" /> + <Tab label="Item Three" /> + <Tab label="Item Four" /> + <Tab label="Item Five" /> + <Tab label="Item Six" /> + <Tab label="Item Seven" /> + </Tabs> + </AppBar> + {value === 0 && <TabContainer>Item One</TabContainer>} + {value === 1 && <TabContainer>Item Two</TabContainer>} + {value === 2 && <TabContainer>Item Three</TabContainer>} + {value === 3 && <TabContainer>Item Four</TabContainer>} + {value === 4 && <TabContainer>Item Five</TabContainer>} + {value === 5 && <TabContainer>Item Six</TabContainer>} + {value === 6 && <TabContainer>Item Seven</TabContainer>} + </div> + ); + } +} + +ScrollTabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ScrollTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tabs/SimpleTabs.js b/front/odiparpack/app/containers/UiElements/demos/Tabs/SimpleTabs.js new file mode 100644 index 0000000..fd791cc --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tabs/SimpleTabs.js @@ -0,0 +1,59 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { AppBar, Tabs, Tab, Typography } from '@material-ui/core'; + +function TabContainer(props) { + return ( + <Typography component="div" style={{ padding: 8 * 3 }}> + {props.children} + </Typography> + ); +} + +TabContainer.propTypes = { + children: PropTypes.node.isRequired, +}; + +const styles = theme => ({ + root: { + flexGrow: 1, + backgroundColor: theme.palette.background.paper, + }, +}); + +class SimpleTabs extends React.Component { + state = { + value: 0, + }; + + handleChange = (event, value) => { + this.setState({ value }); + }; + + render() { + const { classes } = this.props; + const { value } = this.state; + + return ( + <div className={classes.root}> + <AppBar position="static"> + <Tabs value={value} onChange={this.handleChange}> + <Tab label="Item One" /> + <Tab label="Item Two" /> + <Tab label="Item Three" href="#basic-tabs" /> + </Tabs> + </AppBar> + {value === 0 && <TabContainer>Item One</TabContainer>} + {value === 1 && <TabContainer>Item Two</TabContainer>} + {value === 2 && <TabContainer>Item Three</TabContainer>} + </div> + ); + } +} + +SimpleTabs.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(SimpleTabs); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tags/ArrayTags.js b/front/odiparpack/app/containers/UiElements/demos/Tags/ArrayTags.js new file mode 100644 index 0000000..921a668 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tags/ArrayTags.js @@ -0,0 +1,78 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import TagFacesIcon from '@material-ui/icons/TagFaces'; + +import { Avatar, Chip, Paper } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + justifyContent: 'center', + flexWrap: 'wrap', + padding: theme.spacing(0.5), + }, + chip: { + margin: theme.spacing(0.5), + }, +}); + +class ArrayTags extends React.Component { + state = { + chipData: [ + { key: 0, label: 'Angular' }, + { key: 1, label: 'jQuery' }, + { key: 2, label: 'Polymer' }, + { key: 3, label: 'React' }, + { key: 4, label: 'Vue.js' }, + ], + }; + + handleDelete = data => () => { + if (data.label === 'React') { + alert('Why would you want to delete React?! :)'); // eslint-disable-line no-alert + return; + } + + const chipData = [...this.state.chipData]; + const chipToDelete = chipData.indexOf(data); + chipData.splice(chipToDelete, 1); + this.setState({ chipData }); + }; + + render() { + const { classes } = this.props; + + return ( + <Paper className={classes.root}> + {this.state.chipData.map(data => { + let avatar = null; + + if (data.label === 'React') { + avatar = ( + <Avatar> + <TagFacesIcon className={classes.svgIcon} /> + </Avatar> + ); + } + + return ( + <Chip + key={data.key} + avatar={avatar} + label={data.label} + onDelete={this.handleDelete(data)} + className={classes.chip} + /> + ); + })} + </Paper> + ); + } +} + +ArrayTags.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ArrayTags); diff --git a/front/odiparpack/app/containers/UiElements/demos/Tags/BasicTags.js b/front/odiparpack/app/containers/UiElements/demos/Tags/BasicTags.js new file mode 100644 index 0000000..f2e3693 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Tags/BasicTags.js @@ -0,0 +1,72 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import FaceIcon from '@material-ui/icons/Face'; +import DoneIcon from '@material-ui/icons/Done'; + +import { Avatar, Chip } from '@material-ui/core'; + +const styles = theme => ({ + root: { + display: 'flex', + justifyContent: 'center', + flexWrap: 'wrap', + }, + chip: { + margin: theme.spacing(1), + }, +}); + +function handleDelete() { + alert('You clicked the delete icon.'); // eslint-disable-line no-alert +} + +function handleClick() { + alert('You clicked the Chip.'); // eslint-disable-line no-alert +} + +function BasicTags(props) { + const { classes } = props; + return ( + <div className={classes.root}> + <Chip label="Basic Tag" className={classes.chip} color="primary" /> + <Chip + avatar={<Avatar>MB</Avatar>} + label="Clickable Tag" + onClick={handleClick} + className={classes.chip} + color="primary" + /> + <Chip + avatar={<Avatar src="/images/pp_girl.svg" />} + label="Deletable Tag" + onDelete={handleDelete} + className={classes.chip} + /> + <Chip + avatar={( + <Avatar> + <FaceIcon /> + </Avatar> + )} + label="Clickable Deletable Tag" + onClick={handleClick} + onDelete={handleDelete} + className={classes.chip} + /> + <Chip + label="Custom delete icon Tag" + onClick={handleClick} + onDelete={handleDelete} + className={classes.chip} + deleteIcon={<DoneIcon />} + /> + </div> + ); +} + +BasicTags.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(BasicTags); diff --git a/front/odiparpack/app/containers/UiElements/demos/Typography/AlignTypo.js b/front/odiparpack/app/containers/UiElements/demos/Typography/AlignTypo.js new file mode 100644 index 0000000..38088a9 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Typography/AlignTypo.js @@ -0,0 +1,46 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Type from 'ba-styles/Typography.scss'; +import { Typography, Divider } from '@material-ui/core'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +class AlignTypo extends React.Component { + render() { + const { classes } = this.props; + return ( + <div> + <Typography variant="subtitle1" className={Type.textCenter} gutterBottom> + Align center: Nullam in + <span className={Type.bold}> tortor </span> + <span className={Type.italic}> ligula </span> + </Typography> + <Divider className={classes.divider} /> + <Typography variant="h5" className={Type.textLeft} gutterBottom> + Align Left + </Typography> + <Typography variant="h5" className={Type.textRight} gutterBottom> + Align Right + </Typography> + <Divider className={classes.divider} /> + <Typography variant="h4" className={Type.medium} gutterBottom>Justify Align</Typography> + <Typography gutterBottom className={Type.textJustify}> + Vestibulum faucibus eget erat eget pretium. Donec commodo convallis ligula, eget suscipit orci. Suspendisse potenti. + Nulla eget lobortis lacus. Aliquam venenatis magna et odio lobortis maximus. Nullam in tortor ligula. Proin maximus risus nunc, eu aliquam nibh tempus a. Interdum et malesuada fames ac ante ipsum primis in faucibus. + </Typography> + </div> + ); + } +} + +AlignTypo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(AlignTypo); diff --git a/front/odiparpack/app/containers/UiElements/demos/Typography/ColouredTypo.js b/front/odiparpack/app/containers/UiElements/demos/Typography/ColouredTypo.js new file mode 100644 index 0000000..b7b1516 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Typography/ColouredTypo.js @@ -0,0 +1,35 @@ +import React from 'react'; +import Type from 'ba-styles/Typography.scss'; +import { Typography } from '@material-ui/core'; + +class ColouredTypo extends React.Component { + render() { + return ( + <div> + <Typography variant="h5" className={Type.textInfo} gutterBottom> + Ut sed eros finibus + </Typography> + <Typography variant="body1" className={Type.textSuccess} gutterBottom> + Nulla eget lobortis lacus. Aliquam venenatis magna et odio lobortis maximus. + </Typography> + <Typography variant="h5" className={Type.textWarning} gutterBottom> + Aliquam nec ex aliquet + </Typography> + <Typography variant="h6" className={Type.textError} gutterBottom> + Aenean facilisis vitae purus facilisis semper + </Typography> + <Typography className={Type.textGreyDark} gutterBottom> + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse sed urna in justo euismod condimentum. + </Typography> + <Typography className={Type.textGrey} gutterBottom> + Vivamus et luctus mauris. Maecenas nisl libero, tincidunt id odio id, feugiat vulputate quam. + </Typography> + <Typography className={Type.textGreyLight} gutterBottom> + Curabitur egestas consequat lorem, vel fermentum augue porta id. + </Typography> + </div> + ); + } +} + +export default ColouredTypo; diff --git a/front/odiparpack/app/containers/UiElements/demos/Typography/GeneralTypo.js b/front/odiparpack/app/containers/UiElements/demos/Typography/GeneralTypo.js new file mode 100644 index 0000000..6a1079f --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Typography/GeneralTypo.js @@ -0,0 +1,139 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import classNames from 'classnames'; +import { withStyles } from '@material-ui/core/styles'; +import Type from 'ba-styles/Typography.scss'; +import { Typography, Divider } from '@material-ui/core'; + +const background = { + width: '100%', + maxWidth: 500, + background: + 'transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAICAYAAAA4GpVBAAAMKGlDQ1BJQ0MgUHJvZmlsZQAASMetl3dUU8kex+eWJCQktEAoUkJvovQqNbQIAlIFGyEJJJQYEoKKHRUVWAsqFqzoqoiiawFkURELtkWx9wUVFGVdLNhQeZME0PW998c75805c+dzfvc3v/n+7p2ZewcA9RiOWJyNagCQI8qTxIYFMSckpzBJHYACMKAFrIANhysVB8bERAJYhtp/lve3ACJvrzvIY4H/rWjy+FIuAEgM5DSelJsD+QgAuDtXLMkDgNAD7ebT88SQiVAl0JZAgZAt5JyhZE85pyk5UuETH8uCnAqACpXDkWQAoCbXxcznZsA4aqWQHUU8oQhyI2Q/roDDg/wF8sicnGmQ1W0g26T9ECfjHzHThmNyOBnDrMxFUVSChVJxNmcm+H+XnGzZ0BjmsFIFkvBYec7y55Y1LULOVMjnRWlR0ZC1IN8Q8hT+cu4SyMITBv0/cqUs+MwAAwCUyuMER0A2hGwmy0oIHGQ/jkTRF/qjKQWC+CRlfFQkmRY7GB8tEGVHRQ7GKRXw2UNcyZeGxA35pAtD2ZDhO0TrhXns+MGY5/OFiVGQ1SA/kGbFRQz2fVEgYEUNjyWLlWuG7xwDOdKhXDCLdElorNIfcxcI2VGD9sg8QXy4si82hctRaNCDnMmXTogc0sPjB4co9WCFfFHCoE6sTJwXFDvov1OcHTPojzXys8PkdjPIrdL8uKG+vXlwsilzwUEmZ2yMclxcW5wXE6/UhjNBJGCBYMAEMljTwDSQCYStPXU9YOhOKOAACcgAfOAwaBnqkaS4I4LXOFAA/oLEB9LhfkGKu3yQD+1fh63KqwNIV9zNV/TIAl2Qc3AD3A/3wSPhNQBWZ9wT9xrqx1QfGpUYQgwmhhNDibZThYWSn+IyARdmkA2rBETAlg+zkmsQDWn/HofQRWgjPCbcJLQT7oJE8BT6Cf8tw+/RhMO2caAdRg0dzC7tx+xwK6jaDQ/CfaF+qB1n4AbAAXeFmQTi/jA3N2j9/tT+k3bZkGqyIxkl65IDyDY/+6nZqbkN95Hn9qNOpa604UxYw3d+Ho31Q2482Eb87IktxQ5jLdgp7ALWiNUBJnYSq8cuY8flPDw3nirmxtBosQo9WTCOcMjHsdqx2/HLT2NzBseXKN4/yOPPyJMvHNY08UyJMEOQxwyEuzWfyRZxR41kOjs6eQAg3/uVW8tbhmJPRxgXv9sK3wHgyxsYGGj8bouEa/LIYgAoXd9t1ifgctYF4HwJVybJV9pw+YUAvyrqcKXoA2O4d9nAjJyBO/ABASAEjAXRIB4kgynwOQtADlQ9HcwGC0ARKAErwVqwEWwFO8AesB8cAnWgEZwC58AlcBXcBPfhXOkEL0EveA/6EQQhITSEjugjJoglYo84I56IHxKCRCKxSDKSimQgIkSGzEYWIiVIGbIR2Y5UIb8hx5BTyAWkDbmLdCDdyBvkM4qhVFQbNUKt0NGoJxqIRqDx6GQ0A81FC9BF6HJ0PVqJ7kNr0VPoJfQm2o6+RPswgKliDMwUc8A8MRYWjaVg6ZgEm4sVY+VYJVaDNcA3fR1rx3qwTzgRp+NM3AHO13A8AefiufhcvBTfiO/Ba/Ez+HW8A+/FvxFoBEOCPcGbwCZMIGQQphOKCOWEXYSjhLNwTXUS3hOJRAbRmugB12oyMZM4i1hK3Ew8QGwithGfEPtIJJI+yZ7kS4omcUh5pCLSBtI+0knSNVIn6aOKqoqJirNKqEqKikilUKVcZa/KCZVrKs9U+skaZEuyNzmazCPPJK8g7yQ3kK+QO8n9FE2KNcWXEk/JpCygrKfUUM5SHlDeqqqqmql6qY5XFarOV12velD1vGqH6ieqFtWOyqJOosqoy6m7qU3Uu9S3NBrNihZAS6Hl0ZbTqminaY9oH9XoaqPU2Go8tXlqFWq1atfUXqmT1S3VA9WnqBeol6sfVr+i3qNB1rDSYGlwNOZqVGgc07it0adJ13TSjNbM0SzV3Kt5QfO5FknLSitEi6e1SGuH1mmtJ3SMbk5n0bn0hfSd9LP0Tm2itrU2WztTu0R7v3ardq+Olo6rTqLODJ0KneM67QyMYcVgM7IZKxiHGLcYn3WNdAN1+brLdGt0r+l+0BuhF6DH1yvWO6B3U++zPlM/RD9Lf5V+nf5DA9zAzmC8wXSDLQZnDXpGaI/wGcEdUTzi0Ih7hqihnWGs4SzDHYaXDfuMjI3CjMRGG4xOG/UYM4wDjDON1xifMO42oZv4mQhN1picNHnB1GEGMrOZ65lnmL2mhqbhpjLT7aatpv1m1mYJZoVmB8wemlPMPc3TzdeYN5v3WphYjLOYbVFtcc+SbOlpKbBcZ9li+cHK2irJaolVndVzaz1rtnWBdbX1Axuajb9Nrk2lzQ1boq2nbZbtZturdqidm53ArsLuij1q724vtN9s3zaSMNJrpGhk5cjbDlSHQId8h2qHjlGMUZGjCkfVjXo12mJ0yuhVo1tGf3N0c8x23Ol430nLaaxToVOD0xtnO2euc4XzDReaS6jLPJd6l9eu9q581y2ud9zobuPclrg1u31193CXuNe4d3tYeKR6bPK47antGeNZ6nnei+AV5DXPq9Hrk7e7d573Ie+/fRx8snz2+jwfYz2GP2bnmCe+Zr4c3+2+7X5Mv1S/bX7t/qb+HP9K/8cB5gG8gF0BzwJtAzMD9wW+CnIMkgQdDfrA8mbNYTUFY8FhwcXBrSFaIQkhG0MehZqFZoRWh/aGuYXNCmsKJ4RHhK8Kv802YnPZVezesR5j54w9E0GNiIvYGPE40i5SEtkwDh03dtzqcQ+iLKNEUXXRIJodvTr6YYx1TG7M7+OJ42PGV4zvinWKnR3bEkePmxq3N+59fFD8ivj7CTYJsoTmRPXESYlViR+SgpPKktonjJ4wZ8KlZINkYXJ9CiklMWVXSt/EkIlrJ3ZOcptUNOnWZOvJMyZfmGIwJXvK8anqUzlTD6cSUpNS96Z+4URzKjl9aey0TWm9XBZ3HfclL4C3htfN9+WX8Z+l+6aXpT/P8M1YndEt8BeUC3qELOFG4evM8MytmR+yorN2Zw1kJ2UfyFHJSc05JtISZYnOTDOeNmNam9heXCRuz/XOXZvbK4mQ7JIi0snS+jxt+JN9WWYjWyzryPfLr8j/OD1x+uEZmjNEMy7PtJu5bOazgtCCX2fhs7izmmebzl4wu2NO4Jztc5G5aXOb55nPWzSvc37Y/D0LKAuyFvxR6FhYVvhuYdLChkVGi+YverI4bHF1kVqRpOj2Ep8lW5fiS4VLW5e5LNuw7Fsxr/hiiWNJecmXUm7pxV+cfln/y8Dy9OWtK9xXbFlJXClaeWuV/6o9ZZplBWVPVo9bXbuGuaZ4zbu1U9deKHct37qOsk62rn195Pr6DRYbVm74slGw8WZFUMWBTYablm36sJm3+dqWgC01W422lmz9vE247c72sO21lVaV5TuIO/J3dO1M3Nnyq+evVbsMdpXs+rpbtLt9T+yeM1UeVVV7DfeuqEarZdXd+ybtu7o/eH99jUPN9gOMAyUHwUHZwRe/pf5261DEoebDnodrjlge2XSUfrS4FqmdWdtbJ6hrr0+ubzs29lhzg0/D0d9H/b670bSx4rjO8RUnKCcWnRg4WXCyr0nc1HMq49ST5qnN909POH3jzPgzrWcjzp4/F3rudEtgy8nzvucbL3hfOHbR82LdJfdLtZfdLh/9w+2Po63urbVXPK7UX/W62tA2pu3ENf9rp64HXz93g33j0s2om223Em7duT3pdvsd3p3nd7Pvvr6Xf6///vwHhAfFDzUelj8yfFT5p+2fB9rd2493BHdcfhz3+P4T7pOXT6VPv3Qu6qJ1lT8zeVb13Pl5Y3do99UXE190vhS/7O8p+kvzr02vbF4d+Tvg78u9E3o7X0teD7wpfav/dvc713fNfTF9j97nvO//UPxR/+OeT56fWj4nfX7WP/0L6cv6r7ZfG75FfHswkDMwIOZIOIpfAQxWND0dgDe7AaAlA0C/Cv8fJirPZoqCKM+TCgL/jZXnN0VxB6AGNvLfcFYTAAdhtZoPYwcAIP8djw8AqIvLcB0s0nQXZ2UsKjzhED4ODLw1AoDUAMBXycBA/+aBga87odi7ADTlKs+E8iI/g25zldM1Rvb2n89m/wJHBnEU5n9PrQAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAAd0SU1FB+EKBRI2IMFyTLcAAAAaSURBVAjXY/h++dF/hl+/fv1nYmBgYMBJAAAKEQellAoQBwAAAABJRU5ErkJggg==)', // eslint-disable-line max-len +}; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +class GeneralTypo extends React.Component { + render() { + const { classes } = this.props; + return ( + <div style={background}> + <Typography variant="h4" gutterBottom> + Lorem ipsum dolor + {' '} + <span className={Type.bold}>sit amet</span> + </Typography> + <Typography variant="subtitle1" gutterBottom> + Duis tristique metus magna, lobortis aliquam risus euismod sit amet. + </Typography> + <Typography variant="subtitle1" gutterBottom> + Nullam in + <span className={Type.bold}> tortor </span> + <span className={Type.italic}> ligula </span> + </Typography> + <Divider className={classes.divider} /> + <Typography variant="h5" gutterBottom> + <span className={Type.bolder}>Bolder</span> + + <span className={Type.bold}>Bold</span> + + <span className={Type.medium}>Medium</span> + + <br /> + <span className={Type.regular}>Regular</span> + + <span className={Type.light}>Light</span> + + <span className={Type.lighter}>Lighter</span> + + </Typography> + <Typography gutterBottom> + Duis tristique metus magna, lobortis aliquam risus euismod sit amet. Suspendisse porttitor velit nisl, feugiat tincidunt nisl mattis ut. Nulla lobortis nunc vitae nisi semper semper. + {' '} + <br /> + Nulla eget lobortis lacus. Aliquam venenatis magna et odio lobortis maximus. Nullam in tortor ligula. Proin maximus risus nunc, eu aliquam nibh tempus a. Interdum et malesuada fames ac ante ipsum primis in faucibus. + </Typography> + <Divider className={classes.divider} /> + <Typography variant="h4" className={classNames(Type.light, Type.uppercase)} gutterBottom> + Vestibulum nec mi + {' '} + <span className={Type.bolder}>suscipit</span> + </Typography> + <Typography variant="body1" className={Type.lowercase} gutterBottom> + <span className={Type.bolder}>Bolder</span> + + <span className={Type.bold}>Bold</span> + + <span className={Type.medium}>Medium</span> + + <span className={Type.regular}>Regular</span> + + <span className={Type.light}>Light</span> + + <span className={Type.lighter}>Lighter</span> + + </Typography> + <Typography gutterBottom className={Type.uppercase}> + Vestibulum faucibus eget erat eget pretium. Donec commodo convallis ligula, eget suscipit orci. Suspendisse potenti. + <br /> + Curabitur egestas consequat lorem, vel fermentum augue porta id. Aliquam lobortis magna neque, gravida consequat velit venenatis at. Duis sed augue leo. Phasellus ante massa, aliquam non ante at, suscipit ornare ipsum. Quisque a consequat ante, at volutpat enim. + </Typography> + <Divider className={classes.divider} /> + <Typography variant="h6" className={Type.lighter} gutterBottom> + <span className={Type.bold}>Numbers</span> + {' '} +looks great! 1234 + <span className={classNames(Type.bold, Type.italic, Type.underline)}>56</span> +7890 + </Typography> + <Typography variant="h6" className={Type.regular} gutterBottom> + Let your Creativity Flow + {' '} + <span className={Type.bold}> +123 + <sup>$</sup> + </span> + </Typography> + <Typography variant="h6" className={Type.Bold} gutterBottom> + Numerics + {' '} + <span className={Type.light}> +123 + <sup className={Type.italic}>00</sup> + </span> + </Typography> + <Divider className={classes.divider} /> + <Typography variant="body1" gutterBottom> + Body 2 + </Typography> + <Typography variant="body1" gutterBottom align="right"> + Body 1 + </Typography> + <Typography variant="caption" gutterBottom align="center"> + Caption + </Typography> + <Typography gutterBottom noWrap> + {` + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + `} + </Typography> + <Typography variant="button" gutterBottom> + Button + </Typography> + </div> + ); + } +} + +GeneralTypo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(GeneralTypo); diff --git a/front/odiparpack/app/containers/UiElements/demos/Typography/Heading.js b/front/odiparpack/app/containers/UiElements/demos/Typography/Heading.js new file mode 100644 index 0000000..cf97396 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Typography/Heading.js @@ -0,0 +1,56 @@ +import React from 'react'; +import { Typography } from '@material-ui/core'; + +class Heading extends React.Component { + render() { + return ( + <div> + {/* <Typography variant="h1" gutterBottom> + Disp 4 + </Typography> + <Typography variant="h2" gutterBottom> + Display 3 + </Typography> + <Typography variant="h3" gutterBottom> + Display 2 + </Typography> + <Typography variant="h4" gutterBottom> + Display 1 + </Typography> + <Typography variant="h5" gutterBottom> + Headline + </Typography> + <Typography variant="h6" gutterBottom> + Title + </Typography> + <Typography variant="subtitle1" gutterBottom> + Subheading + </Typography> + <Typography gutterBottom noWrap> + {` + Lorem ipsum dolor sit amet, consectetur adipisicing elit, + sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. + `} + </Typography> */} + <Typography variant="h4"> + {`h4 Título`} + </Typography> + + <Typography variant="h5"> + {`h5 Subtítulos`} + </Typography> + + <Typography variant="h6"> + {`h6 Título de tablas`} + </Typography> + + <Typography> + {` Cuerpo de texto `} + </Typography> + + </div> + ); + } +} + +export default Heading; diff --git a/front/odiparpack/app/containers/UiElements/demos/Typography/ListTypo.js b/front/odiparpack/app/containers/UiElements/demos/Typography/ListTypo.js new file mode 100644 index 0000000..2f76ff1 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Typography/ListTypo.js @@ -0,0 +1,71 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import Type from 'ba-styles/Typography.scss'; +import { Typography, Divider } from '@material-ui/core'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +class ListTypo extends React.Component { + render() { + const { classes } = this.props; + return ( + <div> + <Typography variant="button" className={classes.divider}>Unordered List</Typography> + <div> + <ul className={Type.list}> + <li>Lorem ipsum dolor sit amet</li> + <li>Consectetur adipiscing elit</li> + <li>Integer molestie lorem at massa</li> + <li>Facilisis in pretium nisl aliquet</li> + <li> +Nulla volutpat aliquam velit + <ul> + <li>Phasellus iaculis neque</li> + <li>Purus sodales ultricies</li> + <li>Vestibulum laoreet porttitor sem</li> + <li>Ac tristique libero volutpat at</li> + </ul> + </li> + <li>Faucibus porta lacus fringilla vel</li> + <li>Aenean sit amet erat nunc</li> + <li>Eget porttitor lorem</li> + </ul> + </div> + <Divider className={classes.divider} /> + <Typography variant="button" className={classes.divider}>Ordered List</Typography> + <div> + <ul className={Type.orderedlist}> + <li>Lorem ipsum dolor sit amet</li> + <li>Consectetur adipiscing elit</li> + <li>Integer molestie lorem at massa</li> + <li>Facilisis in pretium nisl aliquet</li> + <li> +Nulla volutpat aliquam velit + <ul> + <li>Phasellus iaculis neque</li> + <li>Purus sodales ultricies</li> + <li>Vestibulum laoreet porttitor sem</li> + <li>Ac tristique libero volutpat at</li> + </ul> + </li> + <li>Faucibus porta lacus fringilla vel</li> + <li>Aenean sit amet erat nunc</li> + <li>Eget porttitor lorem</li> + </ul> + </div> + </div> + ); + } +} + +ListTypo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(ListTypo); diff --git a/front/odiparpack/app/containers/UiElements/demos/Typography/QuotesDemo.js b/front/odiparpack/app/containers/UiElements/demos/Typography/QuotesDemo.js new file mode 100644 index 0000000..afd9197 --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/Typography/QuotesDemo.js @@ -0,0 +1,33 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { withStyles } from '@material-ui/core/styles'; +import { Quote } from 'ba-components'; + +const styles = theme => ({ + divider: { + display: 'block', + margin: `${theme.spacing(3)}px 0`, + } +}); + +class QuotesDemo extends React.Component { + render() { + const { classes } = this.props; + return ( + <div> + <div className={classes.divider}> + <Quote align="left" content="Imagine all the people living life in peace. You may say I'm a dreamer, but I'm not the only one. I hope someday you'll join us, and the world will be as one." footnote="John Lennon" /> + </div> + <div className={classes.divider}> + <Quote align="right" content="A lot of people are afraid to say what they want. That's why they don't get what they want." footnote="Madonna" /> + </div> + </div> + ); + } +} + +QuotesDemo.propTypes = { + classes: PropTypes.object.isRequired, +}; + +export default withStyles(styles)(QuotesDemo); diff --git a/front/odiparpack/app/containers/UiElements/demos/index.js b/front/odiparpack/app/containers/UiElements/demos/index.js new file mode 100644 index 0000000..311d50e --- /dev/null +++ b/front/odiparpack/app/containers/UiElements/demos/index.js @@ -0,0 +1,117 @@ +// Badges +export CommonBadges from './Badges/CommonBadges'; +export VariantBadges from './Badges/VariantBadges'; +// Avatars +export AvatarsDemo from './Avatars/AvatarsDemo'; +export AvatarsPractice from './Avatars/AvatarsPractice'; +// Accordion +export SimpleAccordion from './Accordion/SimpleAccordion'; +export AdvancedAccordion from './Accordion/AdvancedAccordion'; +export ControlledAccordion from './Accordion/ControlledAccordion'; +// List +export ListBasic from './List/ListBasic'; +export ListControl from './List/ListControl'; +export ListMenu from './List/ListMenu'; +export ListInteractive from './List/ListInteractive'; +export PinnedList from './List/PinnedList'; +// Popover & Tooltip +export SimpleTooltips from './PopoverTooltip/SimpleTooltips'; +export PositionedTooltips from './PopoverTooltip/PositionedTooltips'; +export SimplePopover from './PopoverTooltip/SimplePopover'; +export PopoverPlayground from './PopoverTooltip/PopoverPlayground'; +export DelayTooltips from './PopoverTooltip/DelayTooltips'; +export TransitionsTooltips from './PopoverTooltip/TransitionsTooltips'; +export TriggersTooltips from './PopoverTooltip/TriggersTooltips'; +export CustomizedTooltips from './PopoverTooltip/CustomizedTooltips'; +// Notification +export SimpleNotif from './Notification/SimpleNotif'; +export StyledNotif from './Notification/StyledNotif'; +export TransitionNotif from './Notification/TransitionNotif'; +export MobileNotif from './Notification/MobileNotif'; +// Typography +export GeneralTypo from './Typography/GeneralTypo'; +export Heading from './Typography/Heading'; +export ListTypo from './Typography/ListTypo'; +export ColouredTypo from './Typography/ColouredTypo'; +export QuotesDemo from './Typography/QuotesDemo'; +export AlignTypo from './Typography/AlignTypo'; +// Tabs +export SimpleTabs from './Tabs/SimpleTabs'; +export LongTextTabs from './Tabs/LongTextTabs'; +export FixedTabs from './Tabs/FixedTabs'; +export CenteredTabs from './Tabs/CenteredTabs'; +export IconTabs from './Tabs/IconTabs'; +export ScrollTabs from './Tabs/ScrollTabs'; +export ScrollIconTabs from './Tabs/ScrollIconTabs'; +export DisabledTab from './Tabs/DisabledTab'; +export CustomTabs from './Tabs/CustomTabs'; +export BottomNav from './Tabs/BottomNav'; +// Card +export StandardCards from './Cards/StandardCards'; +export ControlCards from './Cards/ControlCards'; +export PaperSheet from './Cards/PaperSheet'; +export SocialCards from './Cards/SocialCards'; +export EcommerceCards from './Cards/EcommerceCards'; +// Image Grid +export ImageGridList from './ImageGrid/ImageGridList'; +export TitlebarGridList from './ImageGrid/TitlebarGridList'; +export AdvancedGridList from './ImageGrid/AdvancedGridList'; +export SingleLineGridList from './ImageGrid/SingleLineGridList'; +// Progress +export CircularIndeterminate from './Progress/CircularIndeterminate'; +export CircularIntegration from './Progress/CircularIntegration'; +export CircularDeterminate from './Progress/CircularDeterminate'; +export CircularStatic from './Progress/CircularStatic'; +export LinearIndeterminate from './Progress/LinearIndeterminate'; +export LinearDeterminate from './Progress/LinearDeterminate'; +export LinearBuffer from './Progress/LinearBuffer'; +export LinearQuery from './Progress/LinearQuery'; +export LinearStatic from './Progress/LinearStatic'; +export ProgressDelay from './Progress/ProgressDelay'; +// Dialog +export ModalDemo from './DialogModal/ModalDemo'; +export AlertDialog from './DialogModal/AlertDialog'; +export SelectDialog from './DialogModal/SelectDialog'; +export SelectRadioDialog from './DialogModal/SelectRadioDialog'; +export FormDialog from './DialogModal/FormDialog'; +export FullScreenDialog from './DialogModal/FullScreenDialog'; +export ImagePopup from './DialogModal/ImagePopup'; +export ScrollDialog from './DialogModal/ScrollDialog'; +// Steppers +export HorizontalLinear from './Steppers/HorizontalLinear'; +export HorizontalNonLinear from './Steppers/HorizontalNonLinear'; +export StepperError from './Steppers/StepperError'; +export VerticalStepper from './Steppers/VerticalStepper'; +export MobileSteppers from './Steppers/MobileSteppers'; +export StepperCarousel from './Steppers/StepperCarousel'; +// Menu and Drawer +export TemporaryDrawer from './DrawerMenu/TemporaryDrawer'; +export PermanentDrawer from './DrawerMenu/PermanentDrawer'; +export PersistentDrawer from './DrawerMenu/PersistentDrawer'; +export SwipeDrawer from './DrawerMenu/SwipeDrawer'; +export MiniDrawer from './DrawerMenu/MiniDrawer'; +export BasicMenu from './DrawerMenu/BasicMenu'; +export DropdownMenu from './DrawerMenu/DropdownMenu'; +export MenuTransition from './DrawerMenu/MenuTransition'; +export StyledMenu from './DrawerMenu/StyledMenu'; +// Pagination +export TbPagination from './Pagination/TbPagination'; +export TbPaginationCustom from './Pagination/TbPaginationCustom'; +export GeneralPagination from './Pagination/GeneralPagination'; +// Breadcrumb +export ClassicBreadcrumbs from './Breadcrumbs/ClassicBreadcrumbs'; +export PaperBreadcrumbs from './Breadcrumbs/PaperBreadcrumbs'; +// Slider Carousel +export SingleCarousel from './SliderCaraousel/SingleCarousel'; +export MultipleCarousel from './SliderCaraousel/MultipleCarousel'; +export AutoplayCarousel from './SliderCaraousel/AutoplayCarousel'; +export ThumbnailCarousel from './SliderCaraousel/ThumbnailCarousel'; +export VerticalCarousel from './SliderCaraousel/VerticalCarousel'; +export CustomCarousel from './SliderCaraousel/CustomCarousel'; +export AnimatedSlider from './SliderCaraousel/AnimatedSlider'; +// Tags +export BasicTags from './Tags/BasicTags'; +export ArrayTags from './Tags/ArrayTags'; +// Dividers +export CommonDividers from './Dividers/CommonDividers'; +export SpecialDividers from './Dividers/SpecialDividers'; |
