From e13e630cd6e4fc0b1ff92098a28a770794c7bb9a Mon Sep 17 00:00:00 2001
From: gabrhr <73925454+gabrhr@users.noreply.github.com>
Date: Wed, 20 Apr 2022 10:19:29 -0500
Subject: =?UTF-8?q?A=C3=B1adir=20plantilla?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Base para front
---
.../app/components/Email/ComposeEmail.js | 65 +++++
.../app/components/Email/ComposeEmailForm.js | 262 +++++++++++++++++
.../odiparpack/app/components/Email/EmailHeader.js | 49 ++++
front/odiparpack/app/components/Email/EmailList.js | 314 +++++++++++++++++++++
.../app/components/Email/EmailSidebar.js | 162 +++++++++++
front/odiparpack/app/components/Email/email-jss.js | 238 ++++++++++++++++
6 files changed, 1090 insertions(+)
create mode 100644 front/odiparpack/app/components/Email/ComposeEmail.js
create mode 100644 front/odiparpack/app/components/Email/ComposeEmailForm.js
create mode 100644 front/odiparpack/app/components/Email/EmailHeader.js
create mode 100644 front/odiparpack/app/components/Email/EmailList.js
create mode 100644 front/odiparpack/app/components/Email/EmailSidebar.js
create mode 100644 front/odiparpack/app/components/Email/email-jss.js
(limited to 'front/odiparpack/app/components/Email')
diff --git a/front/odiparpack/app/components/Email/ComposeEmail.js b/front/odiparpack/app/components/Email/ComposeEmail.js
new file mode 100644
index 0000000..8d06ebd
--- /dev/null
+++ b/front/odiparpack/app/components/Email/ComposeEmail.js
@@ -0,0 +1,65 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import Add from '@material-ui/icons/Add';
+import { Fab, Tooltip } from '@material-ui/core';
+import ComposeEmailForm from './ComposeEmailForm';
+import FloatingPanel from '../Panel/FloatingPanel';
+import styles from './email-jss';
+
+
+class ComposeEmail extends React.Component {
+ render() {
+ const {
+ classes,
+ open,
+ closeForm,
+ sendEmail,
+ to,
+ subject,
+ validMail,
+ inputChange,
+ compose
+ } = this.props;
+ const branch = '';
+ return (
+
+
+ compose()} className={classes.addBtn}>
+
+
+
+
+
+
+
+ );
+ }
+}
+
+ComposeEmail.propTypes = {
+ classes: PropTypes.object.isRequired,
+ open: PropTypes.bool.isRequired,
+ to: PropTypes.string.isRequired,
+ subject: PropTypes.string.isRequired,
+ validMail: PropTypes.string.isRequired,
+ compose: PropTypes.func.isRequired,
+ closeForm: PropTypes.func.isRequired,
+ sendEmail: PropTypes.func.isRequired,
+ inputChange: PropTypes.func.isRequired,
+};
+
+export default withStyles(styles)(ComposeEmail);
diff --git a/front/odiparpack/app/components/Email/ComposeEmailForm.js b/front/odiparpack/app/components/Email/ComposeEmailForm.js
new file mode 100644
index 0000000..3620d4d
--- /dev/null
+++ b/front/odiparpack/app/components/Email/ComposeEmailForm.js
@@ -0,0 +1,262 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { Editor } from 'react-draft-wysiwyg';
+import { convertFromRaw, EditorState, convertToRaw } from 'draft-js';
+import draftToHtml from 'draftjs-to-html';
+import Dropzone from 'react-dropzone';
+import { withStyles } from '@material-ui/core/styles';
+import TextField from '@material-ui/core/TextField';
+import Attachment from '@material-ui/icons/Attachment';
+import FileIcon from '@material-ui/icons/Description';
+import ActionDelete from '@material-ui/icons/Delete';
+import Send from '@material-ui/icons/Send';
+import EditorStyle from 'ba-styles/TextEditor.scss';
+import css from 'ba-styles/Form.scss';
+import 'ba-styles/vendors/react-draft-wysiwyg/react-draft-wysiwyg.css';
+import { Button, Grid, Typography, Snackbar, IconButton } from '@material-ui/core';
+import isImage from '../Forms/helpers/helpers.js';
+import styles from './email-jss';
+
+
+const content = {
+ blocks: [{
+ key: '637gr',
+ text: 'Lorem ipsum dolor sit amet 😀',
+ type: 'unstyled',
+ depth: 0,
+ inlineStyleRanges: [],
+ entityRanges: [],
+ data: {}
+ }],
+ entityMap: {}
+};
+
+class ComposeEmailForm extends React.Component {
+ constructor(props) {
+ super(props);
+ const contentBlock = convertFromRaw(content);
+ if (contentBlock) {
+ const editorState = EditorState.createWithContent(contentBlock);
+ this.state = {
+ openSnackBar: false,
+ errorMessage: '',
+ files: [],
+ editorState,
+ emailContent: draftToHtml(convertToRaw(editorState.getCurrentContent())),
+ };
+ }
+ this.onDrop = this.onDrop.bind(this);
+ }
+
+ onDrop(filesVal) {
+ const { files } = this.state;
+ let oldFiles = files;
+ const filesLimit = 3;
+ oldFiles = oldFiles.concat(filesVal);
+ if (oldFiles.length > filesLimit) {
+ console.log('Cannot upload more than ' + filesLimit + ' items.');
+ } else {
+ this.setState({ files: oldFiles });
+ }
+ }
+
+ onEditorStateChange = editorState => {
+ this.setState({
+ editorState,
+ emailContent: draftToHtml(convertToRaw(editorState.getCurrentContent()))
+ });
+ };
+
+ onDropRejected() {
+ this.setState({
+ openSnackBar: true,
+ errorMessage: 'File too big, max size is 3MB',
+ });
+ }
+
+ handleRequestCloseSnackBar = () => {
+ this.setState({
+ openSnackBar: false,
+ });
+ };
+
+ handleRemove(file, fileIndex) {
+ const thisFiles = this.state.files;
+ // This is to prevent memory leaks.
+ window.URL.revokeObjectURL(file.preview);
+
+ thisFiles.splice(fileIndex, 1);
+ this.setState({ files: thisFiles });
+ }
+
+ handleSend = (to, subject, emailContent, files) => {
+ this.props.sendEmail(to, subject, emailContent, files);
+ this.setState({ emailContent: '', files: [] });
+ };
+
+ render() {
+ const {
+ classes,
+ closeForm,
+ to,
+ subject,
+ validMail,
+ inputChange
+ } = this.props;
+ const {
+ editorState,
+ emailContent,
+ files,
+ openSnackBar,
+ errorMessage,
+ } = this.state;
+ let dropzoneRef;
+ const deleteBtn = (file, index) => (
+
+
this.handleRemove(file, index)}>
+
+
+
+ );
+ const previews = filesArray => filesArray.map((file, index) => {
+ if (isImage(file)) {
+ const base64Img = URL.createObjectURL(file);
+ return (
+
+
+

+ {deleteBtn(file, index)}
+
+
{file.name}
+
+ );
+ }
+ return (
+
+
+
+
+ {deleteBtn(file, index)}
+
+
+
{file.name}
+
+ );
+ });
+ const fileSizeLimit = 3000000;
+ return (
+
+ );
+ }
+}
+
+ComposeEmailForm.propTypes = {
+ classes: PropTypes.object.isRequired,
+ to: PropTypes.string.isRequired,
+ subject: PropTypes.string.isRequired,
+ validMail: PropTypes.string.isRequired,
+ sendEmail: PropTypes.func.isRequired,
+ closeForm: PropTypes.func.isRequired,
+ inputChange: PropTypes.func.isRequired,
+};
+
+export default withStyles(styles)(ComposeEmailForm);
diff --git a/front/odiparpack/app/components/Email/EmailHeader.js b/front/odiparpack/app/components/Email/EmailHeader.js
new file mode 100644
index 0000000..eceb757
--- /dev/null
+++ b/front/odiparpack/app/components/Email/EmailHeader.js
@@ -0,0 +1,49 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import SearchIcon from '@material-ui/icons/Search';
+import MenuIcon from '@material-ui/icons/Menu';
+import { AppBar, Hidden, Toolbar, Typography, IconButton } from '@material-ui/core';
+import styles from './email-jss';
+
+
+class EmailHeader extends React.Component {
+ render() {
+ const { classes, search, handleDrawerToggle } = this.props;
+ return (
+
+
+
+
+ Email
+
+
+ handleDrawerToggle()}
+ className={classes.navIconHide}
+ >
+
+
+
+
+
+
+
+
search(event)} placeholder="Search Email" />
+
+
+
+
+ );
+ }
+}
+
+EmailHeader.propTypes = {
+ classes: PropTypes.object.isRequired,
+ search: PropTypes.func.isRequired,
+ handleDrawerToggle: PropTypes.func.isRequired,
+};
+
+export default withStyles(styles)(EmailHeader);
diff --git a/front/odiparpack/app/components/Email/EmailList.js b/front/odiparpack/app/components/Email/EmailList.js
new file mode 100644
index 0000000..1fc3507
--- /dev/null
+++ b/front/odiparpack/app/components/Email/EmailList.js
@@ -0,0 +1,314 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import Bookmark from '@material-ui/icons/Bookmark';
+import Delete from '@material-ui/icons/Delete';
+import ExpandMoreIcon from '@material-ui/icons/ExpandMore';
+import classNames from 'classnames';
+import Flag from '@material-ui/icons/Flag';
+import People from '@material-ui/icons/People';
+import QuestionAnswer from '@material-ui/icons/QuestionAnswer';
+import ReportIcon from '@material-ui/icons/Report';
+import LabelIcon from '@material-ui/icons/Label';
+import FileIcon from '@material-ui/icons/Description';
+import Download from '@material-ui/icons/CloudDownload';
+import StarBorder from '@material-ui/icons/StarBorder';
+import Star from '@material-ui/icons/Star';
+import {
+ List,
+ Typography,
+ ExpansionPanel,
+ ExpansionPanelDetails,
+ ExpansionPanelSummary,
+ ExpansionPanelActions,
+ Tooltip,
+ IconButton,
+ Avatar,
+ Button,
+ ListSubheader,
+ Menu,
+ MenuItem,
+ Divider,
+} from '@material-ui/core';
+import isImage from '../Forms/helpers/helpers.js';
+import styles from './email-jss';
+
+
+const ITEM_HEIGHT = 80;
+class EmailList extends React.Component {
+ state = {
+ anchorElOpt: null,
+ itemToMove: null
+ };
+
+ handleClickOpt = (event, item) => {
+ this.setState({
+ anchorElOpt: event.currentTarget,
+ itemToMove: item
+ });
+ };
+
+ handleCloseOpt = () => {
+ this.setState({ anchorElOpt: null });
+ };
+
+ handleMoveTo = (item, category) => {
+ this.props.moveTo(item, category);
+ this.setState({ anchorElOpt: null });
+ }
+
+ render() {
+ const {
+ classes,
+ emailData,
+ openMail,
+ filterPage,
+ keyword,
+ remove,
+ toggleStar,
+ reply
+ } = this.props;
+ const { anchorElOpt, itemToMove } = this.state;
+ /* Basic Filter */
+ const inbox = emailData.filter(item => item.get('category') !== 'sent' && item.get('category') !== 'spam');
+ const stared = emailData.filter(item => item.get('stared'));
+ const sent = emailData.filter(item => item.get('category') === 'sent');
+ const spam = emailData.filter(item => item.get('category') === 'spam');
+ /* Category Filter */
+ const updates = emailData.filter(item => item.get('category') === 'updates');
+ const social = emailData.filter(item => item.get('category') === 'social');
+ const forums = emailData.filter(item => item.get('category') === 'forums');
+ const promos = emailData.filter(item => item.get('category') === 'promos');
+ const getCategory = cat => {
+ switch (cat) {
+ case 'updates':
+ return (
+
+
+ {' '}
+Updates
+
+ );
+ case 'social':
+ return (
+
+
+ {' '}
+Social
+
+ );
+ case 'promos':
+ return (
+
+
+ {' '}
+Promos
+
+ );
+ case 'forums':
+ return (
+
+
+ {' '}
+Forums
+
+ );
+ default:
+ return false;
+ }
+ };
+ const attachmentPreview = filesArray => filesArray.map((file, index) => {
+ const base64File = URL.createObjectURL(file);
+ if (isImage(file)) {
+ return (
+
+
+
+
+
+
+
+

+
+
{file.name}
+
+ );
+ }
+ return (
+
+ );
+ });
+ const getEmail = dataArray => dataArray.map(mail => {
+ const renderHTML = { __html: mail.get('content') };
+ if (mail.get('subject').toLowerCase().indexOf(keyword) === -1) {
+ return false;
+ }
+ return (
+ openMail(mail)}>
+ }>
+
+
+ toggleStar(mail)} className={classes.starBtn}>{mail.get('stared') ? () : () }
+
+ {mail.get('category') !== 'spam'
+ ? (
)
+ : (
)
+ }
+
+ {mail.get('category') === 'sent' && ('To ')}
+ {mail.get('name')}
+ {mail.get('date')}
+
+
+
+ {mail.get('subject')}
+ {getCategory(mail.get('category'))}
+
+
+
+
+
+
+ {mail.get('category') !== 'sent' && (
+
+From
+ {mail.get('name')}
+ {' '}
+to me
+
+ )}
+
+
+
+ toggleStar(mail)}>{mail.get('stared') ? () : () }
+
+
+ this.handleClickOpt(event, mail)}
+ >
+
+
+
+
+ remove(mail)}>
+
+
+
+
+
{mail.get('subject')}
+
+
+
+ {attachmentPreview(mail.get('attachment'))}
+
+
+
+
+
+
+
+
+
+
+
+ );
+ });
+ const showEmail = category => {
+ switch (category) {
+ case 'inbox':
+ return getEmail(inbox);
+ case 'stared':
+ return getEmail(stared);
+ case 'sent':
+ return getEmail(sent);
+ case 'spam':
+ return getEmail(spam);
+ case 'updates':
+ return getEmail(updates);
+ case 'social':
+ return getEmail(social);
+ case 'promos':
+ return getEmail(promos);
+ case 'forums':
+ return getEmail(forums);
+ default:
+ return getEmail(inbox);
+ }
+ };
+ return (
+
+
+
+ {showEmail(filterPage)}
+
+ );
+ }
+}
+
+EmailList.propTypes = {
+ classes: PropTypes.object.isRequired,
+ emailData: PropTypes.object.isRequired,
+ openMail: PropTypes.func.isRequired,
+ moveTo: PropTypes.func.isRequired,
+ remove: PropTypes.func.isRequired,
+ toggleStar: PropTypes.func.isRequired,
+ reply: PropTypes.func.isRequired,
+ filterPage: PropTypes.string.isRequired,
+ keyword: PropTypes.string.isRequired,
+};
+
+export default withStyles(styles)(EmailList);
diff --git a/front/odiparpack/app/components/Email/EmailSidebar.js b/front/odiparpack/app/components/Email/EmailSidebar.js
new file mode 100644
index 0000000..1951de2
--- /dev/null
+++ b/front/odiparpack/app/components/Email/EmailSidebar.js
@@ -0,0 +1,162 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import InboxIcon from '@material-ui/icons/MoveToInbox';
+import SendIcon from '@material-ui/icons/Send';
+import ReportIcon from '@material-ui/icons/Report';
+import StarIcon from '@material-ui/icons/Star';
+import Flag from '@material-ui/icons/Flag';
+import People from '@material-ui/icons/People';
+import QuestionAnswer from '@material-ui/icons/QuestionAnswer';
+import LabelIcon from '@material-ui/icons/Label';
+import Add from '@material-ui/icons/Add';
+import {
+ Drawer,
+ List,
+ ListItem,
+ ListItemIcon,
+ ListItemText,
+ Hidden,
+ Button,
+ Divider,
+} from '@material-ui/core';
+import styles from './email-jss';
+
+
+const MenuList = props => {
+ const {
+ classes,
+ compose,
+ goto,
+ selected,
+ } = props;
+ return (
+
+
+
+
+
+ goto('inbox')}>
+
+
+
+
+
+ goto('stared')}>
+
+
+
+
+
+ goto('sent')}>
+
+
+
+
+
+ goto('spam')}>
+
+
+
+
+
+
+
+
+ goto('updates')}>
+
+
+
+
+
+ goto('social')}>
+
+
+
+
+
+ goto('promos')}>
+
+
+
+
+
+ goto('forums')}>
+
+
+
+
+
+
+
+ );
+};
+
+MenuList.propTypes = {
+ classes: PropTypes.object.isRequired,
+ compose: PropTypes.func.isRequired,
+ goto: PropTypes.func.isRequired,
+ selected: PropTypes.string.isRequired,
+};
+
+const MenuEmail = withStyles(styles)(MenuList);
+
+class EmailSidebar extends React.Component {
+ render() {
+ const {
+ classes,
+ compose,
+ goto,
+ selected,
+ handleDrawerToggle,
+ mobileOpen
+ } = this.props;
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+EmailSidebar.propTypes = {
+ classes: PropTypes.object.isRequired,
+ compose: PropTypes.func.isRequired,
+ goto: PropTypes.func.isRequired,
+ handleDrawerToggle: PropTypes.func.isRequired,
+ selected: PropTypes.string.isRequired,
+ mobileOpen: PropTypes.bool.isRequired,
+};
+
+export default withStyles(styles)(EmailSidebar);
diff --git a/front/odiparpack/app/components/Email/email-jss.js b/front/odiparpack/app/components/Email/email-jss.js
new file mode 100644
index 0000000..6775966
--- /dev/null
+++ b/front/odiparpack/app/components/Email/email-jss.js
@@ -0,0 +1,238 @@
+import { fade } from '@material-ui/core/styles/colorManipulator';
+import { red, orange, indigo as blue, cyan } from '@material-ui/core/colors';
+const drawerWidth = 240;
+const styles = theme => ({
+ iconRed: {
+ color: red[500]
+ },
+ iconOrange: {
+ color: orange[500]
+ },
+ iconBlue: {
+ color: blue[500]
+ },
+ iconCyan: {
+ color: cyan[500]
+ },
+ appBar: {
+ zIndex: 130,
+ background: theme.palette.secondary.main,
+ '& ::-webkit-input-placeholder': {
+ color: theme.palette.common.white
+ },
+ '& ::-moz-placeholder': {
+ color: theme.palette.common.white
+ },
+ '& :-ms-input-placeholder': {
+ color: theme.palette.common.white
+ },
+ '& :-moz-placeholder': {
+ color: theme.palette.common.white
+ }
+ },
+ flex: {
+ flex: 1,
+ },
+ wrapper: {
+ fontFamily: theme.typography.fontFamily,
+ position: 'relative',
+ marginLeft: theme.spacing(1),
+ borderRadius: 2,
+ background: fade(theme.palette.common.white, 0.15),
+ '&:hover': {
+ background: fade(theme.palette.common.white, 0.25),
+ },
+ '& $input': {
+ transition: theme.transitions.create('width'),
+ },
+ },
+ addBtn: {
+ position: 'fixed',
+ bottom: 30,
+ right: 30,
+ zIndex: 1000
+ },
+ sidebar: {
+ zIndex: 120
+ },
+ search: {
+ width: theme.spacing(9),
+ height: '100%',
+ position: 'absolute',
+ pointerEvents: 'none',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ },
+ input: {
+ font: 'inherit',
+ padding: `${theme.spacing(1)}px ${theme.spacing(1)}px ${theme.spacing(1)}px ${theme.spacing(9)}px`,
+ border: 0,
+ display: 'block',
+ verticalAlign: 'middle',
+ whiteSpace: 'normal',
+ background: 'none',
+ margin: 0, // Reset for Safari
+ color: 'inherit',
+ width: '100%',
+ '&:focus': {
+ outline: 0,
+ },
+ },
+ drawerPaper: {
+ [theme.breakpoints.up('md')]: {
+ position: 'relative',
+ },
+ width: drawerWidth,
+ background: theme.palette.grey[50],
+ border: 'none',
+ padding: 10
+ },
+ selected: {
+ background: theme.palette.secondary.light,
+ borderLeft: `2px solid ${theme.palette.secondary.main}`,
+ paddingLeft: 22,
+ '& h3': {
+ color: theme.palette.secondary.dark
+ }
+ },
+ content: {
+ flexGrow: 1,
+ backgroundColor: theme.palette.background.default,
+ zIndex: 120,
+ marginBottom: theme.spacing(8),
+ [theme.breakpoints.up('md')]: {
+ padding: theme.spacing(3),
+ marginBottom: theme.spacing(4),
+ paddingLeft: 0,
+ },
+ position: 'relative',
+ minWidth: 0, // So the Typography noWrap works
+ },
+ toolbar: {
+ minHeight: 32
+ },
+ title: {
+ width: 205
+ },
+ divider: {
+ margin: '0 20px 0 10px'
+ },
+ /* Email List */
+ column: {
+ flexBasis: '33.33%',
+ overflow: 'hidden',
+ paddingRight: '0 !important',
+ paddingTop: 5,
+ marginLeft: 20
+ },
+ secondaryHeading: {
+ fontSize: 14,
+ color: theme.palette.text.secondary,
+ },
+ icon: {
+ verticalAlign: 'bottom',
+ height: 20,
+ width: 20,
+ },
+ details: {
+ alignItems: 'center',
+ [theme.breakpoints.down('sm')]: {
+ padding: `${theme.spacing(1)}px ${theme.spacing(1)}px ${theme.spacing(3)}px`
+ },
+ '& section': {
+ width: '100%'
+ }
+ },
+ link: {
+ color: theme.palette.secondary.main,
+ textDecoration: 'none',
+ '&:hover': {
+ textDecoration: 'underline',
+ },
+ },
+ avatar: {},
+ fromHeading: {
+ overflow: 'hidden',
+ display: 'flex',
+ alignItems: 'center',
+ '& $avatar': {
+ width: 30,
+ height: 30,
+ marginRight: 20
+ }
+ },
+ topAction: {
+ display: 'flex',
+ background: theme.palette.grey[100],
+ marginBottom: 20,
+ alignItems: 'center',
+ padding: '0 20px',
+ borderRadius: 2,
+ },
+ category: {
+ fontSize: 12,
+ textTransform: 'uppercase',
+ display: 'flex',
+ '& svg': {
+ fontSize: 16,
+ marginRight: 5
+ }
+ },
+ markMenu: {
+ '& svg': {
+ marginRight: 10
+ }
+ },
+ headMail: {
+ flex: 1
+ },
+ field: {
+ width: '100%',
+ marginBottom: 20,
+ '& svg': {
+ color: theme.palette.grey[400],
+ fontSize: 18,
+ }
+ },
+ hiddenDropzone: {
+ display: 'none'
+ },
+ sendIcon: {
+ marginLeft: 10
+ },
+ item: {},
+ preview: {
+ display: 'flex',
+ marginBottom: 20,
+ '& $item': {
+ maxWidth: 160,
+ marginBottom: 5,
+ marginRight: 5
+ }
+ },
+ emailSummary: {
+ paddingLeft: 0,
+ '& > div': {
+ [theme.breakpoints.down('sm')]: {
+ flexDirection: 'column'
+ },
+ }
+ },
+ emailContent: {
+ padding: theme.spacing(2),
+ [theme.breakpoints.down('sm')]: {
+ padding: `${theme.spacing(2)}px ${theme.spacing(2)}px`,
+ },
+ },
+ starBtn: {
+ marginRight: 10
+ },
+ navIconHide: {
+ [theme.breakpoints.up('md')]: {
+ display: 'none',
+ },
+ },
+});
+
+export default styles;
--
cgit v1.2.3