Skip to content
Snippets Groups Projects
Commit 4cef50eb authored by safarte's avatar safarte
Browse files

sol

parent 16f2b70d
No related branches found
No related tags found
No related merge requests found
# Formation React
This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
By Safarte and Soudini
## Available Scripts
## Install
In the project directory, you can run:
* Install NodeJS
* Install yarn
* Run:
### `yarn start`
```bash
git clone https://gitlab.viarezo.fr/LinkCS/react-tutorial-front.git
cd react-tutorial-front
yarn install
```
Runs the app in the development mode.<br />
Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
## Usage
The page will reload if you make edits.<br />
You will also see any lint errors in the console.
You need to complete the code if you want the website to work properly !
### `yarn test`
To run this website locally execute `yarn start` in the working directory.
Launches the test runner in the interactive watch mode.<br />
See the section about [running tests](https://facebook.github.io/create-react-app/docs/running-tests) for more information.
## API
### `yarn build`
`GET /users => [Object]` -> Lists all users
Builds the app for production to the `build` folder.<br />
It correctly bundles React in production mode and optimizes the build for the best performance.
`GET /users/id => Object` -> Get the info about the user with asked id
The build is minified and the filenames include the hashes.<br />
Your app is ready to be deployed!
`GET /boards => [Object]` -> Lists all boards
See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information.
`GET /boards/id => Object` -> Get the info about the board with asked id
### `yarn eject`
`GET /messages?board=id => [Object]` -> Get the messages from the board with asked id
**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
To post a message from specified user on specified board:
If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
```json
POST /messages
body:
{
"content": "blabla",
"userId": 42,
"boardId": 1
}
```
Instead, it will copy all the configuration files and the transitive dependencies (Webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
To register a new user (returns the user):
You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
```json
POST /users => Object
body:
{
"username": "henry",
"paswword": "verysecure"
}
```
## Learn More
To login an user (returns a list containing the matching users):
You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
```json
POST /login => [Object]
body:
{
"username": "henry",
"paswword": "verysecure"
}
```
To learn React, check out the [React documentation](https://reactjs.org/).
### Code Splitting
This section has moved here: https://facebook.github.io/create-react-app/docs/code-splitting
### Analyzing the Bundle Size
This section has moved here: https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size
### Making a Progressive Web App
This section has moved here: https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app
### Advanced Configuration
This section has moved here: https://facebook.github.io/create-react-app/docs/advanced-configuration
### Deployment
This section has moved here: https://facebook.github.io/create-react-app/docs/deployment
### `yarn build` fails to minify
This section has moved here: https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify
......@@ -6,21 +6,12 @@ import Board from './components/Board';
import Login from './components/Login';
// Set this to true in order to use the login page
const USE_LOGIN = false;
// Set this to true in order to use the boards list page
const USE_BOARDSLIST = false;
const BoardsListComponent = USE_BOARDSLIST ? BoardsList : Board;
const LoginComponent = USE_LOGIN ? Login : BoardsListComponent;
function App() {
return (
<div className='App'>
<Switch id='switch'>
<Route exact path='/' component={LoginComponent}/>
<Route exact path='/boards' component={BoardsListComponent}/>
<Route exact path='/' component={Login}/>
<Route exact path='/boards' component={BoardsList}/>
<Route path='/board/:id' component={Board}/>
</Switch>
</div>
......
......@@ -5,58 +5,152 @@ import { Container, Message, TextArea, Button, Grid, Divider } from 'semantic-ui
const API_URL = 'http://138.195.142.10';
// Posts a message on a board
const postMessage = (message, board) => {
const request_options = {
url : `${API_URL}/messages`,
method : 'POST',
data: {
userId: parseInt(localStorage.getItem('userId')) || 1,
content: message,
boardId: parseInt(board)
}
};
return axios.request(request_options);
};
// Gets the list of messages from a board
const getMessagesList = async (board) => {
const request_options = {
method: 'GET',
url: `${API_URL}/messages`,
params: {
board: board
}
};
return axios.request(request_options).then(resp => resp.data);
};
// Gets the list of users
const getUserList = async () => {
const request_options = {
method: 'GET',
url: `${API_URL}/users`
};
return axios.request(request_options).then(resp => resp.data);
};
// Gets the data from a board
const getBoard = async (id) => {
const request_options = {
method: 'GET',
url: `${API_URL}/boards`,
params: {
id: id
}
};
return axios.request(request_options).then(resp => resp.data);
};
const Board = (props) => {
// Get the board's id and data
const [id, setId] = useState(-1);
const [board, setBoard] = useState([]);
useEffect(
() => {
setId(props.location.pathname.split('/')[props.location.pathname.split('/').length-1])
},
[props.location.pathname]
);
useEffect(
() => {
getBoard(id).then(data => setBoard(data))
},
[id]
);
return (
<div>
<Container textAlign='left'>
<Container textAlign='center'><h1>{board[id-1] ? board[id-1].name : ''}</h1></Container>
<Divider/>
<Container>
<MessageWriter board={id}/>
<Divider/>
</Container>
<Container>
<MessageList board={id}/>
</Container>
</Container>
</div>
);
};
const MessageList = (props) => {
// Get the list of users and initialize the message list
// Fetch messages every 1 second
const [messages, setMessages] = useState([]);
const [users, setUsers] = useState([]);
useEffect(
() => {
getMessagesList(props.board).then(data => setMessages(data));
getUserList().then(data => setUsers(data));
},
[props.board]
);
useEffect(
() => {
const timer = setTimeout(() => {
getMessagesList(props.board).then(data => setMessages(data));
}, 1000);
return () => clearTimeout(timer);
},
[messages, props.board]
);
return (
<div>
{messages.map(message => (
<MessageDisplay message={message} user={users[message.userId-1]}/>
))}
</div>
);
};
const MessageDisplay = (props) => {
return(
<div>
</div>
<Container>
<Message
key={props.message.id}
header={(props.user ? props.user.username : '') + '@' + props.message.updatedAt.split('T')[1].split('.')[0]}
content={props.message.content}
/>
<Divider/>
</Container>
);
};
const MessageWriter = (props) => {
// Initialize a message in the state
const [message, setMessage] = useState('');
return (
<div>
<Container textAlign='center'>
<Grid>
<Grid.Column width='16'>
<Grid.Row>
<TextArea style={{width: '100%'}}onChange={(e) => {setMessage(e.target.value)}} value={message}/>
</Grid.Row>
<Grid.Row>
<Button
style={{width: '100%'}}
onClick={() => {if (message.length) {
setMessage('');
postMessage(message, props.board);
}}}
>
Send
</Button>
</Grid.Row>
</Grid.Column>
</Grid>
</Container>
</div>
);
};
......
......@@ -6,16 +6,34 @@ import { Form, Header } from 'semantic-ui-react';
const API_URL = 'http://138.195.142.10';
// Gets the list of boards
const getBoardList = async () => {
const request_options = {
method: 'GET',
url: `${API_URL}/boards`
}
return axios.request(request_options).then(resp => resp.data);
};
const BoardsList = () => {
// Initialize the list of boards
const [boards, setBoards] = useState([]);
useEffect(
() => {
getBoardList().then(data => setBoards(data, []));
},
[]
);
return (
<div>
<div style={{ margin: 'auto', maxWidth: '50%', textAlign: 'center', marginTop: '2%' }}>
<Header as='h1'>Boards</Header>
<Form style={{ marginTop: '8%' }}>
{boards.map(board => (
<Link style={{ margin: '1%' }} to={`/board/${board.id}`}>
<Form.Button fluid content={board.name} />
</Link>
))}
</Form>
</div>
);
};
......
......@@ -5,21 +5,81 @@ import { Form, Image } from 'semantic-ui-react';
const API_URL = 'http://138.195.142.10';
// Attempts to login and if successful stores the userId in localStorage and redirects to the boards list
const handleLogin = async (username, password) => {
const request_options = {
method: 'POST',
url: `${API_URL}/login`,
data: {
username,
password
}
}
return axios.request(request_options).then(resp => {
const res = resp.data;
if (res.length > 0) {
localStorage.setItem('userId', res[0].id);
return window.location.replace('/boards');
}
});
};
// Attempts to register and if successful stores the userId in localStorage and redirects to the boards list
const handleRegister = async (username, password) => {
const request_options = {
method: 'POST',
url: `${API_URL}/users`,
data: {
username,
password
}
}
if (username && password) {
return axios.request(request_options).then(resp => {
if (resp.status === 200) {
console.log(resp);
localStorage.setItem('userId', resp.data.id);
return window.location.replace('/boards');
}
});
}
};
const Login = () => {
// Initializes username and password in the state
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
return (
<div>
<div style={{ margin: 'auto', maxWidth: '40%', textAlign: 'left' }}>
<Image
style={{ marginLeft: 'auto', marginRight: 'auto', marginTop: '20%', marginBottom: '10%' }}
src='https://gitlab.viarezo.fr/uploads/-/system/project/avatar/1987/react_round_red.png' size='medium'
/>
<Form>
<Form.Input
label='Username'
placeholder='Username'
value={username}
onChange={({ target }) => setUsername(target.value)}
/>
<Form.Input
label='Password'
placeholder='Password'
type='password'
value={password}
onChange={({ target }) => setPassword(target.value)}
/>
<Form.Group widths={2}>
<Form.Button
fluid
content='Login'
onClick={() => handleLogin(username, password)}
/>
<Form.Button
fluid
content='Register'
onClick={() => handleRegister(username, password)}
/>
</Form.Group>
</Form>
</div>
);
};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment