diff options
author | Julia McCauley <skurvyj@gmail.com> | 2021-04-16 19:46:45 -0400 |
---|---|---|
committer | Julia McCauley <skurvyj@gmail.com> | 2021-04-16 19:46:45 -0400 |
commit | fa4feff17c9e15b86388fd5ee1ac6771ff4d5148 (patch) | |
tree | 72157df02027b860e74097050349d49ebecebc0a /react-frontend/src/components | |
parent | eab479adc987ab20424a542275a697e0c8dbce61 (diff) | |
parent | a7f1433da5ddf11845251a062da96bc42c631f50 (diff) |
need to pull new frontend Merge branch 'master' of github.com:cs0320-2021/term-project-cohwille-jmccaul3-mfoiani-rhunt2
Diffstat (limited to 'react-frontend/src/components')
-rw-r--r-- | react-frontend/src/components/DateSelector.js | 17 | ||||
-rw-r--r-- | react-frontend/src/components/Hub.js | 24 | ||||
-rw-r--r-- | react-frontend/src/components/HubList.js | 62 | ||||
-rw-r--r-- | react-frontend/src/components/InvestorInfo.js | 66 | ||||
-rw-r--r-- | react-frontend/src/components/Loading.js | 20 | ||||
-rw-r--r-- | react-frontend/src/components/TimeSelector.js | 48 | ||||
-rw-r--r-- | react-frontend/src/components/Visualization.js | 69 |
7 files changed, 306 insertions, 0 deletions
diff --git a/react-frontend/src/components/DateSelector.js b/react-frontend/src/components/DateSelector.js new file mode 100644 index 0000000..bf01d44 --- /dev/null +++ b/react-frontend/src/components/DateSelector.js @@ -0,0 +1,17 @@ +// CSS import +import '../css/Route.css'; +import '../css/CoordSelector.css'; + +/** + * The component that selects and displays a coordinate. + * @param {Object} props The props for the element. + */ +function DateSelector(props) { + return ( + <div className="Flex-coord"> + <input type="date" value={props.value} onChange={(e) => props.changedFunc(new Date(e.target.value))} onClick={() => props.clickedFunc()}/> + </div> + ); +} + +export default DateSelector;
\ No newline at end of file diff --git a/react-frontend/src/components/Hub.js b/react-frontend/src/components/Hub.js new file mode 100644 index 0000000..8a3ac1c --- /dev/null +++ b/react-frontend/src/components/Hub.js @@ -0,0 +1,24 @@ +// React import +import { useState } from "react"; + +// CSS import +import '../css/UserCheckin.css'; + +/** + * Componenet for checkins. Has a toggle to show more info. + * @param {Object} props The props of the component. + * @returns {import('react').HtmlHTMLAttributes} A list element holding a checkin's info. + */ +function Hub(props) { + // State - toggled + + return ( + <li className='Checkin'> + <div className="Img-flex"> + <span className="Clickable-name" onClick= {() => console.log(props.id)}>{props.name}</span> + <span>{props.value.toFixed(3)}</span> + </div> + </li>); +} + +export default Hub;
\ No newline at end of file diff --git a/react-frontend/src/components/HubList.js b/react-frontend/src/components/HubList.js new file mode 100644 index 0000000..f5b1414 --- /dev/null +++ b/react-frontend/src/components/HubList.js @@ -0,0 +1,62 @@ +// React and component imports +import { useEffect, useState } from "react"; +import Hub from "./Hub.js"; +import InvestorInfo from "./InvestorInfo.js"; + +// CSS import +import '../css/UserCheckin.css'; + +/** + * Component that build the checkin list and displays checkin info. + * @returns {import('react').HtmlHTMLAttributes} A div with the hubs + * in a vertical layout. + */ +function HubList(props) { + const [hubItems, setHubItems] = useState([]); + const [isSelected, setIsSelected] = useState(false); + const [name, setName] = useState(''); + + /** + * Loads new the checkins into the current cache/map of hubs. + */ + const updateHubItems = () => { + // sort and create the elemnts + let hubs = []; + const sorted = props.data.sort((a, b) => b.suspicionScore - a.suspicionScore); + sorted.forEach(hub => hubs.push( + <Hub key={hub.id} id={hub.id} name={hub.name} value={hub.suspicionScore} setSelected={props.setSelected}></Hub> + )); + + setHubItems(hubs); + } + + const getName = () => { + props.data.forEach(hub => { + if (hub.id == props.selected) { + setName(hub.name); + } + }) + setName(''); + } + + // React hook that updates when the hubs are recalculated + useEffect(() => updateHubItems(), [props.data]); + + //React hook to show data for an investor + useEffect(() => { + setIsSelected(true) + getName(); + }, [props.selected]); + + return ( + <div className="User-checkin"> + <div className="Checkins"> + <h2>Suspicion Ranks</h2> + <ul className='Checkin-list'>{hubItems}</ul> + </div> + <InvestorInfo personId={props.selected} isSelected={isSelected} name={name} dates={props.dates}></InvestorInfo> + </div> + ); +} + +export default HubList;
\ No newline at end of file diff --git a/react-frontend/src/components/InvestorInfo.js b/react-frontend/src/components/InvestorInfo.js new file mode 100644 index 0000000..d368984 --- /dev/null +++ b/react-frontend/src/components/InvestorInfo.js @@ -0,0 +1,66 @@ +// React import +import { useEffect, useState } from "react"; + +// CSS import +import '../css/UserCheckin.css'; + +/** + * Componenet for checkins. Has a toggle to show more info. + * @param {Object} props The props of the component. + * @returns {import('react').HtmlHTMLAttributes} A list element holding a checkin's info. + */ +function InvestorInfo(props) { + const [info, setInfo] = useState({}); + + const toEpochMilli = date => Date.parse(date); + const getInfo = () => { + console.log({ + person: props.name, + start: toEpochMilli(props.dates.start), + end: toEpochMilli(props.dates.end) + }); + + if (props.name === "") { + return; + } + + fetch("http://localhost:4567/profit", { + method: "POST", + body: JSON.stringify({ + person: props.name, + start: toEpochMilli(props.dates.start), + end: toEpochMilli(props.dates.end) + }), + headers: { + "Content-Type": "application/json", + }, + credentials: "same-origin" + }) + .then(res => { + console.log(res); + res.json(); + }) + .then(data => { + console.log(data); + setInfo(data); + }) + .catch(err => console.log(err)); + } + /* + + const coords = userCoords.map((coord, index) => + <li key={index}> + <span>{'('+coord[0].toFixed(6)}, {coord[1].toFixed(6)+')'}</span> + </li> + );*/ + + useEffect(() => getInfo(), [props.name, props.isSelected, props.personId]) + + return ( + <div className="Chosen-user" hidden={props.isSelected}> + hi + </div> + ); +} + +export default InvestorInfo;
\ No newline at end of file diff --git a/react-frontend/src/components/Loading.js b/react-frontend/src/components/Loading.js new file mode 100644 index 0000000..6fdf5ba --- /dev/null +++ b/react-frontend/src/components/Loading.js @@ -0,0 +1,20 @@ +// CSS import +import '../css/App.css'; + +/** + * Component that shows the program initially loading. + * @returns The loading widget - spinning logo :) + */ +function Loading() { + return ( + <div className="App Loading"> + <header className="App-header"> + <img src={"./logo512.png"} className="App-logo" alt="logo" /> + <h1 className="App-title">Loading WatchDogs</h1> + <p className="App-title">It takes a minute to connect to the servers and database :)</p> + </header> + </div> + ); +} + +export default Loading;
\ No newline at end of file diff --git a/react-frontend/src/components/TimeSelector.js b/react-frontend/src/components/TimeSelector.js new file mode 100644 index 0000000..6960807 --- /dev/null +++ b/react-frontend/src/components/TimeSelector.js @@ -0,0 +1,48 @@ +// React/Component imports +import { useEffect, useState } from "react"; +import DateSelector from './DateSelector.js'; + +// CSS imports +import '../css/Route.css'; + + +/** + * The component that hold the forms for routing. + * @param {Object} props + */ +function TimeSelector(props) { + const [current, setCurrent] = useState(""); + + const toValue = date => new Date(date).toISOString().slice(0, 10); + + const [startDate, setStartDate] = useState(props.dates.start); + const [endDate, setEndDate] = useState(props.dates.end); + + const changeTimeframe = () => { + props.setDates({ + start: startDate, + end: endDate + }); + } + + useEffect(() => setCurrent(""), [startDate, endDate]); + + // The div with the html elements for routing. + return ( + <div className="Route"> + <div className="Coord-selectors-flex"> + <DateSelector side={"left"} name={"Start Date"} className="Coord-select-left" clickedFunc={setCurrent} + changedFunc={setStartDate} disabled={current==='start' || props.isChanging} value={toValue(startDate)}></DateSelector> + <div> + <h2>Adjust Timeframe :)</h2> + <button className="Btn Route-btn" onClick={() => changeTimeframe()} + disabled={current!=="" || props.isChanging}>Change Timeframe</button> + </div> + <DateSelector side={"right"} name={"End Date"} className="Coord-select-right" clickedFunc={setCurrent} + changedFunc={setEndDate} disabled={current==='end' || props.isChanging} value={toValue(endDate)}></DateSelector> + </div> + </div> + ); +} + +export default TimeSelector;
\ No newline at end of file diff --git a/react-frontend/src/components/Visualization.js b/react-frontend/src/components/Visualization.js new file mode 100644 index 0000000..91082e9 --- /dev/null +++ b/react-frontend/src/components/Visualization.js @@ -0,0 +1,69 @@ +// JS module imports +import { useEffect, useRef, useState } from "react"; +import uuid from 'react-uuid'; +import Graph from 'vis-react'; + +// CSS imports +import '../css/Canvas.css'; + +/** + * This function renders and mantains thhe canvas. + * @param {Object} props The props for the canvas. + * @returns {import("react").HtmlHTMLAttributes} The canvas to be retured. + */ +function Visualization(props) { + const options = { + edges: { + color: "#ffffff" + }, + autoResize: true + }; + const events = { + select: () => event => props.setSelected(event.nodes[0]) + }; + + const [graphState, setGraphState] = useState({ + nodes: [], + edges: [] + }); + const getNodes = () => { + let nodes = []; + props.data.forEach(hub => { + nodes.push({ + id: hub.id, + label: hub.name, + size: hub.suspicionScore * 10 + }); + }); + return nodes; + } + const getEdges = () => { + let edges = [] + props.data.forEach(hub => { + hub.followers.forEach(follower => { + edges.push({ + from: hub.id, + to: follower.id + }); + }); + }); + return edges; + } + + // Hooks to update graph state + useEffect(() => setGraphState({nodes: getNodes(), edges: getEdges()}), [JSON.stringify(props.data)]); + + return ( + <div className="Map-canvas"> + <Graph + key={uuid()} + graph={graphState} + options={options} + events={events}> + </Graph> + </div> + ); +} + +export default Visualization; + |