From 0a4c8ef208de44e9296df4df5a8b9dabc6b8560a Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 17 Oct 2021 17:10:42 -0400 Subject: [PATCH 1/5] link dash profilecards --- client/src/pages/Dashboard/Dashboard.tsx | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/client/src/pages/Dashboard/Dashboard.tsx b/client/src/pages/Dashboard/Dashboard.tsx index efa91ad..1e9a3f5 100755 --- a/client/src/pages/Dashboard/Dashboard.tsx +++ b/client/src/pages/Dashboard/Dashboard.tsx @@ -5,15 +5,15 @@ 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 NavBar from '../../components/NavBar/NavBar'; +import { 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'; export default function Dashboard(): JSX.Element { const classes = useStyles(); - + const [profiles, setProfiles] = useState([]); const { loggedInUser } = useAuth(); const { initSocket } = useSocket(); @@ -25,9 +25,14 @@ export default function Dashboard(): JSX.Element { useEffect(() => { initSocket(); + + getAllProfiles().then((data) => { + setProfiles(data.profiles); + }); }, [initSocket]); if (loggedInUser === undefined) return ; + if (!loggedInUser) { history.push('/login'); // loading for a split seconds until history.push works @@ -44,12 +49,12 @@ export default function Dashboard(): JSX.Element { {/**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 - **/} + ***/} - {Array.from(mockProfiles).map((_, index) => ( + {Array.from(profiles).map((_, index) => ( - - {/** */} + + ))} From 0e29d768ee7e98642ccdc35f71cef4a000f2605c Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 17 Oct 2021 20:35:26 -0400 Subject: [PATCH 2/5] add dashboard search and list profiles --- .../components/ProfileCard/ProfileCard.tsx | 4 +- client/src/helpers/APICalls/getAllProfiles.ts | 8 +- client/src/pages/Dashboard/Dashboard.tsx | 67 +++++--- .../DashboardSearch/DashboardSearch.tsx | 43 +++--- client/src/pages/Dashboard/useStyles.ts | 1 - server/controllers/profile.js | 145 ++++++++++-------- 6 files changed, 153 insertions(+), 115 deletions(-) diff --git a/client/src/components/ProfileCard/ProfileCard.tsx b/client/src/components/ProfileCard/ProfileCard.tsx index dd50da0..80152cf 100644 --- a/client/src/components/ProfileCard/ProfileCard.tsx +++ b/client/src/components/ProfileCard/ProfileCard.tsx @@ -13,7 +13,7 @@ interface Props { const ProfileCard = ({ profile }: Props): JSX.Element => { const classes = useStyles(); - const { _id: id, firstName, lastName, description, location } = profile; + const { _id: id, firstName, lastName, description, location, hourlyRate } = profile; return ( { {location} - {`30/hr`} + {`${hourlyRate}/hr`} diff --git a/client/src/helpers/APICalls/getAllProfiles.ts b/client/src/helpers/APICalls/getAllProfiles.ts index 6f6bfcd..5b51f17 100644 --- a/client/src/helpers/APICalls/getAllProfiles.ts +++ b/client/src/helpers/APICalls/getAllProfiles.ts @@ -1,12 +1,16 @@ import { FetchOptions } from '../../interface/FetchOptions'; import { AllProfilesApiData } from '../../interface/Profile'; -const getAllProfiles = async (): Promise => { +const getAllProfiles = async ( + searchValue: string | '', + startValue: Date | null, + endValue: Date | null, +): Promise => { const fetchOptions: FetchOptions = { method: 'GET', credentials: 'include', }; - return await fetch(`/profile/profiles`, fetchOptions) + 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' }, diff --git a/client/src/pages/Dashboard/Dashboard.tsx b/client/src/pages/Dashboard/Dashboard.tsx index 1e9a3f5..3af5890 100755 --- a/client/src/pages/Dashboard/Dashboard.tsx +++ b/client/src/pages/Dashboard/Dashboard.tsx @@ -5,31 +5,48 @@ import useStyles from './useStyles'; import { useAuth } from '../../context/useAuthContext'; import { useSocket } from '../../context/useSocketContext'; import { useHistory } from 'react-router-dom'; -import { useEffect, useState } from 'react'; +import { ChangeEvent, KeyboardEvent, useEffect, useState } from 'react'; import { Box, Typography } from '@material-ui/core'; import ProfileCard from '../../components/ProfileCard/ProfileCard'; import getAllProfiles from '../../helpers/APICalls/getAllProfiles'; import { Profile } from '../../interface/Profile'; +import DashboardSearch from './DashboardSearch/DashboardSearch'; +import { typography } from '@mui/system'; 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'); + const handleStartDateChange = (newValue: Date | null) => { + setStartValue(newValue); + }; + + const handleEndDateChange = (newValue: Date | null) => { + setEndValue(newValue); }; - useEffect(() => { - initSocket(); + const handleSearchChange = (event: ChangeEvent) => { + setSearchValue(event.target.value); + }; - getAllProfiles().then((data) => { - setProfiles(data.profiles); - }); - }, [initSocket]); + const handleKeyPress = (event: KeyboardEvent) => { + // TODO: Temp placeholder, contains values needed from search to be passed on. + if (event.key === 'Enter') { + event.preventDefault(); + getAllProfiles(searchValue, startValue, endValue).then((data) => { + console.log(data); + console.log(data.profiles); + setProfiles(data.profiles); + }); + } + }; if (loggedInUser === undefined) return ; @@ -44,20 +61,32 @@ 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(profiles).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 2a0ce99..a6d3ee1 100644 --- a/client/src/pages/Dashboard/DashboardSearch/DashboardSearch.tsx +++ b/client/src/pages/Dashboard/DashboardSearch/DashboardSearch.tsx @@ -8,33 +8,26 @@ 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 { + handleKeyPress: (event: KeyboardEvent) => void; + handleSearchChange: (event: ChangeEvent) => void; + handleStartDateChange: (newValue: Date | null) => void; + handleEndDateChange: (newValue: Date | null) => void; + startValue: Date | null; + endValue: Date | null; +} + +export default function DashboardSearch({ + handleKeyPress, + 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 ( @@ -43,7 +36,7 @@ export default function DashboardSearch(): JSX.Element { label="Search by city" variant="outlined" onKeyPress={handleKeyPress} - onChange={handleCityChange} + onChange={handleSearchChange} InputProps={{ startAdornment: ( diff --git a/client/src/pages/Dashboard/useStyles.ts b/client/src/pages/Dashboard/useStyles.ts index e807ab7..9444456 100755 --- a/client/src/pages/Dashboard/useStyles.ts +++ b/client/src/pages/Dashboard/useStyles.ts @@ -33,7 +33,6 @@ const useStyles = makeStyles((theme) => ({ marginTop: 50, }, listingItem: { - border: '1px solid blue', textAlign: 'center', alignContent: 'center', flexWrap: 'wrap', diff --git a/server/controllers/profile.js b/server/controllers/profile.js index 685ae4d..dda3169 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,58 @@ 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 != "null" || end != "null") { + const profilesMatch = await Profile.find({ + location: { $regex: search, $options: "i" }, + isSitter: true, + }); + //TODO: Need to check dates to be valid res.status(200).json({ - profiles, + profilesMatch, }); + return; + } + + const profiles = await Profile.find(); + if (!profiles) { + res.status(500); + throw new Error("0 results"); + } + + res.status(200).json({ + profiles, + }); }); From a2da48897392da89b074d615f2c08000cea2f752 Mon Sep 17 00:00:00 2001 From: Jason Date: Sun, 17 Oct 2021 21:09:13 -0400 Subject: [PATCH 3/5] fixup, make dynamic --- client/src/pages/Dashboard/Dashboard.tsx | 24 ++++++------------- .../DashboardSearch/DashboardSearch.tsx | 3 --- server/controllers/profile.js | 4 ++-- 3 files changed, 9 insertions(+), 22 deletions(-) diff --git a/client/src/pages/Dashboard/Dashboard.tsx b/client/src/pages/Dashboard/Dashboard.tsx index 3af5890..6976367 100755 --- a/client/src/pages/Dashboard/Dashboard.tsx +++ b/client/src/pages/Dashboard/Dashboard.tsx @@ -3,15 +3,13 @@ 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 { ChangeEvent, KeyboardEvent, useEffect, useState } from 'react'; +import { ChangeEvent, useEffect, useState } from 'react'; import { Box, Typography } from '@material-ui/core'; import ProfileCard from '../../components/ProfileCard/ProfileCard'; import getAllProfiles from '../../helpers/APICalls/getAllProfiles'; import { Profile } from '../../interface/Profile'; import DashboardSearch from './DashboardSearch/DashboardSearch'; -import { typography } from '@mui/system'; export default function Dashboard(): JSX.Element { const classes = useStyles(); @@ -21,9 +19,14 @@ export default function Dashboard(): JSX.Element { const [endValue, setEndValue] = useState(null); const { loggedInUser } = useAuth(); - const { initSocket } = useSocket(); const history = useHistory(); + useEffect(() => { + getAllProfiles(searchValue, startValue, endValue).then((data) => { + setProfiles(data.profiles); + }); + }, [searchValue, startValue, endValue]); + const handleStartDateChange = (newValue: Date | null) => { setStartValue(newValue); }; @@ -36,18 +39,6 @@ export default function Dashboard(): JSX.Element { setSearchValue(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(); - getAllProfiles(searchValue, startValue, endValue).then((data) => { - console.log(data); - console.log(data.profiles); - setProfiles(data.profiles); - }); - } - }; - if (loggedInUser === undefined) return ; if (!loggedInUser) { @@ -62,7 +53,6 @@ export default function Dashboard(): JSX.Element { Search for Users ) => void; handleSearchChange: (event: ChangeEvent) => void; handleStartDateChange: (newValue: Date | null) => void; handleEndDateChange: (newValue: Date | null) => void; @@ -18,7 +17,6 @@ interface Props { } export default function DashboardSearch({ - handleKeyPress, handleSearchChange, handleStartDateChange, handleEndDateChange, @@ -35,7 +33,6 @@ export default function DashboardSearch({ id="city" label="Search by city" variant="outlined" - onKeyPress={handleKeyPress} onChange={handleSearchChange} InputProps={{ startAdornment: ( diff --git a/server/controllers/profile.js b/server/controllers/profile.js index dda3169..f75d774 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -101,14 +101,14 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { const { search, start, end } = req.query; if (search != "" || start != "null" || end != "null") { - const profilesMatch = await Profile.find({ + const profiles = await Profile.find({ location: { $regex: search, $options: "i" }, isSitter: true, }); //TODO: Need to check dates to be valid res.status(200).json({ - profilesMatch, + profiles, }); return; } From fc1c9029a72a7b53ad12a45c86ff872f3069327f Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 19 Oct 2021 18:16:25 -0400 Subject: [PATCH 4/5] req changes --- client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx | 1 - server/controllers/profile.js | 6 +----- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx b/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx index 06cbeb8..d0d2595 100644 --- a/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx +++ b/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx @@ -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/server/controllers/profile.js b/server/controllers/profile.js index f75d774..8df5565 100644 --- a/server/controllers/profile.js +++ b/server/controllers/profile.js @@ -100,7 +100,7 @@ exports.getProfile = asyncHandler(async (req, res, next) => { exports.getAllProfiles = asyncHandler(async (req, res, next) => { const { search, start, end } = req.query; - if (search != "" || start != "null" || end != "null") { + if (!search || !start || !end) { const profiles = await Profile.find({ location: { $regex: search, $options: "i" }, isSitter: true, @@ -114,10 +114,6 @@ exports.getAllProfiles = asyncHandler(async (req, res, next) => { } const profiles = await Profile.find(); - if (!profiles) { - res.status(500); - throw new Error("0 results"); - } res.status(200).json({ profiles, From 118565b9b3ac2646d05b63631d5d32bcaf72955c Mon Sep 17 00:00:00 2001 From: Jason Date: Tue, 19 Oct 2021 18:19:21 -0400 Subject: [PATCH 5/5] change to prevState --- client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx b/client/src/components/NavBar/BecomeSitter/BecomeSitter.tsx index d0d2595..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) => {