From 37a5dfa310e402d2506618cbcc1e09e4824e001e Mon Sep 17 00:00:00 2001 From: "(Grace) Gunyasorn Sawatyanon" Date: Tue, 19 Mar 2024 22:23:33 -0400 Subject: [PATCH 1/9] apartment header --- frontend/src/components/Apartment/Header.tsx | 179 +++++++++--------- .../ApartmentCard/ApartmentCard.tsx | 2 + .../PhotoCarousel/PhotoCarousel.tsx | 64 ++++--- frontend/src/pages/ApartmentPage.tsx | 2 +- 4 files changed, 136 insertions(+), 111 deletions(-) diff --git a/frontend/src/components/Apartment/Header.tsx b/frontend/src/components/Apartment/Header.tsx index d5dcbb6b..5130107f 100644 --- a/frontend/src/components/Apartment/Header.tsx +++ b/frontend/src/components/Apartment/Header.tsx @@ -7,6 +7,7 @@ import { withStyles, makeStyles, Avatar, + ButtonBase, } from '@material-ui/core'; import styles from './Header.module.scss'; import { ApartmentWithId } from '../../../../common/types/db-types'; @@ -43,54 +44,44 @@ const useStyles = makeStyles((theme) => ({ marginLeft: '-4.3%', resizeMode: 'contain', }, + headerInfoContainer: { + bottom: 0, + position: 'absolute', + display: 'flex', + alignItems: 'center', + height: '30%', + }, + mobileHeaderInfoContainer: { + bottom: '0', + position: 'absolute', + display: 'flex', + flexDirection: 'row', + flexWrap: 'wrap', + justifyContent: 'center', + height: 'auto', + width: '100%', + paddingTop: '10px', + paddingBottom: '10px', + }, logo: { height: '86px', width: '86px', fontSize: '3rem', - marginLeft: '5px', - marginBottom: '10px', - [theme.breakpoints.up('md')]: { - marginLeft: '5%', - marginBottom: '20px', - }, + marginLeft: '20px', }, mobileLogo: { height: '56px', width: '56px', fontSize: '3rem', - marginTop: '120px', - marginLeft: '10%', + marginRight: '15px', [theme.breakpoints.up('md')]: { marginLeft: '5%', marginBottom: '20px', }, }, - photoButton: { - marginRight: '5px', - height: '45px', - width: '133px', - lineHeight: '17px', - textTransform: 'none', - color: colors.black, - background: 'rgba(255, 255, 255, 1.0)', - border: '2px solid black', - borderColor: colors.black, - boxSizing: 'border-box', - borderRadius: '8px', - padding: '0px', - '&:hover': { - background: 'rgba(255, 255, 255, 0.8)', - }, - '&:focus': { - borderColor: 'black !important', - }, - [theme.breakpoints.up('md')]: { - marginRight: '25px', - }, - }, aptName: { color: colors.white, - paddingLeft: 0, + paddingLeft: '20px', paddingBottom: 0, fontWeight: 'bold', fontSize: '36px', @@ -100,9 +91,11 @@ const useStyles = makeStyles((theme) => ({ }, aptAddress: { color: colors.white, + paddingLeft: '20px', fontStyle: 'normal', fontSize: '20px', letterSpacing: '0.02em', + marginBottom: '10px', }, mobileAptName: { color: colors.white, @@ -110,8 +103,11 @@ const useStyles = makeStyles((theme) => ({ fontSize: '23px', lineHeight: '43px', letterSpacing: '0.02em', - marginTop: '115px', - marginLeft: '-55%', + overflow: 'hidden', + textOverflow: 'ellipsis', + display: '-webkit-box', + WebkitBoxOrient: 'vertical', + maxHeight: 'none', // Adjust based on your font size and desired number of lines }, mobileAptAddress: { color: colors.white, @@ -119,13 +115,20 @@ const useStyles = makeStyles((theme) => ({ fontSize: '17px', letterSpacing: '0.02em', marginTop: '-5px', - marginLeft: '-55%', }, headerSection: { + bottom: 0, + textAlign: 'left', [theme.breakpoints.down('sm')]: { marginLeft: '10px', }, }, + mobileHeaderSection: { + textAlign: 'left', + display: 'flex', + flexDirection: 'column', + justifyContent: 'center', + }, btnSection: { height: '94%', [theme.breakpoints.down('sm')]: { @@ -135,6 +138,11 @@ const useStyles = makeStyles((theme) => ({ logoGrid: { marginRight: '1em', }, + logoGridMobile: { + display: 'flex', + justifyContent: 'flex-end', + alignItems: 'center', + }, })); const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { @@ -142,19 +150,22 @@ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { const [isMobile, setIsMobile] = useState(false); const icon = defaultIcon; - const photoLink = defaultHeader; + const photoLink = photos.length > 0 ? photos[0] : defaultHeader; const { media, mobileMedia, + headerInfoContainer, + mobileHeaderInfoContainer, logo, mobileLogo, - photoButton, aptName, aptAddress, headerSection, + mobileHeaderSection, btnSection, logoGrid, + logoGridMobile, mobileAptName, mobileAptAddress, } = useStyles(); @@ -166,67 +177,59 @@ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { return () => window.removeEventListener('resize', handleResize); }, []); - const header = ( - - <> - - - - - - - - - - - - - - - {photos.length > 0 && ( - - - - )} - - - + const headerContent = ( + 0 + ? { backgroundColor: 'rgba(0, 0, 0, 0.45)' } + : { backgroundColor: 'rgba(0, 0, 0, 0.15)' } + } + > + + + + + + + ); - const mobileHeader = ( + + return ( <> - - - - - - - - - - - + + + {!isMobile ? ( + + {headerContent} + + ) : ( + headerContent + )} + + ); - - return isMobile ? mobileHeader : header; }; export default ApartmentHeader; diff --git a/frontend/src/components/ApartmentCard/ApartmentCard.tsx b/frontend/src/components/ApartmentCard/ApartmentCard.tsx index c108a79c..b2bb80a6 100644 --- a/frontend/src/components/ApartmentCard/ApartmentCard.tsx +++ b/frontend/src/components/ApartmentCard/ApartmentCard.tsx @@ -42,6 +42,8 @@ const useStyles = makeStyles({ imgStyle: { borderRadius: '12%', padding: '17px', + width: '205px', + height: '205px', }, aptNameTxt: { fontWeight: 800, diff --git a/frontend/src/components/PhotoCarousel/PhotoCarousel.tsx b/frontend/src/components/PhotoCarousel/PhotoCarousel.tsx index 83d59f5f..c2d127e8 100644 --- a/frontend/src/components/PhotoCarousel/PhotoCarousel.tsx +++ b/frontend/src/components/PhotoCarousel/PhotoCarousel.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Modal, Box, styled, Container, CardMedia } from '@material-ui/core'; +import { Modal, Box, styled, Container, CardMedia, Dialog, makeStyles } from '@material-ui/core'; import Carousel from 'react-material-ui-carousel'; interface Props { @@ -8,31 +8,51 @@ interface Props { onClose?: () => void; } -const CenteredModal = styled(Modal)({ - display: 'flex', - flexDirection: 'column', - justifyContent: 'center', -}); - +const useStyles = makeStyles((theme) => ({ + modalBackground: { + backgroundColor: 'transparent', + overflowY: 'unset', + boxShadow: 'none', + }, + navButton: { + backgroundColor: 'rgba(0, 0, 0, 0.5)', + opacity: 1, + }, +})); const ImageBox = styled(Box)({ width: 'fit-content', margin: 'auto', + borderRadius: '10px', + overflow: 'hidden', }); -const PhotoCarousel = ({ photos, open, onClose }: Props) => ( - - - - {photos.map((src, index) => { - return ( - - - - ); - })} - - - -); +const PhotoCarousel = ({ photos, open, onClose }: Props) => { + const { modalBackground, navButton } = useStyles(); + return ( + + + + {photos.map((src, index) => { + return ( + + + + ); + })} + + + + ); +}; export default PhotoCarousel; diff --git a/frontend/src/pages/ApartmentPage.tsx b/frontend/src/pages/ApartmentPage.tsx index 90ad3867..d904146d 100644 --- a/frontend/src/pages/ApartmentPage.tsx +++ b/frontend/src/pages/ApartmentPage.tsx @@ -386,7 +386,7 @@ const ApartmentPage = ({ user, setUser }: Props): ReactElement => { user={user} /> setCarouselOpen(false)} /> From 690dd6e6d8972e759ab248d463731a8399af24de Mon Sep 17 00:00:00 2001 From: "(Grace) Gunyasorn Sawatyanon" Date: Fri, 22 Mar 2024 22:31:38 -0400 Subject: [PATCH 2/9] gradient, icon, adaptability --- frontend/src/assets/default_icon.svg | 8 +++ frontend/src/components/Apartment/Header.tsx | 63 ++++++++++++-------- 2 files changed, 46 insertions(+), 25 deletions(-) create mode 100644 frontend/src/assets/default_icon.svg diff --git a/frontend/src/assets/default_icon.svg b/frontend/src/assets/default_icon.svg new file mode 100644 index 00000000..7d29e10d --- /dev/null +++ b/frontend/src/assets/default_icon.svg @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/frontend/src/components/Apartment/Header.tsx b/frontend/src/components/Apartment/Header.tsx index 5130107f..a81d5be2 100644 --- a/frontend/src/components/Apartment/Header.tsx +++ b/frontend/src/components/Apartment/Header.tsx @@ -12,7 +12,7 @@ import { import styles from './Header.module.scss'; import { ApartmentWithId } from '../../../../common/types/db-types'; import defaultHeader from '../../assets/default_header.svg'; -import defaultIcon from '../../assets/default_icon.png'; +import { ReactComponent as DefaultIcon } from '../../assets/default_icon.svg'; import { colors } from '../../colors'; type Props = { @@ -32,10 +32,19 @@ const GlobalCss = withStyles({ const useStyles = makeStyles((theme) => ({ media: { - height: '400px', + height: '352px', backgroundBlendMode: 'darken', position: 'relative', }, + overlayContainer: { + position: 'relative', + width: '100%', + }, + mediaGradient: { + height: '100%', + background: 'linear-gradient(to top, rgba(0, 0, 0, 0.5), transparent)', + position: 'relative', + }, mobileMedia: { height: '200px', backgroundBlendMode: 'darken', @@ -49,7 +58,7 @@ const useStyles = makeStyles((theme) => ({ position: 'absolute', display: 'flex', alignItems: 'center', - height: '30%', + minHeight: '40%', }, mobileHeaderInfoContainer: { bottom: '0', @@ -61,7 +70,7 @@ const useStyles = makeStyles((theme) => ({ height: 'auto', width: '100%', paddingTop: '10px', - paddingBottom: '10px', + paddingBottom: '20px', }, logo: { height: '86px', @@ -137,6 +146,10 @@ const useStyles = makeStyles((theme) => ({ }, logoGrid: { marginRight: '1em', + flex: '0 0 auto', + display: 'flex', + justifyContent: 'flex-start', + alignItems: 'center', }, logoGridMobile: { display: 'flex', @@ -148,12 +161,12 @@ const useStyles = makeStyles((theme) => ({ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { const { name, address, photos } = apartment; const [isMobile, setIsMobile] = useState(false); - - const icon = defaultIcon; const photoLink = photos.length > 0 ? photos[0] : defaultHeader; const { media, + overlayContainer, + mediaGradient, mobileMedia, headerInfoContainer, mobileHeaderInfoContainer, @@ -178,17 +191,13 @@ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { }, []); const headerContent = ( - 0 - ? { backgroundColor: 'rgba(0, 0, 0, 0.45)' } - : { backgroundColor: 'rgba(0, 0, 0, 0.15)' } - } - > + - + 0 ? 'rgba(185, 70, 48, 0.8)' : 'rgb(185, 70, 48)'} + /> { disableRipple disabled={photos.length === 0} > - - {!isMobile ? ( - - {headerContent} - - ) : ( - headerContent - )} - +
+ +
0 ? mediaGradient : ''}> + {!isMobile ? ( + + {headerContent} + + ) : ( + headerContent + )} +
+
+
From 738d85a2ff6f6c8a5ac94165d80f28dda5eb35a0 Mon Sep 17 00:00:00 2001 From: "(Grace) Gunyasorn Sawatyanon" Date: Sat, 23 Mar 2024 22:02:03 -0400 Subject: [PATCH 3/9] make landlord icon red --- frontend/src/colors.js | 1 + frontend/src/components/Apartment/Header.tsx | 2 +- frontend/src/components/Landlord/Header.tsx | 16 ++++++++++++---- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/frontend/src/colors.js b/frontend/src/colors.js index d8447c4d..e9e6bafd 100644 --- a/frontend/src/colors.js +++ b/frontend/src/colors.js @@ -1,5 +1,6 @@ export const colors = { red1: '#B94630', + red1Transparent: 'rgba(185, 70, 48, 0.8)', red2: '#EB5757', red3: '#E8725C', red4: '#FFCFC7', diff --git a/frontend/src/components/Apartment/Header.tsx b/frontend/src/components/Apartment/Header.tsx index a81d5be2..99ede140 100644 --- a/frontend/src/components/Apartment/Header.tsx +++ b/frontend/src/components/Apartment/Header.tsx @@ -196,7 +196,7 @@ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { 0 ? 'rgba(185, 70, 48, 0.8)' : 'rgb(185, 70, 48)'} + color={photos.length > 0 ? colors.red1Transparent : colors.red1} />
diff --git a/frontend/src/components/Landlord/Header.tsx b/frontend/src/components/Landlord/Header.tsx index 27244a7e..c996887e 100644 --- a/frontend/src/components/Landlord/Header.tsx +++ b/frontend/src/components/Landlord/Header.tsx @@ -12,7 +12,7 @@ import { import styles from './Header.module.scss'; import { Landlord } from '../../../../common/types/db-types'; import defaultHeader from '../../assets/default_header.svg'; -import defaultIcon from '../../assets/default_icon.png'; +import { ReactComponent as DefaultIcon } from '../../assets/default_icon.svg'; import { colors } from '../../colors'; type Props = { @@ -147,7 +147,7 @@ const useStyles = makeStyles((theme) => ({ const LandlordHeader = ({ landlord, handleClick }: Props): ReactElement => { const { name, profilePhoto, photos } = landlord; - const icon = profilePhoto ? profilePhoto : defaultIcon; + const icon = profilePhoto ? profilePhoto : DefaultIcon; const photoLink = photos.length ? photos[0] : defaultHeader; const [isMobile, setIsMobile] = useState(false); @@ -180,7 +180,11 @@ const LandlordHeader = ({ landlord, handleClick }: Props): ReactElement => { - + 0 ? colors.red1Transparent : colors.red1} + /> @@ -218,7 +222,11 @@ const LandlordHeader = ({ landlord, handleClick }: Props): ReactElement => { - + 0 ? colors.red1Transparent : colors.red1} + /> From b3287be2aac690a41e72b2a83227c11734a5dc93 Mon Sep 17 00:00:00 2001 From: "(Grace) Gunyasorn Sawatyanon" Date: Sun, 24 Mar 2024 00:33:36 -0400 Subject: [PATCH 4/9] documentation for ApartmentHeader --- frontend/src/components/Apartment/Header.tsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/frontend/src/components/Apartment/Header.tsx b/frontend/src/components/Apartment/Header.tsx index 99ede140..d6833e3e 100644 --- a/frontend/src/components/Apartment/Header.tsx +++ b/frontend/src/components/Apartment/Header.tsx @@ -158,6 +158,18 @@ const useStyles = makeStyles((theme) => ({ }, })); +/** + * ApartmentHeader Component + * + * This component represents a header with an apartment image, apartment name, apartment adress, and icon seen on each apartment page. + * When clicking on the header, handleClick will be called. The component is responsive for all screen sizes and mobile display. + * + * @component + * @param props - The props for the ApartmentHeader component. + * @param {ApartmentWithId} props.apartment - The apartment that the header displays information about. + * @param props.handleClick - Function that will be called when the header is clicked. + * @returns ApartmentHeader – The ApartmentHeader component. + */ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => { const { name, address, photos } = apartment; const [isMobile, setIsMobile] = useState(false); From f1fc4d252b48531baefceb3ec37d40f68f3f0dc7 Mon Sep 17 00:00:00 2001 From: "(Grace) Gunyasorn Sawatyanon" Date: Sun, 24 Mar 2024 00:37:16 -0400 Subject: [PATCH 5/9] update documentation --- frontend/src/components/Apartment/Header.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/Apartment/Header.tsx b/frontend/src/components/Apartment/Header.tsx index d6833e3e..056714ec 100644 --- a/frontend/src/components/Apartment/Header.tsx +++ b/frontend/src/components/Apartment/Header.tsx @@ -161,8 +161,9 @@ const useStyles = makeStyles((theme) => ({ /** * ApartmentHeader Component * - * This component represents a header with an apartment image, apartment name, apartment adress, and icon seen on each apartment page. - * When clicking on the header, handleClick will be called. The component is responsive for all screen sizes and mobile display. + * This component represents a header with an apartment photo, apartment name, apartment adress, and icon seen on each apartment page. + * When clicking on the header, handleClick will be called if the apartment has more than zero photos. The component is responsive for + * all screen sizes and mobile display. * * @component * @param props - The props for the ApartmentHeader component. From 4f54859a04625a9c4549c1f9c50eb405f3c471b9 Mon Sep 17 00:00:00 2001 From: Kea-Roy Ong <146872846+kea-roy@users.noreply.github.com> Date: Sun, 14 Apr 2024 01:52:07 -0400 Subject: [PATCH 6/9] Revamped FAQ Page --- frontend/src/App.tsx | 83 +++++----- frontend/src/colors.js | 2 + .../components/FAQ/CollapsibleQuestion.tsx | 66 ++++++-- frontend/src/index.tsx | 5 +- frontend/src/pages/FAQPage.tsx | 142 +++++++++++++++++- 5 files changed, 235 insertions(+), 63 deletions(-) diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 823d1f57..133b7ce7 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,6 +1,6 @@ import React, { ReactElement, useEffect, useState } from 'react'; import './App.scss'; -import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; +import { Route, Switch, useLocation } from 'react-router-dom'; import HomePage from './pages/HomePage'; import FAQPage from './pages/FAQPage'; import ReviewPage from './pages/ReviewPage'; @@ -95,7 +95,7 @@ hotjar.initialize(HJID, HJSV); const App = (): ReactElement => { const [user, setUser] = useState(null); - + const { pathname } = useLocation(); useEffect(() => { const setData = async () => { await axios.post('/api/set-data'); @@ -105,50 +105,45 @@ const App = (): ReactElement => { return ( - - -
- - } /> + +
+ + } /> - - } - /> + + } + /> - - } - /> - } - /> - } - /> - } - /> - } - /> - - } - /> - {isAdmin(user) && } - -
-
- + + } + /> + } + /> + } /> + } + /> + } + /> + + } + /> + {isAdmin(user) && } + +
+ {pathname !== '/faq' &&