Skip to content

Commit

Permalink
Add Reef check surveys (#1060)
Browse files Browse the repository at this point in the history
Co-authored-by: snyk-bot <[email protected]>
Co-authored-by: ericboucher <[email protected]>
Co-authored-by: Eric Boucher <[email protected]>
  • Loading branch information
3 people authored Jan 15, 2025
1 parent 17afb83 commit 7a6ad93
Show file tree
Hide file tree
Showing 54 changed files with 2,067 additions and 96 deletions.
2 changes: 1 addition & 1 deletion packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"rxjs": "^7",
"sharp": "^0.32.6",
"ts-exif-parser": "^0.2.1",
"typeorm": "^0.3.18",
"typeorm": "^0.3.19",
"typeorm-naming-strategies": "^1.1.0"
},
"devDependencies": {
Expand Down
1 change: 1 addition & 0 deletions packages/api/src/sites/sites.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,7 @@ export class SitesService {
.leftJoinAndSelect('site.region', 'region')
.leftJoinAndSelect('site.sketchFab', 'sketchFab')
.leftJoinAndSelect('site.admins', 'admins')
.leftJoinAndSelect('site.reefCheckSite', 'reefCheckSite')
.andWhere('display = true')
.getMany();

Expand Down
2 changes: 2 additions & 0 deletions packages/api/src/time-series/time-series.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ export const timeSeriesTests = () => {
];

beforeAll(async () => {
// Define missing global function in test environment
global.structuredClone = (val) => JSON.parse(JSON.stringify(val));
app = await testService.getApp();
dataSource = await testService.getDataSource();
});
Expand Down
4 changes: 3 additions & 1 deletion packages/api/test/jest.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"globalSetup": "./test/global-setup.js",
"moduleNameMapper": {
"^csv-stringify/sync":
"<rootDir>/../../node_modules/csv-stringify/dist/cjs/sync.cjs"
"<rootDir>/../../node_modules/csv-stringify/dist/cjs/sync.cjs",
"^typeorm$": "<rootDir>/../../node_modules/typeorm",
"^uuid$": "uuid"
}
}
5 changes: 4 additions & 1 deletion packages/website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
"react-material-ui-carousel": "3.4.2",
"react-redux": "^7.2.0",
"react-router-dom": "^6.0.0",
"react-router-hash-link": "^2.4.3",
"react-slick": "^0.30.3",
"react-swipeable-bottom-sheet": "^1.1.2",
"react-swipeable-views": "^0.14.0",
Expand All @@ -76,7 +77,8 @@
"axios": "axios/dist/node/axios.cjs",
"^csv-stringify/browser/esm/sync": "<rootDir>/../../node_modules/csv-stringify/dist/cjs/sync.cjs"
},
"globalSetup": "./src/global-setup.js"
"globalSetup": "./src/global-setup.js",
"resetMocks": false
},
"browserslist": {
"production": [
Expand Down Expand Up @@ -110,6 +112,7 @@
"@types/react-leaflet": "^2.5.1",
"@types/react-redux": "^7.1.7",
"@types/react-router-dom": "^5.1.3",
"@types/react-router-hash-link": "^2.4.9",
"@types/react-slick": "^0.23.4",
"@types/react-swipeable-views": "^0.13.0",
"@types/redux-mock-store": "^1.0.2",
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added packages/website/src/assets/img/reef-check.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,26 @@ exports[`Featured Media Card should render with given state from Redux store 1`]
<div
class="MuiGrid-root MuiGrid-container MuiGrid-spacing-xs-2 MuiGrid-direction-xs-column css-1qhqgqb-MuiGrid-root"
>
<div
class="MuiGrid-root MuiGrid-item css-x7bhrq-MuiGrid-root"
<mock-box
alignitems="center"
classname="FeaturedMedia-noVideoCardHeaderText-4"
component="[object Object]"
display="flex"
gap="1"
to="/sites/1#surveys"
>
<img
alt="Reef Check"
src="reef-check-logo.png"
width="50"
/>
<mock-typography
classname="FeaturedMedia-noVideoCardHeaderText-4"
variant="h5"
>
SURVEY TO BE UPLOADED
REEF CHECK DATA AVAILABLE
</mock-typography>
</div>
<mock-keyboarddoublearrowdown />
</mock-box>
</div>
</div>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ describe('Featured Media Card', () => {
let element: HTMLElement;
beforeEach(() => {
const store = mockStore({
reefCheckSurveyList: {
list: [],
},
user: {
userInfo: mockUser,
},
Expand Down
60 changes: 46 additions & 14 deletions packages/website/src/common/SiteDetails/FeaturedMedia/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable no-nested-ternary */
import React from 'react';
import {
Card,
Expand All @@ -7,18 +8,23 @@ import {
Typography,
IconButton,
Theme,
Box,
} from '@mui/material';
import { WithStyles } from '@mui/styles';
import withStyles from '@mui/styles/withStyles';
import createStyles from '@mui/styles/createStyles';
import { KeyboardDoubleArrowDown } from '@mui/icons-material';
import { Link } from 'react-router-dom';
import { HashLink } from 'react-router-hash-link';
import { useSelector } from 'react-redux';

import { userInfoSelector } from 'store/User/userSlice';
import { isAdmin } from 'helpers/user';
import { convertOptionsToQueryParams } from 'helpers/video';
import { reefCheckSurveyListSelector } from 'store/ReefCheckSurveys';
import reefImage from '../../../assets/reef-image.jpg';
import uploadIcon from '../../../assets/icon_upload.svg';
import reefCheckLogo from '../../../assets/img/reef-check-logo.png';

const playerOptions = {
autoplay: 1,
Expand All @@ -35,6 +41,10 @@ const FeaturedMedia = ({
classes,
}: FeaturedMediaProps) => {
const user = useSelector(userInfoSelector);
const { list: reefCheckSurveyList } = useSelector(
reefCheckSurveyListSelector,
);
const hasReefCheckSurveys = true || reefCheckSurveyList.length > 0;
const isSiteAdmin = isAdmin(user, siteId);

if (url) {
Expand Down Expand Up @@ -71,21 +81,43 @@ const FeaturedMedia = ({
<Card className={classes.card}>
<div className={classes.noVideoCardHeader}>
<Grid container direction="column" alignItems="center" spacing={2}>
<Grid item>
{isSiteAdmin ? (
<>
<Grid item>
<Typography
className={classes.noVideoCardHeaderText}
variant="h5"
>
ADD YOUR FIRST SURVEY
</Typography>
</Grid>
<Grid item>
<IconButton
component={Link}
to={`/sites/${siteId}/new_survey`}
size="large"
>
<img src={uploadIcon} alt="upload" />
</IconButton>
</Grid>
</>
) : hasReefCheckSurveys ? (
<Box
component={HashLink}
to={`/sites/${siteId}#surveys`}
display="flex"
alignItems="center"
gap={1}
className={classes.noVideoCardHeaderText}
>
<img src={reefCheckLogo} alt="Reef Check" width={50} />
<Typography variant="h5">REEF CHECK DATA AVAILABLE</Typography>
<KeyboardDoubleArrowDown />
</Box>
) : (
<Typography className={classes.noVideoCardHeaderText} variant="h5">
{isSiteAdmin ? 'ADD YOUR FIRST SURVEY' : 'SURVEY TO BE UPLOADED'}
SURVEY TO BE UPLOADED
</Typography>
</Grid>
{isSiteAdmin && (
<Grid item>
<IconButton
component={Link}
to={`/sites/${siteId}/new_survey`}
size="large"
>
<img src={uploadIcon} alt="upload" />
</IconButton>
</Grid>
)}
</Grid>
</div>
Expand Down Expand Up @@ -118,7 +150,7 @@ const styles = (theme: Theme) => {
zIndex: 1,
},
noVideoCardHeaderText: {
opacity: 0.5,
color: 'white',
[theme.breakpoints.between('md', 1350)]: {
fontSize: 15,
},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import React from 'react';
import { render } from '@testing-library/react';
import { mockReefCheckSurvey } from 'mocks/mockReefCheckSurvey';
import { ReefCheckSurvey } from 'store/ReefCheckSurveys';
import { BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from '@mui/material';
import theme from 'layout/App/theme';
import { ReefCheckSurveyCard } from '.';

describe('ReefCheckSurveyCard', () => {
function renderReefCheckSurveyCard(overrides: Partial<ReefCheckSurvey> = {}) {
return render(
<ThemeProvider theme={theme}>
<BrowserRouter>
<ReefCheckSurveyCard
survey={{ ...mockReefCheckSurvey, ...overrides }}
/>
</BrowserRouter>
</ThemeProvider>,
);
}

it('should render date', () => {
const { getByText } = renderReefCheckSurveyCard();

expect(
getByText(`Date: ${new Date(mockReefCheckSurvey.date).toLocaleString()}`),
).toBeInTheDocument();
});

it('should render user if submittedBy is present', () => {
const { getByText } = renderReefCheckSurveyCard({
submittedBy: 'Test User',
});
expect(getByText('User: Test User')).toBeInTheDocument();
});

it('should render table with correct number of rows', () => {
const { container } = renderReefCheckSurveyCard();

expect(container.querySelectorAll('mock-tablerow').length).toBe(3);
});

it('should show correct counts in headers', () => {
const { container } = renderReefCheckSurveyCard();
const headers = [
...container.querySelectorAll('mock-tablehead mock-tablecell').values(),
].map((el) => el.textContent);
expect(headers).toEqual(
expect.arrayContaining([
'FISH (2)',
'Count',
'INVERTEBRATES (2)',
'Count',
'BLEACHING AND CORAL DIDEASES',
'YES/NO',
'IMPACT',
'YES/NO',
]),
);
});

it('should display link to survey details', () => {
const { getByRole } = renderReefCheckSurveyCard();

expect(getByRole('link', { name: 'VIEW DETAILS' })).toHaveAttribute(
'href',
`/reef_check_survey/${mockReefCheckSurvey.id}`,
);
});
});
Loading

0 comments on commit 7a6ad93

Please sign in to comment.