-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
edd78ba
commit 1ba373e
Showing
3 changed files
with
243 additions
and
4 deletions.
There are no files selected for viewing
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
129 changes: 127 additions & 2 deletions
129
packages/website/src/routes/SiteRoutes/ReefCheckSurveys/ReefCheckSurveyDetails.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,128 @@ | ||
export const ReefCheckSurveyDetails = () => { | ||
return null; | ||
import React from 'react'; | ||
import { | ||
Box, | ||
createStyles, | ||
Grid, | ||
Paper, | ||
Theme, | ||
Typography, | ||
WithStyles, | ||
withStyles, | ||
} from '@material-ui/core'; | ||
import { useSelector } from 'react-redux'; | ||
import { reefCheckSurveySelector } from 'store/ReefCheckSurveys/reefCheckSurveySlice'; | ||
import { ReefCheckSurvey } from 'store/ReefCheckSurveys/types'; | ||
|
||
type SurveyField<T extends keyof ReefCheckSurvey> = { | ||
field: T; | ||
label: string; | ||
formatter?: (v: ReefCheckSurvey[T]) => string; | ||
}; | ||
type SurveyFields = { [K in keyof ReefCheckSurvey]: SurveyField<K> }; | ||
|
||
const surveyFields = [ | ||
{ field: 'depth', label: 'Survey Depth', formatter: (v) => `${v}m` }, | ||
{ field: 'timeOfDayWorkBegan', label: 'Time of Day Work Began' }, | ||
{ field: 'weather', label: 'Weather' }, | ||
{ field: 'airTemp', label: 'Air Temperature', formatter: (v) => `${v}°C` }, | ||
{ | ||
field: 'waterTempAtSurface', | ||
label: 'Water Temperature at Surface', | ||
formatter: (v) => `${v}°C`, | ||
}, | ||
{ | ||
field: 'waterTempAt3M', | ||
label: 'Water Temperature at 3M', | ||
formatter: (v) => `${v}°C`, | ||
}, | ||
{ | ||
field: 'waterTempAt10M', | ||
label: 'Water Temperature at 10M', | ||
formatter: (v) => `${v}°C`, | ||
}, | ||
{ field: 'overallAnthroImpact', label: 'Overall Anthropogenic Impact' }, | ||
{ field: 'siltation', label: 'Siltation' }, | ||
{ field: 'dynamiteFishing', label: 'Dynamite Fishing' }, | ||
{ field: 'poisonFishing', label: 'Poison Fishing' }, | ||
{ field: 'aquariumFishCollection', label: 'Aquarium Fish Collection' }, | ||
{ | ||
field: 'harvestOfInvertsForFood', | ||
label: 'Harvest of Invertebrates for Food', | ||
}, | ||
{ | ||
field: 'harvestOfInvertsForCurio', | ||
label: 'Harvest of Invertebrates for Curio', | ||
}, | ||
{ field: 'touristDivingSnorkeling', label: 'Tourist Diving/Snorkeling' }, | ||
{ field: 'sewagePollution', label: 'Sewage Pollution' }, | ||
{ field: 'industrialPollution', label: 'Industrial Pollution' }, | ||
{ field: 'commercialFishing', label: 'Commercial Fishing' }, | ||
{ field: 'liveFoodFishing', label: 'Live Food Fishing' }, | ||
{ field: 'artisinalRecreational', label: 'Artisanal/Recreational Fishing' }, | ||
{ field: 'yachts', label: 'Yachts' }, | ||
{ field: 'isSiteProtected', label: 'Is Site Protected?' }, | ||
{ field: 'isProtectionEnforced', label: 'Is Protection Enforced?' }, | ||
{ field: 'levelOfPoaching', label: 'Level of Poaching' }, | ||
] satisfies Array<NonNullable<SurveyFields[keyof SurveyFields]>>; | ||
|
||
const ReefCheckSurveyDetailsComponent = ({ | ||
classes, | ||
}: ReefCheckSurveyDetailsProps) => { | ||
const { survey, loading, error } = useSelector(reefCheckSurveySelector); | ||
|
||
if (loading || error || !survey) { | ||
return null; | ||
} | ||
return ( | ||
<Paper className={classes.paper}> | ||
<Box className={classes.container}> | ||
{surveyFields.map(({ field, label, formatter }) => ( | ||
<Grid key={field} container className={classes.item}> | ||
<Typography className={classes.label}>{label}</Typography> | ||
<Typography className={classes.value}> | ||
{formatter?.(survey[field]) ?? survey[field] ?? ''} | ||
</Typography> | ||
</Grid> | ||
))} | ||
</Box> | ||
</Paper> | ||
); | ||
}; | ||
|
||
const styles = (theme: Theme) => | ||
createStyles({ | ||
paper: { | ||
padding: 16, | ||
color: theme.palette.text.secondary, | ||
}, | ||
container: { | ||
display: 'inline-block', | ||
columnCount: 3, | ||
columnGap: 0, | ||
width: '100%', | ||
borderTop: '1px solid #E0E0E0', | ||
borderLeft: '1px solid #E0E0E0', | ||
}, | ||
item: { | ||
display: 'flex', | ||
flexWrap: 'nowrap', | ||
}, | ||
label: { | ||
backgroundColor: '#FAFAFA', | ||
flexBasis: 260, | ||
padding: 8, | ||
borderBottom: '1px solid #E0E0E0', | ||
borderRight: '1px solid #E0E0E0', | ||
}, | ||
value: { | ||
padding: 8, | ||
borderBottom: '1px solid #E0E0E0', | ||
borderRight: '1px solid #E0E0E0', | ||
flex: 1, | ||
}, | ||
}); | ||
|
||
type ReefCheckSurveyDetailsProps = WithStyles<typeof styles>; | ||
export const ReefCheckSurveyDetails = withStyles(styles)( | ||
ReefCheckSurveyDetailsComponent, | ||
); |
118 changes: 116 additions & 2 deletions
118
packages/website/src/routes/SiteRoutes/ReefCheckSurveys/ReefCheckSurveySummary.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,117 @@ | ||
export const ReefCheckSurveySummary = () => { | ||
return null; | ||
import { | ||
Box, | ||
Button, | ||
createStyles, | ||
Link, | ||
Paper, | ||
Theme, | ||
Typography, | ||
WithStyles, | ||
withStyles, | ||
} from '@material-ui/core'; | ||
import React from 'react'; | ||
import { useSelector } from 'react-redux'; | ||
import cls from 'classnames'; | ||
import { reefCheckSurveySelector } from 'store/ReefCheckSurveys/reefCheckSurveySlice'; | ||
import { siteDetailsSelector } from 'store/Sites/selectedSiteSlice'; | ||
import ObservationBox from 'routes/Surveys/View/ObservationBox'; | ||
import reefCheckLogo from '../../../assets/img/reef-check.png'; | ||
|
||
export const ReefCheckSurveySummaryComponent = ({ | ||
classes, | ||
}: ReefCheckSurveySummaryProps) => { | ||
const { survey, loading, error } = useSelector(reefCheckSurveySelector); | ||
const siteDetails = useSelector(siteDetailsSelector); | ||
|
||
if (loading || error || !survey || !siteDetails) { | ||
return null; | ||
} | ||
|
||
return ( | ||
<Paper className={classes.paper}> | ||
<Box className={cls(classes.surveySource, classes.columnSpaceBetween)}> | ||
<Typography>Reef check Survey Data</Typography> | ||
<Typography>{formatDate(survey.date)}</Typography> | ||
<img src={reefCheckLogo} width={180} alt="Reef Check" /> | ||
</Box> | ||
<Box className={classes.columnCenter} flexShrink={0}> | ||
<Typography variant="h4">{survey.reefCheckSite?.reefName}</Typography> | ||
<Typography>{survey.reefCheckSite?.region}</Typography> | ||
</Box> | ||
<Box className={cls(classes.note, classes.columnSpaceBetween)}> | ||
<Typography> | ||
Data is collected along four 5-meter-wide by 20-meter-long segments of | ||
a 100-meter transect line for a total survey area of 400m². Each | ||
segment has an area of 100m² and is labelled as s1, s2, s3, or s4. | ||
</Typography> | ||
<Link | ||
href="https://www.reefcheck.org/tropical-program/tropical-monitoring-instruction/" | ||
target="_blank" | ||
> | ||
Learn more about the data and how it’s collected | ||
</Link> | ||
</Box> | ||
<Box className={cls(classes.observationBox, classes.columnSpaceBetween)}> | ||
<ObservationBox | ||
depth={survey.depth} | ||
satelliteTemperature={survey.satelliteTemperature ?? undefined} | ||
/> | ||
<Button variant="outlined" color="primary"> | ||
REQUEST TO DOWNLOAD REEF CHECK DATA | ||
</Button> | ||
</Box> | ||
</Paper> | ||
); | ||
}; | ||
|
||
const formatDate = (dateStr: string): string => { | ||
const date = new Date(dateStr); | ||
return date.toLocaleTimeString([], { | ||
year: 'numeric', | ||
month: 'numeric', | ||
day: 'numeric', | ||
hour: '2-digit', | ||
minute: '2-digit', | ||
}); | ||
}; | ||
|
||
const styles = (theme: Theme) => | ||
createStyles({ | ||
paper: { | ||
padding: 12, | ||
color: theme.palette.text.secondary, | ||
display: 'flex', | ||
gap: 32, | ||
}, | ||
|
||
surveySource: { | ||
padding: 12, | ||
borderRadius: 8, | ||
border: '1px solid #E0E0E0', | ||
}, | ||
note: { | ||
padding: 12, | ||
borderRadius: 8, | ||
backgroundColor: '#F5F6F6', | ||
}, | ||
observationBox: { | ||
gap: 32, | ||
flexShrink: 0, | ||
}, | ||
columnSpaceBetween: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
justifyContent: 'space-between', | ||
}, | ||
columnCenter: { | ||
display: 'flex', | ||
flexDirection: 'column', | ||
justifyContent: 'center', | ||
}, | ||
}); | ||
|
||
type ReefCheckSurveySummaryProps = WithStyles<typeof styles>; | ||
|
||
export const ReefCheckSurveySummary = withStyles(styles)( | ||
ReefCheckSurveySummaryComponent, | ||
); |