src/components/collection/Collection.js
import React, { Component } from "react";
import Select from "react-select";
import {
    Button,
    ButtonBase,
    Icon,
    Modal,
    TextField
} from "@material-ui/core";
import { withStyles } from "@material-ui/core/styles";
import "../../css/Collection.css";
/**
 * FUNC to position modal in the middle of the screen
 */
function getModalStyle() {
    const top = 50;
    const left = 50;
    return {
        top: `${top}%`,
        left: `${left}%`,
        transform: `translate(-${top}%, -${left}%)`,
        maxWidth: "90%"
    };
}
/**
 * CSS for modal
 * 
 * @param {*} theme Will use default theme if not provided
 */
const modelStyles = theme => ({
    paper: {
        position: "absolute",
        width: theme.spacing(60),
        backgroundColor: theme.palette.background.paper,
        boxShadow: theme.shadows[5],
        padding: theme.spacing(4),
    },
    button: {
        margin: theme.spacing(1),
    }
});
const btnStyle = {
    base: {
        marginTop: 20,
        justifyContent: "left",
        width: "100%"
    },
    on: {
        color: "#3f51b5",
    },
    off: {
        color: "#333",
    },
    save: {
        padding: 5,
        margin: 5,
        color: "#333",
        width: "100%"
    },
    cancel: {
        padding: 5,
        margin: 5,
        color: "red",
        width: "100%"
    }
};
/**
 * React Component for Create Collection Modal to Navigate different options for collection
 */
