Skip to content

Commit a9823eb

Browse files
committed
Feature: Adoption and Foster tables with events
1 parent 3f5293e commit a9823eb

File tree

4 files changed

+136
-146
lines changed

4 files changed

+136
-146
lines changed

src/client/src/pages/DataView360/View/View.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ class View360 extends Component {
4040
this.state = {
4141
participantData: {},
4242
animalData: {},
43+
adoptionEvents: {},
44+
fosterEvents: {},
4345
matchId: undefined,
4446
isDataBusy: false,
4547
}
@@ -63,13 +65,15 @@ class View360 extends Component {
6365
animalInfo = await animalInfo.json()
6466
const animalIds = _.keys(animalInfo);
6567

68+
let adoptionEvents = {};
69+
let fosterEvents = {};
70+
6671
for (let id of animalIds) {
6772
this.getAnimalEvents(id).then((events) => {
68-
animalInfo[id]["events"] = events[id]
69-
animalInfo[id]["adoptionEvents"] = _.filter(events[id], function(e) {
73+
adoptionEvents[id] = _.filter(events[id], function(e) {
7074
return e["Type"] && e["Type"].toLowerCase().includes("adopt");
7175
});
72-
animalInfo[id]["fosterEvents"] = _.filter(events[id], function(e) {
76+
fosterEvents[id] = _.filter(events[id], function(e) {
7377
return e["Type"] && e["Type"].toLowerCase().includes("foster");
7478
});
7579
})
@@ -78,6 +82,8 @@ class View360 extends Component {
7882
this.setState({
7983
participantData: response.result,
8084
animalData: animalInfo,
85+
adoptionEvents: adoptionEvents,
86+
fosterEvents: fosterEvents,
8187
isDataBusy: false
8288
});
8389
}
@@ -138,8 +144,10 @@ class View360 extends Component {
138144
<Grid item sm>
139145
<Grid container direction="column" style={{"marginTop": "1em"}}>
140146
<Donations donations={_.get(this.state, 'participantData.donations')}/>
141-
<Adoptions adoptions={_.get(this.state, 'animalData')}/>
142-
<Fosters fosters={_.get(this.state, 'animalData')}/>
147+
<Adoptions adoptions={_.get(this.state, 'animalData')}
148+
events={_.get(this.state, 'adoptionEvents')} />
149+
<Fosters fosters={_.get(this.state, 'animalData')}
150+
events={_.get(this.state, 'fosterEvents')} />
143151
<Volunteer volunteer={this.extractVolunteerActivity()}
144152
volunteerShifts={_.get(this.state, 'participantData.shifts')}/>
145153
</Grid>

src/client/src/pages/DataView360/View/components/Adoptions.js

Lines changed: 3 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
import React, {Component} from 'react';
22
import {
3-
Button,
4-
Dialog,
53
Paper,
64
Typography,
7-
Table,
8-
TableContainer,
9-
TableHead,
10-
TableBody,
11-
TableRow,
12-
TableCell,
135
Container,
146
IconButton
157
} from '@material-ui/core';
@@ -20,7 +12,7 @@ import moment from "moment";
2012
import Grid from "@material-ui/core/Grid";
2113
import PetsIcon from "@material-ui/icons/Pets";
2214

23-
import EventsModal from './EventsModal';
15+
import CollapsibleTable from './CollapsibleTable';
2416

2517

2618
const customStyles = theme => ({
@@ -43,35 +35,17 @@ const customStyles = theme => ({
4335

4436
const PET_COUNT = 5;
4537

46-
let modalIsOpen = false;
47-
let modalData = [];
48-
4938
class Adoptions extends Component {
5039

51-
handleOpen(data) {
52-
modalIsOpen = true;
53-
modalData = data;
54-
}
55-
56-
handleClose() {
57-
modalIsOpen = false;
58-
modalData = [];
59-
}
60-
6140
getLatestPets(petObject) {
6241
return petObject;
6342
}
6443

65-
getAnimalAge(epochTime) {
66-
let dateOfBirth = moment(epochTime * 1000);
67-
return moment().diff(dateOfBirth, 'years');
68-
}
69-
7044
render() {
7145
const {classes} = this.props;
7246
const numOfPets = _.size(this.props.adoptions);
7347
const latestPets = this.getLatestPets(this.props.adoptions);
74-
48+
const events = this.props.events;
7549
return (<Container component={Paper} style={{"marginTop": "1em"}}>
7650
<Typography variant='h5'>
7751
<Grid container style={{"margin": "0.5em"}} direction={'row'}>
@@ -88,51 +62,7 @@ class Adoptions extends Component {
8862
</Grid>
8963
</Grid>
9064
</Typography>
91-
<Dialog
92-
open={modalIsOpen}
93-
onClose={this.handleClose}
94-
aria-labelledby="simple-dialog-title"
95-
aria-describedby="simple-dialog-description"
96-
>
97-
<EventsModal data={modalData}/>
98-
<Button variant="contained" color="primary" onClick={this.handleClose}>
99-
Close
100-
</Button>
101-
</Dialog>
102-
<TableContainer component={Paper} style={{"marginBottom": "1em"}} variant='outlined'>
103-
<Table>
104-
<TableHead>
105-
<TableRow>
106-
<TableCell className={classes.headerCell} align="center">Name</TableCell>
107-
<TableCell className={classes.headerCell} align="center">Animal Type</TableCell>
108-
<TableCell className={classes.headerCell} align="center">Breed</TableCell>
109-
<TableCell className={classes.headerCell} align="center">Age</TableCell>
110-
<TableCell className={classes.headerCell} align="center">Photo</TableCell>
111-
<TableCell className={classes.headerCell} align="center"></TableCell>
112-
</TableRow>
113-
</TableHead>
114-
<TableBody>
115-
{_.map(latestPets, (adoptionInfo, index) => {
116-
const photoLink = _.get(adoptionInfo, "Photos.[0]");
117-
const photo = <img src={photoLink} alt="animal" style={{"maxWidth": "100px"}}/>
118-
119-
return <TableRow key={index}>
120-
<TableCell align="center">{adoptionInfo["Name"]}</TableCell>
121-
<TableCell align="center">{adoptionInfo["Type"]}</TableCell>
122-
<TableCell align="center">{adoptionInfo["Breed"]}</TableCell>
123-
<TableCell
124-
align="center">{this.getAnimalAge(adoptionInfo["DOBUnixTime"])}</TableCell>
125-
<TableCell align="center">{photo}</TableCell>
126-
<TableCell align="center">
127-
<Button variant="contained" color="primary" onClick={() => this.handleOpen(adoptionInfo.adoptionEvents)}>
128-
More
129-
</Button>
130-
</TableCell>
131-
</TableRow>
132-
})}
133-
</TableBody>
134-
</Table>
135-
</TableContainer>
65+
<CollapsibleTable data={latestPets} events={events} />
13666
</Container>
13767
);
13868
}
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import { makeStyles } from '@material-ui/core/styles';
4+
import Box from '@material-ui/core/Box';
5+
import Collapse from '@material-ui/core/Collapse';
6+
import IconButton from '@material-ui/core/IconButton';
7+
import Table from '@material-ui/core/Table';
8+
import TableBody from '@material-ui/core/TableBody';
9+
import TableCell from '@material-ui/core/TableCell';
10+
import TableContainer from '@material-ui/core/TableContainer';
11+
import TableHead from '@material-ui/core/TableHead';
12+
import TableRow from '@material-ui/core/TableRow';
13+
import Typography from '@material-ui/core/Typography';
14+
import Paper from '@material-ui/core/Paper';
15+
import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
16+
import KeyboardArrowUpIcon from '@material-ui/icons/KeyboardArrowUp';
17+
18+
import _ from 'lodash';
19+
import moment from "moment";
20+
21+
const useRowStyles = makeStyles({
22+
root: {
23+
'& > *': {
24+
borderBottom: 'unset',
25+
},
26+
},
27+
});
28+
29+
function getAnimalAge(epochTime) {
30+
let dateOfBirth = moment(epochTime * 1000);
31+
return moment().diff(dateOfBirth, 'years');
32+
}
33+
34+
function Row(props) {
35+
const [open, setOpen] = React.useState(false);
36+
const classes = useRowStyles();
37+
const { row, events } = props;
38+
return (
39+
<React.Fragment>
40+
<TableRow className={classes.root}>
41+
<TableCell>
42+
<IconButton aria-label="expand row" size="small" onClick={() => setOpen(!open)}>
43+
{open ? <KeyboardArrowUpIcon /> : <KeyboardArrowDownIcon />}
44+
</IconButton>
45+
</TableCell>
46+
<TableCell component="th" scope="row">
47+
{row.Name}
48+
</TableCell>
49+
<TableCell align="center">{row.Type}</TableCell>
50+
<TableCell align="center">{row.Breed}</TableCell>
51+
<TableCell align="center">{getAnimalAge(row.DOBUnixTime)}</TableCell>
52+
<TableCell align="center">{<img src={row.Photos[0]} alt="animal" style={{ "maxWidth": "100px" }} />}</TableCell>
53+
</TableRow>
54+
<TableRow>
55+
<TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={6}>
56+
<Collapse in={open} timeout="auto" unmountOnExit>
57+
<Box margin={1}>
58+
<Typography variant="h6" gutterBottom component="div">
59+
History
60+
</Typography>
61+
<Table size="small" aria-label="purchases">
62+
<TableHead>
63+
<TableRow>
64+
<TableCell align="center">Subtype</TableCell>
65+
<TableCell align="center">Time</TableCell>
66+
<TableCell align="center">Type</TableCell>
67+
<TableCell align="center">User</TableCell>
68+
</TableRow>
69+
</TableHead>
70+
<TableBody>
71+
{events.map((historyRow) => (
72+
<TableRow key={historyRow.Time}>
73+
<TableCell component="th" scope="row">
74+
{historyRow.Subtype}
75+
</TableCell>
76+
<TableCell align="center">{moment.unix(historyRow.Time).format("DD MMM YYYY")}</TableCell>
77+
<TableCell align="center">{historyRow.Type}</TableCell>
78+
<TableCell align="center">{historyRow.User}</TableCell>
79+
</TableRow>
80+
))}
81+
</TableBody>
82+
</Table>
83+
</Box>
84+
</Collapse>
85+
</TableCell>
86+
</TableRow>
87+
</React.Fragment>
88+
);
89+
}
90+
91+
export default function CollapsibleTable(props) {
92+
const data = props.data;
93+
let events = props.events;
94+
const rows = _.values(data)
95+
return (
96+
<TableContainer component={Paper}>
97+
<Table aria-label="collapsible table">
98+
<TableHead>
99+
<TableRow>
100+
<TableCell />
101+
<TableCell align="center">Name</TableCell>
102+
<TableCell align="center">Animal Type</TableCell>
103+
<TableCell align="center">Breed</TableCell>
104+
<TableCell align="center">Age</TableCell>
105+
<TableCell align="center">Photo</TableCell>
106+
</TableRow>
107+
</TableHead>
108+
<TableBody>
109+
{rows.map((row) => {
110+
const eventsData = events[row["Internal-ID"]];
111+
return (eventsData && <Row key={row["Internal-ID"]} row={row} events={eventsData}/>)
112+
})}
113+
</TableBody>
114+
</Table>
115+
</TableContainer>
116+
);
117+
}

src/client/src/pages/DataView360/View/components/Fosters.js

Lines changed: 3 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,7 @@
11
import React, {Component} from 'react';
22
import {
3-
Button,
4-
Dialog,
53
Paper,
64
Typography,
7-
Table,
8-
TableContainer,
9-
TableHead,
10-
TableBody,
11-
TableRow,
12-
TableCell,
135
Container,
146
IconButton
157
} from '@material-ui/core';
@@ -20,7 +12,7 @@ import moment from "moment";
2012
import Grid from "@material-ui/core/Grid";
2113
import PetsIcon from "@material-ui/icons/Pets";
2214

23-
import EventsModal from './EventsModal';
15+
import CollapsibleTable from './CollapsibleTable';
2416

2517

2618
const customStyles = theme => ({
@@ -35,21 +27,8 @@ const customStyles = theme => ({
3527

3628
const PET_COUNT = 5;
3729

38-
let modalIsOpen = false;
39-
let modalData = [];
40-
4130
class Fosters extends Component {
4231

43-
handleOpen(data) {
44-
modalIsOpen = true;
45-
modalData = data;
46-
}
47-
48-
handleClose() {
49-
modalIsOpen = false;
50-
modalData = [];
51-
}
52-
5332
getLatestPets(petObject) {
5433
return petObject;
5534
}
@@ -63,7 +42,7 @@ class Fosters extends Component {
6342
const {classes} = this.props;
6443
const numOfPets = _.size(this.props.fosters);
6544
const latestPets = this.getLatestPets(this.props.fosters);
66-
45+
const events = this.props.events;
6746
return (<Container component={Paper} style={{"marginTop": "1em"}}>
6847
<Typography variant='h5'>
6948
<Grid container style={{"margin": "0.5em"}} direction={'row'}>
@@ -80,51 +59,7 @@ class Fosters extends Component {
8059
</Grid>
8160
</Grid>
8261
</Typography>
83-
<Dialog
84-
open={modalIsOpen}
85-
onClose={this.handleClose}
86-
aria-labelledby="simple-dialog-title"
87-
aria-describedby="simple-dialog-description"
88-
>
89-
<EventsModal data={modalData}/>
90-
<Button variant="contained" color="primary" onClick={this.handleClose}>
91-
Close
92-
</Button>
93-
</Dialog>
94-
<TableContainer component={Paper} style={{"marginBottom": "1em"}} variant='outlined'>
95-
<Table>
96-
<TableHead>
97-
<TableRow>
98-
<TableCell className={classes.headerCell} align="center">Name</TableCell>
99-
<TableCell className={classes.headerCell} align="center">Animal Type</TableCell>
100-
<TableCell className={classes.headerCell} align="center">Breed</TableCell>
101-
<TableCell className={classes.headerCell} align="center">Age</TableCell>
102-
<TableCell className={classes.headerCell} align="center">Photo</TableCell>
103-
<TableCell className={classes.headerCell} align="center"></TableCell>
104-
</TableRow>
105-
</TableHead>
106-
<TableBody>
107-
{_.map(latestPets, (fosterInfo, index) => {
108-
const photoLink = _.get(fosterInfo, "Photos.[0]");
109-
const photo = <img src={photoLink} alt="animal" style={{"maxWidth": "100px"}}/>
110-
111-
return <TableRow key={index}>
112-
<TableCell align="center">{fosterInfo["Name"]}</TableCell>
113-
<TableCell align="center">{fosterInfo["Type"]}</TableCell>
114-
<TableCell align="center">{fosterInfo["Breed"]}</TableCell>
115-
<TableCell
116-
align="center">{this.getAnimalAge(fosterInfo["DOBUnixTime"])}</TableCell>
117-
<TableCell align="center">{photo}</TableCell>
118-
<TableCell align="center">
119-
<Button variant="contained" color="primary" onClick={() => this.handleOpen(fosterInfo.fosterEvents)}>
120-
More
121-
</Button>
122-
</TableCell>
123-
</TableRow>
124-
})}
125-
</TableBody>
126-
</Table>
127-
</TableContainer>
62+
<CollapsibleTable data={latestPets} events={events} />
12863
</Container>
12964
);
13065
}

0 commit comments

Comments
 (0)