From 6b061dde92ce2086c522adb34a1ceb9330f01fe3 Mon Sep 17 00:00:00 2001 From: DieMyst Date: Fri, 16 Aug 2019 17:20:50 +0300 Subject: [PATCH] init frontend --- frontend/src/actions/messages.js | 36 ++++++++++++++ frontend/src/actions/shared.js | 21 ++++++++ frontend/src/components/App.js | 42 ++++++++++++++++ frontend/src/components/Dashboard.js | 30 +++++++++++ frontend/src/components/Message.js | 34 +++++++++++++ frontend/src/components/NewMessage.js | 71 +++++++++++++++++++++++++++ frontend/src/middleware/index.js | 6 +++ frontend/src/middleware/logger.js | 11 +++++ frontend/src/reducers/index.js | 10 ++++ frontend/src/reducers/messages.js | 20 ++++++++ frontend/src/utils/_DATA.js | 48 ++++++++++++++++++ frontend/src/utils/api.js | 38 ++++++++++++++ 12 files changed, 367 insertions(+) create mode 100644 frontend/src/actions/messages.js create mode 100644 frontend/src/actions/shared.js create mode 100644 frontend/src/components/App.js create mode 100644 frontend/src/components/Dashboard.js create mode 100644 frontend/src/components/Message.js create mode 100644 frontend/src/components/NewMessage.js create mode 100644 frontend/src/middleware/index.js create mode 100644 frontend/src/middleware/logger.js create mode 100644 frontend/src/reducers/index.js create mode 100644 frontend/src/reducers/messages.js create mode 100644 frontend/src/utils/_DATA.js create mode 100644 frontend/src/utils/api.js diff --git a/frontend/src/actions/messages.js b/frontend/src/actions/messages.js new file mode 100644 index 0000000..ab3fda5 --- /dev/null +++ b/frontend/src/actions/messages.js @@ -0,0 +1,36 @@ +import { saveMessage } from "../utils/api"; + +//importing loading bar to show when we submit a tweet +import { showLoading, hideLoading } from "react-redux-loading"; + +export const ADD_MESSAGE = "ADD_MESSAGE"; +export const RECEIVE_MESSAGES = "RECEIVE_MESSAGES"; + +function addMessage(message) { + return { + type: ADD_MESSAGE, + message + }; +} + +//args: message text and the message that the newTweet is replying to, if any +export function handleAddMessage(text, name) { + //using getState to get the current state of our store + return (dispatch) => { + dispatch(showLoading()); + return saveMessage({ + text: text, + name: name + }) + .then(message => dispatch(addMessage(message))) + .then(() => dispatch(hideLoading())); + }; +} + +//action creator +export function receiveMessages(messages) { + return { + type: RECEIVE_MESSAGES, + messages + }; +} diff --git a/frontend/src/actions/shared.js b/frontend/src/actions/shared.js new file mode 100644 index 0000000..47b3503 --- /dev/null +++ b/frontend/src/actions/shared.js @@ -0,0 +1,21 @@ +import { getMessages } from "../utils/api"; + +//importing action creators +import { receiveMessages } from "./messages"; + +//importing action creators of loading bar +import { showLoading, hideLoading } from "react-redux-loading"; + +export function handleInitialData() { + return dispatch => { + //before retrieving info, show loading bar + dispatch(showLoading()); + + return getMessages().then((messages) => { + dispatch(receiveMessages(messages)); + + //after everything has loaded, hide loading bar + dispatch(hideLoading()); + }); + }; +} diff --git a/frontend/src/components/App.js b/frontend/src/components/App.js new file mode 100644 index 0000000..4de2b95 --- /dev/null +++ b/frontend/src/components/App.js @@ -0,0 +1,42 @@ +import React, { Component, Fragment } from "react"; +import { BrowserRouter as Router, Route } from "react-router-dom"; +import { connect } from "react-redux"; +import { handleInitialData } from "../actions/shared"; + +import LoadingBar from "react-redux-loading"; //importing the loading bar given by react-redux-loading + +import Dashboard from "./Dashboard"; +import NewMessage from "./NewMessage"; + +class App extends Component { + componentDidMount() { + this.props.dispatch(handleInitialData()); + } + + render() { + return ( + + {/* using a fragment so we don't add another element (div) to the DOM */} + + +
+ {this.props.loading === true ? null : ( +
+ + +
+ )} +
+
+
+ ); + } +} + +function mapStateToProps({ }) { + return { + + }; +} + +export default connect(mapStateToProps)(App); diff --git a/frontend/src/components/Dashboard.js b/frontend/src/components/Dashboard.js new file mode 100644 index 0000000..bd6867f --- /dev/null +++ b/frontend/src/components/Dashboard.js @@ -0,0 +1,30 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; + +import Message from "./Message"; + +class Dashboard extends Component { + render() { + return ( +
+

Your Timeline

+ +
+ ); + } +} + +//destructuring messages from state +function mapStateToProps(state) { + return state; +} + +export default connect(mapStateToProps)(Dashboard); diff --git a/frontend/src/components/Message.js b/frontend/src/components/Message.js new file mode 100644 index 0000000..3c8fd1e --- /dev/null +++ b/frontend/src/components/Message.js @@ -0,0 +1,34 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { withRouter } from "react-router-dom"; + +class Message extends Component { + render() { + const { message } = this.props; + + if (message === null) { + return

This message doesn't exist

; + } + + const { + name, + text + } = message; + + return ( +
+
+ {name} +

{text}

+
+
+ ); + } +} + +function mapStateToProps(message) { + return message; +} + +//using withRouter because this component is not being rendered by react router, so to have access to history props, we need to use withRouter +export default withRouter(connect(mapStateToProps)(Message)); diff --git a/frontend/src/components/NewMessage.js b/frontend/src/components/NewMessage.js new file mode 100644 index 0000000..9ba45ad --- /dev/null +++ b/frontend/src/components/NewMessage.js @@ -0,0 +1,71 @@ +import React, { Component } from "react"; +import { connect } from "react-redux"; +import { handleAddMessage } from "../actions/messages"; + +class NewMessage extends Component { + state = { + text: "", + name: "" + }; + + handleChangeText = e => { + const text = e.target.value; + + this.setState(() => ({ + text + })); + }; + + handleChangeName = e => { + const name = e.target.value; + + this.setState(() => ({ + name + })); + }; + + handleSubmit = e => { + e.preventDefault(); + const { text, name } = this.state; + + const { dispatch } = this.props; + + dispatch(handleAddMessage(text, name)); + + //reset state to default + this.setState(() => ({ + text: "", + name: "" + })); + }; + + render() { + const { text, name } = this.state; + const messageLeft = 280 - text.length; + + return ( +
+

Compose new Tweet

+
+