Skip to content

Commit

Permalink
Merge pull request #359 from cornell-dti/apartmentImageStyle
Browse files Browse the repository at this point in the history
Implemented Apartment Image Frontend
  • Loading branch information
dan-ieljin authored May 1, 2024
2 parents 025f2d2 + e4bd832 commit bc25d44
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 119 deletions.
8 changes: 8 additions & 0 deletions frontend/src/assets/default_icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions frontend/src/colors.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export const colors = {
red1: '#B94630',
red1Transparent: 'rgba(185, 70, 48, 0.8)',
red2: '#EB5757',
red3: '#E8725C',
red4: '#FFCFC7',
Expand Down
213 changes: 121 additions & 92 deletions frontend/src/components/Apartment/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@ import {
withStyles,
makeStyles,
Avatar,

Check warning on line 9 in frontend/src/components/Apartment/Header.tsx

View workflow job for this annotation

GitHub Actions / lint

'Avatar' is defined but never used
ButtonBase,
} from '@material-ui/core';
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 = {
Expand All @@ -31,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',
Expand All @@ -43,54 +53,44 @@ const useStyles = makeStyles((theme) => ({
marginLeft: '-4.3%',
resizeMode: 'contain',
},
headerInfoContainer: {
bottom: 0,
position: 'absolute',
display: 'flex',
alignItems: 'center',
minHeight: '40%',
},
mobileHeaderInfoContainer: {
bottom: '0',
position: 'absolute',
display: 'flex',
flexDirection: 'row',
flexWrap: 'wrap',
justifyContent: 'center',
height: 'auto',
width: '100%',
paddingTop: '10px',
paddingBottom: '20px',
},
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',
Expand All @@ -100,32 +100,44 @@ const useStyles = makeStyles((theme) => ({
},
aptAddress: {
color: colors.white,
paddingLeft: '20px',
fontStyle: 'normal',
fontSize: '20px',
letterSpacing: '0.02em',
marginBottom: '10px',
},
mobileAptName: {
color: colors.white,
fontWeight: 'bold',
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,
fontStyle: 'normal',
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')]: {
Expand All @@ -134,27 +146,52 @@ const useStyles = makeStyles((theme) => ({
},
logoGrid: {
marginRight: '1em',
flex: '0 0 auto',
display: 'flex',
justifyContent: 'flex-start',
alignItems: 'center',
},
logoGridMobile: {
display: 'flex',
justifyContent: 'flex-end',
alignItems: 'center',
},
}));

/**
* ApartmentHeader Component
*
* 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.
* @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<boolean>(false);

const icon = defaultIcon;
const photoLink = defaultHeader;
const photoLink = photos.length > 0 ? photos[0] : defaultHeader;

const {
media,
overlayContainer,
mediaGradient,
mobileMedia,
headerInfoContainer,
mobileHeaderInfoContainer,
logo,
mobileLogo,
photoButton,
aptName,
aptAddress,
headerSection,
mobileHeaderSection,
btnSection,

Check warning on line 192 in frontend/src/components/Apartment/Header.tsx

View workflow job for this annotation

GitHub Actions / lint

'btnSection' is assigned a value but never used
logoGrid,
logoGridMobile,
mobileAptName,
mobileAptAddress,
} = useStyles();
Expand All @@ -166,67 +203,59 @@ const ApartmentHeader = ({ apartment, handleClick }: Props): ReactElement => {
return () => window.removeEventListener('resize', handleResize);
}, []);

const header = (
<Grid container spacing={0} alignItems="flex-end" className={styles.HeaderDiv}>
<>
<GlobalCss />
<Grid item xs={12}>
<CardMedia className={media} image={photoLink}>
<Grid item xs={12}>
<Grid container className={styles.HeaderRow}>
<Grid item xs={12} md={1} className={logoGrid}>
<Avatar src={icon} alt={name} className={logo} />
</Grid>
<Grid className={headerSection}>
<CardHeader title={name} className={aptName} disableTypography={true} />
<CardHeader title={address} className={aptAddress} disableTypography={true} />
</Grid>
</Grid>
</Grid>
{photos.length > 0 && (
<Grid
container
alignItems="flex-end"
justifyContent="flex-end"
className={btnSection}
>
<Button
disableFocusRipple
variant="outlined"
className={photoButton}
onClick={handleClick}
>
Show all photos
</Button>
</Grid>
)}
</CardMedia>
</Grid>
</>
const headerContent = (
<Grid container className={!isMobile ? headerInfoContainer : mobileHeaderInfoContainer}>
<Grid item xs={!isMobile ? 12 : 3} md={1} className={!isMobile ? logoGrid : logoGridMobile}>
<DefaultIcon
className={!isMobile ? logo : mobileLogo}
aria-label={name}
color={photos.length > 0 ? colors.red1Transparent : colors.red1}
/>
</Grid>
<Grid item xs={!isMobile ? 6 : 9} className={!isMobile ? headerSection : mobileHeaderSection}>
<CardHeader
title={name}
className={!isMobile ? aptName : mobileAptName}
disableTypography={true}
/>
<CardHeader
title={address}
className={!isMobile ? aptAddress : mobileAptAddress}
disableTypography={true}
/>
</Grid>
</Grid>
);
const mobileHeader = (

return (
<Grid container spacing={0} alignItems="flex-end" className={styles.HeaderDiv}>
<>
<GlobalCss />
<Grid item xs={12}>
<CardMedia className={mobileMedia} image={photoLink}>
<Grid container alignItems="center" className={headerSection}>
<Grid item xs={6}>
<Avatar src={icon} alt={name} className={mobileLogo} />
</Grid>
<Grid item xs={6}>
<CardHeader title={name} className={mobileAptName} disableTypography={true} />
<CardHeader title={address} className={mobileAptAddress} disableTypography={true} />
</Grid>
</Grid>
</CardMedia>
<ButtonBase
onClick={handleClick}
style={{ width: '100%', display: 'block' }}
disableRipple
disabled={photos.length === 0}
>
<div className={!isMobile ? overlayContainer : ''}>
<CardMedia className={!isMobile ? media : mobileMedia} image={photoLink}>
<div className={photos.length > 0 ? mediaGradient : ''}>
{!isMobile ? (
<Grid item xs={12}>
{headerContent}
</Grid>
) : (
headerContent
)}
</div>
</CardMedia>
</div>
</ButtonBase>
</Grid>
</>
</Grid>
);

return isMobile ? mobileHeader : header;
};

export default ApartmentHeader;
2 changes: 2 additions & 0 deletions frontend/src/components/ApartmentCard/ApartmentCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ const useStyles = makeStyles({
imgStyle: {
borderRadius: '12%',
padding: '17px',
width: '205px',
height: '205px',
},
aptNameTxt: {
fontWeight: 800,
Expand Down
16 changes: 12 additions & 4 deletions frontend/src/components/Landlord/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down Expand Up @@ -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;

Check warning on line 150 in frontend/src/components/Landlord/Header.tsx

View workflow job for this annotation

GitHub Actions / lint

'icon' is assigned a value but never used
const photoLink = photos.length ? photos[0] : defaultHeader;
const [isMobile, setIsMobile] = useState<boolean>(false);

Expand Down Expand Up @@ -180,7 +180,11 @@ const LandlordHeader = ({ landlord, handleClick }: Props): ReactElement => {
<Grid item xs={12}>
<Grid container className={styles.HeaderRow}>
<Grid item xs={12} md={1} className={logoGrid}>
<Avatar src={icon} alt={name} className={logo} />
<DefaultIcon
className={logo}
aria-label={name}
color={photos.length > 0 ? colors.red1Transparent : colors.red1}
/>
</Grid>
<Grid className={headerSection}>
<CardHeader title={name} className={landlordName} disableTypography={true} />
Expand Down Expand Up @@ -218,7 +222,11 @@ const LandlordHeader = ({ landlord, handleClick }: Props): ReactElement => {
<CardMedia className={mobileMedia} image={photoLink}>
<Grid container alignItems="center" className={headerSection}>
<Grid item xs={6}>
<Avatar src={icon} alt={name} className={mobileLogo} />
<DefaultIcon
className={mobileLogo}
aria-label={name}
color={photos.length > 0 ? colors.red1Transparent : colors.red1}
/>
</Grid>
<Grid item xs={6}>
<CardHeader title={name} className={mobileLandlordName} disableTypography={true} />
Expand Down
Loading

0 comments on commit bc25d44

Please sign in to comment.