From f7c029efa3838336e78dce7d733a044c756895d8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joonas=20Sepp=C3=A4?= <joasep@utu.fi>
Date: Mon, 13 Mar 2023 17:40:46 +0200
Subject: [PATCH] Refactoring front-end: Adding Message Component

---
 messages-app-frontend/src/App.tsx        | 125 ++++++++++++-----------
 messages-app-frontend/src/Message.tsx    |  58 ++++++++---
 messages-app-frontend/src/NewMessage.tsx |  17 ++-
 messages-app-frontend/src/Welcome.tsx    |  15 ++-
 4 files changed, 140 insertions(+), 75 deletions(-)

diff --git a/messages-app-frontend/src/App.tsx b/messages-app-frontend/src/App.tsx
index 5c1c077..5bec660 100644
--- a/messages-app-frontend/src/App.tsx
+++ b/messages-app-frontend/src/App.tsx
@@ -1,13 +1,9 @@
 import React from 'react';
 import axios from 'axios';
-import {Button, IconButton, Container, Box, Input, Paper} from '@mui/material';
-import DeleteIcon from '@mui/icons-material/Delete';
-import EditIcon from '@mui/icons-material/Edit';
+import {Button, Container, Box, Input, Paper} from '@mui/material';
 import NewMessage from "./NewMessage";
 import Welcome from "./Welcome";