class CollectionModal extends Component {
    constructor(props) {
        super(props);
        this.state = {
            addOpen: false,
            openOpen: false,
            deleteOpen: false,
            newcollectionID: ""
        };
    }
    /**
     * Move to selected collection page when selected
     * @param {object} selectedCollection passed the data of selected collection
     */
    handleChange = (selectedCollection) => {
        window.location.assign(window.origin + "/collection/" + selectedCollection.value);
    }
    /**
     * Handle when user deleted the selected collection
     * @param {object} selectedCollection passed the data of selected collection
     */
    handleDelete = (selectedCollection) => {
        let needsToRedirect = (this.props.openCollection === selectedCollection.label);
        this.props.collectionActions.deleteCollection(selectedCollection.value, selectedCollection.label, this.props.user.uid);
        this.handleCloseAll();
        if(needsToRedirect){
            window.location.assign("/");
        }
        this.props.deleteCallback(selectedCollection.label);
    }
    /**
     * Update the state with the collection name user enter in the field
     * @param {string} name name of the state to be change
     * @param {object} event  Event interface when the onChnage event was dispatched
     */
    handleTextChange = name => event => {
        this.setState({
            [name]: event.target.value,
        });
    };
    /**
     * Toggle the addOpen state, whether to open "add collection" option
     */
    handleAddCollectionToggle = () => {
        this.setState({ addOpen: !this.state.addOpen });
    }
    /**
     * Toggle the openOpen state, whether to open "open collection" option
     */
    handleOpenCollectionToggle = () => {
        this.setState({ openOpen: !this.state.openOpen });
    }
    /**
     * Toggle the deleteOpen state, whether to open "delete collection" option
     */
    handleDeleteCollectionToggle = () => {
        this.setState({ deleteOpen: !this.state.deleteOpen });
    }
    /**
     * Close the collection modal and all options
     */
    handleCloseAll = () => {
        this.setState({ addOpen: false, openOpen: false, deleteOpen: false });
        this.props.handleCollectionClose();
    }
    /**
     * Returns DOM element for modal to select collections
     */
    selectCollection = () => {
        const userCollections = this.props.collections.collections;
        let optionItems = [];
        const placeholder = "Select a collection";
        userCollections.map((collection) =>
            optionItems.push({
                value: collection.collectionID,
                label: collection.collectionID
            })
        );
        return (
            <div>
                <h5>Select a collection to open.</h5>
                <Select placeholder={placeholder} options={optionItems} onChange={this.handleChange} />
            </div>
        );
    }
    /**
     * Returns DOM element for modal to delete collections
     */
    deleteCollection = () => {
        const userCollections = this.props.collections.collections;
        let optionItems = [];
        const placeholder = "Select a collection";
        userCollections.map((collection) =>
            optionItems.push({
                value: collection._id,
                label: collection.collectionID
            })
        );
        return (
            <div>
                <h5>Select a collection to delete.</h5>
                <Select placeholder={placeholder} options={optionItems} onChange={this.handleDelete} />
            </div>
        );
    }
    /**
     * Add new collection to the backend if possible
     */
    handleSubmit = () => {
        if (!this.props.user) {
            window.alert("You must be signed in to create a collection.");
            this.handleAddCollectionToggle();
        }
        else {
            let name = this.state.newcollectionID.toLowerCase();
    
            fetch("/apiv1/collections", {
                method: "POST", 
                body: JSON.stringify({collectID: name}),
                headers:{"Content-Type": "application/json", "x-access-token": this.props.user.uid}
            }).then((resp) => {
                switch(resp.status) {
                    case 201://Success
                        this.props.collectionActions.asyncCollections(this.props.user.uid);
                        window.alert("Collection added!");
                        this.handleCloseAll();
                        break;
                    case 409:
                        window.alert("Error: A collection already exists with that collection name.");
                        break;
                    default:
                        window.alert(`Error creating collection: ${resp.statusText}`);
                        break;
                }
            });
        }
    }
    /**
     * Returns DOM element for modal to add collections
     */
    addClass = () => (
        <div>
            <h5>Please enter a new collection name.</h5>
            <TextField
                id="standard-name"
                type="text"
                onChange={this.handleTextChange("newcollectionID")}
            />
            <Button
                color="primary"
                onClick={() => {
                    this.handleSubmit();
                }} >
                Submit
            </Button>
        </div>
    );
    /**
     * Render all of the elements
     */
    render() {
        const { classes } = this.props;
        return (
            <div>
                <Modal
                    aria-labelledby="simple-modal-title"
                    aria-describedby="simple-modal-description"
                    open={this.props.open}
                    onClose={this.props.handleCollectionToggle} >
                    <div style={getModalStyle()} className={classes.paper}>
                        <ButtonBase
                            style={{ position: "absolute", right: 15, top: 15 }}
                            onClick={this.props.handleCollectionToggle} >
                            <Icon className="material-icons">clear</Icon>
                        </ButtonBase >
                        <div className="row d-flex">
                            <div className="col-12 border-bottom">Collection Options</div>
                            <div className="col-6">
                                <ButtonBase
                                    style={btnStyle.base}
                                    onClick={() => { this.handleOpenCollectionToggle(); }} >
                                    <Icon className="material-icons collection-icon">storage</Icon>
                                    Open a Collection
                                </ButtonBase>
                                <ButtonBase
                                    style={btnStyle.base}
                                    onClick={() => { this.handleDeleteCollectionToggle(); }} >
                                    <Icon className="material-icons collection-icon">delete</Icon>
                                    Delete a Collection
                                </ButtonBase>
                            </div>
                            <div className="col-6">
                                <ButtonBase
                                    style={btnStyle.base}
                                    onClick={() => { this.handleAddCollectionToggle(); }} >
                                    <Icon className="material-icons collection-icon">add_circle</Icon>
                                    Create a Collection
                                </ButtonBase>
                                <ButtonBase
                                    style={btnStyle.base}
                                    onClick={() => window.open(window.origin + "/about/collections")} >
                                    <Icon className="material-icons collection-icon">info</Icon>
                                    About Collections
                                </ButtonBase>
                            </div>
                        </div>
                    </div>
                </Modal >
                <Modal
                    aria-labelledby="simple-modal-title"
                    aria-describedby="simple-modal-description"
                    open={this.state.addOpen}
                    onClose={this.handleAddCollectionToggle} >
                    <div style={getModalStyle()} className={classes.paper}>
                        <ButtonBase
                            style={{ position: "absolute", right: 15, top: 15 }}
                            onClick={() => this.handleAddCollectionToggle()} >
                            <Icon className="material-icons">clear</Icon>
                        </ButtonBase >
                        <this.addClass />
                    </div>
                </Modal>
                <Modal
                    aria-labelledby="simple-modal-title"
                    aria-describedby="simple-modal-description"
                    open={this.state.openOpen}
                    onClose={this.handleOpenCollectionToggle} >
                    <div style={getModalStyle()} className={classes.paper}>
                        <ButtonBase
                            style={{ position: "absolute", right: 15, top: 15 }}
                            onClick={() => this.handleOpenCollectionToggle()} >
                            <Icon className="material-icons">clear</Icon>
                        </ButtonBase >
                        <this.selectCollection />
                    </div>
                </Modal>
                <Modal
                    aria-labelledby="simple-modal-title"
                    aria-describedby="simple-modal-description"
                    open={this.state.deleteOpen}
                    onClose={this.handleDeleteCollectionToggle} >
                    <div style={getModalStyle()} className={classes.paper}>
                        <ButtonBase
                            style={{ position: "absolute", right: 15, top: 15 }}
                            onClick={() => this.handleDeleteCollectionToggle()} >
                            <Icon className="material-icons">clear</Icon>
                        </ButtonBase >
                        <this.deleteCollection />
                    </div>
                </Modal>
            </div >
        );
    }
}
const Collection = withStyles(modelStyles)(CollectionModal);
export default Collection;