diff --git a/.vscode/settings.json b/.vscode/settings.json index 650faf99d..af43e57ed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -14,7 +14,13 @@ "titleBar.activeBackground": "#c334b5", "titleBar.activeForeground": "#e7e7e7", "titleBar.inactiveBackground": "#c334b599", - "titleBar.inactiveForeground": "#e7e7e799" + "titleBar.inactiveForeground": "#e7e7e799", + "editorGroup.border": "#d258c6", + "panel.border": "#d258c6", + "sash.hoverBorder": "#d258c6", + "sideBar.border": "#d258c6", + "statusBarItem.remoteBackground": "#c334b5", + "statusBarItem.remoteForeground": "#e7e7e7" }, "peacock.color": "#c334b5" } diff --git a/components/GlobalStyles.tsx b/components/GlobalStyles.tsx index 39b51d9e9..5aaad7740 100644 --- a/components/GlobalStyles.tsx +++ b/components/GlobalStyles.tsx @@ -20,6 +20,7 @@ export const GlobalStyle = createGlobalStyle` --tertiary: 231,241,251; --inputBackground: 255,255,255; --navbarBackground: 255,255,255; + --modalBackground: 251,251,253; } .dark-theme { @@ -33,6 +34,7 @@ export const GlobalStyle = createGlobalStyle` --z-navbar: 8888; --z-drawer: 9999; + --z-modal: 9999; } /* Box sizing rules */ diff --git a/components/Navbar.tsx b/components/Navbar.tsx index 9741bfb32..f5732532f 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -10,6 +10,7 @@ import { NavItems, SingleNavItem } from 'types'; import { HamburgerIcon } from './HamburgerIcon'; import { media } from 'utils/media'; import Button from './Button'; +import { useNewsletterModalContext } from 'contexts/newsletter-modal.context'; type NavbarProps = { items: NavItems }; type ScrollingDirections = 'up' | 'down' | 'none'; @@ -82,12 +83,14 @@ export default function Navbar({ items }: NavbarProps) { } function NavItem({ href, title, outlined }: SingleNavItem) { + const { setIsModalOpened } = useNewsletterModalContext(); + + function showNewsletterModal() { + setIsModalOpened(true); + } + if (outlined) { - return ( - - {title} - - ); + return {title}; } return ( diff --git a/components/NewsletterModal.tsx b/components/NewsletterModal.tsx new file mode 100644 index 000000000..c1e86f517 --- /dev/null +++ b/components/NewsletterModal.tsx @@ -0,0 +1,107 @@ +import useEscClose from 'hooks/useEscKey'; +import styled from 'styled-components'; +import { media } from 'utils/media'; +import Button from './Button'; +import CloseIcon from './CloseIcon'; +import Container from './Container'; +import Input from './Input'; +import Overlay from './Overlay'; + +export interface NewsletterModalProps { + onClose: () => void; +} + +export default function NewsletterModal({ onClose }: NewsletterModalProps) { + useEscClose({ onClose }); + + return ( + + + + + + + Are you ready to enroll to the best newsletter ever? + + + Submit + + + + + ); +} + +const Card = styled.div` + display: flex; + position: relative; + flex-direction: column; + margin: auto; + padding: 10rem 5rem; + background: rgb(var(--modalBackground)); + border-radius: 0.6rem; + max-width: 70rem; + overflow: hidden; + + ${media('<=tablet')} { + padding: 7.5rem 2.5rem; + } +`; + +const CloseIconContainer = styled.div` + position: absolute; + right: 2rem; + top: 2rem; + + svg { + cursor: pointer; + width: 2rem; + } +`; + +const Title = styled.div` + font-size: 3.2rem; + font-weight: bold; + line-height: 1.1; + letter-spacing: -0.03em; + text-align: center; + color: rgb(var(--text)); + + ${media('<=tablet')} { + font-size: 2.6rem; + } +`; + +const Row = styled.div` + display: flex; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; + margin-top: 3rem; + + ${media('<=tablet')} { + flex-direction: column; + } +`; + +const CustomButton = styled(Button)` + height: 100%; + padding: 1.8rem; + margin-left: 1.5rem; + box-shadow: var(--shadow-lg); + + ${media('<=tablet')} { + width: 100%; + margin-left: 0; + margin-top: 1rem; + } +`; + +const CustomInput = styled(Input)` + width: 60%; + + ${media('<=tablet')} { + width: 100%; + } +`; diff --git a/components/Overlay.tsx b/components/Overlay.tsx new file mode 100644 index 000000000..5ba91bba5 --- /dev/null +++ b/components/Overlay.tsx @@ -0,0 +1,15 @@ +import styled from 'styled-components'; + +const Overlay = styled.div` + position: fixed; + inset: 0; + background: rgba(var(--secondary), 0.997); + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + z-index: var(--z-modal); + color: rgb(var(--textSecondary)); +`; + +export default Overlay; diff --git a/contexts/newsletter-modal.context.tsx b/contexts/newsletter-modal.context.tsx new file mode 100644 index 000000000..e72108a72 --- /dev/null +++ b/contexts/newsletter-modal.context.tsx @@ -0,0 +1,31 @@ +import React, { Dispatch, PropsWithChildren, SetStateAction, useContext, useState } from 'react'; + +interface NewsletterModalContextProps { + isModalOpened: boolean; + setIsModalOpened: Dispatch>; +} + +export const NewsletterModalContext = React.createContext(null); + +export function NewsletterModalContextProvider({ children }: PropsWithChildren) { + const [isModalOpened, setIsModalOpened] = useState(false); + + return ( + + {children} + + ); +} + +export function useNewsletterModalContext() { + const context = useContext(NewsletterModalContext); + if (!context) { + throw new Error('useNewsletterModalContext can only be used inside NewsletterModalContextProvider'); + } + return context; +} diff --git a/hooks/useEscKey.ts b/hooks/useEscKey.ts new file mode 100644 index 000000000..42a2fb0bb --- /dev/null +++ b/hooks/useEscKey.ts @@ -0,0 +1,25 @@ +import { useCallback, useEffect } from 'react'; + +export interface UseEscCloseProps { + onClose: () => void; +} + +export default function useEscClose({ onClose }: UseEscCloseProps) { + const handleUserKeyPress = useCallback( + (event) => { + const { keyCode } = event; + const escapeKeyCode = 27; + if (keyCode === escapeKeyCode) { + onClose(); + } + }, + [onClose], + ); + + useEffect(() => { + window.addEventListener('keydown', handleUserKeyPress); + return () => { + window.removeEventListener('keydown', handleUserKeyPress); + }; + }, [handleUserKeyPress]); +} diff --git a/pages/_app.tsx b/pages/_app.tsx index 0ab75ffa5..f95974b5f 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -9,6 +9,9 @@ import { GlobalStyle } from 'components/GlobalStyles'; import Navbar from 'components/Navbar'; import { NavItems } from 'types'; import NavigationDrawer from 'components/NavigationDrawer'; +import NewsletterModal from 'components/NewsletterModal'; +import { NewsletterModalContextProvider, useNewsletterModalContext } from 'contexts/newsletter-modal.context'; +import { PropsWithChildren } from 'react'; const navItems: NavItems = [ { title: 'Why logoipsum', href: '/' }, @@ -37,15 +40,30 @@ function MyApp({ Component, pageProps }: AppProps) { {/* */} - + + + - - {/* */} - {/* */} - {/* */} - {standaloneMarkup} + {standaloneMarkup} + ); } +function Providers({ children }: PropsWithChildren) { + return ( + + {children} + + ); +} + +function Modals() { + const { isModalOpened, setIsModalOpened } = useNewsletterModalContext(); + if (!isModalOpened) { + return null; + } + return setIsModalOpened(false)} />; +} + export default MyApp;