-//import IconButton from '@mui/material';
-
-//import SendIcon from '@mui/icons-material';
+import Message from "./Message";
 
 type messageType = {
   message: string,
@@ -29,6 +25,16 @@ const api = axios.create({
   baseURL: `https://messages-app-backend.herokuapp.com/`
 });
 
+const messageBox = {
+  bgcolor: "darkgreen", 
+  marginX: 10, 
+  padding: 3, 
+  display: "grid", 
+  justifyContent: "center", 
+  boxShadow: 20, 
+  borderRadius: 5
+}
+
 
 
 export default class App extends React.Component{
@@ -49,7 +55,6 @@ export default class App extends React.Component{
   }
 
   createMessage = async () => {
-    console.log("New message has been created!")
     await api.post('/messages', {message: this.state.newMessage});
     this.setState({newMessage: ""});
     this.getMessages();
@@ -79,39 +84,53 @@ export default class App extends React.Component{
 
   inputValueChanged = (newValue: any) => {
     this.setState({newMessage: newValue});
-    //(p) => this.setState({newMessage: p.target.value})
   }
 
   updatingMessage = (p: messageType) => {
     if(p._id === this.state.editingMessage._id){
       return (
-        <Paper elevation={5} sx={{padding: 1, margin: 1.5, width: "fit-content"}}>
-          <Input value={this.state.editedMessage} onChange={(e) => this.setState({editedMessage: e.target.value})}></Input> 
-          <Button color="success" sx={{marginLeft: 2}} variant="contained" onClick={() => this.updateMessageApi()}>Confirm</Button> 
-          <Button sx={{marginLeft: 1}} variant="contained" onClick={() => this.setState({editingMessage: {bool: false}})}>Back</Button>
+
+        <Paper 
+          elevation={5} 
+          sx={{
+            padding: 1, 
+            margin: 1.5, 
+            width: "fit-content"
+          }}
+        >
+
+          <Input 
+            value={this.state.editedMessage} 
+            onChange={(e) => this.setState({editedMessage: e.target.value})}
+          /> 
+          
+          <Button 
+            color="success" 
+            sx={{marginLeft: 2}} 
+            variant="contained" 
+            onClick={() => this.updateMessageApi()}
+          >
+            Confirm
+          </Button> 
+          
+          <Button 
+            sx={{marginLeft: 1}} 
+            variant="contained" 
+            onClick={() => this.setState({editingMessage: {bool: false}})}
+          >
+            Back
+          </Button>
         </Paper>
-        /*
-        <div>
-          <input value={this.state.editedMessage} onChange={(e) => this.setState({editedMessage: e.target.value})}></input> <button onClick={() => this.updateMessageApi()}>Confirm</button> <button onClick={() => this.setState({editingMessage: {bool: false}})}>Back</button>
-        </div>
-        */
       )
     }
     else{
       return(
-        <Paper elevation={5} sx={{padding: 1, margin: 1.5, width: "fit-content"}}>
-          {p.message}
-
-          <IconButton aria-label="edit" onClick={() => this.updateMessage(p._id, p.message)}>
-            <EditIcon />
-          </IconButton>
-
-          <IconButton color="error" aria-label="delete" onClick={() => this.deleteMessage(p._id)}>
-            <DeleteIcon />
-          </IconButton>
-        </Paper>
+        <Message 
+          singleMessage={p} 
+          updateMessage={this.updateMessage} 
+          deleteMessage={this.deleteMessage}
+        />
       )
-      //return <p>{p.message} <button onClick={() => this.updateMessage(p._id, p.message)}>Edit</button> <button onClick={() => this.deleteMessage(p._id)}>Delete</button></p>
     }
   }
 
@@ -124,11 +143,15 @@ export default class App extends React.Component{
 
           <Welcome />
 
-          <Box sx={{bgcolor: "darkgreen", marginX: 10, padding: 3, display: "grid", /*flexDirection: "column", alignItems: "center",*/ justifyContent: "center", boxShadow: 20, borderRadius: 5}}>
+          <Box sx={messageBox}>
             {this.state.messages.map((p) => this.updatingMessage(p))}
           </Box>
 
-          <NewMessage inputValue={this.state.newMessage} createMessage={this.createMessage} onChangeValue={this.inputValueChanged}/>
+          <NewMessage 
+            inputValue={this.state.newMessage} 
+            createMessage={this.createMessage} 
+            onChangeValue={this.inputValueChanged}
+          />
         </Container>
       )
     }
@@ -139,36 +162,24 @@ export default class App extends React.Component{
 
           <Welcome />
 
-          <Box sx={{bgcolor: "darkgreen", marginX: 10, padding: 3, display: "grid", /*flexDirection: "column", alignItems: "center",*/ justifyContent: "center", boxShadow: 20, borderRadius: 5}}>
-            
-            {this.state.messages.map((p) =>
-              <Paper elevation={5} sx={{padding: 1, margin: 1.5, width: "fit-content"}}>
-                {p.message}
-
-                <IconButton aria-label="edit" onClick={() => this.updateMessage(p._id, p.message)}>
-                  <EditIcon />
-                </IconButton>
-
-                <IconButton color="error" aria-label="delete" onClick={() => this.deleteMessage(p._id)}>
-                  <DeleteIcon />
-                </IconButton>
-              </Paper>
+          <Box sx={messageBox}>
+            {this.state.messages.map((p) => 
+              <Message 
+                singleMessage={p} 
+                updateMessage={this.updateMessage} 
+                deleteMessage={this.deleteMessage}
+              />
             )}
-          </Box>
+          </Box>  
           
-          <NewMessage inputValue={this.state.newMessage} createMessage={this.createMessage} onChangeValue={this.inputValueChanged}/>
+          <NewMessage 
+            inputValue={this.state.newMessage} 
+            createMessage={this.createMessage} 
+            onChangeValue={this.inputValueChanged}
+          />
         </Container>
 
       )
     }
   }
-}
-//<NewMessage inputValue={this.state.newMessage} createMessage={this.createMessage} onChangeValue={this.inputValueChanged}/>
-
-/*
-
-    inputValue: string,
-    createMessage: Function,
-    onChangeValue: Function
-
-*/
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/messages-app-frontend/src/Message.tsx b/messages-app-frontend/src/Message.tsx
index d7358ce..081e8ff 100644
--- a/messages-app-frontend/src/Message.tsx
+++ b/messages-app-frontend/src/Message.tsx
@@ -1,25 +1,55 @@
-import { Component } from "react";
+import React from 'react';
+import {IconButton, Paper} from '@mui/material';
+import DeleteIcon from '@mui/icons-material/Delete';
+import EditIcon from '@mui/icons-material/Edit';
 
-interface IState {
-    message: String;
-    _id: String;
+type messageType = {
+    message: string,
+    __v: Number,
+    _id: string
 }
 
-class Message extends Component<IState>{
+type IProps = {
+    singleMessage: messageType,
+    updateMessage: Function,
+    deleteMessage: Function
+}
 
-    
-    state = {
-        message: this.props.message,
-        _id: this.props._id
-    }
+export default class Message extends React.Component<IProps>{
     
 
     render(): React.ReactNode{
         return(
-            <p>{this.props.message}<button>X</button></p>
+            <Paper 
+                elevation={5} 
+                sx={{
+                    padding: 1, 
+                    margin: 1.5, 
+                    width: "fit-content"
+                }}
+            >
+                {this.props.singleMessage.message}
+
+                <IconButton 
+                    aria-label="edit" 
+                    onClick={() => this.props.updateMessage(
+                        this.props.singleMessage._id, 
+                        this.props.singleMessage.message
+                    )}
+                >
+                    <EditIcon />
+                </IconButton>
+
+                <IconButton 
+                    color="error" 
+                    aria-label="delete" 
+                    onClick={() => this.props.deleteMessage(this.props.singleMessage._id)}
+                >
+                    <DeleteIcon />
+                </IconButton>
+                
+            </Paper>
         )
     }
 
-}
-
-export default Message;
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/messages-app-frontend/src/NewMessage.tsx b/messages-app-frontend/src/NewMessage.tsx
index c7974eb..d235a0e 100644
--- a/messages-app-frontend/src/NewMessage.tsx
+++ b/messages-app-frontend/src/NewMessage.tsx
@@ -13,8 +13,21 @@ export default class NewMessage extends React.Component<IProps>{
     render(){
         return(
             <Box sx={{textAlign: "center", paddingTop: 5}}>
-                <Input value={this.props.inputValue} onChange={(p) => this.props.onChangeValue(p.target.value)}></Input>
-                <Button sx={{margin: 1.5}} variant="contained" endIcon={<SendIcon />} onClick={() => this.props.createMessage()}>Send</Button>
+
+                <Input 
+                    value={this.props.inputValue} 
+                    onChange={(p) => this.props.onChangeValue(p.target.value)}
+                />
+
+                <Button 
+                    sx={{margin: 1.5}} 
+                    variant="contained" 
+                    endIcon={<SendIcon />} 
+                    onClick={() => this.props.createMessage()}
+                >
+                    Send
+                </Button>
+                
             </Box>
         )
     }
diff --git a/messages-app-frontend/src/Welcome.tsx b/messages-app-frontend/src/Welcome.tsx
index f6a1a93..a53143d 100644
--- a/messages-app-frontend/src/Welcome.tsx
+++ b/messages-app-frontend/src/Welcome.tsx
@@ -4,8 +4,19 @@ import {Typography, Box} from '@mui/material';
 export default class Welcome extends React.Component{
     render(): React.ReactNode {
         return(
-            <Box sx={{bgcolor: 'white', marginX: 10, padding: 1, marginY: 2, borderRadius: 5, boxShadow: 20}}>
-                <Typography variant="h3" sx={{textAlign: "center", margin: 3}}>Welcome to my Messaging Application!</Typography>
+            <Box 
+                sx={{
+                    bgcolor: 'white', 
+                    marginX: 10, 
+                    padding: 1, 
+                    marginY: 2, 
+                    borderRadius: 5, 
+                    boxShadow: 20
+                }}
+            >
+                <Typography variant="h3" sx={{textAlign: "center", margin: 3}}>
+                    Welcome to my Messaging Application!
+                </Typography>
             </Box>
         )
     }
-- 
GitLab