Commit 009d1583 authored by Daniel Rilo's avatar Daniel Rilo

Final day

parent 025047a9
......@@ -13,7 +13,8 @@
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
"eject": "react-scripts eject",
"start-json": "json-server db.json --port=3004"
},
"eslintConfig": {
"extends": "react-app"
......
......@@ -98,7 +98,7 @@ class App extends Component {
// ]
// }
// };
constructor(props) {
super(props);
this.state = {
......@@ -110,7 +110,7 @@ class App extends Component {
componentDidMount() {
const SERVER = Config.SERVER;
const interval = setInterval(() => {
this.callMessages(SERVER);
}, 1000);
......@@ -120,7 +120,7 @@ class App extends Component {
fetch(`${SERVER}/people`)
.then(res => res.json())
.then(res => this.setState({ people: res}))
.then(res => this.setState({ people: res }))
.catch(err => console.err('Error with people: ', err));
}
......@@ -128,7 +128,7 @@ class App extends Component {
clearInterval(this.state.dateInterval);
}
callMessages = (SERVER) => fetch(`${SERVER}/messages`).then(res => res.json()).then(res => this.setState({ messages: res})).catch(err => console.err('Error with messages: ', err));
callMessages = (SERVER) => fetch(`${SERVER}/messages`).then(res => res.json()).then(res => this.setState({ messages: res })).catch(err => console.err('Error with messages: ', err));
render() {
return (
......
.App {
text-align: center;
text-align: center;
}
.App-logo {
animation: App-logo-spin infinite 20s linear;
height: 40vmin;
pointer-events: none;
animation: App-logo-spin infinite 20s linear;
height: 40vmin;
pointer-events: none;
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
......@@ -5,22 +5,22 @@ import AvatarHeader from './AvatarHeader';
import Config from './Config';
const useCallPeople = SERVER => {
console.log("useCallPeople:");
const [people, setPeople] = useState([]);
fetch(`${SERVER}/people`)
.then(res => res.json())
.then(res => setPeople(res))
.catch(err => {
console.error('Error with people: ', err)
setPeople([])
});
return people;
useEffect(() => {
fetch(`${SERVER}/people`)
.then(res => res.json())
.then(res => setPeople(res))
.catch(err => {
console.error('Error with people: ', err)
setPeople([])
});
}, []);
return people;
}
const useCallMessages = SERVER => {
console.log("useCallMessages");
const [messages, setMessages] = useState([]);
useEffect(() => {
......@@ -32,33 +32,19 @@ const useCallMessages = SERVER => {
console.error('Error with messages: ', err)
setMessages([]);
});
}, 1000);
}, Config.TIMER);
return () => clearInterval(messagesTimer);
});
}, []);
return messages;
return messages;
}
const App = props => {
const SERVER = Config.SERVER;
// useEffect(() => {
// console.log("useEffect Messages");
// let messagesTimer = setInterval(() => {
// fetch(`${SERVER}/messages`)
// .then(res => res.json())
// .then(res => {
// setMessages(res)
// })
// .catch(err => console.error('Error with messages: ', err));
// }, 1000);
// return () => clearInterval(messagesTimer);
// }, []);
return (
<div>
<AvatarHeader peoples={useCallMessages(SERVER) } />
<AvatarHeader peoples={useCallPeople(SERVER)} />
<ChatRoom body={{ people: useCallPeople(SERVER), messages: useCallMessages(SERVER) }} />
</div>
);
......
......@@ -3,15 +3,15 @@ import React from 'react';
// This is a function, that is why I have to create a varible BEFORE the return statement.
// In this varible, I'll calculate the link to the avatar image.
const Avatar = (props) => {
const imgID = `avatars/${props.people.id}.png`;
const name = props.people.name;
const imgID = `avatars/${props.people.id}.png`;
const name = props.people.name;
return (
<div className={`chat__avatar ${props.selectedOne === name ? 'selected' : ''}`} onClick={props.clickFnd}>
<img src={imgID} alt='Avatar' />
<p>{name}</p>
</div>
);
return (
<div className={`chat__avatar ${props.selectedOne === name ? 'selected' : ''}`} onClick={props.clickFnd}>
<img src={imgID} alt='Avatar' />
<p>{name}</p>
</div>
);
}
export default Avatar;
\ No newline at end of file
......@@ -13,16 +13,16 @@ class AvatarHeader extends Component {
e.preventDefault();
this.setState({ nameSelected: people.name })
};
render() {
return (
<div>
<h1 className="chat__title">Selecciona tu perfil</h1>
{ this.state.nameSelected ? <p className="chat__selected-one">Perfil seleccionado: <span className="chat__selected-one-name">{this.state.nameSelected}</span></p> : <p className="chat__selected-one">Por favor, selecciona un perfil</p>}
{this.state.nameSelected ? <p className="chat__selected-one">Perfil seleccionado: <span className="chat__selected-one-name">{this.state.nameSelected}</span></p> : <p className="chat__selected-one">Por favor, selecciona un perfil</p>}
<div className="chat__avatar-display">
{
/* this.props.peoples.map(el => <a href="/#" onClick={e => {this.selectPeople(e, el)}} key={el.id} className={this.state.nameSelected === el.name ? 'selected' : '' }><Avatar people={el} /> </a>) */
this.props.peoples.map(el => <Avatar key={el.id} people={el} clickFnd={e => {this.selectPeople(e, el)}} selectedOne={this.state.nameSelected} /> )
/* this.props.peoples.map(el => <a href="/#" onClick={e => {this.selectPeople(e, el)}} key={el.id} className={this.state.nameSelected === el.name ? 'selected' : '' }><Avatar people={el} /> </a>) */
this.props.peoples.map(el => <Avatar key={el.id} people={el} clickFnd={e => { this.selectPeople(e, el) }} selectedOne={this.state.nameSelected} />)
}
</div>
</div>
......
import React, { Component } from 'react';
import ChatRoomHeader from './ChatRoomHeader';
// import ChatRoomHeader from './ChatRoomHeader';
import ChatRoomHeader from './ChatRoomHeader.hoc';
import SendMessage from './SendMessage';
class ChatRoom extends Component {
render() {
console.log(this.props)
return (
<div className="chat">
{/* <ChatRoomHeader body={this.state.messages[0]['body']}/> */}
<SendMessage/>
<ChatRoomHeader body={this.props}/>
<SendMessage />
<ChatRoomHeader body={this.props} />
</div>
);
}
......
import React, { Component } from 'react';
import moment from 'moment';
import Message from './Message';
import withInterval from './hoc/withInterval';
import Config from './Config';
class ChatRoomHeader extends Component {
render() {
return (
<div className="chat__room-header">
<div className="chat__room-hour">
{this.props.data}
</div>
{this.props.body.body.messages.map(el => this.props.body.body.people.map(el2 => (el2.id === el.author) ? <Message key={el.id} body={el} msg={el2} /> : ''))}
</div>
);
}
}
const newDate = () => moment().format('h:mm:ss, Do MMMM YYYY');
export default withInterval(newDate, Config.TIMER)(ChatRoomHeader);
\ No newline at end of file
import React, { Component } from 'react';
import moment from 'moment';
import Message from './Message';
import Config from './Config'
class ChatRoomHeader extends Component {
constructor(props) {
......@@ -12,14 +13,10 @@ class ChatRoomHeader extends Component {
}
componentDidMount() {
const interval = setInterval(() => this.setState({ hour: newDate() }), 1000);
const interval = setInterval(() => this.setState({ hour: newDate() }), Config.TIMER);
this.setState({ dateInterval: interval });
}
// componentDidUpdate() {
// console.log("componentDidUpdate");
// }
componentWillUnmount() {
clearInterval(this.state.dateInterval);
}
......@@ -30,10 +27,7 @@ class ChatRoomHeader extends Component {
<div className="chat__room-hour">
{this.state.hour}
</div>
{
this.props.body.body.messages.map(el => this.props.body.body.people.map(el2 => (el2.id === el.author) ? <Message key={el.id} body={el} msg={el2} /> : ''))
/* this.props.body.messages.map(el => this.props.body.people.find(el2 => el2.id === el.author ? <Message key={el.id} body={el} msg={el2} />)) */
}
{this.props.body.body.messages.map(el => this.props.body.body.people.map(el2 => (el2.id === el.author) ? <Message key={el.id} body={el} msg={el2} /> : ''))}
</div>
);
}
......@@ -41,5 +35,4 @@ class ChatRoomHeader extends Component {
const newDate = () => moment().format('h:mm:ss, Do MMMM YYYY');
export default ChatRoomHeader;
export default ChatRoomHeader;
\ No newline at end of file
const CONFIG = {
SERVER: 'http://localhost:3004'
SERVER: 'http://localhost:3004',
TIMER: 1000
}
export default CONFIG;
\ No newline at end of file
......@@ -3,7 +3,7 @@ import Avatar from './Avatar';
import MessageBody from './MessageBody';
class Message extends Component {
render() {
render() {
return (
<div className="chat__message">
<Avatar people={this.props.msg} />
......
......@@ -4,11 +4,10 @@ import moment from 'moment';
class MessageBody extends Component {
render() {
return (
<div className="chat__message-body">
<div className="chat__message-header">enviado a las {formatDate(this.props.msg.date)}</div>
{/* <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam arcu nisi, accumsan sit amet nisl in, dictum ornare mauris. Maecenas interdum interdum eros vitae volutpat.</p> */ }
<p>{this.props.msg.body}</p>
</div>
<div className="chat__message-body">
<div className="chat__message-header">enviado a las {formatDate(this.props.msg.date)}</div>
<p>{this.props.msg.body}</p>
</div>
);
}
}
......
......@@ -3,68 +3,67 @@ import moment from 'moment';
import Config from './Config';
class SendMessage extends Component {
constructor(props) {
super(props);
this.state = {
text: '',
error: ''
}
constructor(props) {
super(props);
this.state = {
text: '',
error: ''
}
}
inputFormHandler = e => {
this.setState({ text: e.target.value });
};
submitFormController = e => {
e.preventDefault();
if (this.state.text) {
this.setState({ error: ''})
} else {
this.setState({ error: 'El texto no puede estar vacío'})
return false;
}
inputFormHandler = e => {
this.setState({ text: e.target.value });
};
const SERVER = Config.SERVER;
fetch(`${SERVER}/messages`, {
method: "post",
headers: {
"Content-Type": "application/json" // <--- don't forget this!
},
body: JSON.stringify({
// author: this.props.authorId,
author: 456317,
body: this.state.text,
date: moment().format()
})
})
.then(res => res.json())
.then(res => {
console.log("Resp:", res)
this.setState({
text: '',
error: ''
})
})
.catch(e => console.error(e));
};
render() {
return (
<div className="chat__form-wrapper">
{ this.state.error ? <p className="chat__form-error">{this.state.error}</p> : '' }
<form onSubmit={this.submitFormController} className="chat__form">
<div className="chat__form-header">
<div className="chat__form-header-avatar"><img src='avatars/456317.png' alt='Avatar' /></div>
<div className="chat__form-header-name">Ze Pequenho</div>
</div>
<div className="chat__form-submit">
<input type="text" value={this.state.text} onChange={e => this.inputFormHandler(e)} />
<button>Submit</button>
</div>
</form>
</div>
);
submitFormController = e => {
e.preventDefault();
if (this.state.text) {
this.setState({ error: '' })
} else {
this.setState({ error: 'El texto no puede estar vacío' })
return false;
}
const SERVER = Config.SERVER;
fetch(`${SERVER}/messages`, {
method: "post",
headers: {
"Content-Type": "application/json" // <--- don't forget this!
},
body: JSON.stringify({
author: 456317,
body: this.state.text,
date: moment().format()
})
})
.then(res => res.json())
.then(res => {
console.log("Resp:", res)
this.setState({
text: '',
error: ''
})
})
.catch(e => console.error(e));
};
render() {
return (
<div className="chat__form-wrapper">
{this.state.error ? <p className="chat__form-error">{this.state.error}</p> : ''}
<form onSubmit={this.submitFormController} className="chat__form">
<div className="chat__form-header">
<div className="chat__form-header-avatar"><img src='avatars/456317.png' alt='Avatar' /></div>
<div className="chat__form-header-name">Ze Pequenho</div>
</div>
<div className="chat__form-submit">
<input type="text" value={this.state.text} onChange={e => this.inputFormHandler(e)} />
<button>Submit</button>
</div>
</form>
</div>
);
}
}
export default SendMessage;
import React from 'react';
const withInterval = (effectFunction, time) => WrappedComponent => {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
timer: null,
data: effectFunction()
}
}
componentDidMount() {
let timer = setInterval(() => this.setState({ data: effectFunction() }), time);
this.setState({ timer: timer });
}
componentWillUnmount() {
clearInterval(this.state.timer);
}
render() {
return <WrappedComponent {...this.props} data={this.state.data} />;
}
};
};
export default withInterval;
\ No newline at end of file
<
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-size:62.5%;
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans",
"Droid Sans", "Helvetica Neue", sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-size: 62.5%;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
}
#root {
margin: 0 auto;
width: 50%;
margin: 0 auto;
width: 50%;
}
img {
display: block;
height: auto;
margin: 0 auto;
width: 50%;
display: block;
height: auto;
margin: 0 auto;
width: 50%;
}
.chat__room-header {
border: .1rem dashed #ddd;
border: 0.1rem dashed #ddd;
}
.chat__room-hour {
background-color: aliceblue;
border-bottom: .1rem dashed #ddd;
padding: .5rem 0;
text-align: center;
background-color: aliceblue;
border-bottom: 0.1rem dashed #ddd;
padding: 0.5rem 0;
text-align: center;
}
.chat__message {
border: .1rem solid grey;
border-radius: .5rem;
margin: .5rem;
display: flex;
justify-content: space-between;
padding: .5rem;
border: 0.1rem solid grey;
border-radius: 0.5rem;
margin: 0.5rem;
display: flex;
justify-content: space-between;
padding: 0.5rem;
}
.chat__message-body {
border: .1rem solid #333;
flex: 0 0 73%;
border: 0.1rem solid #333;
flex: 0 0 73%;
}
.chat__message-body p {
padding: .5rem;
padding: 0.5rem;
}
.chat__message-header {
border-bottom: .1rem solid #333;
padding: .5rem;
border-bottom: 0.1rem solid #333;
padding: 0.5rem;
}
.chat__avatar-display p {
text-align: center;
text-align: center;
}
.chat__avatar-display {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.chat__avatar-display > div {
flex: 0 0 20%;
margin-bottom: 1.5rem;
border: .1rem solid #eee;
padding: .5rem;
flex: 0 0 20%;
margin-bottom: 1.5rem;
border: 0.1rem solid #eee;
padding: 0.5rem;
}
.chat__avatar-display > div.selected {
border: .1rem solid #f00;
border: 0.1rem solid #f00;
}
.chat__avatar-display >div:hover {
background-color: rgba(0, 0, 0, .1);
cursor: pointer;
.chat__avatar-display > div:hover {
background-color: rgba(0, 0, 0, 0.1);
cursor: pointer;
}
.chat__title {
font-size: 2rem;
text-align: center;
font-size: 2rem;
text-align: center;
}
.chat__selected-one {
font-size: 1.4rem;
font-size: 1.4rem;
}
.chat__selected-one-name {
font-size: 1.2rem;
font-weight: 700;
text-decoration: underline;
font-size: 1.2rem;
font-weight: 700;
text-decoration: underline;
}
.chat__form-error {
color: #f00;
font-size: 1.4rem;
padding: .5rem;
border: .1rem dashed #f00;
font-weight: 700;
margin: .5rem;
color: #f00;
font-size: 1.4rem;
padding: 0.5rem;
border: 0.1rem dashed #f00;
font-weight: 700;
margin: 0.5rem;
}
.chat__form-header {
display: flex;
border-bottom: .1rem solid #eee;
justify-content: flex-end;
padding: .5rem;
display: flex;
border-bottom: 0.1rem solid #eee;