diff --git a/README.md b/README.md index f782ef97..56853bda 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,7 @@ -

- - Project Banner Image - -

- -### Remove git - -rm -rf .git - # Design Handoff Project -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. - -## Getting Started with the Project - -### Dependency Installation & Startup Development Server - -Once cloned, navigate to the project's root directory and this project uses npm (Node Package Manager) to manage its dependencies. - -The command below is a combination of installing dependencies, opening up the project on VS Code and it will run a development server on your terminal. - -```bash -npm i && code . && npm run dev -``` - -### The Problem - -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +Transform a UX student's design into a React-based landing page for a gym/fitness club. This project bridges the gap between design and development, showcasing the art of bringing visuals to life with code. ### View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. - -## Instructions - - - See instructions of this project - +https://golden-kitsune-efb49e.netlify.app/ diff --git a/index.html b/index.html index a52ab900..4308c6cc 100644 --- a/index.html +++ b/index.html @@ -4,7 +4,11 @@ - Music Releases - Project - Week 5 + + + Sunny Yoga
diff --git a/package.json b/package.json index 4ba5ff02..ae6f6687 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ }, "dependencies": { "react": "^18.2.0", - "react-dom": "^18.2.0" + "react-dom": "^18.2.0", + "react-responsive-carousel": "^3.2.23", + "styled-components": "^6.1.8" }, "devDependencies": { "@types/react": "^18.2.15", @@ -21,6 +23,7 @@ "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", - "vite": "^4.4.5" + "vite": "^4.4.5", + "vite-plugin-svgr": "^4.2.0" } } diff --git a/public/vite.svg b/public/vite.svg deleted file mode 100644 index e7b8dfb1..00000000 --- a/public/vite.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/pull_request_template.md b/pull_request_template.md deleted file mode 100644 index d92c89b5..00000000 --- a/pull_request_template.md +++ /dev/null @@ -1,7 +0,0 @@ -## Netlify link -Add your Netlify link here. -PS. Don't forget to add it in your readme as well. - -## Collaborators -Add your collaborators here. Write their GitHub usernames in square brackets. If there's more than one, separate them with a comma, like this: -[github-username-1, github-username-2] diff --git a/src/App.jsx b/src/App.jsx index 1091d431..244bb310 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,3 +1,33 @@ -export const App = () => { - return
Find me in src/app.jsx!
; +import { About } from "./components/pages/About.jsx"; +import { AboutTabletDesk } from "./components/pages/AboutTabletDesk.jsx"; +import Arrow from "./components/pages/Arrow.jsx"; +import { Teachers } from "./components/pages/Teachers.jsx"; +import { TeachersTabletdesk } from "./components/pages/TeachersTabletdesk"; +import Introduction from "./components/pages/Introduction.jsx"; +import { Border } from "./components/pages/Border.jsx"; +import { Promise } from "./components/pages/Promise.jsx"; +import { Register } from "./components/pages/Register.jsx"; +import { Quote } from "./components/pages/Quote.jsx"; +import { Contact } from "./components/pages/Contact.jsx"; +import { Questions } from "./components/pages/Questions.jsx"; +const App = () => { + return ( +
+ + + + + + + + + + + + + +
+ ); }; + +export default App; diff --git a/src/assets/EasterEgg.svg b/src/assets/EasterEgg.svg new file mode 100644 index 00000000..7dce57d4 --- /dev/null +++ b/src/assets/EasterEgg.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/HeartIcon.svg b/src/assets/HeartIcon.svg new file mode 100644 index 00000000..3240d5d6 --- /dev/null +++ b/src/assets/HeartIcon.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/assets/LogoDesktop.svg b/src/assets/LogoDesktop.svg new file mode 100644 index 00000000..8cd102dc --- /dev/null +++ b/src/assets/LogoDesktop.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/LogoMobile.svg b/src/assets/LogoMobile.svg new file mode 100644 index 00000000..e714ad95 --- /dev/null +++ b/src/assets/LogoMobile.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/LogoTablet.svg b/src/assets/LogoTablet.svg new file mode 100644 index 00000000..3b2eddd9 --- /dev/null +++ b/src/assets/LogoTablet.svg @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/src/assets/Minus.svg b/src/assets/Minus.svg new file mode 100644 index 00000000..14b4546f --- /dev/null +++ b/src/assets/Minus.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/Plus.svg b/src/assets/Plus.svg new file mode 100644 index 00000000..ce0e277e --- /dev/null +++ b/src/assets/Plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/Union.svg b/src/assets/Union.svg new file mode 100644 index 00000000..2eb282fd --- /dev/null +++ b/src/assets/Union.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/about-one.jpg b/src/assets/about-one.jpg new file mode 100644 index 00000000..9848e710 Binary files /dev/null and b/src/assets/about-one.jpg differ diff --git a/src/assets/about-two.jpg b/src/assets/about-two.jpg new file mode 100644 index 00000000..d6f2673c Binary files /dev/null and b/src/assets/about-two.jpg differ diff --git a/src/assets/anna.png b/src/assets/anna.png new file mode 100644 index 00000000..0745d1fa Binary files /dev/null and b/src/assets/anna.png differ diff --git a/src/assets/arrow.svg b/src/assets/arrow.svg new file mode 100644 index 00000000..83dd6e0a --- /dev/null +++ b/src/assets/arrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/contact.jpg b/src/assets/contact.jpg new file mode 100644 index 00000000..3c60d9a9 Binary files /dev/null and b/src/assets/contact.jpg differ diff --git a/src/assets/desktop-dec.svg b/src/assets/desktop-dec.svg new file mode 100644 index 00000000..fd4931b6 --- /dev/null +++ b/src/assets/desktop-dec.svg @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/drink.svg b/src/assets/drink.svg new file mode 100644 index 00000000..8cc8ab98 --- /dev/null +++ b/src/assets/drink.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/intro-one.jpg b/src/assets/intro-one.jpg new file mode 100644 index 00000000..b75ea532 Binary files /dev/null and b/src/assets/intro-one.jpg differ diff --git a/src/assets/lotus.svg b/src/assets/lotus.svg new file mode 100644 index 00000000..1bbb96a7 --- /dev/null +++ b/src/assets/lotus.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/mobil-dec.svg b/src/assets/mobil-dec.svg new file mode 100644 index 00000000..3dfcee20 --- /dev/null +++ b/src/assets/mobil-dec.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/questions.jpg b/src/assets/questions.jpg new file mode 100644 index 00000000..1e5b6383 Binary files /dev/null and b/src/assets/questions.jpg differ diff --git a/src/assets/tablet-dec.svg b/src/assets/tablet-dec.svg new file mode 100644 index 00000000..e49c2b9a --- /dev/null +++ b/src/assets/tablet-dec.svg @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/teacher-one.jpg b/src/assets/teacher-one.jpg new file mode 100644 index 00000000..38ea122c Binary files /dev/null and b/src/assets/teacher-one.jpg differ diff --git a/src/assets/teacher-two.jpg b/src/assets/teacher-two.jpg new file mode 100644 index 00000000..5e72c7bc Binary files /dev/null and b/src/assets/teacher-two.jpg differ diff --git a/src/assets/yoga.svg b/src/assets/yoga.svg new file mode 100644 index 00000000..a2d9d605 --- /dev/null +++ b/src/assets/yoga.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/components/CheckBox.jsx b/src/components/CheckBox.jsx new file mode 100644 index 00000000..fe0fa440 --- /dev/null +++ b/src/components/CheckBox.jsx @@ -0,0 +1,52 @@ +import styled from "styled-components"; +import PropTypes from "prop-types"; + +const CheckboxContainer = styled.div` + display: flex; + align-items: center; +`; + +const Icon = styled.svg` + fill: none; + stroke: #1c2996; + stroke-width: 2px; +`; + +const HiddenCheckbox = styled.input.attrs({ type: "checkbox" })` + border: 0; + clip: rect(0 0 0 0); + clip-path: inset(50%); + width: 1px; +`; + +const StyledCheckbox = styled.div` + display: inline-block; + width: 28px; + height: 28px; + background: ${(props) => (props.checked ? "#F9CDCC" : "#FFFFFF")}; + border: 2px solid #1c2996; + transition: all 150ms; + + ${Icon} { + visibility: ${(props) => (props.checked ? "visible" : "hidden")}; + } +`; + +const CheckBox = ({ className, checked, ...props }) => ( + + + + + + + + +); + +CheckBox.propTypes = { + className: PropTypes.string, + checked: PropTypes.bool.isRequired, + onChange: PropTypes.func.isRequired, +}; + +export default CheckBox; diff --git a/src/components/StyledAbout.jsx b/src/components/StyledAbout.jsx new file mode 100644 index 00000000..c1318f3f --- /dev/null +++ b/src/components/StyledAbout.jsx @@ -0,0 +1,163 @@ +import styled, { createGlobalStyle } from "styled-components"; +import Lotus from "../assets/lotus.svg"; +import Buddha from "../assets/yoga.svg"; +import Glasses from "../assets/drink.svg"; + +export const StyledAboutBox = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: var(--gap-compact); + padding-bottom: 80px; + margin-top: 25px; + max-width: 1050px; + + @media (min-width: 651px) { + flex-direction: row-reverse; + align-items: flex-start; + margin-top: var(--gap-medium); + padding-bottom: var(--gap-medium); + } + + @media (min-width: 1025px) { + margin-top: var(--gap-big); + padding-bottom: var(--gap-big); + } +`; + +export const GlobalCarouselStyles = createGlobalStyle` + + .carousel .control-dots { + position: absolute; + bottom: -12px; + margin:40px 0 ; + width: 100%; + display: flex; + justify-content: center; +} + + .carousel .control-dots .dot { + background: var(--dark-grey); + width: 12px; + height: 12px; + top: 1px; + left: 1px; + } + + .carousel .control-dots .dot.selected { + background: var(--red); + width: 12px; + height: 12px; + top: 1px; + left: 1px; + } +`; + +export const LotusIcon = styled(Lotus)` + width: 20px; + height: 20px; + + @media (min-width: 651px) { + width: 28.83px; + height: 24px; + } +`; + +export const BuddhaIcon = styled(Buddha)` + width: 20px; + height: 20px; + + @media (min-width: 651px) { + width: 28.83px; + height: 24px; + } +`; + +export const GlassesIcon = styled(Glasses)` + width: ${(props) => props.$width || "20px"}; + height: ${(props) => props.$height || "20px"}; + + @media (min-width: 651px) { + width: 28.83px; + height: 24px; + } +`; + +export const TitleBox = styled.div` + display: flex; + justify-content: center; + margin-bottom: 35px; + margin-top: 10px; + + @media (min-width: 1025px) { + margin-top: var(--gap-extra); + } +`; + +export const Slide = styled.div` + display: flex; + flex-direction: column; + align-items: flex-start; + gap: var(--gap-comfortable); +`; + +export const AboutInfoBox = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-compact); +`; + +export const AboutTextBox = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-comfortable); + width: 100%; + margin-bottom: ${(props) => props.$margin || "0"}; + @media (min-width: 651px) { + } +`; + +export const AboutTitleBox = styled.div` + display: flex; + align-items: center; + gap: 10px; +`; + +export const AboutOneImage = styled.img` + width: 50%; + height: 100%; + object-fit: cover; + + @media (min-width: 651px) { + padding-right: var(--gap-compact); + } +`; + +export const AboutTwoImage = styled.img` + width: 50%; + height: 100%; + object-fit: cover; + + @media (min-width: 651px) { + padding-left: var(--gap-compact); + } +`; + +export const MeditaionBox = styled.div` + display: flex; + gap: var(--gap-compact); + margin-top: var(--gap-spacious); + max-width: 1050px; + justify-self: center; +`; + +export const MeditationText = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-comfortable); + max-width: 100%; + + @media (min-width: 651px) { + gap: var(--gap-extra); + } +`; diff --git a/src/components/StyledArrow.jsx b/src/components/StyledArrow.jsx new file mode 100644 index 00000000..d69b8cd5 --- /dev/null +++ b/src/components/StyledArrow.jsx @@ -0,0 +1,20 @@ +import styled from "styled-components"; +import arrow from "../assets/arrow.svg"; + +export const ArrowBox = styled.div` + display: flex; + flex-direction: column; + align-items: center; + gap: var(--gap-compact); + margin: var(--gap-spacious) 0; + + @media (min-width: 651px) and (max-width: 1024px) { + margin-top: 0; + margin-bottom: 5px; + } +`; + +export const ArrowIcon = styled(arrow)` + width: 24px; + height: 12.84px; +`; diff --git a/src/components/StyledBorder.jsx b/src/components/StyledBorder.jsx new file mode 100644 index 00000000..c1a5ba9d --- /dev/null +++ b/src/components/StyledBorder.jsx @@ -0,0 +1,19 @@ +import styled from "styled-components"; +import MobileDec from "../assets/mobil-dec.svg"; +import TabletDec from "../assets/tablet-dec.svg"; +import DesktopDec from "../assets/desktop-dec.svg"; + +export const Mobiledec = styled(MobileDec)` + width: 100%; + height: auto; +`; + +export const Tabletdec = styled(TabletDec)` + width: 100%; + height: auto; +`; + +export const Desktopdec = styled(DesktopDec)` + width: 100%; + height: auto; +`; diff --git a/src/components/StyledComponents.jsx b/src/components/StyledComponents.jsx new file mode 100644 index 00000000..b8eb85cc --- /dev/null +++ b/src/components/StyledComponents.jsx @@ -0,0 +1,173 @@ +import styled, { css } from "styled-components"; + +export const Container = styled.div` + display: flex; + flex-direction: column; + align-items: center; + + @media (min-width: 651px) and (max-width: 1024px) { + padding: 0 var(--gap-medium); + } + + @media (min-width: 1025px) { + padding: 0 var(--gap-huge); + } +`; + +export const Page = styled.div` + max-width: 100%; + width: 100%; + display: grid; + background-color: var(--light-grey); + padding: 0 var(--gap-compact); + + @media (min-width: 651px) and (max-width: 1024px) { + padding: var(--gap-default) var(--gap-spacious); + } + + @media (min-width: 1025px) { + padding: 0 var(--gap-huge); + } +`; + +export const StyledImage = styled.img` + width: 100%; + aspect-ratio: 16 / 15; + object-fit: cover; + + @media (min-width: 651px) { + width: 50%; + height: 100%; + object-fit: cover; + } + + @media (max-width: 349px) { + display: none; + } +`; + +export const StyledText = styled.div` + font-family: "Lato"; + font-weight: 400; + font-size: 16px; + line-height: 25.6px; + color: var(--blue); + line-height: 25.6px; + text-align: ${(props) => props.$textAlign || "left"}; + + @media (min-width: 651px) and (max-width: 1024px) { + } + + @media (min-width: 1025px) { + } +`; + +export const StyledH1 = styled.div` + font-family: Yeseva One; + font-size: 24px; + font-weight: 400; + line-height: 27.72px; + color: var(--blue); + + @media (min-width: 350px) and (max-width: 650px) { + } + + @media (min-width: 651px) and (max-width: 1024px) { + font-size: 32px; + line-height: 36.96px; + } + + @media (min-width: 1025px) { + font-size: 48px; + + line-height: 55.44px; + } +`; + +export const StyledH2 = styled.h2` + font-family: "Yeseva One", serif; + font-size: 20px; + font-weight: 400; + font-style: normal; + color: var(--blue); + + @media (min-width: 350px) and (max-width: 650px) { + } + + @media (min-width: 651px) and (max-width: 1024px) { + font-size: 24px; + line-height: 27.72px; + } + + @media (min-width: 1025px) { + font-family: Yeseva One; + font-size: 32px; + line-height: 36.96px; + } +`; + +export const UnderlinedWord = styled.span` + text-decoration: underline; + text-decoration-thickness: 2px; + text-underline-offset: 5px; +`; + +export const StyledButton = styled.button` + display: flex; + align-items: center; + justify-content: center; + background-color: ${(props) => props.$backgroundColor || "var(--red)"}; + color: ${(props) => props.$textColor || "white"}; + border: ${(props) => props.$border || "none"}; + padding: var(--gap-default) var(--gap-comfortable); + font-family: "Lato", sans-serif; + font-weight: 700; + + ${(props) => + props.$mobile && + css` + font-size: 18px; + flex: 1; + line-height: 28.8px; + letter-spacing: 0.5px; + `} + + ${(props) => + props.$tablet && + css` + font-size: 18px; + `} + + ${(props) => + props.$desktop && + css` + font-size: 20px; + `} + + &:hover { + border: 2px solid var(--blue); + } + + &.about-button:hover { + background-color: white; + } +`; + +export const ButtonBox = styled.div` + display: flex; + width: 100%; + padding: ${(props) => + props.$padding || + "0 var(--gap-compact) var(--gap-compact) var(--gap-compact)"}; + + @media (min-width: 1025px) { + padding: ${(props) => + props.$padding || "0 0 var(--gap-huge) var(--gap-extra) "}; + } + + @media (min-width: 651px) and (max-width: 1024px) { + padding: ${(props) => + props.$padding || + "0 var(--gap-compact) var(--gap-spacious) var(--gap-compact)"}; + } +`; diff --git a/src/components/StyledForm.jsx b/src/components/StyledForm.jsx new file mode 100644 index 00000000..ee9d5b96 --- /dev/null +++ b/src/components/StyledForm.jsx @@ -0,0 +1,147 @@ +import styled, { css } from "styled-components"; +import Minus from "../assets/Minus.svg"; +import Plus from "../assets/Plus.svg"; + +export const MinusIcon = styled(Minus)` + width: 24px; + height: 12.84px; + cursor: pointer; +`; + +export const PlusIcon = styled(Plus)` + width: 24px; + height: 24px; + cursor: pointer; +`; + +export const FormContainer = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-compact); + margin-top: 10px; + max-width: 616px; + width: 100%; + + @media (min-width: 651px) { + } +`; + +export const FormGroup = styled.div` + display: flex; + flex-direction: column; + gap: 8px; +`; + +export const Label = styled.label``; + +export const Input = styled.input` + padding: var(--gap-compact) var(--gap-default); + height: 53px; + border: 2px solid var(--blue); +`; + +export const FlexibleButton = styled.button` + padding: var(--gap-compact) var(--gap-comfortable); + background-color: ${(props) => + props.disabled ? "var(--dark-grey)" : "var(--red)"}; + border: none; + color: ${(props) => (props.disabled ? "var(--light-grey)" : "#fff")}; + text-transform: uppercase; + font-family: Lato; + font-size: 18px; + font-weight: 700; + line-height: 28.8px; + letter-spacing: 0.02em; + cursor: ${(props) => (props.disabled ? "not-allowed" : "pointer")}; + + ${(props) => + props.$mobile && + css` + font-size: 18px; + flex: 1; + line-height: 28.8px; + letter-spacing: 0.5px; + `} + + ${(props) => + props.$tablet && + css` + font-size: 18px; + `} + +${(props) => + props.$desktop && + css` + font-size: 20px; + `} + + @media (min-width:651px) { + margin-bottom: 0; + } + + @media (min-width: 1025px) { + margin-bottom: var(--gap-extra); + } +`; + +export const IncrementDecrementContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; + background-color: #fff; + width: 115px; + height: 53px; + border: 2px solid var(--blue); + padding: 10px; +`; + +export const NumberInput = styled.input` + padding: 0px !important; + padding-left: 10px !important; + border: none; + line-height: normal; + text-align: center; + width: 43px; + font-family: Lato; + font-weight: 400; + font-size: 18px; + box-sizing: content-box; + color: var(--blue); +`; + +export const CounterBox = styled.div` + display: flex; + align-items: center; + align-self: center; + gap: var(--gap-compact); +`; + +export const CounterContainer = styled.div` + display: flex; + flex-direction: column; + justify-content: center; + gap: var(--gap-comfortable); + margin-bottom: 18px; + margin-top: 15px; + + @media (min-width: 651px) { + flex-direction: row; + justify-content: space-between; + } +`; + +export const TotalBox = styled.div` + font-family: Yeseva One; + font-size: 48px; + font-weight: 400; + line-height: 55.44px; + text-align: center; + color: var(--blue); +`; + +export const CalenderBox = styled.div` + display: flex; + align-items: center; + gap: var(--gap-compact); + margin-bottom: var(--gap-compact); +`; diff --git a/src/components/StyledIntro.jsx b/src/components/StyledIntro.jsx new file mode 100644 index 00000000..5760b153 --- /dev/null +++ b/src/components/StyledIntro.jsx @@ -0,0 +1,146 @@ +import styled, { keyframes } from "styled-components"; +import HeartIcon from "../assets/HeartIcon.svg"; +import mobileLogo from "../assets/LogoMobile.svg"; +import tabletLogo from "../assets/LogoTablet.svg"; +import desktopLogo from "../assets/LogoDesktop.svg"; +import NamasteCircle from "../assets/EasterEgg.svg"; + +import "../index.css"; + +export const NamasteIcon = styled(NamasteCircle)` + align-self: flex-end; + position: relative; + top: -57px; + left: 0; +`; + +export const EasterEggContainer = styled.div` + display: flex; + flex-direction: column; + background-color: var(--pink); + padding: var(--gap-comfortable) var(--gap-compact); + margin: 0 var(--gap-default) var(--gap-comfortable) var(--gap-default); + gap: var(--gap-compact); + justify-content: center; + align-items: center; +`; + +export const OuterContainer = styled.div` + display: flex; + flex-direction: column; + background-color: var(--light-grey); +`; + +export const IconTitleBox = styled.div` + gap: var(--gap-compact); +`; + +export const MobileLogo = styled(mobileLogo)` + display: none; + @media (max-width: 650px) { + display: block; + } +`; + +const TabletLogo = styled(tabletLogo)` + display: none; + @media (min-width: 651px) and (max-width: 1024px) { + display: block; + } +`; + +const DesktopLogo = styled(desktopLogo)` + display: none; + @media (min-width: 1025px) { + display: block; + } +`; + +const LogoBox = styled.div` + display: flex; + justify-content: center; +`; + +export const LogoContainer = () => { + return ( + + + + + + ); +}; + +export const HeaderBox = styled.div` + display: flex; + justify-content: center; + margin-bottom: 10px; + + @media (min-width: 651px) { + justify-content: space-between; + } +`; + +export const NavBox = styled.div` + display: flex; + align-items: center; + gap: var(--gap-extra); +`; + +export const IntroTextButton = styled.div` + display: flex; + flex-direction: column; +`; + +const pulse = keyframes` + 0% { + transform: scaleX(1) scaleY(1); + } + + 50% { + transform: scaleX(1.04) scaleY(1.3); + } + + 100% { + transform: scaleX(1) scaleY(1); + } +`; + +export const IconHeart = styled(HeartIcon)` + animation: ${pulse} 2s infinite; + width: 20px; + height: 18.35px; + margin-left: 13px; +`; + +export const IntroContentBox = styled.div` + display: flex; + flex-direction: column; + align-items: center; + padding-bottom: var(--gap-default); + background-color: var(--pink); + gap: var(--gap-compact); + + @media (min-width: 651px) { + flex-direction: row; + padding-bottom: 0; + } + + @media (min-width: 1025px) { + } +`; + +export const IntroTextBox = styled.div` + display: flex; + flex-direction: column; + padding: var(--gap-default) var(--gap-compact); + gap: var(--gap-compact); + + @media (min-width: 651px) and (max-width: 1024px) { + padding: var(--gap-extra) var(--gap-compact) var(--gap-compact); + } + + @media (min-width: 1025px) { + padding: var(--gap-huge) var(--gap-extra) var(--gap-comfortable); + } +`; diff --git a/src/components/StyledPromise.jsx b/src/components/StyledPromise.jsx new file mode 100644 index 00000000..e748a878 --- /dev/null +++ b/src/components/StyledPromise.jsx @@ -0,0 +1,59 @@ +import styled from "styled-components"; + +export const PromiseBox = styled.div` + display: flex; + flex-direction: column; + align-items: center; + flex-wrap: wrap; + background-color: var(--yellow); + gap: var(--gap-spacious); + padding: var(--gap-extra) 0; + + @media (min-width: 1025px) { + flex-direction: row; + flex-wrap: nowrap; + justify-content: center; + padding: var(--gap-big) var(--gap-huge); + gap: 86px; + } +`; + +export const PromiseTextBox = styled.div` + display: flex; + flex-direction: column; + flex-wrap: wrap; + text-align: center; + gap: var(--gap-default); + justify-content: center; + + @media (min-width: 651px) { + flex-direction: row; + gap: var(--gap-comfortable); + padding: 0 var(--gap-comfortable); + } + + @media (min-width: 1025px) { + flex-wrap: nowrap; + padding: 0; + } +`; + +export const PromiseSmallTextBox = styled.div` + display: flex; + justify-content: center; +`; + +export const PromiseText = styled.div` + font-family: Lato; + font-size: 14px; + font-weight: 400; + line-height: 22.4px; + letter-spacing: 0.06em; + color: var(--blue); + margin-right: 13px; + text-transform: uppercase; + + @media (min-width: 1025px) { + margin-right: 0; + } +`; diff --git a/src/components/StyledQuestions.jsx b/src/components/StyledQuestions.jsx new file mode 100644 index 00000000..d14be35d --- /dev/null +++ b/src/components/StyledQuestions.jsx @@ -0,0 +1,58 @@ +import styled from "styled-components"; + +export const QuestionContainer = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-default); + align-items: center; + margin: var(--gap-comfortable) 0; + + @media (min-width: 1025px) { + padding: 0 var(--gap-huge); + } + + @media (min-width: 1054px) { + padding: 30px 0; + row-gap: 50px; + } +`; + +export const QuestionInfoBox = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-comfortable); + + @media (min-width: 651px) { + flex-direction: row; + } + + @media (min-width: 1054px) { + display: grid; + grid-template-columns: 1fr 1fr; + width: 1054px; + } +`; + +export const QuestionImgContainer = styled.div``; +export const QuestionImg = styled.img` + width: 100%; + aspect-ratio: 16 / 15; + object-fit: cover; + object-position: 100% 0; + + @media (min-width: 651px) { + height: 100%; + } +`; + +export const QuestionTextBox = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-comfortable); +`; + +export const QuestionSmallTextBox = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-default); +`; diff --git a/src/components/StyledRegister.jsx b/src/components/StyledRegister.jsx new file mode 100644 index 00000000..6641a260 --- /dev/null +++ b/src/components/StyledRegister.jsx @@ -0,0 +1,34 @@ +import styled from "styled-components"; +import Union from "../assets/Union.svg"; + +export const RegisterContainer = styled.div` + display: flex; + flex-direction: column; + gap: var(--gap-default); + margin-bottom: var(--gap-spacious); + align-items: center; + + @media (min-width: 651px) { + padding: 0 var(--gap-huge); + } +`; + +export const UnionContainer = styled.div` + display: flex; + justify-content: center; + align-items: center; + text-align: center; + margin-top: var(--gap-medium); + margin-bottom: var(--gap-default); +`; + +export const UnionStyled = styled(Union)` + width: 146.87px; + height: 71.87px; + display: flex; +`; + +export const TitleReg = styled.div` + display: flex; + justify-content: center; +`; diff --git a/src/components/StyledTeachers.jsx b/src/components/StyledTeachers.jsx new file mode 100644 index 00000000..40ba14ed --- /dev/null +++ b/src/components/StyledTeachers.jsx @@ -0,0 +1,37 @@ +import styled from "styled-components"; + +export const TeacherTitleBox = styled.div` + display: flex; + justify-content: center; + align-items: center; + text-align: center; + margin-top: var(--gap-medium); +`; + +export const StyledTeacherOne = styled.img` + width: 100%; + aspect-ratio: 16 / 18.5; + object-fit: cover; + overflow: hidden; +`; + +export const StyledTeacherTwo = styled.img` + width: 100%; + aspect-ratio: 16 / 17.3; + object-fit: cover; + overflow: hidden; +`; + +export const TeacherBox = styled.div` + display: flex; + gap: var(--gap-extra); + margin: var(--gap-extra) 0; + max-width: 1050px; + justify-self: center; +`; + +export const TeacherBoxOne = styled.div` + display: flex; + flex-direction: column-reverse; + gap: ${(props) => props.$gap || "var(--gap-default)"}; +`; diff --git a/src/components/pages/About.jsx b/src/components/pages/About.jsx new file mode 100644 index 00000000..915a03c9 --- /dev/null +++ b/src/components/pages/About.jsx @@ -0,0 +1,130 @@ +import useDeviceType from "../useDeviceType"; +import { + Page, + StyledH1, + StyledH2, + StyledText, + StyledImage, + StyledButton, + ButtonBox, + Container, +} from "../StyledComponents"; +import AboutOne from "../../assets/about-one.jpg"; +import AboutTwo from "../../assets/about-two.jpg"; +import { Carousel } from "react-responsive-carousel"; +import { + AboutInfoBox, + AboutTextBox, + AboutTitleBox, + BuddhaIcon, + Slide, + GlassesIcon, + LotusIcon, + StyledAboutBox, + AboutTwoImage, + TitleBox, +} from "../StyledAbout"; +import "react-responsive-carousel/lib/styles/carousel.min.css"; + +export const About = () => { + const deviceType = useDeviceType(); + + if (deviceType !== "mobile") { + return null; + } + + return ( + + + + Here is the plan: + + + + + + + Join us this Midsommar at noon in Djurgården, Stockholm, for a memorable summer celebration with your + friends, indulging in a revitalizing yoga session amidst the beauty of nature. The activities at our + feast will include: + + + + + + + + + Astanga session + + + + We will kick off our Midsommar festivities with a rejuvenating 120-minute yoga session, featuring a + variety of asanas suitable for practitioners of all levels. + + + From gentle stretches to more advanced poses, each movement will let you cultivate strength, + flexibility, and inner peace, awakening a sense of joy about the summer. + + + + + + + Meditation + + + + + Following our invigorating yoga practice, join us for an hour-long session dedicated to guided + breath exercises. + + + These exercises are designed to enhance your connection with the present, fostering a sense of joy + at this special day. + + + + + + + + + + + + + Feast among friends + + + + Feast among friends. Last but not least we will invite you to gather among friends and indulge in + delectable treats. + + + You will get baskets brimming with delights, including fresh strawberries, knäckebröd paired with + potato salad, smoked salmon and cookies straight from the oven. Oh, and yes - there will be some + bubbles. + + + + + + + + + SIGN UP WITH YOUR FRIENDS + + + + + ); +}; diff --git a/src/components/pages/AboutTabletDesk.jsx b/src/components/pages/AboutTabletDesk.jsx new file mode 100644 index 00000000..8c3bb82a --- /dev/null +++ b/src/components/pages/AboutTabletDesk.jsx @@ -0,0 +1,112 @@ +import useDeviceType from "../useDeviceType"; +import { Page, StyledH1, StyledH2, StyledText, StyledButton, ButtonBox, Container } from "../StyledComponents"; +import AboutOne from "../../assets/about-one.jpg"; +import AboutTwo from "../../assets/about-two.jpg"; +import { + AboutInfoBox, + AboutTextBox, + AboutTitleBox, + BuddhaIcon, + GlassesIcon, + LotusIcon, + StyledAboutBox, + AboutTwoImage, + TitleBox, + MeditaionBox, + MeditationText, + AboutOneImage, +} from "../StyledAbout"; + +export const AboutTabletDesk = () => { + const deviceType = useDeviceType(); + + if (deviceType !== "tablet" && deviceType !== "desktop") { + return null; + } + + return ( + + + + Here is the plan: + + + + Join us this Midsommar at noon in Djurgården, Stockholm, for a memorable summer celebration with your friends, + indulging in a revitalizing yoga session amidst the beauty of nature. The activities at our feast will + include: + + + + + + + + + Astanga session + + + + We will kick off our Midsommar festivities with a rejuvenating 120-minute yoga session, featuring a + variety of asanas suitable for practitioners of all levels. + + + From gentle stretches to more advanced poses, each movement will let you cultivate strength, + flexibility, and inner peace, awakening a sense of joy about the summer. + + + + + + + Meditation + + + + Following our invigorating yoga practice, join us for an hour-long session dedicated to guided breath + exercises. + + + These exercises are designed to enhance your connection with the present, fostering a sense of joy at + this special day. + + + + + + + + + + + + Feast among friends + + + + Last but not least we will invite you to gather among friends and indulge in delectable treats. + + + You will get baskets brimming with delights, including fresh strawberries, knäckebröd paired with potato + salad, smoked salmon and cookies straight from the oven. Oh, and yes - there will be some bubbles. + + + + + + + SIGN UP WITH YOUR FRIENDS + + + + + ); +}; diff --git a/src/components/pages/Arrow.jsx b/src/components/pages/Arrow.jsx new file mode 100644 index 00000000..7bb8f95b --- /dev/null +++ b/src/components/pages/Arrow.jsx @@ -0,0 +1,31 @@ +import { ArrowBox, ArrowIcon } from "../StyledArrow"; +import { Page, StyledText } from "../StyledComponents"; +import useDeviceType from "../useDeviceType"; + +const Arrow = () => { + const deviceType = useDeviceType(); + + const handleArrowClick = () => { + window.scrollTo({ + top: window.scrollY + 600, + behavior: "smooth", + }); + }; + + if (deviceType === "none") { + return null; + } + + return ( + + + + Find out more about event + + + + + ); +}; + +export default Arrow; diff --git a/src/components/pages/Border.jsx b/src/components/pages/Border.jsx new file mode 100644 index 00000000..5f276cc5 --- /dev/null +++ b/src/components/pages/Border.jsx @@ -0,0 +1,16 @@ +import { Desktopdec, Mobiledec, Tabletdec } from "../StyledBorder"; +import useDeviceType from "../useDeviceType"; + +export const Border = () => { + const deviceType = useDeviceType(); + + if (deviceType === "none") { + return null; + } else if (deviceType === "tablet") { + return ; + } else if (deviceType === "desktop") { + return ; + } else { + return ; + } +}; diff --git a/src/components/pages/Contact.jsx b/src/components/pages/Contact.jsx new file mode 100644 index 00000000..98568fe3 --- /dev/null +++ b/src/components/pages/Contact.jsx @@ -0,0 +1,180 @@ +// This is where we create styled compontens for the Contact page +import styled from "styled-components"; +import { css } from "styled-components"; +import useDeviceType from "../useDeviceType"; + +const YellowWrapper = styled.div` + background-color: var(--yellow); + display: flex; + align-items: center; + justify-content: center; +`; + +const Layout = styled.div` + flex: 1; + background-color: var(--yellow); + display: flex; + flex-direction: column; + align-items: center; + padding: 30px 0; + row-gap: 20px; + + @media (min-width: 650px) { + row-gap: 30px; + padding: 40px 0; + } + + @media (min-width: 1054px) { + flex-direction: row; + justify-content: space-between; + max-width: 1032px; + column-gap: 70px; + } +`; + +const IconWrapper = styled.div` + display: flex; + flex-direction: row; + column-gap: 20px; +`; + +// styled.a is a styled component that is an anchor tag +const IconSome = styled.a` + color: var(--yellow); + font-size: 2rem; + line-height: 0; +`; + +const Heading = styled.h2` + font-size: 2rem; + font-family: Yeseva One; + color: #1c2996; + font-size: 24px; + font-weight: 400; + line-height: 27.72px; + text-align: center; + + @media (min-width: 1054px) { + font-size: 32px; + } +`; + +const ContactInfoWrapper = styled.div` + display: flex; + flex-direction: column; + row-gap: 10px; + flex: 1; + + @media (min-width: 650px) { + flex-direction: row; + column-gap: 20px; + } + + @media (min-width: 1054px) { + justify-content: space-between; + } +`; + +// https://stackoverflow.com/questions/49618997/idiomatic-way-to-share-styles-in-styled-components +const ContactInfo = css` + color: black; + font-size: 1.5rem; + font-family: "Lato"; + color: #1c2996; + font-size: 16px; + font-weight: 400; + line-height: 25.6px; + letter-spacing: 0.02em; + text-align: center; + + @media (min-width: 1054px) { + font-size: 18px; + } +`; + +const ContactLink = styled.a` + ${ContactInfo} + text-decoration: none; +`; + +const ContactText = styled.p` + ${ContactInfo} +`; + +export const Contact = () => { + const deviceType = useDeviceType(); + + if (deviceType === "none") { + return null; + } + + return ( + + + + + + Facebook + + + + + + Instagram + + + + + + + + + + + + + + {/* because its costume component, the elements starts with capital */} + + Contact us + + fake@sunnyyoga.se + + +46 123 456 789 + Fake Gatan 23, Stockholm + + + + ); +}; + +// FFCD64 (yellow) diff --git a/src/components/pages/Form.jsx b/src/components/pages/Form.jsx new file mode 100644 index 00000000..5d46b9aa --- /dev/null +++ b/src/components/pages/Form.jsx @@ -0,0 +1,141 @@ +import { useState } from "react"; +import CheckBox from "../CheckBox"; +import useDeviceType from "../useDeviceType"; +import { StyledText } from "../StyledComponents"; +import { + FormContainer, + FormGroup, + Label, + IncrementDecrementContainer, + Input, + NumberInput, + MinusIcon, + PlusIcon, + CounterBox, + CounterContainer, + TotalBox, + FlexibleButton, + CalenderBox, +} from "../StyledForm"; +import { PromiseText } from "../StyledPromise"; + +export const Form = () => { + const [name, setName] = useState(""); + const [email, setEmail] = useState(""); + const [phoneNumber, setPhoneNumber] = useState(""); + const [numberOfPeople, setNumberOfPeople] = useState(0); + const pricePerPerson = 20; + const deviceType = useDeviceType(); + const [isChecked, setIsChecked] = useState(false); + + const handleNameChange = (e) => { + setName(e.target.value); + }; + + const handleEmailChange = (e) => { + setEmail(e.target.value); + }; + + const handlePhoneNumberChange = (e) => { + setPhoneNumber(e.target.value); + }; + + const handleDecrement = () => { + setNumberOfPeople(Math.max(0, numberOfPeople - 1)); + }; + + const handleIncrement = () => { + setNumberOfPeople(numberOfPeople + 1); + }; + + const handleCheckboxChange = () => { + setIsChecked(!isChecked); + }; + + const totalAmount = numberOfPeople * pricePerPerson; + + const isSubmitDisabled = name === "" || email === "" || phoneNumber === "" || numberOfPeople === 0; + + const handleSubmit = () => { + setName(""); + setEmail(""); + setPhoneNumber(""); + setNumberOfPeople(0); + setIsChecked(false); + }; + + if (deviceType === "none") { + return null; + } + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + + + {totalAmount} $ + + + + + + + + Register now + + + + ); +}; diff --git a/src/components/pages/Introduction.jsx b/src/components/pages/Introduction.jsx new file mode 100644 index 00000000..918e7128 --- /dev/null +++ b/src/components/pages/Introduction.jsx @@ -0,0 +1,119 @@ +import { useState } from "react"; +import useDeviceType from "../useDeviceType"; +import { + Page, + StyledText, + StyledH1, + StyledButton, + ButtonBox, + StyledImage, + UnderlinedWord, + StyledH2, +} from "../StyledComponents"; +import { + IconHeart, + LogoContainer, + IntroTextBox, + IntroContentBox, + HeaderBox, + NavBox, + IntroTextButton, + EasterEggContainer, + IconTitleBox, + NamasteIcon, + OuterContainer, +} from "../StyledIntro"; +import ImgIntro from "../../assets/intro-one.jpg"; +import { GlassesIcon } from "../StyledAbout"; + +const Introduction = () => { + const [isClicked, setIsClicked] = useState(false); + const [isHeartVisible, setIsHeartVisible] = useState(true); + const deviceType = useDeviceType(); + + const handleClick = () => { + setIsClicked((prevIsClicked) => !prevIsClicked); + setIsHeartVisible((prevIsHeartVisible) => !prevIsHeartVisible); + }; + + return ( + + + + {(deviceType === "tablet" || deviceType === "desktop") && ( + + About us + + CONTACT US + + + )} + + {deviceType === "none" && ( + + + + Congratulations + + + + You're unable to access this website on your current phone. + + + But fear not! We are looking for individuals like you to participate in our Midsommar yoga event. + + + So, simply invite a friend with a newer phone to access this page, and if they succeed, you'll get + + 1 ticket for free + Just remember to insert the code DSFHSIUG! + + + + + )} + + {deviceType !== "none" && ( + + + + + + Celebrate Midsommar with yoga and friends + + + Embrace summer vibes doing yoga among friends. Experience energising asanas under the sun and feed your + mind with a relaxing meditation. Afterwards, indulge in prosecco and delectable treats to celebrate the + harmony of body and mind. + + + + + + BOOK YOUR SPOT + {isHeartVisible && } + + + + + )} + + ); +}; + +export default Introduction; diff --git a/src/components/pages/Promise.jsx b/src/components/pages/Promise.jsx new file mode 100644 index 00000000..7ff32631 --- /dev/null +++ b/src/components/pages/Promise.jsx @@ -0,0 +1,39 @@ +import { PromiseBox, PromiseSmallTextBox, PromiseText, PromiseTextBox } from "../StyledPromise"; +import { StyledH2 } from "../StyledComponents"; +import useDeviceType from "../useDeviceType"; + +export const Promise = () => { + const deviceType = useDeviceType(); + + if (deviceType === "none") { + return null; + } + + if (deviceType === "desktop" || deviceType === "tablet") { + return ( + + WE PROMISE: + + 1 000 Calories burned + Beautiful midsommar among friends + 3 Hours of Yoga + A delicious feast + + + ); + } + + return ( + + WE PROMISE: + + 1 000 Calories burned + Beautiful midsommar among friends + + 3 Hours of Yoga + A delicious feast + + + + ); +}; diff --git a/src/components/pages/Questions.jsx b/src/components/pages/Questions.jsx new file mode 100644 index 00000000..9485ddb9 --- /dev/null +++ b/src/components/pages/Questions.jsx @@ -0,0 +1,62 @@ +import { LotusIcon } from "../StyledAbout"; +import { Page, StyledH2, StyledText } from "../StyledComponents"; +import QuestionImage from "../../assets/questions.jpg"; +import { + QuestionContainer, + QuestionImg, + QuestionInfoBox, + QuestionTextBox, + QuestionImgContainer, + QuestionSmallTextBox, +} from "../StyledQuestions"; +import useDeviceType from "../useDeviceType"; + +export const Questions = () => { + const deviceType = useDeviceType(); + + if (deviceType === "none") { + return null; + } + + return ( + + + + Frequently asked questions + + + + + + + What should I bring with me? + + We recommend bringing a yoga mat, comfortable clothing suitable for movement, a water bottle, and any + props you typically use during your practice. Don't forget sunscreen and a hat because our event is + outdoors! + + + + + Can I bring children to the event? + + Yes, children are welcome to join the event! However, please note that our yoga sessions are primarily + designed for adults. We recommend assessing whether the event atmosphere and activities are suitable for + your child's age and interests. Parental supervision is required for children attending the event. + + + + + What happens if it rains on Midsommar? + + In the event of inclement weather, we will provide updates via email and our website regarding any + changes to the event schedule or location. If the event is moved indoors registered participants will be + notified accordingly. Please ensure your contact information is up-to-date to receive timely updates. + + + + + + + ); +}; diff --git a/src/components/pages/Quote.jsx b/src/components/pages/Quote.jsx new file mode 100644 index 00000000..6e15cc9c --- /dev/null +++ b/src/components/pages/Quote.jsx @@ -0,0 +1,100 @@ +import styled from "styled-components"; +// import { css } from "styled-components"; +import anna from "../../assets/anna.png"; +import useDeviceType from "../useDeviceType"; + +const PinkWrapper = styled.div` + background-color: #f9cdcc; + display: flex; + align-items: center; + justify-content: center; +`; + +const Layout = styled.div` + flex: 1; + display: flex; + flex-direction: column; + align-items: center; + padding: 30px 16px; + row-gap: 30px; + + @media (min-width: 650px) { + flex-direction: row; + column-gap: 30px; + + max-width: 1273px; + } +`; + +const Icon = styled.svg` + width: 40px; + height: 40px; + + @media (min-width: 650px) { + width: 110px; + height: 110px; + order: 1; + } +`; + +const Blockquote = styled.blockquote` + color: #1c2996; + font-family: Lato; + font-size: 16px; + font-weight: 400; + line-height: 25.6px; + letter-spacing: 0.02em; + text-align: left; + + @media (min-width: 650px) { + order: 2; + } +`; + +const Image = styled.img` + width: 120px; + + @media (min-width: 650px) { + order: 3; + } +`; + +export const Quote = () => { + const deviceType = useDeviceType(); + + if (deviceType === "none") { + return null; + } + + return ( + + + Portrait photo of a white woman with black hair smiling. The caption below reads 'Anna Lindgren + + + + +
+ I love attending Sunny Yoga events, and I must say, they are truly a + transformative experience. The instructors are not only highly + knowledgeable and skilled but also incredibly supportive, guiding me + through each pose with patience and encouragement. +
+
+
+ ); +}; diff --git a/src/components/pages/Register.jsx b/src/components/pages/Register.jsx new file mode 100644 index 00000000..7aa1b7a8 --- /dev/null +++ b/src/components/pages/Register.jsx @@ -0,0 +1,30 @@ +import { UnionContainer, UnionStyled, TitleReg, RegisterContainer } from "../StyledRegister"; +import { Page, StyledH1, StyledText } from "../StyledComponents"; +import { Form } from "./Form.jsx"; +import useDeviceType from "../useDeviceType"; + +export const Register = () => { + const deviceType = useDeviceType(); + + if (deviceType === "none") { + return null; + } + + return ( + + + + + + + Register for the event + + + Ensure a spot and invite your friends to join in the celebration of Midsommar with a blend of yoga, meditation + and feasting. + +
+ + + ); +}; diff --git a/src/components/pages/Teachers.jsx b/src/components/pages/Teachers.jsx new file mode 100644 index 00000000..ec52e079 --- /dev/null +++ b/src/components/pages/Teachers.jsx @@ -0,0 +1,61 @@ +import useDeviceType from "../useDeviceType"; +import { StyledTeacherOne, StyledTeacherTwo, TeacherTitleBox } from "../StyledTeachers"; +import { Page, Container, StyledH1, StyledH2, StyledText } from "../StyledComponents"; +import TeacherOne from "../../assets/teacher-one.jpg"; +import TeacherTwo from "../../assets/teacher-two.jpg"; +import { Carousel } from "react-responsive-carousel"; +import { AboutInfoBox, AboutTextBox, AboutTitleBox, Slide, StyledAboutBox } from "../StyledAbout"; +import "react-responsive-carousel/lib/styles/carousel.min.css"; + +export const Teachers = () => { + const deviceType = useDeviceType(); + + if (deviceType !== "mobile") { + return null; + } + + return ( + + + + Get to know our yoga teachers: + + + + + + + + Astrid Andersson + + + Astrid received their 200- and 300-hour teacher certification through Sunny Yoga. She are also a + high-school science educator with the mission to bring equitable education, of mind, body, and spirit, + to students across identity and experience. + + + + + + + + + + + Frida Berg + + + + Frida is a tech professional and yoga instructor. She received her a 200- and 300-hour through Sunny + Yoga. Frida believes that this simple yet powerful practice informs the way we communicate with + ourselves and the way we communicate with the world. + + + + + + + + + ); +}; diff --git a/src/components/pages/TeachersTabletdesk.jsx b/src/components/pages/TeachersTabletdesk.jsx new file mode 100644 index 00000000..f954e70e --- /dev/null +++ b/src/components/pages/TeachersTabletdesk.jsx @@ -0,0 +1,58 @@ +import useDeviceType from "../useDeviceType"; +import { StyledTeacherOne, StyledTeacherTwo, TeacherBox, TeacherBoxOne, TeacherTitleBox } from "../StyledTeachers"; +import { Page, StyledH1, StyledH2, StyledText } from "../StyledComponents"; +import TeacherOne from "../../assets/teacher-one.jpg"; +import TeacherTwo from "../../assets/teacher-two.jpg"; +import { AboutInfoBox, AboutTextBox, AboutTitleBox, Slide } from "../StyledAbout"; + +export const TeachersTabletdesk = () => { + const deviceType = useDeviceType(); + + if (deviceType !== "tablet" && deviceType !== "desktop") { + return null; + } + + return ( + + + Get to know our yoga teachers: + + + + + + + + Astrid Andersson + + + + Astrid received their 200- and 300-hour teacher certification through Sunny Yoga. She are also a + high-school science educator with the mission to bring equitable education, of mind, body, and spirit, + to students across identity and experience. + + + + + + + + + + + Frida Berg + + + + Frida is a tech professional and yoga instructor. She received her a 200- and 300-hour through Sunny + Yoga. Frida believes that this simple yet powerful practice informs the way we communicate with + ourselves and the way we communicate with the world. + + + + + + + + ); +}; diff --git a/src/components/useDeviceType.jsx b/src/components/useDeviceType.jsx new file mode 100644 index 00000000..7488b1a2 --- /dev/null +++ b/src/components/useDeviceType.jsx @@ -0,0 +1,29 @@ +import { useState, useEffect } from "react"; + +const useDeviceType = () => { + const [deviceType, setDeviceType] = useState("desktop"); + + useEffect(() => { + const handleResize = () => { + const width = window.innerWidth; + if (width < 350) { + setDeviceType("none"); + } else if (width >= 350 && width <= 650) { + setDeviceType("mobile"); + } else if (width <= 1024) { + setDeviceType("tablet"); + } else { + setDeviceType("desktop"); + } + }; + + window.addEventListener("resize", handleResize); + handleResize(); + + return () => window.removeEventListener("resize", handleResize); + }, []); + + return deviceType; +}; + +export default useDeviceType; diff --git a/src/index.css b/src/index.css index 4558f538..63e9bad3 100644 --- a/src/index.css +++ b/src/index.css @@ -1,13 +1,23 @@ :root { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", - "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", - sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + --gap-default: 16px; + --gap-compact: 12px; + --gap-comfortable: 24px; + --gap-spacious: 32px; + --gap-medium: 36px; + --gap-extra: 48px; + --gap-big: 64px; + --gap-huge: 96px; + + --pink: #f9cdcc; + --blue: #1c2996; + --red: #e02b0b; + --dark-grey: #7e7c7c; + --light-grey: #f6f6f6; + --yellow: #ffcd64; } -code { - font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", - monospace; +* { + margin: 0; + padding: 0; + box-sizing: border-box; } diff --git a/src/main.jsx b/src/main.jsx index 51294f39..00b48ccf 100644 --- a/src/main.jsx +++ b/src/main.jsx @@ -1,10 +1,12 @@ import React from "react"; import ReactDOM from "react-dom/client"; -import { App } from "./App.jsx"; +import App from "./App.jsx"; import "./index.css"; +import { GlobalCarouselStyles } from "./components/StyledAbout"; ReactDOM.createRoot(document.getElementById("root")).render( + ); diff --git a/vite.config.js b/vite.config.js index 5a33944a..2e40a3a6 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,7 +1,13 @@ -import { defineConfig } from 'vite' -import react from '@vitejs/plugin-react' +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import svgr from "vite-plugin-svgr"; // https://vitejs.dev/config/ export default defineConfig({ - plugins: [react()], -}) + plugins: [ + svgr({ + include: "**/**.svg", + }), + react(), + ], +});