Last active
February 21, 2020 17:26
-
-
Save DDavis1025/db77b2f7a44c2ea26a8b18ba7aa70952 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import ReactDOM from "react-dom"; | |
import styled from 'styled-components'; | |
import { Delete } from 'styled-icons/typicons/Delete'; | |
import Downloaded from './downloaded'; | |
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; | |
import { ButtonToggle } from "reactstrap"; | |
import { Container, Row, Col } from 'reactstrap'; | |
import axios from 'axios'; | |
const reorder = (list, startIndex, endIndex) => { | |
const result = Array.from(list); | |
const [removed] = result.splice(startIndex, 1); | |
result.splice(endIndex, 0, removed); | |
return result; | |
}; | |
const grid = 3; | |
const getItemStyle = (isDragging, draggableStyle) => ({ | |
userSelect: "none", | |
padding: grid * 2, | |
margin: `0 0 ${grid}px 0`, | |
background: isDragging ? "blue" : "white", | |
...draggableStyle | |
}); | |
const getListStyle = isDraggingOver => ({ | |
background: isDraggingOver ? "lightgrey" : "lightgrey", | |
padding: grid, | |
width: 700, | |
}); | |
const Handle = styled.div` | |
width: 20px; | |
height: 20px; | |
margin-top: 7.5px; | |
background-color: gray; | |
border-radius: 4px; | |
float: left; | |
` | |
const LIDelete = styled(Delete)` | |
width: 20px; | |
height: 20px; | |
color: gray; | |
float: right; | |
margin-top: -50px; | |
` | |
let id = 0; | |
class AddAlbum extends Component { | |
constructor(props) { | |
super(props); | |
this.handleClick = this.handleClick.bind(this); | |
this.replaceClick = this.replaceClick.bind(this); | |
this.onDragEnd = this.onDragEnd.bind(this); | |
this.secondInputClick = this.secondInputClick.bind(this); | |
this.clickFileInput = this.clickFileInput.bind(this); | |
this.replaceInput = this.replaceInput.bind(this); | |
this.clickAddFiles = this.clickAddFiles.bind(this); | |
this.handleChange = this.handleChange.bind(this); | |
this.downloadChange = this.downloadChange.bind(this); | |
this.onClick = this.onClick.bind(this); | |
this.onChange = this.onChange.bind(this); | |
this.save2 = this.save2.bind(this); | |
this.replaceInputRef = React.createRef(); | |
this.fileRef = React.createRef(); | |
this.inputRef = React.createRef(); | |
this.addFiles = React.createRef(); | |
this.resetFile = this.resetFile.bind(this); | |
this.removeItem = this.removeItem.bind(this) | |
this.state = { | |
beforeImageSave: null, | |
file: null, | |
files: [], | |
albums: {title:"", date:"", description:""}, | |
}; | |
} | |
onChange(event) { | |
console.log(event.target.files[0]) | |
this.setState({ | |
beforeImageSave: URL.createObjectURL(event.target.files[0]), | |
file: event.target.files[0], | |
loaded: 0, | |
}); | |
console.log(this.state.file) | |
} | |
resetFile(event) { | |
event.preventDefault(); | |
this.setState({ file: null }); | |
} | |
onClickHandler = () => { | |
const data = new FormData() | |
data.append('file', this.state.file) | |
axios.post("http://localhost:3000/albums", data, { | |
}).then(res => { // then print response status | |
console.log(res.statusText) | |
}) | |
} | |
downloadChange (event) { | |
const { name, value } = event.target; | |
this.setState(prevState => ({ | |
albums: {...prevState.albums, [name]: value} | |
})); | |
} | |
changeCursor = (e) => { | |
e.target.style.background = 'red'; | |
} | |
handleClick = event => { | |
// Helper code to read file and return promise | |
const readFile = (file) => { | |
const fileReader = new FileReader(); | |
// create the promise and return it | |
return new Promise((resolve, reject) => { | |
// if file reader has an error, report it | |
fileReader.onerror = (error) => { | |
reject({ error }) | |
} | |
// if success, resolve the promise | |
fileReader.onload = (e) => { | |
resolve({ | |
name: file.name.replace( /_|\.mp3/gi, " "), | |
id: id++, | |
}) | |
} | |
// start reading the file | |
fileReader.readAsArrayBuffer(file); | |
}) | |
} | |
// create all the file reader promises | |
// create an array from the files list and use map to generate | |
// an array of promises | |
const allReaders = Array.from(event.target.files).map(readFile) | |
// Now handle the array of promises we just created | |
Promise.all(allReaders) | |
.then(fileList => { | |
// set the state that we have all the files | |
this.setState({ files: fileList }); | |
console.log(this.state.files) | |
}) | |
.catch(error => { | |
console.error(error) | |
}); | |
} | |
replaceClick = event => { | |
const readFile = (file) => { | |
const fileReader = new FileReader(); | |
// create the promise and return it | |
return new Promise((resolve, reject) => { | |
// if file reader has an error, report it | |
fileReader.onerror = (error) => { | |
reject({ error }) | |
} | |
// if success, resolve the promise | |
fileReader.onload = (e) => { | |
resolve({ | |
name: file.name.replace( /_|\.mp3/gi, " "), | |
id: id++, | |
}) | |
} | |
// start reading the file | |
fileReader.readAsDataURL(file); | |
}) | |
} | |
// create all the file reader promises | |
// create an array from the files list and use map to generate | |
// an array of promises | |
const allReaders = Array.from(event.target.files).map(readFile) | |
// Now handle the array of promises we just created | |
Promise.all(allReaders) | |
.then(fileList => { | |
console.log(this.state.files) | |
// set the state that we have all the files | |
this.setState({ files: fileList }); | |
}) | |
.catch(error => { | |
console.error(error) | |
}); | |
clicked = true; | |
} | |
secondInputClick = event => { | |
// Helper code to read file and return promise | |
const readFile = (file) => { | |
const fileReader = new FileReader(); | |
// create the promise and return it | |
return new Promise((resolve, reject) => { | |
// if file reader has an error, report it | |
fileReader.onerror = (error) => { | |
reject({ error }) | |
} | |
// if success, resolve the promise | |
fileReader.onload = (e) => { | |
resolve({ | |
name: file.name.replace( /_|\.mp3/gi, " "), | |
id: id++, | |
}) | |
} | |
// start reading the file | |
fileReader.readAsDataURL(file); | |
}) | |
} | |
// create all the file reader promises | |
// create an array from the files list and use map to generate | |
// an array of promises | |
const allReaders = Array.from(event.target.files).map(readFile) | |
// Now handle the array of promises we just created | |
Promise.all(allReaders) | |
.then(fileList => { | |
console.log(this.state.files) | |
// set the state that we have all the files | |
this.setState(prevState => ({ ...prevState, files: [...prevState.files, ...fileList ]})); | |
}) | |
.catch(error => { | |
console.error(error) | |
}); | |
} | |
async save2(event) { | |
event.preventDefault(); | |
await this.setState(prevState => ({ | |
files: prevState.files.map((file, index) => ({...file, index}) | |
)})); | |
let files = this.state.files; | |
await this.setState(prevState => ({ | |
albums: {...prevState.albums, files} | |
})) | |
let albums = this.state.albums; | |
console.log(albums); | |
axios.post("http://localhost:3000/albums", albums, { | |
}).then(res => { // then print response status | |
console.log(res.statusText) | |
}) | |
} | |
onDragEnd(result) { | |
// dropped outside the list | |
if (!result.destination) { | |
return; | |
} | |
const files = reorder( | |
this.state.files, | |
result.source.index, | |
result.destination.index | |
); | |
this.setState({ | |
files | |
}); | |
} | |
removeItem = (index) => { | |
this.setState(({ files }) => ({ | |
files: files.filter((_, ind) => ind !== index) })); | |
} | |
clickFileInput() { | |
this.inputRef.current.click(); | |
} | |
replaceInput() { | |
this.replaceInputRef.current.click(); | |
} | |
clickAddFiles () { | |
this.addFiles.current.click(); | |
} | |
handleChange(index, event) { | |
let files = this.state.files.slice(); | |
files[index].name = event.target.value; | |
this.setState({ files: files }); | |
} | |
onClick(event) { | |
let albums = this.state.albums; | |
if(albums.date === "" || albums.title === "" || albums.description === "") { | |
alert("ERROR: Fields Must Be Filled In Before You Save"); | |
} else { | |
this.save2(event); | |
} | |
} | |
render() { | |
const filesExist = this.state.files; | |
return ( | |
<div className="downloadMusic"> | |
<Container> | |
<Row> | |
<Col> | |
<div> | |
{filesExist != 0 ? ( | |
<ButtonToggle onClick={this.replaceInput} color="secondary">Replace Music Files | |
</ButtonToggle> | |
) : ( | |
<ButtonToggle onClick={this.clickFileInput} color="secondary">Upload Files | |
</ButtonToggle> | |
)} | |
</div> | |
<div className="input"> | |
<input | |
accept="audio/*" | |
id="upload-file" | |
onChange={this.handleClick} | |
className="inputName" | |
type="file" | |
multiple | |
style={{display:"none"}} | |
ref={this.inputRef} | |
/> | |
<input | |
accept="audio/*" | |
id="upload-file" | |
onChange={this.replaceClick} | |
className="inputName" | |
type="file" | |
multiple | |
style={{display:"none"}} | |
ref={this.replaceInputRef} | |
/> | |
</div> | |
</Col> | |
</Row> | |
</Container> | |
<div>{this.state.files.length > 0 && | |
<Downloaded | |
beforeImageSave={this.state.beforeImageSave} | |
file={this.state.file} | |
onChange={this.onChange} | |
onSubmit={this.onSubmit} | |
key={this.state.albums.id} | |
onClick={this.resetFile} | |
album={this.state.albums} | |
downloadChange={this.downloadChange} | |
/> | |
}</div> | |
<Container> | |
<Row> | |
<Col> | |
<DragDropContext onDragEnd={this.onDragEnd}> | |
<Droppable droppableId="droppable"> | |
{(provided, snapshot) => ( | |
<div | |
{...provided.droppableProps} | |
ref={provided.innerRef} | |
style={getListStyle(snapshot.isDraggingOver)} | |
> | |
{this.state.files.map((file, index) => ( | |
<Draggable key={file.id.toString()} draggableId={file.id.toString()} index={index} style={{marginTop:"400px"}}> | |
{(provided, snapshot) => ( | |
<div | |
ref={provided.innerRef} | |
{...provided.draggableProps} | |
style={getItemStyle( | |
snapshot.isDragging, | |
provided.draggableProps.style | |
)} | |
> | |
<div className="handle"> | |
<Handle {...provided.dragHandleProps}/> | |
</div> | |
<div> | |
<form> | |
<label> | |
<p> <input type="text" value={file.name} onChange={this.handleChange.bind(this, index)} name="name" ref={this.fileRef} style={{width:'600px', height:'30px', fontSize: '16px'}} /></p> | |
</label> | |
</form> | |
</div> | |
<div className="delete"> | |
<LIDelete onClick = {() => this.removeItem(index)}/> | |
</div> | |
</div> | |
)} | |
</Draggable> | |
))} | |
{provided.placeholder} | |
</div> | |
)} | |
</Droppable> | |
</DragDropContext> | |
</Col> | |
</Row> | |
</Container> | |
<Container> | |
<div className="belowList">{this.state.files.length > 0 && <div> | |
<Row> | |
<Col> | |
<ButtonToggle onClick={this.clickAddFiles} color="secondary">Add More Files | |
</ButtonToggle> | |
<input | |
accept="audio/*" | |
onChange={this.secondInputClick} | |
id="second-input" | |
className="inputName" | |
type="file" | |
multiple | |
style={{display:"none"}} | |
ref={this.addFiles} | |
/> | |
</Col> | |
</Row> | |
</div> | |
}</div> | |
<Row> | |
<Col> | |
<ButtonToggle onClick={this.onClick} color="success">Save | |
</ButtonToggle> | |
</Col> | |
</Row> | |
</Container> | |
</div> | |
); | |
} | |
} | |
export default AddAlbum; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from 'react'; | |
import { BrowserRouter, Router, Route, Switch } from "react-router-dom"; | |
import Profile from "./components/Profile"; | |
import history from "./utils/history"; | |
import './css/styles.css'; | |
import Navbar from './components/navbar'; | |
import Downloaded from './components/downloaded'; | |
import DownloadTest from './components/downloadTest'; | |
import ImageUpload from './components/image-upload'; | |
import AddAlbum from './components/add-album'; | |
import Album from './components/album'; | |
import 'bootstrap/dist/css/bootstrap.min.css'; | |
import NavBar2 from "./components/NavBar2"; | |
import { useAuth0 } from "./react-auth0-spa"; | |
import PrivateRoute from "./components/PrivateRoute"; | |
import Upload from "./components/upload"; | |
class App extends Component { | |
render() { | |
return ( | |
<BrowserRouter> | |
<div className="App"> | |
<Router history={history}> | |
<NavBar2 /> | |
<Navbar title="Oscars 2019"/> | |
<Switch> | |
<Route path="/" exact /> | |
<PrivateRoute path="/profile" component={Profile} /> | |
</Switch> | |
<Route exact path="/" render={() => <DownloadTest />} /> | |
<Route path="/download-test" component={DownloadTest} /> | |
<Route path="/image-upload" component={ImageUpload}/> | |
<Route path="/add-album" component={AddAlbum}/> | |
<Route path="/downloaded" component={Downloaded} /> | |
<Route path="/album/create" component={AddAlbum}/> | |
<Route path="/albums/:albumId" component={Album}/> | |
<Route path="/upload" component={Upload}/> | |
</Router> | |
</div> | |
</BrowserRouter> | |
); | |
} | |
} | |
export default App; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { Component } from "react"; | |
import ReactDOM from "react-dom"; | |
import { Link } from 'react-router-dom'; | |
import ImageUpload from './image-upload'; | |
import AddAlbum from './add-album'; | |
import { Container, Row, Col } from 'reactstrap'; | |
import { Button, Form, FormGroup, Label, Input, FormText } from 'reactstrap'; | |
class Downloaded extends Component { | |
constructor(props) { | |
super(props); | |
} | |
render() { | |
return( | |
<div className="main-content"> | |
<Container> | |
<div className="container"> | |
<div className="downloaded"> | |
<Row xs="2" className="downloaded-row"> | |
<Col xs="7" sm="10" md="6" lg="5" className=""> | |
<div className="image"><ImageUpload file={this.props.file} beforeImageSave={this.props.beforeImageSave} onChange={this.props.onChange} onClick={this.props.onClick}/></div> | |
</Col> | |
<Col xs="6" sm="2" md="5" lg="5" className=""> | |
<Form onSubmit={this.props.onSubmit} className="form"> | |
<FormGroup row> | |
<Label for="title">Title:</Label> | |
<Input type="text" name="title" id="title" placeholder="Title" value={this.props.album.title} onChange={this.props.downloadChange}/> | |
</FormGroup> | |
<FormGroup row> | |
<Label for="date">Date:</Label> | |
<Input type="date" name="date" id="date" placeholder="Date" value={this.props.album.date.slice(0, 10)} onChange={this.props.downloadChange} required="required"/> | |
</FormGroup> | |
<FormGroup row> | |
<Label for="description">Description:</Label> | |
<Input type="textarea" name="description" id="description" placeholder="Description" value={this.props.album.description} onChange={this.props.downloadChange}/> | |
</FormGroup> | |
</Form> | |
</Col> | |
</Row> | |
</div> | |
</div> | |
</Container> | |
</div> | |
); | |
} | |
}; | |
export default Downloaded; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import ReactDom from 'react-dom'; | |
import { ButtonToggle } from "reactstrap"; | |
class ImageUpload extends React.Component { | |
constructor(props) { | |
super(props); | |
this.clickAddImage = this.clickAddImage.bind(this); | |
this.imageRef = React.createRef(); | |
} | |
clickAddImage () { | |
this.imageRef.current.click(); | |
} | |
render() { | |
return ( | |
<div> | |
<label> | |
<ButtonToggle onClick={this.clickAddImage} outline color="secondary">Add Image | |
</ButtonToggle> | |
<input type="file" style={{display:"none"}} accept="image/*" ref={this.imageRef} onChange={this.props.onChange} /> | |
</label> | |
<div className="image" style={{ width: '300px', height: '300px', | |
border: '1px dotted black'}}> | |
{this.props.file && ( | |
<img style={{ width: "300px", height: "300px"}} src={this.props.file[0] ? "http://localhost:3000/" + this.props.file[0].path : this.props.beforeImageSave} /> | |
)} | |
</div> | |
{this.props.file && this.props.file.length !== 0 && ( | |
<div> | |
<ButtonToggle onClick={this.props.onClick} color="danger" size="sm">Remove Image | |
</ButtonToggle> | |
</div> | |
)} | |
</div> | |
); | |
} | |
} | |
export default ImageUpload; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// src/index.js | |
import React from "react"; | |
import ReactDOM from "react-dom"; | |
import App from "./App"; | |
import * as serviceWorker from "./serviceWorker"; | |
import { Auth0Provider } from "./react-auth0-spa"; | |
import config from "./auth_config.json"; | |
import history from "./utils/history"; | |
// A function that routes the user to the right place | |
// after login | |
const onRedirectCallback = appState => { | |
history.push( | |
appState && appState.targetUrl | |
? appState.targetUrl | |
: window.location.pathname | |
); | |
}; | |
ReactDOM.render( | |
<Auth0Provider | |
domain={config.domain} | |
client_id={config.clientId} | |
redirect_uri={window.location.origin} | |
onRedirectCallback={onRedirectCallback} | |
> | |
<App /> | |
</Auth0Provider>, | |
document.getElementById("root") | |
); | |
serviceWorker.unregister(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment