diff --git a/client/src/App.tsx b/client/src/App.tsx
index de05df1..f1ad9d6 100755
--- a/client/src/App.tsx
+++ b/client/src/App.tsx
@@ -26,7 +26,7 @@ function App(): JSX.Element {
-
+
diff --git a/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx b/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx
index 06cbeb8..6e8efc0 100644
--- a/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx
+++ b/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx
@@ -37,10 +37,10 @@ const BecomeSitter = (): JSX.Element => {
};
const handleChange = (event: ChangeEvent) => {
- setState({
- ...state,
+ setState((prevState) => ({
+ ...prevState,
[event.target.name]: event.target.checked,
- });
+ }));
};
const handleSitter = (event: ChangeEvent) => {
@@ -49,7 +49,6 @@ const BecomeSitter = (): JSX.Element => {
const handleSubmit = () => {
//TODO: Placeholder for editing profile info to switch between sitter and not a sitter
- console.log('hello');
setOpen(false);
};
diff --git a/client/src/components/ProfileCard/ProfileCard.tsx b/client/src/components/ProfileCard/ProfileCard.tsx
index 6ec08bb..80152cf 100644
--- a/client/src/components/ProfileCard/ProfileCard.tsx
+++ b/client/src/components/ProfileCard/ProfileCard.tsx
@@ -5,6 +5,7 @@ import CardContent from '@mui/material/CardContent';
import Typography from '@mui/material/Typography';
import picture from '../../Images/d9fc84a0d1d545d77e78aaad39c20c11d3355074.png';
import { Profile } from '../../interface/Profile';
+import { Link } from 'react-router-dom';
interface Props {
profile: Profile;
@@ -12,24 +13,33 @@ interface Props {
const ProfileCard = ({ profile }: Props): JSX.Element => {
const classes = useStyles();
+ const { _id: id, firstName, lastName, description, location, hourlyRate } = profile;
return (
-
-
-
-
+
-
- {`${profile.firstName} ${profile.lastName}`}
-
-
- {profile.description}
-
+
+
+
+
+ {`${firstName} ${lastName}`}
+
+
+ {description}
+
+
+
+ {location}
+ {`${hourlyRate}/hr`}
+
+
-
- {profile.location}
- $14/hr
-
);
};
diff --git a/client/src/components/ProfileCard/useStyles.ts b/client/src/components/ProfileCard/useStyles.ts
index 1a5c939..2be35b6 100644
--- a/client/src/components/ProfileCard/useStyles.ts
+++ b/client/src/components/ProfileCard/useStyles.ts
@@ -1,15 +1,20 @@
import { makeStyles } from '@material-ui/core/styles';
const useStyles = makeStyles((theme) => ({
+ profileCard: {
+ textDecoration: 'none',
+ overflow: 'hidden',
+ '&:hover': {
+ overflow: 'auto',
+ boxShadow: theme.shadows[23],
+ },
+ },
picture: {
borderRadius: '50%',
width: 150,
},
infoWrapper: {
borderTop: '1px solid grey',
- display: 'flex',
- padding: 5,
- justifyContent: 'space-evenly',
},
}));
diff --git a/client/src/helpers/APICalls/getAllProfiles.ts b/client/src/helpers/APICalls/getAllProfiles.ts
new file mode 100644
index 0000000..5b51f17
--- /dev/null
+++ b/client/src/helpers/APICalls/getAllProfiles.ts
@@ -0,0 +1,20 @@
+import { FetchOptions } from '../../interface/FetchOptions';
+import { AllProfilesApiData } from '../../interface/Profile';
+
+const getAllProfiles = async (
+ searchValue: string | '',
+ startValue: Date | null,
+ endValue: Date | null,
+): Promise => {
+ const fetchOptions: FetchOptions = {
+ method: 'GET',
+ credentials: 'include',
+ };
+ return await fetch(`/profile/profiles?search=${searchValue}&start=${startValue}&end=${endValue}`, fetchOptions)
+ .then((res) => res.json())
+ .catch(() => ({
+ error: { message: 'Unable to connect to server. Please try again' },
+ }));
+};
+
+export default getAllProfiles;
diff --git a/client/src/pages/Dashboard/Dashboard.tsx b/client/src/pages/Dashboard/Dashboard.tsx
index 8c2eb82..9746e1f 100755
--- a/client/src/pages/Dashboard/Dashboard.tsx
+++ b/client/src/pages/Dashboard/Dashboard.tsx
@@ -3,30 +3,44 @@ import CssBaseline from '@material-ui/core/CssBaseline';
import CircularProgress from '@material-ui/core/CircularProgress';
import useStyles from './useStyles';
import { useAuth } from '../../context/useAuthContext';
-import { useSocket } from '../../context/useSocketContext';
import { useHistory } from 'react-router-dom';
-import { useEffect } from 'react';
+import { ChangeEvent, useEffect, useState } from 'react';
import { Box, Typography } from '@material-ui/core';
import ProfileCard from '../../components/ProfileCard/ProfileCard';
-import { mockProfiles } from '../../mocks/mockProfile';
+import getAllProfiles from '../../helpers/APICalls/getAllProfiles';
+import { Profile } from '../../interface/Profile';
+import DashboardSearch from './DashboardSearch/DashboardSearch';
export default function Dashboard(): JSX.Element {
const classes = useStyles();
+ const [profiles, setProfiles] = useState([]);
+ const [searchValue, setSearchValue] = useState('');
+ const [startValue, setStartValue] = useState(new Date());
+ const [endValue, setEndValue] = useState(null);
const { loggedInUser } = useAuth();
- const { initSocket } = useSocket();
-
const history = useHistory();
- const handleSubmit = () => {
- console.log('submitted');
+ useEffect(() => {
+ getAllProfiles(searchValue, startValue, endValue).then((data) => {
+ setProfiles(data.profiles);
+ });
+ }, [searchValue, startValue, endValue]);
+
+ const handleStartDateChange = (newValue: Date | null) => {
+ setStartValue(newValue);
};
- useEffect(() => {
- initSocket();
- }, [initSocket]);
+ const handleEndDateChange = (newValue: Date | null) => {
+ setEndValue(newValue);
+ };
+
+ const handleSearchChange = (event: ChangeEvent) => {
+ setSearchValue(event.target.value);
+ };
if (loggedInUser === undefined) return ;
+
if (!loggedInUser) {
history.push('/login');
// loading for a split seconds until history.push works
@@ -38,19 +52,30 @@ export default function Dashboard(): JSX.Element {
Search for Users
+
{/**TODO:
- * 1. Each Card should be a link to the userprofile route
- * 2. Currently using mock profiles, need to change to actual list of profiles from api call
- **/}
+ *
+ * Currently using mock profiles, need to change to actual list of profiles from api call
+ ***/}
- {Array.from(mockProfiles).map((_, index) => (
-
-
-
-
-
- ))}
+ {profiles.length ? (
+ Array.from(profiles).map((_, index) => (
+
+
+
+
+
+ ))
+ ) : (
+ No users found.
+ )}
);
diff --git a/client/src/pages/Dashboard/DashboardSearch/DashboardSearch.tsx b/client/src/pages/Dashboard/DashboardSearch/DashboardSearch.tsx
index 9e0edba..de9cb18 100644
--- a/client/src/pages/Dashboard/DashboardSearch/DashboardSearch.tsx
+++ b/client/src/pages/Dashboard/DashboardSearch/DashboardSearch.tsx
@@ -8,33 +8,24 @@ import MobileDatePicker from '@mui/lab/MobileDatePicker';
import { IconButton, Typography } from '@material-ui/core';
import { SearchOutlined } from '@material-ui/icons';
-export default function DashboardSearch(): JSX.Element {
+interface Props {
+ handleSearchChange: (event: ChangeEvent) => void;
+ handleStartDateChange: (newValue: Date | null) => void;
+ handleEndDateChange: (newValue: Date | null) => void;
+ startValue: Date | null;
+ endValue: Date | null;
+}
+
+export default function DashboardSearch({
+ handleSearchChange,
+ handleStartDateChange,
+ handleEndDateChange,
+ startValue,
+ endValue,
+}: Props): JSX.Element {
const classes = useStyles();
- const [cityValue, setCityValue] = useState('Search');
- const [startValue, setStartValue] = useState(new Date());
- const [endValue, setEndValue] = useState(new Date());
const initialDate = new Date();
- const handleStartDateChange = (newValue: Date | null) => {
- setStartValue(newValue);
- };
-
- const handleEndDateChange = (newValue: Date | null) => {
- setEndValue(newValue);
- };
-
- const handleCityChange = (event: ChangeEvent) => {
- setCityValue(event.target.value);
- };
-
- const handleKeyPress = (event: KeyboardEvent) => {
- // TODO: Temp placeholder, contains values needed from search to be passed on.
- if (event.key === 'Enter') {
- event.preventDefault();
- alert(`${cityValue}, ${startValue}, ${endValue}`);
- }
- };
-
return (
@@ -42,8 +33,7 @@ export default function DashboardSearch(): JSX.Element {
id="city"
label="Search by city"
variant="outlined"
- onKeyPress={handleKeyPress}
- onChange={handleCityChange}
+ onChange={handleSearchChange}
InputProps={{
startAdornment: (
diff --git a/server/controllers/profile.js b/server/controllers/profile.js
index b6b029c..8df5565 100644
--- a/server/controllers/profile.js
+++ b/server/controllers/profile.js
@@ -5,45 +5,59 @@ const asyncHandler = require("express-async-handler");
// @desc Create new profile
// @access Public
exports.createProfile = asyncHandler(async (req, res, next) => {
+ const {
+ firstName,
+ lastName,
+ gender,
+ birthday,
+ email,
+ phoneNumber,
+ location,
+ profilePic,
+ description,
+ availability,
+ } = req.body;
- const {
- firstName,
- lastName,
- gender,
- birthday,
- email,
- phoneNumber,
- location,
- profilePic,
- description,
- availability,
- } = req.body;
-
- const profile = await Profile.create({
- firstName,
- lastName,
- gender,
- birthday,
- email,
- phoneNumber,
- location,
- profilePic,
- description,
- availability,
- });
+ const profile = await Profile.create({
+ firstName,
+ lastName,
+ gender,
+ birthday,
+ email,
+ phoneNumber,
+ location,
+ profilePic,
+ description,
+ availability,
+ });
- res.status(201).json({
- profile,
- });
+ res.status(201).json({
+ profile,
+ });
});
// @route PUT /profile
// @desc updates a profile with given ID
// @access Private
exports.updateProfile = asyncHandler(async (req, res, next) => {
- const id = req.user._id;
+ const id = req.user._id;
- const {
+ const {
+ firstName,
+ lastName,
+ gender,
+ birthday,
+ email,
+ phoneNumber,
+ location,
+ profilePic,
+ description,
+ availability,
+ } = req.body;
+
+ const profile = await Profile.findOneAndUpdate(
+ { user: id },
+ {
firstName,
lastName,
gender,
@@ -54,59 +68,54 @@ exports.updateProfile = asyncHandler(async (req, res, next) => {
profilePic,
description,
availability,
- } = req.body;
-
- const profile = await Profile.findOneAndUpdate(
- { user: id },
- {
- firstName,
- lastName,
- gender,
- birthday,
- email,
- phoneNumber,
- location,
- profilePic,
- description,
- availability,
- },
- { new: true }
- );
+ },
+ { new: true }
+ );
- res.status(200).json({
- profile,
- });
+ res.status(200).json({
+ profile,
+ });
});
// @route GET /profile
// @desc gets a profile with the given ID
// @access Private
exports.getProfile = asyncHandler(async (req, res, next) => {
- const id = req.user._id;
- const profile = await Profile.findOne({ user: id });
+ const id = req.user._id;
+ const profile = await Profile.findOne({ user: id });
- if (!profile) {
- res.status(404);
- throw new Error("The profile does not exist");
- }
+ if (!profile) {
+ res.status(404);
+ throw new Error("The profile does not exist");
+ }
- res.status(200).json({
- profile,
- });
+ res.status(200).json({
+ profile,
+ });
});
// @route GET /profiles
// @desc gets all profiles
// @access Private
exports.getAllProfiles = asyncHandler(async (req, res, next) => {
- const profiles = await Profile.find();
+ const { search, start, end } = req.query;
- if (!profiles) {
- res.status(500);
- throw new Error("0 results");
- }
+ if (!search || !start || !end) {
+ const profiles = await Profile.find({
+ location: { $regex: search, $options: "i" },
+ isSitter: true,
+ });
+ //TODO: Need to check dates to be valid
res.status(200).json({
profiles,
});
-});
\ No newline at end of file
+ return;
+ }
+
+ const profiles = await Profile.find();
+
+ res.status(200).json({
+ profiles,
+ });
+});