diff --git a/package.json b/package.json index 1a90b36..0ba7722 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,9 @@ "react-icons": "^3.10.0", "react-instantsearch": "^6.4.0", "react-instantsearch-dom-maps": "^6.4.0", + "react-native-elements": "^2.0.4", "react-places-autocomplete": "^7.2.1", + "react-responsive": "^8.1.0", "react-scripts": "^3.4.1", "styled-components": "^5.1.0", "typescript": "^3.9.5" diff --git a/src/App.css b/src/App.css index f6579c0..abc6970 100644 --- a/src/App.css +++ b/src/App.css @@ -42,6 +42,8 @@ em { text-decoration: underline; } + + .search-container { position: relative; } @@ -210,7 +212,6 @@ footer { #popover-contained { background-color: #ffffff; box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.4); - height: 490px; max-width: 532px; padding: 40px 40px; } @@ -221,7 +222,6 @@ footer { line-height: 1.15; font-size: 15px; font-weight: 400; - height: 509px; max-width: 410px; text-align: justify; width: 410px; @@ -232,7 +232,6 @@ footer { } .map-popover__address { - height: 23px; font-size: 15px; font-weight: normal; font-stretch: normal; @@ -249,7 +248,6 @@ footer { font-stretch: normal; font-style: normal; font-weight: bold; - height: 23px; margin-bottom: 12px; letter-spacing: 0.75px; line-height: normal; @@ -263,7 +261,6 @@ footer { font-stretch: normal; font-style: normal; font-weight: normal; - height: 23px; letter-spacing: 0.75px; line-height: normal; margin-bottom: 34px; @@ -280,7 +277,6 @@ footer { font-stretch: normal; font-style: normal; font-weight: bold; - height: 23px; letter-spacing: 0.8px; line-height: normal; text-transform: uppercase; @@ -302,3 +298,14 @@ footer { .place__info-contact { margin-bottom: 20px; } + +@media (max-width: 400px) { + .navbar { + padding: 1rem 1rem .5rem !important; + align-items: flex-start !important; + } + #map-popover { + left: -5px!important; + max-width: 100%; + } +} diff --git a/src/App.tsx b/src/App.tsx index 65f8e90..45d3b5e 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,7 +8,7 @@ function App() {
diff --git a/src/assets/genericPinSelected.png b/src/assets/genericPinSelected.png new file mode 100644 index 0000000..6532cce Binary files /dev/null and b/src/assets/genericPinSelected.png differ diff --git a/src/assets/list.png b/src/assets/list.png new file mode 100644 index 0000000..befcd18 Binary files /dev/null and b/src/assets/list.png differ diff --git a/src/assets/map.png b/src/assets/map.png new file mode 100644 index 0000000..da0b1f7 Binary files /dev/null and b/src/assets/map.png differ diff --git a/src/components/UI/ButtonExample.tsx b/src/components/UI/ButtonExample.tsx index 57a95d8..d70a32e 100644 --- a/src/components/UI/ButtonExample.tsx +++ b/src/components/UI/ButtonExample.tsx @@ -1,4 +1,4 @@ -import React from 'react'; +import React, { Component } from 'react'; interface IProps { buttonStyle?: object; @@ -18,3 +18,8 @@ const Button: React.FC = props => { }; export default Button; + + +// access state => Callback in parent Component +// toggles state +// 2. Set state variable in parent component, pass it to child as prop diff --git a/src/components/UI/Map.tsx b/src/components/UI/Map.tsx index 17b5c31..14395f6 100644 --- a/src/components/UI/Map.tsx +++ b/src/components/UI/Map.tsx @@ -13,54 +13,67 @@ import Marker from "./Marker" import { Location } from "./types" import { HitComponent } from "../common/Hit" import filterIcon from "../../assets/filter.png" +import mapIcon from "../../assets/map.png" +import listIcon from "../../assets/list.png" import LocationProvider from "../../contexts/LocationContext" -import { IconButton as FilterButton } from "../common/Button" +import { IconButton as FilterButton, MapListButton } from "../common/Button" +import { useWindowSize } from '../common/MediaQuery'; + +export const MapContainer = styled.div` + height: calc(100vh - 71px); + position: absolute; + right: 0; + top: 71px; + width: calc(100vw - 430px); -const MapContainer = styled.div` - height: calc(100vh - 76px); - width: 100vw; @media (min-width: 980px) { - position: absolute; - right: 0; - top: 76px; + // position: absolute; + // right: 0; + // top: 71px; width: calc(100vw - 430px); } + @media (max-width: 575px) { + top: 0; + position: relative; + height: calc(96vh - 76px); + width: 100%; + } ` const Filter = styled.div` - display: none; + align-content: center; + align-items: center; + background: white; + border-bottom: 1px solid lightgray; + box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.3); + display: flex; + height: 92px; + // position: absolute; + padding: 17.5px 30px; + top: 70px; + width: 414px; + z-index: 500; + justify-content: space-between; - @media (min-width: 980px) { - align-content: center; - align-items: center; - background: white; - border-bottom: 1px solid lightgray; - box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.3); - display: flex; - height: 92px; - left: 0; - position: absolute; - padding: 17.5px 30px; - top: 76px; - width: 430px; - z-index: 500; + @media (max-width: 575px) { + width: 100%; } ` -const ResultsList = styled.div` - display: none; +export const ResultsList = styled.div` + background: white; + box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.3); + display: block; + height: calc(100vh - (70px + 92px)); + overflow: scroll; + top: calc(70px + 92px); + width: 414px; + z-index: 1000; + + @media (max-width: 575px) { + width: 100%; + height: calc(100vh - (70px + 150px)); - @media (min-width: 980px) { - background: white; - box-shadow: 0 8px 8px 0 rgba(0, 0, 0, 0.3); - display: block; - height: calc(100vh - (76px + 92px)); - left: 0; - overflow: scroll; - position: absolute; - top: calc(76px + 92px); - width: 430px; - z-index: 500; } ` @@ -84,6 +97,9 @@ export default ({ defaultLocation }: Map) => { const [location, setLocation] = useState( defaultLocation || US_LOCATION ) + const mq = useWindowSize(); + const mdScreen = mq.width < 575 + let [show, setShow] = useState(true) return ( @@ -115,12 +131,20 @@ export default ({ defaultLocation }: Map) => { src={filterIcon}> Filter + {mdScreen ? setShow(!show)} + toggle={show} > + {show ? 'map' : 'list'} + + :
} - - - - - + { !mdScreen || show ? + { )} + :
} + { !mdScreen || !show ? + + + :
}
)} ) -} +} \ No newline at end of file diff --git a/src/components/UI/Marker.tsx b/src/components/UI/Marker.tsx index e040c84..8c9f527 100644 --- a/src/components/UI/Marker.tsx +++ b/src/components/UI/Marker.tsx @@ -1,5 +1,5 @@ import styled from "styled-components" -import { Overlay, Popover } from "react-bootstrap" +import { Popover, Overlay } from "react-bootstrap" import React, { useContext, useRef, useState } from "react" import { CustomMarker } from "react-instantsearch-dom-maps" @@ -34,10 +34,17 @@ const Title = styled.div` font-stretch: normal; font-style: normal; font-weight: bold; - height: 23px; margin-bottom: 5px; line-height: normal; ` +const MarkerContainer = styled.div` + width: 375px; + height: 517px; + border-radius: 5px; + box-shadow: 0 2px 15px 0 rgba(0, 0, 0, 0.4); + background-color: #ffffff; +` + const Marker: React.FC = (props) => { const ref = useRef(null) @@ -83,6 +90,12 @@ const Marker: React.FC = (props) => { selectHit(true) } + const direction = () => { + const smallScreen = window.matchMedia('(min-width: 400px)') + return smallScreen.matches ? "right" : "bottom-end" + } + + return (
@@ -94,7 +107,7 @@ const Marker: React.FC = (props) => { rootClose show={open} target={target} - placement="right" + placement={direction()} transition={false} onHide={handleClose} container={ref.current}> diff --git a/src/components/UI/Menu.tsx b/src/components/UI/Menu.tsx index 4ede384..c1589dc 100644 --- a/src/components/UI/Menu.tsx +++ b/src/components/UI/Menu.tsx @@ -1,29 +1,20 @@ import React from "react" import styled from "styled-components" -import { IoMdMenu } from "react-icons/all" // import InfoPopover from "./InfoPopover" import MenuButton from '../common/MenuButton' - -const MenuContainer = styled("div")` - display: flex; - justify-content: space-between; - margin-left: 0px; - - @media (max-width: 400px) { - top: 80px; - } -` +import { Navbar } from 'react-bootstrap' const MobileMenu = styled("div")` - @media (min-width: 400px) { - display: none; - } + position: absolute; + padding: .5rem .75rem; + right: 0; + top: 0; ` const ButtonsContainer = styled("div")` display: flex; justify-content: space-around; - width: 380px; + right: 0; & button { border: none; @@ -35,11 +26,12 @@ const ButtonsContainer = styled("div")` } @media (max-width: 400px) { - position: fixed; - top: 120px; - left: 0; - width: 100%; - height: 100%; + // display: block; + // top: 7rem; + // left: -18rem; + // width: 300px; + // height: 100%; + bottom: 0; z-index: 1000; background: white; @@ -63,52 +55,54 @@ const ButtonsContainer = styled("div")` // ` export default () => ( - - - - + <> + + + + + - - - - - {/* -

- For over 30 years, the Souper Bowl of Caring campaign has been a local - effort with a collective impact using the energy of the Big Game to - tackle hunger. -

-

- Churches, schools and civic groups around the country join in through - hosting food and donation campaigns each year that benefit local - charities picked by participants. -

-

- Since 1990, over $163 million has been raised for almost 10,000 local - charities around the nation and world. -

-

- The Souper Bowl of Caring illustrates the importance of a collective - impact from local grassroots efforts to tackle hunger. -

- Learn more about our history -
- -

- Contributing, Branching, & Forking While we actively accept help, as - well as encourage you to fork this repo and build it out for your - city, we do not take pull requests directly to this repo - please - contact us before you plan to do so. Reach out to:
- Repo - Github - {" "} -
- Twitter @dariceshelter -

-
- -

Coming soon

-
*/} -
-
+ + + + {/* +

+ For over 30 years, the Souper Bowl of Caring campaign has been a local + effort with a collective impact using the energy of the Big Game to + tackle hunger. +

+

+ Churches, schools and civic groups around the country join in through + hosting food and donation campaigns each year that benefit local + charities picked by participants. +

+

+ Since 1990, over $163 million has been raised for almost 10,000 local + charities around the nation and world. +

+

+ The Souper Bowl of Caring illustrates the importance of a collective + impact from local grassroots efforts to tackle hunger. +

+ Learn more about our history +
+ +

+ Contributing, Branching, & Forking While we actively accept help, as + well as encourage you to fork this repo and build it out for your + city, we do not take pull requests directly to this repo - please + contact us before you plan to do so. Reach out to:
+ Repo + Github + {" "} +
+ Twitter @dariceshelter +

+
+ +

Coming soon

+
*/} + + + ) diff --git a/src/components/UI/Search.tsx b/src/components/UI/Search.tsx index 519d32e..b4af1fc 100644 --- a/src/components/UI/Search.tsx +++ b/src/components/UI/Search.tsx @@ -8,7 +8,7 @@ import searchIcon from "../../assets/images/search@3x.png"; const Suggestions = styled.div` border-radius: 0 0 10px 10px; - position: absolute; + // position: absolute; z-index: 1000; background: white; width: 100%; @@ -32,12 +32,19 @@ const Container = styled.div` justify-content: center; z-index: 1000; height: 48px; + min-width: 300px; + + @media (max-width: 575px) { + margin: 15px 0 0 0; + } @media (max-width: 400px) { position: relative; - top: 50px; + margin-top: 50px; min-width: 100%; + } + `; const SearchBar = styled.div` @@ -54,6 +61,8 @@ const SearchIcon = styled.img` top: 13px; width: 24px; z-index: 999; + + `; type SearchProps = { @@ -77,30 +86,30 @@ export default ({ setLocation }: SearchProps) => { > {({ getInputProps, suggestions, getSuggestionItemProps, loading }) => ( - - -
- - - - - - {!loading && - suggestions.map((suggestion) => ( - - {suggestion.description} - - ))} - -
-
+ + +
+ + + + + + {!loading && + suggestions.map((suggestion) => ( + + {suggestion.description} + + ))} + +
+
)} diff --git a/src/components/UI/TopBar.tsx b/src/components/UI/TopBar.tsx index 9819719..e9183de 100644 --- a/src/components/UI/TopBar.tsx +++ b/src/components/UI/TopBar.tsx @@ -6,19 +6,21 @@ import Search from "./Search"; import { SetLocation } from "./types"; import BrandLogo from "../common/BrandLogo"; import "bootstrap/dist/css/bootstrap.min.css"; +import { Navbar } from "react-bootstrap"; const Container = styled("div")` background-color: #ffffff; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2) !important; display: flex; - padding: 14px 25px; - position: absolute; + padding: 5px 0 0; + // position: absolute; top: 0; width: 100%; + // height: 75px; z-index: 1000; @media (max-width: 400px) { - height: 120px; + // height: 150px; } `; @@ -29,9 +31,11 @@ type TopBarProps = { export default ({ setLocation }: TopBarProps) => { return ( - - - + + + + + ); }; diff --git a/src/components/common/Button.tsx b/src/components/common/Button.tsx index 6187e7a..b9ce0ca 100644 --- a/src/components/common/Button.tsx +++ b/src/components/common/Button.tsx @@ -4,11 +4,12 @@ import styled from "styled-components" const getWidth = (size = "medium") => ({ small: "53.5px", medium: "107px", large: "244px" }[size] || "107px") -interface ButtonProps { +interface ButtonProps extends React.ButtonHTMLAttributes{ border?: boolean - size?: string primary?: boolean width?: string + size?: string + toggle?: boolean } const Button = styled.button` @@ -38,7 +39,6 @@ const Button = styled.button` interface IconButtonProps extends ButtonProps { alt?: string - children: React.ReactNode src: string } @@ -61,4 +61,24 @@ export const IconButton = ({ ) } +interface MapListButtonProps extends ButtonProps { + alt?: string + src: string +} + +export const MapListButton = ({ + alt, + children, + src, + toggle, + ...buttonProps +}: MapListButtonProps) => { + return ( + + ) +} + export default Button diff --git a/src/components/common/MediaQuery.tsx b/src/components/common/MediaQuery.tsx new file mode 100644 index 0000000..7fb85d8 --- /dev/null +++ b/src/components/common/MediaQuery.tsx @@ -0,0 +1,30 @@ +import { useState, useEffect } from 'react'; + + +export const useWindowSize = () => { + const isClient = typeof window === 'object'; + + const getSize = () => { + return { + width: window.innerWidth, + height: window.innerHeight + }; + } + + const [windowSize, setWindowSize] = useState(getSize); + + useEffect(() => { + if (!isClient) { + return () => false; + } + + const handleResize = () => { + setWindowSize(getSize()); + } + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); // Empty array ensures that effect is only run on mount and unmount + + return windowSize; +} \ No newline at end of file diff --git a/src/components/common/MenuButton.tsx b/src/components/common/MenuButton.tsx index fbe58a7..23fe127 100644 --- a/src/components/common/MenuButton.tsx +++ b/src/components/common/MenuButton.tsx @@ -13,7 +13,7 @@ const ButtonLink = styled.a` color: #171b50; font-weight: bold; letter-spacing: 0.8px; - padding-top: 12px; + padding: 12px; text-transform: uppercase; width: auto; text-decoration: none; @@ -27,7 +27,7 @@ const ButtonLink = styled.a` @media (max-width: 400px) { width: 100%; - margin-bottom: 20px; + padding: .2rem; } `