summaryrefslogtreecommitdiffstats
path: root/front/odiparpack/app/components/SocialMedia
diff options
context:
space:
mode:
authorDayana31 <[email protected]>2022-04-21 17:27:08 -0500
committerDayana31 <[email protected]>2022-04-21 17:27:08 -0500
commit67c50667678dd0ce4709b29a854f6a47093a1ac5 (patch)
treeb6f9f39092ad54bf6b815984d32b37d7c7ca67ab /front/odiparpack/app/components/SocialMedia
parent91140b24f0d49a9f89a080ee063e9eb023a4b73a (diff)
parente13e630cd6e4fc0b1ff92098a28a770794c7bb9a (diff)
downloadDP1_project-67c50667678dd0ce4709b29a854f6a47093a1ac5.tar.gz
DP1_project-67c50667678dd0ce4709b29a854f6a47093a1ac5.tar.bz2
DP1_project-67c50667678dd0ce4709b29a854f6a47093a1ac5.zip
Merge branch 'gabshr' into dayana
Diffstat (limited to 'front/odiparpack/app/components/SocialMedia')
-rw-r--r--front/odiparpack/app/components/SocialMedia/Comment.js135
-rw-r--r--front/odiparpack/app/components/SocialMedia/Cover.js103
-rw-r--r--front/odiparpack/app/components/SocialMedia/SideSection.js209
-rw-r--r--front/odiparpack/app/components/SocialMedia/Timeline.js177
-rw-r--r--front/odiparpack/app/components/SocialMedia/WritePost.js169
-rw-r--r--front/odiparpack/app/components/SocialMedia/jss/cover-jss.js55
-rw-r--r--front/odiparpack/app/components/SocialMedia/jss/socialMedia-jss.js89
-rw-r--r--front/odiparpack/app/components/SocialMedia/jss/timeline-jss.js95
-rw-r--r--front/odiparpack/app/components/SocialMedia/jss/writePost-jss.js73
9 files changed, 1105 insertions, 0 deletions
diff --git a/front/odiparpack/app/components/SocialMedia/Comment.js b/front/odiparpack/app/components/SocialMedia/Comment.js
new file mode 100644
index 0000000..9ead6e7
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/Comment.js
@@ -0,0 +1,135 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import Type from 'ba-styles/Typography.scss';
+import { withStyles } from '@material-ui/core/styles';
+import Send from '@material-ui/icons/Send';
+import CommentIcon from '@material-ui/icons/Comment';
+import CloseIcon from '@material-ui/icons/Close';
+import dummy from 'ba-api/dummyContents';
+import {
+ Typography,
+ List,
+ ListItem,
+ Avatar,
+ Input,
+ Dialog,
+ DialogActions,
+ DialogContent,
+ DialogTitle,
+ IconButton,
+ Fab,
+ Slide,
+ Divider,
+ withMobileDialog,
+} from '@material-ui/core';
+import styles from './jss/socialMedia-jss';
+
+const Transition = React.forwardRef(function Transition(props, ref) { // eslint-disable-line
+ return <Slide direction="up" ref={ref} {...props} />;
+});
+
+class Comment extends React.Component {
+ state = {
+ comment: ''
+ };
+
+ handleChange = event => {
+ this.setState({ comment: event.target.value });
+ };
+
+ handleSubmit = comment => {
+ this.props.submitComment(comment);
+ this.setState({ comment: '' });
+ }
+
+ render() {
+ const {
+ open,
+ handleClose,
+ classes,
+ dataComment,
+ fullScreen
+ } = this.props;
+ const { comment } = this.state;
+ const getItem = dataArray => dataArray.map(data => (
+ <Fragment key={data.get('id')}>
+ <ListItem>
+ <div className={classes.commentContent}>
+ <div className={classes.commentHead}>
+ <Avatar alt="avatar" src={data.get('avatar')} className={classes.avatar} />
+ <section>
+ <Typography variant="subtitle1">{data.get('from')}</Typography>
+ <Typography variant="caption"><span className={classNames(Type.light, Type.textGrey)}>{data.get('date')}</span></Typography>
+ </section>
+ </div>
+ <Typography className={classes.commentText}>{data.get('message')}</Typography>
+ </div>
+ </ListItem>
+ <Divider variant="inset" />
+ </Fragment>
+ ));
+
+ return (
+ <div>
+ <Dialog
+ fullScreen={fullScreen}
+ open={open}
+ onClose={handleClose}
+ aria-labelledby="form-dialog-title"
+ TransitionComponent={Transition}
+ maxWidth="md"
+ >
+ <DialogTitle id="form-dialog-title">
+ <CommentIcon />
+ {' '}
+ {dataComment !== undefined && dataComment.size}
+ &nbsp;Comment
+ {dataComment !== undefined && dataComment.size > 1 ? 's' : ''}
+ <IconButton onClick={handleClose} className={classes.buttonClose} aria-label="Close">
+ <CloseIcon />
+ </IconButton>
+ </DialogTitle>
+ <DialogContent>
+ <List>
+ {dataComment !== undefined && getItem(dataComment)}
+ </List>
+ </DialogContent>
+ <DialogActions className={classes.commentAction}>
+ <div className={classes.commentForm}>
+ <Avatar alt="avatar" src={dummy.user.avatar} className={classes.avatarMini} />
+ <Input
+ placeholder="Write Comment"
+ onChange={this.handleChange}
+ value={comment}
+ className={classes.input}
+ inputProps={{
+ 'aria-label': 'Comment',
+ }}
+ />
+ <Fab size="small" onClick={() => this.handleSubmit(comment)} color="secondary" aria-label="send" className={classes.button}>
+ <Send />
+ </Fab>
+ </div>
+ </DialogActions>
+ </Dialog>
+ </div>
+ );
+ }
+}
+
+Comment.propTypes = {
+ open: PropTypes.bool.isRequired,
+ handleClose: PropTypes.func.isRequired,
+ submitComment: PropTypes.func.isRequired,
+ classes: PropTypes.object.isRequired,
+ dataComment: PropTypes.object,
+ fullScreen: PropTypes.bool.isRequired,
+};
+
+Comment.defaultProps = {
+ dataComment: undefined
+};
+
+const CommentResponsive = withMobileDialog()(Comment);
+export default withStyles(styles)(CommentResponsive);
diff --git a/front/odiparpack/app/components/SocialMedia/Cover.js b/front/odiparpack/app/components/SocialMedia/Cover.js
new file mode 100644
index 0000000..4823f13
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/Cover.js
@@ -0,0 +1,103 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import VerifiedUser from '@material-ui/icons/VerifiedUser';
+import Info from '@material-ui/icons/Info';
+import MoreVertIcon from '@material-ui/icons/MoreVert';
+import { withStyles } from '@material-ui/core/styles';
+import { Avatar, Typography, Menu, MenuItem, Button, IconButton } from '@material-ui/core';
+import styles from './jss/cover-jss';
+
+
+const optionsOpt = [
+ 'Edit Profile',
+ 'Change Cover',
+ 'Option 1',
+ 'Option 2',
+ 'Option 3',
+];
+
+const ITEM_HEIGHT = 48;
+
+class Cover extends React.Component {
+ state = {
+ anchorElOpt: null,
+ };
+
+ handleClickOpt = event => {
+ this.setState({ anchorElOpt: event.currentTarget });
+ };
+
+ handleCloseOpt = () => {
+ this.setState({ anchorElOpt: null });
+ };
+
+ render() {
+ const {
+ classes,
+ avatar,
+ name,
+ desc,
+ coverImg,
+ } = this.props;
+ const { anchorElOpt } = this.state;
+ return (
+ <div className={classes.cover} style={{ backgroundImage: `url(${coverImg})` }}>
+ <div className={classes.opt}>
+ <IconButton className={classes.button} aria-label="Delete">
+ <Info />
+ </IconButton>
+ <IconButton
+ aria-label="More"
+ aria-owns={anchorElOpt ? 'long-menu' : null}
+ aria-haspopup="true"
+ className={classes.button}
+ 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 === 'Edit Profile'} onClick={this.handleCloseOpt}>
+ {option}
+ </MenuItem>
+ ))}
+ </Menu>
+ </div>
+ <div className={classes.content}>
+ <Avatar alt={name} src={avatar} className={classes.avatar} />
+ <Typography variant="h4" className={classes.name} gutterBottom>
+ {name}
+ <VerifiedUser className={classes.verified} />
+ </Typography>
+ <Typography className={classes.subheading} gutterBottom>
+ {desc}
+ </Typography>
+ <Button className={classes.button} size="large" variant="contained" color="secondary">
+ Add to Connection
+ </Button>
+ </div>
+ </div>
+ );
+ }
+}
+
+Cover.propTypes = {
+ classes: PropTypes.object.isRequired,
+ avatar: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ desc: PropTypes.string.isRequired,
+ coverImg: PropTypes.string.isRequired,
+};
+
+export default withStyles(styles)(Cover);
diff --git a/front/odiparpack/app/components/SocialMedia/SideSection.js b/front/odiparpack/app/components/SocialMedia/SideSection.js
new file mode 100644
index 0000000..1fe8d9c
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/SideSection.js
@@ -0,0 +1,209 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+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 avatarApi from 'ba-api/avatars';
+import {
+ Grid,
+ Typography,
+ MobileStepper,
+ Paper,
+ Avatar,
+ Button,
+ Divider,
+ List,
+ ListItem,
+ ListItemText,
+} from '@material-ui/core';
+import PapperBlock from '../PapperBlock/PapperBlock';
+import NewsCard from '../CardPaper/NewsCard';
+import ProfileCard from '../CardPaper/ProfileCard';
+import styles from './jss/socialMedia-jss';
+
+
+const slideData = [
+ {
+ label: 'How to be happy :)',
+ imgPath: imgApi[49],
+ },
+ {
+ label: '1. Work with something that you like, like…',
+ imgPath: imgApi[17],
+ },
+ {
+ label: '2. Keep your friends close to you and hangout with them',
+ imgPath: imgApi[34],
+ },
+ {
+ label: '3. Travel everytime that you have a chance',
+ imgPath: imgApi[10],
+ },
+ {
+ label: '4. And contribute to Material-UI :D',
+ imgPath: imgApi[40]
+ },
+];
+
+class SideSection extends React.Component {
+ state = {
+ activeStepSwipe: 0,
+ };
+
+ 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 { activeStepSwipe } = this.state;
+
+ const maxStepsSwipe = slideData.length;
+ return (
+ <div>
+ {/* Profile */}
+ <ProfileCard
+ cover={imgApi[43]}
+ avatar={avatarApi[6]}
+ name="John Doe"
+ title="UX designer"
+ connection={10}
+ btnText="My Profile"
+ isVerified
+ />
+ <Divider className={classes.divider} />
+ {/* ----------------------------------------------------------------------*/}
+ {/* News Or Ads Block */}
+ <Paper>
+ <SwipeableViews
+ axis={theme.direction === 'rtl' ? 'x-reverse' : 'x'}
+ index={this.state.activeStepSwipe}
+ onChangeIndex={this.handleStepChangeSwipe}
+ enableMouseEvents
+ className={classes.sliderWrap}
+ >
+ {slideData.map((slide, index) => (
+ <div className={classes.figure} key={index.toString()}>
+ <NewsCard
+ image={slide.imgPath}
+ title="slide.label"
+ >
+ <Typography gutterBottom className={classes.title} variant="h5" component="h2">
+ {slide.label}
+ </Typography>
+ </NewsCard>
+ </div>
+ ))}
+ </SwipeableViews>
+ <MobileStepper
+ variant="dots"
+ 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>
+ )}
+ />
+ </Paper>
+ {/* ----------------------------------------------------------------------*/}
+ {/* People */}
+ <PapperBlock title="People You May Know" whiteBg noMargin desc="">
+ <List component="nav" dense className={classes.profileList}>
+ <ListItem button className={classes.noPadding}>
+ <Avatar className={classNames(classes.avatar, classes.orangeAvatar)}>H</Avatar>
+ <ListItemText primary="Harry Wells" secondary="2 Mutual Connection" />
+ <Button color="secondary" size="small">Connect</Button>
+ </ListItem>
+ <ListItem button className={classes.noPadding}>
+ <Avatar className={classNames(classes.avatar, classes.purpleAvatar)}>J</Avatar>
+ <ListItemText primary="John Doe" secondary="8 Mutual Connection" />
+ <Button color="secondary" size="small">Connect</Button>
+ </ListItem>
+ <ListItem button className={classes.noPadding}>
+ <Avatar className={classNames(classes.avatar, classes.pinkAvatar)}>V</Avatar>
+ <ListItemText primary="Victor Wanggai" secondary="12 Mutual Connection" />
+ <Button color="secondary" size="small">Connect</Button>
+ </ListItem>
+ <ListItem button className={classes.noPadding}>
+ <Avatar className={classNames(classes.avatar, classes.greenAvatar)}>H</Avatar>
+ <ListItemText primary="Baron Phoenix" secondary="10 Mutual Connection" />
+ <Button color="secondary" size="small">Connect</Button>
+ </ListItem>
+ </List>
+ <Divider className={classes.divider} />
+ <Grid container justify="center">
+ <Button color="secondary" className={classes.button}>
+ See All
+ </Button>
+ </Grid>
+ </PapperBlock>
+ {/* ----------------------------------------------------------------------*/}
+ {/* Trending */}
+ <PapperBlock title="Trends For You" whiteBg desc="">
+ <List dense className={classes.trendingList}>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Lorem ipsum dolor</a>
+ <ListItemText secondary="2987 Posts" />
+ </ListItem>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Aliquam venenatis</a>
+ <ListItemText secondary="2345 Posts" />
+ </ListItem>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Nam sollicitudin</a>
+ <ListItemText secondary="1234 Posts" />
+ </ListItem>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Cras convallis</a>
+ <ListItemText secondary="6789 Connection" />
+ </ListItem>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Aenean sit amet</a>
+ <ListItemText secondary="2987 Connection" />
+ </ListItem>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Quisque</a>
+ <ListItemText secondary="1456 Connection" />
+ </ListItem>
+ <ListItem className={classes.noPadding}>
+ <a href="#" className={classes.link}>#Lorem ipusm dolor</a>
+ <ListItemText secondary="2987 Connection" />
+ </ListItem>
+ </List>
+ </PapperBlock>
+ </div>
+ );
+ }
+}
+
+SideSection.propTypes = {
+ classes: PropTypes.object.isRequired,
+ theme: PropTypes.object.isRequired,
+};
+
+export default withStyles(styles, { withTheme: true })(SideSection);
diff --git a/front/odiparpack/app/components/SocialMedia/Timeline.js b/front/odiparpack/app/components/SocialMedia/Timeline.js
new file mode 100644
index 0000000..e46826b
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/Timeline.js
@@ -0,0 +1,177 @@
+import React, { Fragment } from 'react';
+import PropTypes from 'prop-types';
+import { withStyles } from '@material-ui/core/styles';
+import FavoriteIcon from '@material-ui/icons/Favorite';
+import ShareIcon from '@material-ui/icons/Share';
+import CommentIcon from '@material-ui/icons/Comment';
+import MoreVertIcon from '@material-ui/icons/MoreVert';
+import {
+ Typography,
+ Card,
+ Menu,
+ MenuItem,
+ CardHeader,
+ CardMedia,
+ CardContent,
+ CardActions,
+ IconButton,
+ Icon,
+ Avatar,
+ Tooltip,
+} from '@material-ui/core';
+import Comment from './Comment';
+import styles from './jss/timeline-jss';
+
+
+const optionsOpt = [
+ 'Option 1',
+ 'Option 2',
+ 'Option 3',
+];
+
+const ITEM_HEIGHT = 48;
+
+class Timeline extends React.Component {
+ state = {
+ anchorElOpt: null,
+ openComment: false,
+ };
+
+ handleClickOpt = event => {
+ this.setState({ anchorElOpt: event.currentTarget });
+ };
+
+ handleCloseOpt = () => {
+ this.setState({ anchorElOpt: null });
+ };
+
+ handleOpenComment = (data) => {
+ this.props.fetchComment(data);
+ this.setState({ openComment: true });
+ };
+
+ handleCloseComment = () => {
+ this.setState({ openComment: false });
+ };
+
+ render() {
+ const {
+ classes,
+ dataTimeline,
+ onlike,
+ commentIndex,
+ submitComment,
+ } = this.props;
+ const { anchorElOpt, openComment } = this.state;
+ const getItem = dataArray => dataArray.map(data => (
+ <li key={data.get('id')}>
+ <div className={classes.iconBullet}>
+ <Tooltip id={'tooltip-icon-' + data.get('id')} title={data.get('time')}>
+ <Icon className={classes.icon}>
+ {data.get('icon')}
+ </Icon>
+ </Tooltip>
+ </div>
+ <Card className={classes.cardSocmed}>
+ <CardHeader
+ avatar={
+ <Avatar alt="avatar" src={data.get('avatar')} className={classes.avatar} />
+ }
+ action={(
+ <IconButton
+ aria-label="More"
+ aria-owns={anchorElOpt ? 'long-menu' : null}
+ aria-haspopup="true"
+ className={classes.button}
+ onClick={this.handleClickOpt}
+ >
+ <MoreVertIcon />
+ </IconButton>
+ )}
+ title={data.get('name')}
+ subheader={data.get('date')}
+ />
+ { data.get('image') !== ''
+ && (
+ <CardMedia
+ className={classes.media}
+ image={data.get('image')}
+ title={data.get('name')}
+ />
+ )
+ }
+ <CardContent>
+ <Typography component="p">
+ {data.get('content')}
+ </Typography>
+ </CardContent>
+ <CardActions className={classes.actions}>
+ <IconButton aria-label="Like this" onClick={() => onlike(data)}>
+ <FavoriteIcon className={data.get('liked') ? classes.liked : ''} />
+ </IconButton>
+ <IconButton aria-label="Share">
+ <ShareIcon />
+ </IconButton>
+ <div className={classes.rightIcon}>
+ <Typography variant="caption" component="span">
+ {data.get('comments') !== undefined ? data.get('comments').size : 0}
+ </Typography>
+ <IconButton aria-label="Comment" onClick={() => this.handleOpenComment(data)}>
+ <CommentIcon />
+ </IconButton>
+ </div>
+ </CardActions>
+ </Card>
+ </li>
+ ));
+ return (
+ <Fragment>
+ <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 === 'Edit Profile'} onClick={this.handleCloseOpt}>
+ {option}
+ </MenuItem>
+ ))}
+ </Menu>
+ <Comment
+ open={openComment}
+ handleClose={this.handleCloseComment}
+ submitComment={submitComment}
+ dataComment={dataTimeline.getIn([commentIndex, 'comments'])}
+ />
+ <ul className={classes.timeline}>
+ {getItem(dataTimeline)}
+ </ul>
+ </Fragment>
+ );
+ }
+}
+
+Timeline.propTypes = {
+ classes: PropTypes.object.isRequired,
+ onlike: PropTypes.func,
+ dataTimeline: PropTypes.object.isRequired,
+ fetchComment: PropTypes.func,
+ submitComment: PropTypes.func,
+ commentIndex: PropTypes.number,
+};
+
+Timeline.defaultProps = {
+ onlike: () => (false),
+ fetchComment: () => {},
+ submitComment: () => {},
+ commentIndex: 0,
+};
+
+export default withStyles(styles)(Timeline);
diff --git a/front/odiparpack/app/components/SocialMedia/WritePost.js b/front/odiparpack/app/components/SocialMedia/WritePost.js
new file mode 100644
index 0000000..3452aea
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/WritePost.js
@@ -0,0 +1,169 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import classNames from 'classnames';
+import Dropzone from 'react-dropzone';
+import { withStyles } from '@material-ui/core/styles';
+import PhotoCamera from '@material-ui/icons/PhotoCamera';
+import Send from '@material-ui/icons/Send';
+import ActionDelete from '@material-ui/icons/Delete';
+import dummy from 'ba-api/dummyContents';
+import { IconButton, Fab, MenuItem, FormControl, Avatar, Paper, Select, Tooltip } from '@material-ui/core';
+import styles from './jss/writePost-jss';
+
+
+function isImage(file) {
+ const fileName = file.name || file.path;
+ const suffix = fileName.substr(fileName.indexOf('.') + 1).toLowerCase();
+ if (suffix === 'jpg' || suffix === 'jpeg' || suffix === 'bmp' || suffix === 'png') {
+ return true;
+ }
+ return false;
+}
+
+class WritePost extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ privacy: 'public',
+ files: [],
+ message: ''
+ };
+ this.onDrop = this.onDrop.bind(this);
+ }
+
+ onDrop(filesVal) {
+ const { files } = this.state;
+ let oldFiles = files;
+ const filesLimit = 2;
+ oldFiles = oldFiles.concat(filesVal);
+ if (oldFiles.length > filesLimit) {
+ console.log('Cannot upload more than ' + filesLimit + ' items.');
+ } else {
+ this.setState({ files: filesVal });
+ }
+ }
+
+ 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 });
+ }
+
+ handleChange = event => {
+ this.setState({ privacy: event.target.value });
+ };
+
+ handleWrite = event => {
+ this.setState({ message: event.target.value });
+ };
+
+ handlePost = (message, files, privacy) => {
+ // Submit Post to reducer
+ this.props.submitPost(message, files, privacy);
+ // Reset all fields
+ this.setState({
+ privacy: 'public',
+ files: [],
+ message: ''
+ });
+ }
+
+ render() {
+ const { classes } = this.props;
+ let dropzoneRef;
+ const { privacy, files, message } = this.state;
+ const acceptedFiles = ['image/jpeg', 'image/png', 'image/bmp'];
+ const fileSizeLimit = 3000000;
+ const deleteBtn = (file, index) => (
+ <div className={classNames(classes.removeBtn, 'middle')}>
+ <IconButton onClick={() => this.handleRemove(file, index)}>
+ <ActionDelete className="removeBtn" />
+ </IconButton>
+ </div>
+ );
+ const previews = filesArray => filesArray.map((file, index) => {
+ const path = URL.createObjectURL(file) || '/pic' + file.path;
+ if (isImage(file)) {
+ return (
+ <div key={index.toString()}>
+ <figure><img src={path} alt="preview" /></figure>
+ {deleteBtn(file, index)}
+ </div>
+ );
+ }
+ return false;
+ });
+ return (
+ <div className={classes.statusWrap}>
+ <Paper>
+ <Avatar alt="avatar" src={dummy.user.avatar} className={classes.avatarMini} />
+ <textarea
+ row="2"
+ placeholder="What's on your mind?"
+ value={message}
+ onChange={this.handleWrite}
+ />
+ <Dropzone
+ className={classes.hiddenDropzone}
+ accept={acceptedFiles.join(',')}
+ acceptClassName="stripes"
+ onDrop={this.onDrop}
+ maxSize={fileSizeLimit}
+ ref={(node) => { dropzoneRef = node; }}
+ >
+ {({ getRootProps, getInputProps }) => (
+ <div {...getRootProps()}>
+ <input {...getInputProps()} />
+ </div>
+ )}
+ </Dropzone>
+ <div className={classes.preview}>
+ {previews(files)}
+ </div>
+ <div className={classes.control}>
+ <Tooltip id="tooltip-upload" title="Upload Photo">
+ <IconButton
+ className={classes.button}
+ component="button"
+ onClick={() => {
+ dropzoneRef.open();
+ }}
+ >
+ <PhotoCamera />
+ </IconButton>
+ </Tooltip>
+ <div className={classes.privacy}>
+ <FormControl className={classes.formControl}>
+ <Select
+ value={privacy}
+ onChange={this.handleChange}
+ name="privacy"
+ className={classes.selectEmpty}
+ >
+ <MenuItem value="public">Public</MenuItem>
+ <MenuItem value="friends">Friends</MenuItem>
+ <MenuItem value="private">Only Me</MenuItem>
+ </Select>
+ </FormControl>
+ </div>
+ <Tooltip id="tooltip-post" title="Post">
+ <Fab onClick={() => this.handlePost(message, files, privacy)} size="small" color="secondary" aria-label="send" className={classes.sendBtn}>
+ <Send />
+ </Fab>
+ </Tooltip>
+ </div>
+ </Paper>
+ </div>
+ );
+ }
+}
+
+WritePost.propTypes = {
+ classes: PropTypes.object.isRequired,
+ submitPost: PropTypes.func.isRequired
+};
+
+export default withStyles(styles)(WritePost);
diff --git a/front/odiparpack/app/components/SocialMedia/jss/cover-jss.js b/front/odiparpack/app/components/SocialMedia/jss/cover-jss.js
new file mode 100644
index 0000000..695512d
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/jss/cover-jss.js
@@ -0,0 +1,55 @@
+import { fade } from '@material-ui/core/styles/colorManipulator';
+const styles = theme => ({
+ root: {
+ flexGrow: 1,
+ },
+ cover: {
+ '& $name, & $subheading': {
+ color: theme.palette.common.white
+ },
+ position: 'relative',
+ width: '100%',
+ overflow: 'hidden',
+ height: 360,
+ backgroundColor: theme.palette.primary.main,
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'flex-end',
+ borderRadius: 2,
+ backgroundSize: 'cover',
+ textAlign: 'center',
+ boxShadow: theme.shadows[7]
+ },
+ content: {
+ background: fade(theme.palette.secondary.main, 0.3),
+ height: '100%',
+ width: '100%',
+ padding: `70px ${theme.spacing(3)}px 30px`
+ },
+ name: {},
+ subheading: {},
+ avatar: {
+ margin: '0 auto',
+ width: 120,
+ height: 120,
+ border: '3px solid rgba(255, 255, 255, .5)'
+ },
+ opt: {
+ position: 'absolute',
+ top: 10,
+ right: 10,
+ '& button': {
+ color: theme.palette.common.white
+ }
+ },
+ verified: {
+ margin: theme.spacing(1),
+ top: 10,
+ position: 'relative'
+ },
+ button: {
+ marginTop: theme.spacing(1)
+ }
+});
+
+export default styles;
diff --git a/front/odiparpack/app/components/SocialMedia/jss/socialMedia-jss.js b/front/odiparpack/app/components/SocialMedia/jss/socialMedia-jss.js
new file mode 100644
index 0000000..03f5726
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/jss/socialMedia-jss.js
@@ -0,0 +1,89 @@
+import { deepOrange, deepPurple, pink, green } from '@material-ui/core/colors';
+
+const styles = theme => ({
+ mobileStepper: {
+ margin: `0 auto ${theme.spacing(4)}px`,
+ textAlign: 'center'
+ },
+ avatar: {
+ marginRight: 15,
+ },
+ orangeAvatar: {
+ backgroundColor: deepOrange[500],
+ },
+ purpleAvatar: {
+ backgroundColor: deepPurple[500],
+ },
+ pinkAvatar: {
+ backgroundColor: pink[500],
+ },
+ greenAvatar: {
+ backgroundColor: green[500],
+ },
+ divider: {
+ margin: `${theme.spacing(2)}px 0`,
+ background: 'none'
+ },
+ link: {
+ color: theme.palette.primary.main
+ },
+ noPadding: {
+ padding: '5px',
+ marginLeft: -10
+ },
+ sliderWrap: {
+ height: 310,
+ overflow: 'hidden'
+ },
+ title: {
+ whiteSpace: 'nowrap',
+ textOverflow: 'ellipsis',
+ overflow: 'hidden',
+ fontSize: 18
+ },
+ profileList: {},
+ trendingList: {
+ '& li': {
+ display: 'block'
+ }
+ },
+ input: {},
+ commentContent: {
+ padding: 10
+ },
+ commentText: {
+ marginTop: 5
+ },
+ buttonClose: {
+ position: 'absolute',
+ top: 20,
+ right: 20
+ },
+ avatarMini: {
+ width: 30,
+ height: 30,
+ },
+ commentAction: {
+ background: theme.palette.grey[100],
+ margin: 0,
+ },
+ commentForm: {
+ display: 'flex',
+ alignItems: 'center',
+ [theme.breakpoints.up('md')]: {
+ minWidth: 600,
+ },
+ width: '100%',
+ padding: '15px 20px',
+ margin: 0,
+ '& $input': {
+ flex: 1,
+ margin: '0 10px'
+ }
+ },
+ commentHead: {
+ display: 'flex'
+ }
+});
+
+export default styles;
diff --git a/front/odiparpack/app/components/SocialMedia/jss/timeline-jss.js b/front/odiparpack/app/components/SocialMedia/jss/timeline-jss.js
new file mode 100644
index 0000000..dcdb018
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/jss/timeline-jss.js
@@ -0,0 +1,95 @@
+import { pink } from '@material-ui/core/colors';
+const styles = theme => ({
+ card: {
+ display: 'flex',
+ justifyContent: 'space-between'
+ },
+ content: {
+ flex: '1 0 auto',
+ },
+ cover: {
+ width: 150,
+ height: 150,
+ },
+ avatar: {
+ width: 40,
+ height: 40
+ },
+ cardSocmed: {
+ [theme.breakpoints.up('md')]: {
+ marginLeft: 90,
+ minWidth: 400,
+ },
+ marginBottom: theme.spacing(3),
+ position: 'relative',
+ },
+ media: {
+ height: 0,
+ paddingTop: '56.25%', // 16:9
+ },
+ actions: {
+ display: 'flex',
+ },
+ expandOpen: {
+ transform: 'rotate(180deg)',
+ },
+ iconBullet: {},
+ icon: {},
+ timeline: {
+ position: 'relative',
+ '&:before': {
+ left: 39,
+ content: '""',
+ top: 40,
+ height: '101%',
+ border: `1px solid ${theme.palette.grey[300]}`,
+ position: 'absolute',
+ [theme.breakpoints.down('sm')]: {
+ display: 'none'
+ },
+ },
+ '& li': {
+ position: 'relative',
+ display: 'block'
+ },
+ '& time': {
+ top: 70,
+ left: 20,
+ position: 'absolute',
+ textAlign: 'center',
+ background: theme.palette.common.white,
+ boxShadow: theme.shadows[3],
+ padding: '4px 40px 4px 15px',
+ borderLeft: `3px solid ${theme.palette.secondary.main}`
+ },
+ '& $iconBullet': {
+ position: 'absolute',
+ borderRadius: '50%',
+ top: 20,
+ width: 40,
+ height: 40,
+ background: theme.palette.secondary.main,
+ boxShadow: theme.shadows[5],
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ left: 20,
+ '& $icon': {
+ color: theme.palette.common.white,
+ },
+ [theme.breakpoints.down('sm')]: {
+ display: 'none'
+ },
+ },
+ },
+ rightIcon: {
+ marginLeft: 'auto',
+ display: 'flex',
+ alignItems: 'center'
+ },
+ liked: {
+ color: pink[500]
+ }
+});
+
+export default styles;
diff --git a/front/odiparpack/app/components/SocialMedia/jss/writePost-jss.js b/front/odiparpack/app/components/SocialMedia/jss/writePost-jss.js
new file mode 100644
index 0000000..cd18422
--- /dev/null
+++ b/front/odiparpack/app/components/SocialMedia/jss/writePost-jss.js
@@ -0,0 +1,73 @@
+const styles = theme => ({
+ statusWrap: {
+ marginBottom: theme.spacing(3),
+ '& > div': {
+ overflow: 'hidden'
+ },
+ '& textarea': {
+ border: 'none',
+ padding: '20px 20px 20px 50px',
+ outline: 'none',
+ width: '100%',
+ resize: 'none',
+ overflow: 'hidden',
+ height: 50,
+ transition: theme.transitions.create(['height'], {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ '&:focus': {
+ height: 100,
+ overflow: 'auto',
+ }
+ }
+ },
+ avatarMini: {
+ width: 30,
+ height: 30,
+ position: 'absolute',
+ top: 40,
+ left: 10
+ },
+ control: {
+ padding: '10px 20px 0',
+ display: 'flex'
+ },
+ privacy: {
+ flex: 1,
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'flex-end',
+ textAlign: 'right',
+ },
+ button: {
+ margin: theme.spacing(0.5)
+ },
+ sendBtn: {
+ position: 'relative',
+ top: 5
+ },
+ formControl: {
+ margin: '0 20px',
+ width: 150,
+ paddingLeft: 10,
+ textAlign: 'left',
+ '&:before, &:after': {
+ borderBottom: 'none'
+ }
+ },
+ hiddenDropzone: {
+ display: 'none'
+ },
+ preview: {
+ position: 'relative',
+ '& figure': {
+ textAlign: 'center'
+ }
+ },
+ removeBtn: {
+ opacity: 1
+ }
+});
+
+export default styles;