Skip to content

Commit

Permalink
MyModal complete
Browse files Browse the repository at this point in the history
  • Loading branch information
MatthewHsu1 committed Feb 5, 2024
1 parent c59745d commit 311814e
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 34 deletions.
26 changes: 26 additions & 0 deletions houston/src/components/MyModal.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
.lds-dual-ring {
display: inline-block;
width: 80px;
height: 80px;
}

.lds-dual-ring:after {
content: " ";
display: block;
width: 64px;
height: 64px;
margin: 8px;
border-radius: 50%;
border: 6px solid #022149;
border-color: #022149 transparent #022149 transparent;
animation: lds-dual-ring 1.2s linear infinite;
}

@keyframes lds-dual-ring {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
78 changes: 78 additions & 0 deletions houston/src/components/MyModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import "./MyModal.css"
import exit from "../assets/close.svg";
import { Box, Button, Modal, Typography} from "@mui/material";
import { ReactNode } from "react";

interface Props {
children?: ReactNode;
modalVisible: boolean;
closeModal: () => void;
type?:string;
disable?:boolean;
}

/**
* Selects background color given a string.
* @param {String} type The description of the type of modal.
* @returns {string} The hex code of the background color.
*/
function backgroundColorPicker(type:string){
switch(type) {
case 'error':
return '#AC3344';
default:
return '#2C6CFB';
}
}


/**
* A modal component that comes with background color and an exit button.
* @param children react components to be embedded inside MyModal.
* @param modalVisible boolean value to represent the satus of the modal component.
* @param closeModal function tp close the modal.
* @param type if provided, a string value representing the type of modal, ex: "deauflt", "error"...
* @param disable if provide, boolean value if set to true, will dispaly a loading circle animation.
* @returns MyModal component.
*/
function MyModal({children, modalVisible, closeModal, type="default", disable=false}: Props){

let backgroundColor = backgroundColorPicker(type);

const style = {
position: 'absolute' as const,
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: backgroundColor,
border: '2px solid #000',
borderRadius: "7px",
boxShadow: 24,
p: 2,
justifyContent: "space-between",
};

return (
<Modal
open={modalVisible}
onClose={closeModal}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
disableEscapeKeyDown={disable}
>
<Box sx={style}>
<Button onClick={closeModal} disabled={disable}>
<img src={exit} />
</Button>
<Typography id="modal-modal-title" variant="h6" component="h2" textAlign={"center"}>
{disable ? <div className="lds-dual-ring"></div> : null}
</Typography>
{children}
</Box>
</Modal>
)
}


export default MyModal;
21 changes: 21 additions & 0 deletions houston/src/components/UseMyModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { useState } from "react";

/**
* Returns function to open and close modal.
* @returns {boolean} modalVisible, the boolean to represent the state of modal.
* @returns openModal. The function to turn the state of modalVisible to true.
* @returns closeModal. The function to turn the state of modalVisible to false.
*/
export function useModal() {
const [modalVisible, setModalVisible] = useState(false);

const openModal = () => {
setModalVisible(true);
};

const closeModal = () => {
setModalVisible(false);
};

return { modalVisible, openModal, closeModal };
}
1 change: 1 addition & 0 deletions houston/src/pages/Layout.css
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,6 @@ nav.topbar button:is(:hover, :focus) {
transform: scale(1);
}
}



44 changes: 10 additions & 34 deletions houston/src/pages/Layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ import "./Layout.css";
import duck from "../assets/duck.png"
import csvRunning from "../assets/csv-running.svg";
import csvReady from "../assets/csv-ready.svg";
import exit from "../assets/close.svg";

import {getIconFromStatus, } from "../utilities/connection"
import {ConnectionStatus, } from "../utilities/temp"
import { Box, Button, Modal, Typography } from "@mui/material";
import { Button, Typography } from "@mui/material";
import { useState } from "react";

import MyModal from "../components/MyModal";
import { useModal } from "../components/UseMyModal";

/**
* @param props Props
Expand All @@ -27,14 +27,13 @@ function Layout({statuses}:{statuses:ConnectionStatus[]}) {
}

const influxURL = "http://localhost:5000/api/influx";

const [influxLoading, setLoading] = useState(false);
const [modalVisible, setModalVisible] = useState(false);
const [dataString, setDataString] = useState('');
const {modalVisible, openModal, closeModal} = useModal();

const handleInflux = () => {
setLoading(true);
setModalVisible(true);
openModal()
fetch(influxURL)
.then(response => response.json())
.then(data => {
Expand All @@ -47,24 +46,6 @@ function Layout({statuses}:{statuses:ConnectionStatus[]}) {
});
}

const closeModal = () => {
setModalVisible(false);
};

const style = {
position: 'absolute' as const,
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
bgcolor: '#2C6CFB',
border: '2px solid #000',
borderRadius: "7px",
boxShadow: 24,
p: 2,
justifyContent: "space-between",
};

return (
<>
<nav className="topbar">
Expand All @@ -89,16 +70,11 @@ function Layout({statuses}:{statuses:ConnectionStatus[]}) {
<img src={csvReady} alt="csv icon" style={{ width: "50px", height: "50px"}} className="pulse"/>
}
</Button>
<Modal open={modalVisible} onClose={closeModal} aria-labelledby="modal-modal-title" aria-describedby="modal-modal-description">
<Box sx={style}>
<Button onClick={closeModal}>
<img src={exit} />
</Button>
<Typography id="modal-modal-title" variant="h6" component="h2" textAlign={"center"}>
{influxLoading ? "Loading": dataString}
</Typography>
</Box>
</Modal>
<MyModal modalVisible={modalVisible} closeModal={closeModal} type="error" disable={influxLoading}>
<Typography id="modal-modal-title" variant="h6" component="h2" textAlign={"center"}>
{influxLoading ? null : dataString}
</Typography>
</MyModal>
{/* If another page is added, need to adjust the nth child rule in the css
so that the status icons are still right aligned */}
{statuses.map(getIconFromStatus)}
Expand Down

0 comments on commit 311814e

Please sign in to comment.