├── CNAME
├── public
├── CNAME
├── logo.png
└── index.html
├── src
├── assets
│ ├── bgc1.jpg
│ ├── faq.webp
│ ├── logo.png
│ ├── about.webp
│ ├── bgc1.webp
│ ├── bgc3.webp
│ ├── bgc6.webp
│ ├── bgc7.webp
│ ├── blog1.jpg
│ ├── blog1.webp
│ ├── blog2.webp
│ ├── blog3.webp
│ ├── blog4.webp
│ ├── blog5.webp
│ ├── blog6.webp
│ ├── hero.webp
│ ├── logo1.png
│ ├── logo2.png
│ ├── logo3.png
│ ├── logo4.png
│ ├── m_logo.png
│ ├── team1.webp
│ ├── team2.jpg
│ ├── team2.webp
│ ├── team3.jpg
│ ├── team3.webp
│ ├── aboutus1.jpg
│ ├── aboutus1.png
│ ├── aboutus2.jpg
│ ├── aboutus2.png
│ ├── aboutus3.jpg
│ ├── aboutus3.png
│ ├── blog_big1.jpg
│ ├── blog_big2.jpg
│ ├── blog_big3.jpg
│ ├── blog_big4.jpg
│ ├── blog_big5.jpg
│ ├── blog_big6.jpg
│ ├── client1.webp
│ ├── client2.webp
│ ├── client3.jpg
│ ├── client3.webp
│ ├── client4.webp
│ ├── client5.webp
│ ├── client6.webp
│ ├── contact.webp
│ ├── counter.webp
│ ├── creatine1.png
│ ├── creatine2.png
│ ├── creatine3.png
│ ├── creatine4.png
│ ├── creatine5.png
│ ├── creatine6.png
│ ├── fitness.webp
│ ├── header-bg.jpg
│ ├── protein1.png
│ ├── protein2.png
│ ├── protein3.png
│ ├── protein4.png
│ ├── protein5.png
│ ├── protein6.png
│ ├── protein7.png
│ ├── blog_big1.webp
│ ├── blog_big2.webp
│ ├── blog_big3.webp
│ ├── blog_big4.webp
│ ├── blog_big5.webp
│ ├── blog_big6.webp
│ ├── hero_blog.webp
│ ├── preworkout1.png
│ ├── preworkout2.png
│ ├── preworkout3.png
│ ├── preworkout4.png
│ ├── preworkout5.png
│ ├── blog_big1-m.webp
│ ├── fitnessClass.webp
│ ├── testimonials.webp
│ └── fitnessgym.dawidolko.pl_.png
├── global.scss
├── components
│ ├── Hero
│ │ ├── Hero.jsx
│ │ └── Hero.scss
│ ├── NotFound
│ │ ├── NotFound.scss
│ │ └── NotFound.jsx
│ ├── Map
│ │ ├── Map.scss
│ │ └── Map.jsx
│ ├── LogoSlider
│ │ ├── LogoSlider.scss
│ │ └── LogoSlider.jsx
│ ├── ContactContent
│ │ ├── ContactBox.jsx
│ │ ├── ContactContent.jsx
│ │ ├── BoxData.js
│ │ ├── ContactContent.scss
│ │ └── ContactForm.jsx
│ ├── FixedBg
│ │ ├── FixedBg.jsx
│ │ └── FixedBg.scss
│ ├── BlogContent
│ │ ├── Article
│ │ │ ├── ArticleItem.jsx
│ │ │ ├── Article.jsx
│ │ │ ├── Article.scss
│ │ │ └── ArticleData.js
│ │ ├── BlogContent.jsx
│ │ ├── BlogItem.jsx
│ │ ├── BlogData.js
│ │ └── BlogContent.scss
│ ├── Testimonials
│ │ ├── TestimonialsItem.jsx
│ │ ├── Testimonials.jsx
│ │ ├── Testimonials.scss
│ │ └── TestimonialsData.js
│ ├── Pricing
│ │ ├── PricingData.js
│ │ ├── Pricing.jsx
│ │ ├── PricingItem.jsx
│ │ └── Pricing.scss
│ ├── AnimatedPage
│ │ └── AnimatedPage.jsx
│ ├── Team
│ │ ├── TeamData.js
│ │ ├── Team.jsx
│ │ └── Team.scss
│ ├── Message
│ │ ├── Message.scss
│ │ └── Message.jsx
│ ├── CallBack
│ │ ├── CallBack.scss
│ │ └── CallBack.jsx
│ ├── Counter
│ │ ├── Counter.scss
│ │ └── Counter.jsx
│ ├── ShopContent
│ │ ├── ShopProduct.jsx
│ │ ├── ShopContent.jsx
│ │ ├── ShopContent.scss
│ │ └── ShopData.js
│ ├── AboutUs
│ │ └── AboutUs.jsx
│ ├── Modal
│ │ ├── Modal.jsx
│ │ ├── ModalComponent.jsx
│ │ ├── Modal.scss
│ │ └── FormComponent.jsx
│ ├── Accordion
│ │ ├── Accordion.scss
│ │ ├── Accordion.jsx
│ │ └── AccordionData.js
│ ├── CartContent
│ │ ├── CartModal.jsx
│ │ ├── CartProduct.jsx
│ │ ├── TotalAmount.jsx
│ │ ├── CartContent.jsx
│ │ └── CartContent.scss
│ ├── AboutContent
│ │ ├── AboutContent.scss
│ │ └── AboutContent.jsx
│ ├── MainBackground
│ │ ├── MainBackgroundData.js
│ │ ├── MainBackground.jsx
│ │ ├── MainBackgroundItem.jsx
│ │ └── MainBackground.scss
│ ├── NewProducts
│ │ └── NewProducts.jsx
│ ├── Fitness
│ │ └── Fitness.jsx
│ ├── AnimationVariants
│ │ └── AnimationVariants.jsx
│ ├── ShopContext
│ │ └── ShopContext.jsx
│ ├── Footer
│ │ ├── Footer.scss
│ │ └── Footer.jsx
│ └── Navbar
│ │ ├── Navbar.scss
│ │ └── Navbar.jsx
├── pages
│ ├── Cart.jsx
│ ├── Shop.jsx
│ ├── Blog.jsx
│ ├── Faq.jsx
│ ├── Contact.jsx
│ ├── About.jsx
│ └── Home.jsx
├── index.js
├── App.js
└── index.css
├── .github
├── ISSUE_TEMPLATE
│ ├── custom.md
│ ├── feature_request.md
│ └── bug_report.md
└── FUNDING.yml
├── .gitignore
├── LICENSE
├── package.json
└── README.md
/CNAME:
--------------------------------------------------------------------------------
1 | fitnessgym.dawidolko.pl
2 |
--------------------------------------------------------------------------------
/public/CNAME:
--------------------------------------------------------------------------------
1 | fitnessgym.dawidolko.pl
2 |
--------------------------------------------------------------------------------
/public/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/public/logo.png
--------------------------------------------------------------------------------
/src/assets/bgc1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/bgc1.jpg
--------------------------------------------------------------------------------
/src/assets/faq.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/faq.webp
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/about.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/about.webp
--------------------------------------------------------------------------------
/src/assets/bgc1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/bgc1.webp
--------------------------------------------------------------------------------
/src/assets/bgc3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/bgc3.webp
--------------------------------------------------------------------------------
/src/assets/bgc6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/bgc6.webp
--------------------------------------------------------------------------------
/src/assets/bgc7.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/bgc7.webp
--------------------------------------------------------------------------------
/src/assets/blog1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog1.jpg
--------------------------------------------------------------------------------
/src/assets/blog1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog1.webp
--------------------------------------------------------------------------------
/src/assets/blog2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog2.webp
--------------------------------------------------------------------------------
/src/assets/blog3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog3.webp
--------------------------------------------------------------------------------
/src/assets/blog4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog4.webp
--------------------------------------------------------------------------------
/src/assets/blog5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog5.webp
--------------------------------------------------------------------------------
/src/assets/blog6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog6.webp
--------------------------------------------------------------------------------
/src/assets/hero.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/hero.webp
--------------------------------------------------------------------------------
/src/assets/logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/logo1.png
--------------------------------------------------------------------------------
/src/assets/logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/logo2.png
--------------------------------------------------------------------------------
/src/assets/logo3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/logo3.png
--------------------------------------------------------------------------------
/src/assets/logo4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/logo4.png
--------------------------------------------------------------------------------
/src/assets/m_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/m_logo.png
--------------------------------------------------------------------------------
/src/assets/team1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/team1.webp
--------------------------------------------------------------------------------
/src/assets/team2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/team2.jpg
--------------------------------------------------------------------------------
/src/assets/team2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/team2.webp
--------------------------------------------------------------------------------
/src/assets/team3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/team3.jpg
--------------------------------------------------------------------------------
/src/assets/team3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/team3.webp
--------------------------------------------------------------------------------
/src/assets/aboutus1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/aboutus1.jpg
--------------------------------------------------------------------------------
/src/assets/aboutus1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/aboutus1.png
--------------------------------------------------------------------------------
/src/assets/aboutus2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/aboutus2.jpg
--------------------------------------------------------------------------------
/src/assets/aboutus2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/aboutus2.png
--------------------------------------------------------------------------------
/src/assets/aboutus3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/aboutus3.jpg
--------------------------------------------------------------------------------
/src/assets/aboutus3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/aboutus3.png
--------------------------------------------------------------------------------
/src/assets/blog_big1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big1.jpg
--------------------------------------------------------------------------------
/src/assets/blog_big2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big2.jpg
--------------------------------------------------------------------------------
/src/assets/blog_big3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big3.jpg
--------------------------------------------------------------------------------
/src/assets/blog_big4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big4.jpg
--------------------------------------------------------------------------------
/src/assets/blog_big5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big5.jpg
--------------------------------------------------------------------------------
/src/assets/blog_big6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big6.jpg
--------------------------------------------------------------------------------
/src/assets/client1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client1.webp
--------------------------------------------------------------------------------
/src/assets/client2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client2.webp
--------------------------------------------------------------------------------
/src/assets/client3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client3.jpg
--------------------------------------------------------------------------------
/src/assets/client3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client3.webp
--------------------------------------------------------------------------------
/src/assets/client4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client4.webp
--------------------------------------------------------------------------------
/src/assets/client5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client5.webp
--------------------------------------------------------------------------------
/src/assets/client6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/client6.webp
--------------------------------------------------------------------------------
/src/assets/contact.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/contact.webp
--------------------------------------------------------------------------------
/src/assets/counter.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/counter.webp
--------------------------------------------------------------------------------
/src/assets/creatine1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/creatine1.png
--------------------------------------------------------------------------------
/src/assets/creatine2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/creatine2.png
--------------------------------------------------------------------------------
/src/assets/creatine3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/creatine3.png
--------------------------------------------------------------------------------
/src/assets/creatine4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/creatine4.png
--------------------------------------------------------------------------------
/src/assets/creatine5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/creatine5.png
--------------------------------------------------------------------------------
/src/assets/creatine6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/creatine6.png
--------------------------------------------------------------------------------
/src/assets/fitness.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/fitness.webp
--------------------------------------------------------------------------------
/src/assets/header-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/header-bg.jpg
--------------------------------------------------------------------------------
/src/assets/protein1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein1.png
--------------------------------------------------------------------------------
/src/assets/protein2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein2.png
--------------------------------------------------------------------------------
/src/assets/protein3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein3.png
--------------------------------------------------------------------------------
/src/assets/protein4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein4.png
--------------------------------------------------------------------------------
/src/assets/protein5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein5.png
--------------------------------------------------------------------------------
/src/assets/protein6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein6.png
--------------------------------------------------------------------------------
/src/assets/protein7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/protein7.png
--------------------------------------------------------------------------------
/src/assets/blog_big1.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big1.webp
--------------------------------------------------------------------------------
/src/assets/blog_big2.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big2.webp
--------------------------------------------------------------------------------
/src/assets/blog_big3.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big3.webp
--------------------------------------------------------------------------------
/src/assets/blog_big4.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big4.webp
--------------------------------------------------------------------------------
/src/assets/blog_big5.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big5.webp
--------------------------------------------------------------------------------
/src/assets/blog_big6.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big6.webp
--------------------------------------------------------------------------------
/src/assets/hero_blog.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/hero_blog.webp
--------------------------------------------------------------------------------
/src/assets/preworkout1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/preworkout1.png
--------------------------------------------------------------------------------
/src/assets/preworkout2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/preworkout2.png
--------------------------------------------------------------------------------
/src/assets/preworkout3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/preworkout3.png
--------------------------------------------------------------------------------
/src/assets/preworkout4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/preworkout4.png
--------------------------------------------------------------------------------
/src/assets/preworkout5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/preworkout5.png
--------------------------------------------------------------------------------
/src/assets/blog_big1-m.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/blog_big1-m.webp
--------------------------------------------------------------------------------
/src/assets/fitnessClass.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/fitnessClass.webp
--------------------------------------------------------------------------------
/src/assets/testimonials.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/testimonials.webp
--------------------------------------------------------------------------------
/src/assets/fitnessgym.dawidolko.pl_.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dawidolko/FitnessGym-Project-React/HEAD/src/assets/fitnessgym.dawidolko.pl_.png
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/custom.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Custom issue template
3 | about: Describe this issue template's purpose here.
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/global.scss:
--------------------------------------------------------------------------------
1 | $main: #369669;
2 | $white: #fff;
3 | $dark: #161616;
4 | $darker: #292525;
5 |
6 | @mixin flexCenter($direction) {
7 | display: flex;
8 | flex-direction: $direction;
9 | justify-content: center;
10 | align-items: center;
11 | }
12 |
--------------------------------------------------------------------------------
/src/components/Hero/Hero.jsx:
--------------------------------------------------------------------------------
1 | import "./Hero.scss";
2 |
3 | const Hero = (props) => {
4 | return (
5 |
6 |
7 |
{props.title}
8 |
9 |
10 | );
11 | };
12 |
13 | export default Hero;
14 |
--------------------------------------------------------------------------------
/src/pages/Cart.jsx:
--------------------------------------------------------------------------------
1 | import CartContent from "../components/CartContent/CartContent";
2 | import Hero from "../components/Hero/Hero";
3 |
4 | const Cart = () => {
5 | return (
6 | <>
7 |
8 |
9 | >
10 | );
11 | };
12 |
13 | export default Cart;
14 |
--------------------------------------------------------------------------------
/src/pages/Shop.jsx:
--------------------------------------------------------------------------------
1 | import ShopContent from "../components/ShopContent/ShopContent";
2 | import Hero from "../components/Hero/Hero";
3 |
4 | const Shop = () => {
5 | return (
6 |
7 |
8 |
9 |
10 | );
11 | };
12 |
13 | export default Shop;
14 |
--------------------------------------------------------------------------------
/src/components/NotFound/NotFound.scss:
--------------------------------------------------------------------------------
1 | .notFound {
2 | height: 100vh;
3 | display: flex;
4 | flex-direction: column;
5 | justify-content: center;
6 | align-items: center;
7 | gap: 1em;
8 | background-color: #2e2e2e;
9 |
10 | &__icon {
11 | font-size: 20rem;
12 | }
13 |
14 | &__error {
15 | font-size: 8rem;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/pages/Blog.jsx:
--------------------------------------------------------------------------------
1 | import AnimatedPage from "../components/AnimatedPage/AnimatedPage";
2 | import Hero from "../components/Hero/Hero";
3 | import BlogContent from "../components/BlogContent/BlogContent";
4 |
5 | const Blog = () => {
6 | return (
7 |
8 |
9 |
10 |
11 | );
12 | };
13 |
14 | export default Blog;
15 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom/client";
3 | import "./index.css";
4 | import App from "./App";
5 | import { BrowserRouter } from "react-router-dom";
6 |
7 | const root = ReactDOM.createRoot(document.getElementById("root"));
8 | root.render(
9 |
10 |
11 |
12 |
13 |
14 | );
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
--------------------------------------------------------------------------------
/src/components/Map/Map.scss:
--------------------------------------------------------------------------------
1 | .map {
2 | position: relative;
3 | height: 0;
4 | overflow: hidden;
5 | padding-bottom: 55%;
6 |
7 | &__frame {
8 | position: absolute;
9 | left: 0;
10 | top: 0;
11 | height: 100%;
12 | width: 100%;
13 | border: 0;
14 | }
15 | }
16 |
17 | @media (min-width: 796px) {
18 | .map {
19 | padding-bottom: 40%;
20 | }
21 | }
22 |
23 | @media (min-width: 1024px) {
24 | .map {
25 | padding-bottom: 25%;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/pages/Faq.jsx:
--------------------------------------------------------------------------------
1 | import AnimatedPage from "../components/AnimatedPage/AnimatedPage";
2 | import Hero from "../components/Hero/Hero";
3 | import Accordion from "../components/Accordion/Accordion";
4 | import Message from "../components/Message/Message";
5 |
6 | const Faq = () => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 | );
14 | };
15 |
16 | export default Faq;
17 |
--------------------------------------------------------------------------------
/src/components/LogoSlider/LogoSlider.scss:
--------------------------------------------------------------------------------
1 | .slider {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 |
6 | &__wrapper {
7 | width: 70%;
8 | margin: 0 auto;
9 | }
10 |
11 | &__box {
12 | height: 200px;
13 | display: flex !important;
14 | justify-content: center;
15 | align-items: center;
16 | background-color: #fff;
17 |
18 | img {
19 | filter: grayscale(1);
20 | opacity: 0.7;
21 | object-fit: cover;
22 | }
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/pages/Contact.jsx:
--------------------------------------------------------------------------------
1 | import AnimatedPage from "../components/AnimatedPage/AnimatedPage";
2 | import Hero from "../components/Hero/Hero";
3 | import ContactContent from "../components/ContactContent/ContactContent";
4 | import Map from "../components/Map/Map";
5 |
6 | const Contact = () => {
7 | return (
8 |
9 |
10 |
11 |
12 |
13 | );
14 | };
15 |
16 | export default Contact;
17 |
--------------------------------------------------------------------------------
/src/components/ContactContent/ContactBox.jsx:
--------------------------------------------------------------------------------
1 | const ContactBox = (props) => {
2 | return (
3 |
15 | );
16 | };
17 |
18 | export default ContactBox;
19 |
--------------------------------------------------------------------------------
/src/components/FixedBg/FixedBg.jsx:
--------------------------------------------------------------------------------
1 | import "./FixedBg.scss";
2 | import { Link } from "react-router-dom";
3 |
4 | const FixedBg = (props) => {
5 | return (
6 |
7 |
8 |
{props.text}
9 |
{props.title}
10 |
11 | JOIN US
12 |
13 |
14 |
15 | );
16 | };
17 |
18 | export default FixedBg;
19 |
--------------------------------------------------------------------------------
/src/components/BlogContent/Article/ArticleItem.jsx:
--------------------------------------------------------------------------------
1 | const ArticleItem = (props) => {
2 | return (
3 |
4 |
5 |
6 |
{props.title}
7 |
{props.text}
8 |
{props.highlight}
9 |
{props.text2}
10 |
11 |
12 | );
13 | };
14 |
15 | export default ArticleItem;
16 |
--------------------------------------------------------------------------------
/src/components/Testimonials/TestimonialsItem.jsx:
--------------------------------------------------------------------------------
1 | const TestimonialsItem = (props) => {
2 | return (
3 |
4 |
5 |
6 |
7 |
{props.name}
8 |
Our Client
9 |
10 |
11 |
{props.review}
12 |
13 | );
14 | };
15 |
16 | export default TestimonialsItem;
17 |
--------------------------------------------------------------------------------
/src/components/BlogContent/BlogContent.jsx:
--------------------------------------------------------------------------------
1 | import "./BlogContent.scss";
2 | import blogData from "./BlogData";
3 | import BlogItem from "./BlogItem";
4 |
5 | const BlogContent = () => {
6 | return (
7 |
8 |
9 | Explore the Latest Fitness Insights & News
10 |
11 |
12 | {blogData.map((item) => (
13 |
14 | ))}
15 |
16 |
17 | );
18 | };
19 |
20 | export default BlogContent;
21 |
--------------------------------------------------------------------------------
/src/components/Pricing/PricingData.js:
--------------------------------------------------------------------------------
1 | const pricingData = [
2 | {
3 | id: 1,
4 | title: "Basic Plan",
5 | price: "59",
6 | yoga: false,
7 | fashion: false,
8 | swimming: false,
9 | },
10 | {
11 | id: 2,
12 | title: "Standard Plan",
13 | price: "99",
14 | yoga: true,
15 | fashion: true,
16 | swimming: false,
17 | bestOffer: true,
18 | },
19 | {
20 | id: 3,
21 | title: "Premium Plan",
22 | price: "156",
23 | yoga: true,
24 | fashion: true,
25 | swimming: true,
26 | },
27 | ];
28 |
29 | export default pricingData;
30 |
--------------------------------------------------------------------------------
/src/components/AnimatedPage/AnimatedPage.jsx:
--------------------------------------------------------------------------------
1 | import { motion } from "framer-motion";
2 |
3 | const animation = {
4 | initial: { opacity: 0, y: 50 },
5 | animate: { opacity: 1, y: 0 },
6 | exit: {
7 | opacity: 0,
8 | y: -50,
9 | transition: { duration: 0.3, ease: "easeInOut" },
10 | },
11 | };
12 |
13 | const AnimatedPage = ({ children }) => {
14 | return (
15 |
20 | {children}
21 |
22 | );
23 | };
24 |
25 | export default AnimatedPage;
26 |
--------------------------------------------------------------------------------
/src/components/ContactContent/ContactContent.jsx:
--------------------------------------------------------------------------------
1 | import "./ContactContent.scss";
2 | import boxData from "./BoxData";
3 | import ContactBox from "./ContactBox";
4 | import ContactForm from "./ContactForm";
5 |
6 | const ContactContent = () => {
7 | return (
8 |
9 |
10 |
11 | {boxData.map((box) => (
12 |
13 | ))}
14 |
15 |
16 |
17 |
18 |
19 |
20 | );
21 | };
22 |
23 | export default ContactContent;
24 |
--------------------------------------------------------------------------------
/src/components/Team/TeamData.js:
--------------------------------------------------------------------------------
1 | import team1 from "../../assets/team1.webp";
2 | import team2 from "../../assets/team2.webp";
3 | import team3 from "../../assets/team3.webp";
4 |
5 | const teamData = [
6 | {
7 | id: 1,
8 | img: team1,
9 | alt: "Photo of the fitness coach - John Carter.",
10 | name: "John Carter",
11 | },
12 | {
13 | id: 2,
14 | img: team2,
15 | alt: "Photo of the personal trainer - Emily Brown.",
16 | name: "Emily Brown",
17 | },
18 | {
19 | id: 3,
20 | img: team3,
21 | alt: "Photo of the fitness expert - Michael Green.",
22 | name: "Michael Green",
23 | },
24 | ];
25 |
26 | export default teamData;
27 |
--------------------------------------------------------------------------------
/src/components/Hero/Hero.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .hero {
4 | &__img {
5 | height: 50vh;
6 | background: url("../../assets/hero.webp") rgba(0, 0, 0, 0.8);
7 | background-blend-mode: darken;
8 | background-size: cover;
9 | background-position: center;
10 | }
11 |
12 | &__title {
13 | @include flexCenter(row);
14 | height: 100%;
15 | color: rgb(66, 66, 66);
16 | font-size: 5rem;
17 | font-style: italic;
18 | }
19 |
20 | &__img-blog {
21 | height: 50vh;
22 | background: url("../../assets/hero_blog.webp") rgba(0, 0, 0, 0.8);
23 | background-blend-mode: darken;
24 | background-size: cover;
25 | background-position: top;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/src/components/Map/Map.jsx:
--------------------------------------------------------------------------------
1 | import "./Map.scss";
2 |
3 | const Map = () => {
4 | return (
5 |
6 |
15 |
16 | );
17 | };
18 |
19 | export default Map;
20 |
--------------------------------------------------------------------------------
/src/components/BlogContent/Article/Article.jsx:
--------------------------------------------------------------------------------
1 | import "./Article.scss";
2 | import Hero from "../../Hero/Hero";
3 | import articleData from "./ArticleData";
4 | import ArticleItem from "./ArticleItem";
5 | import { useParams } from "react-router-dom";
6 |
7 | const Article = () => {
8 | const { id } = useParams();
9 |
10 | const selectedArticle = articleData.find((item) => item.id === Number(id));
11 |
12 | if (!selectedArticle) {
13 | return Article not found
;
14 | }
15 |
16 | return (
17 | <>
18 |
19 |
22 | >
23 | );
24 | };
25 |
26 | export default Article;
27 |
--------------------------------------------------------------------------------
/src/components/Message/Message.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .message {
4 | @include flexCenter(column);
5 | gap: 1em;
6 | padding: 3em 1em 2em;
7 | background-color: rgb(230, 229, 228);
8 |
9 | &__title {
10 | font-size: 4rem;
11 | text-align: center;
12 | }
13 |
14 | &__link {
15 | display: flex;
16 | align-items: center;
17 | gap: 0.5em;
18 | margin-top: 0.5em;
19 | padding: 0.8em 1.8em;
20 | background-color: $main;
21 | color: $white;
22 | border-radius: 5px;
23 | }
24 |
25 | &__icon {
26 | font-size: 2.2rem;
27 | }
28 | }
29 |
30 | @media (min-width: 768px) {
31 | .message {
32 | &__link {
33 | transition: background-color 0.3s ease;
34 | &:hover {
35 | background-color: $dark;
36 | }
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/NotFound/NotFound.jsx:
--------------------------------------------------------------------------------
1 | import "./NotFound.scss";
2 | import { useEffect } from "react";
3 | import { FaRegFaceFrown } from "react-icons/fa6";
4 | import { useNavigate } from "react-router-dom";
5 |
6 | const NotFound = () => {
7 | const navigate = useNavigate();
8 |
9 | useEffect(() => {
10 | setTimeout(() => {
11 | navigate(-1);
12 | }, 8000);
13 | });
14 |
15 | return (
16 |
17 |
18 | 404
19 | Page not found
20 |
21 | We're sorry, the page you requsted could not be found.
22 |
23 |
24 | );
25 | };
26 |
27 | export default NotFound;
28 |
--------------------------------------------------------------------------------
/src/components/Message/Message.jsx:
--------------------------------------------------------------------------------
1 | import "./Message.scss";
2 | import { Link } from "react-router-dom";
3 | import { AiOutlineMail } from "react-icons/ai";
4 |
5 | const Message = () => {
6 | return (
7 |
8 | Experience Your First Session for Free
9 |
10 | Try our services at no cost and discover the workout that suits you
11 | best. Let us know your preferences, and we’ll guide you to the perfect
12 | training plan.
13 |
14 |
15 |
16 | CONTACT US
17 |
18 |
19 | );
20 | };
21 |
22 | export default Message;
23 |
--------------------------------------------------------------------------------
/src/components/ContactContent/BoxData.js:
--------------------------------------------------------------------------------
1 | import { FaMapLocationDot, FaPhoneVolume } from "react-icons/fa6";
2 | import { LuMails } from "react-icons/lu";
3 |
4 | const boxData = [
5 | {
6 | id: 1,
7 | link: "https://maps.app.goo.gl/jKPN2oKWiUrcJuuD9",
8 | icon: ,
9 | boxTitle: "Our Location",
10 | details: "38 Fitness Street, New York",
11 | target: "_blank",
12 | },
13 | {
14 | id: 2,
15 | link: "tel:+1234567890",
16 | icon: ,
17 | boxTitle: "Contact Us",
18 | details: "(123) 456 7890",
19 | },
20 | {
21 | id: 3,
22 | link: "mailto:contact@fitnessgym.com",
23 | icon: ,
24 | boxTitle: "Email Us",
25 | details: "contact@fitnessgym.com",
26 | },
27 | ];
28 |
29 | export default boxData;
30 |
--------------------------------------------------------------------------------
/src/components/BlogContent/Article/Article.scss:
--------------------------------------------------------------------------------
1 | @import "../../../global.scss";
2 |
3 | .article {
4 | @include flexCenter(column);
5 | padding: 3em 0;
6 | background-color: aliceblue;
7 |
8 | &__container {
9 | max-width: 800px;
10 | padding: 1em 1em 3em;
11 | box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.2);
12 | }
13 |
14 | &__img {
15 | width: 100%;
16 | margin-bottom: 1em;
17 | }
18 |
19 | &__title {
20 | margin-bottom: 1em;
21 | font-size: 3rem;
22 | line-height: 1.3;
23 | }
24 |
25 | &__text-highlight {
26 | margin: 2em 0;
27 | padding: 1.5em;
28 | color: rgb(54, 54, 54);
29 | background-color: rgb(233, 233, 233);
30 | font-style: italic;
31 | border-left: 4px solid $main;
32 | }
33 | }
34 |
35 | @media (min-width: 996px) {
36 | .article {
37 | padding: 4em 0 6em;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/components/CallBack/CallBack.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .callBack {
4 | @include flexCenter(column);
5 | gap: 1em;
6 | padding: 3em 0.5em;
7 | background-color: $main;
8 | color: $white;
9 | text-align: center;
10 |
11 | &__title {
12 | font-size: 4rem;
13 | }
14 |
15 | &__icon {
16 | font-size: 5rem;
17 | }
18 |
19 | &__text {
20 | font-size: 3rem;
21 | }
22 |
23 | &__btn {
24 | margin-top: 1em;
25 | padding: 1em 2em;
26 | border-radius: 6px;
27 | background-color: $dark;
28 | color: $white;
29 | font-weight: 500;
30 | border: none;
31 | font-size: 1.4rem;
32 | }
33 | }
34 |
35 | @media (min-width: 768px) {
36 | .callBack {
37 | &__btn {
38 | transition: background-color 0.3s ease, color 0.3s ease;
39 |
40 | &:hover {
41 | background-color: #fff;
42 | color: #000;
43 | }
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/pages/About.jsx:
--------------------------------------------------------------------------------
1 | import AnimatedPage from "../components/AnimatedPage/AnimatedPage";
2 | import Hero from "../components/Hero/Hero";
3 | import AboutUs from "../components/AboutUs/AboutUs";
4 | import Testimonials from "../components/Testimonials/Testimonials";
5 | import Team from "../components/Team/Team";
6 | import FixedBg from "../components/FixedBg/FixedBg";
7 | import Message from "../components/Message/Message";
8 |
9 | const About = () => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
21 |
22 |
23 | );
24 | };
25 |
26 | export default About;
27 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: [dawidolko]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry
12 | polar: # Replace with a single Polar username
13 | buy_me_a_coffee: # Replace with a single Buy Me a Coffee username
14 | thanks_dev: # Replace with a single thanks.dev username
15 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
16 |
--------------------------------------------------------------------------------
/src/components/Counter/Counter.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .counter {
4 | @include flexCenter(column);
5 | gap: 4em;
6 | padding: 3em 0;
7 | background: url("../../assets/counter.webp") rgba(0, 0, 0, 0.8);
8 | background-blend-mode: darken;
9 | background-size: cover;
10 | background-position: center;
11 |
12 | &__box {
13 | @include flexCenter(column);
14 | }
15 |
16 | &__number {
17 | font-size: 7rem;
18 | color: $main;
19 | font-weight: 500;
20 | }
21 |
22 | &__text {
23 | color: $white;
24 | font-size: 2rem;
25 | font-weight: 500;
26 | letter-spacing: 1px;
27 | }
28 | }
29 |
30 | @media (min-width: 778px) {
31 | .counter {
32 | flex-direction: row;
33 | gap: 3em;
34 | padding: 8em 0.5em;
35 | background-attachment: fixed;
36 |
37 | &__number {
38 | font-size: 8rem;
39 | }
40 | }
41 | }
42 |
43 | @media (min-width: 996px) {
44 | .counter {
45 | gap: 5em;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/components/ShopContent/ShopProduct.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { CartContext } from "../ShopContext/ShopContext";
3 |
4 | const ShopProduct = (props) => {
5 | const { id, img, name, price, isNew } = props;
6 | const { items, addToCart } = useContext(CartContext);
7 | const itemsInfo = items[id];
8 |
9 | return (
10 |
11 | {isNew &&
NEW }
12 |
13 |
14 |
15 |
16 |
{name}
17 |
${price}
18 |
addToCart(id)}>
19 | Add To Cart {itemsInfo > 0 && ( {itemsInfo} ) }
20 |
21 |
22 |
23 | );
24 | };
25 |
26 | export default ShopProduct;
27 |
--------------------------------------------------------------------------------
/src/components/Pricing/Pricing.jsx:
--------------------------------------------------------------------------------
1 | import "./Pricing.scss";
2 | import pricingData from "./PricingData";
3 | import PricingItem from "./PricingItem";
4 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
5 | import { motion, useInView } from "framer-motion";
6 | import { useRef } from "react";
7 |
8 | const Pricing = () => {
9 | const ref = useRef();
10 | const isInView = useInView(ref, { once: true });
11 |
12 | return (
13 |
20 | Best Pricing Plan For You
21 |
22 | {pricingData.map((data) => (
23 |
24 | ))}
25 |
26 |
27 | );
28 | };
29 |
30 | export default Pricing;
31 |
--------------------------------------------------------------------------------
/src/components/CallBack/CallBack.jsx:
--------------------------------------------------------------------------------
1 | import "./CallBack.scss";
2 | import Modal from "../Modal/Modal";
3 | import { FaPhoneVolume } from "react-icons/fa6";
4 | import { useState } from "react";
5 |
6 | const CallBack = () => {
7 | const [openModal, setOpenModal] = useState(false);
8 |
9 | return (
10 |
11 | Your Fitness Journey Starts With Us
12 |
13 | Get a FREE consultation call
14 |
15 | Our dedicated team is ready to guide you on your path to fitness
16 | success.
17 |
18 | setOpenModal(true)}>
19 | Request Call
20 |
21 | setOpenModal(false)} />
22 |
23 | );
24 | };
25 |
26 | export default CallBack;
27 |
--------------------------------------------------------------------------------
/src/components/AboutUs/AboutUs.jsx:
--------------------------------------------------------------------------------
1 | import AboutContent from "../AboutContent/AboutContent";
2 | import about from "../../assets/about.webp";
3 |
4 | const AboutUs = () => {
5 | return (
6 | <>
7 |
14 | >
15 | );
16 | };
17 |
18 | export default AboutUs;
19 |
--------------------------------------------------------------------------------
/src/components/Modal/Modal.jsx:
--------------------------------------------------------------------------------
1 | import "./Modal.scss";
2 | import { useState } from "react";
3 | import { AnimatePresence } from "framer-motion";
4 | import ModalComponent from "./ModalComponent";
5 |
6 | const Modal = ({ open, onClose }) => {
7 | const [message, setMessage] = useState("");
8 | const [isMessageSent, setIsMessageSent] = useState(false);
9 |
10 | const handleSubmit = (_, { resetForm }) => {
11 | setIsMessageSent(true);
12 | setMessage("Message sent successfully!");
13 | resetForm();
14 | setTimeout(() => {
15 | setMessage("");
16 | onClose();
17 | }, 2000);
18 | };
19 |
20 | return (
21 |
22 | {open && (
23 |
32 | )}
33 |
34 | );
35 | };
36 |
37 | export default Modal;
38 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/src/components/Accordion/Accordion.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .accordion {
4 | @include flexCenter(column);
5 | gap: 2em;
6 | padding: 3em 1em;
7 |
8 | &__img {
9 | max-width: 500px;
10 | width: 100%;
11 | height: 100%;
12 | }
13 |
14 | &__title {
15 | margin-bottom: 1.5em;
16 | text-align: center;
17 | font-size: 4rem;
18 | font-style: italic;
19 | }
20 |
21 | &__item {
22 | max-width: 500px;
23 | margin-bottom: 10px;
24 | overflow: hidden;
25 | }
26 |
27 | &__box {
28 | display: flex;
29 | justify-content: space-between;
30 | align-items: center;
31 | padding: 1em;
32 | cursor: pointer;
33 | background-color: #d8d8d8cc;
34 | }
35 |
36 | &__answer {
37 | padding: 10px;
38 | background-color: rgba(253, 253, 253, 0.678);
39 | }
40 | }
41 |
42 | @media (min-width: 1024px) {
43 | .accordion {
44 | flex-direction: row;
45 | padding: 5em 0.5em;
46 |
47 | &__box {
48 | transition: color 0.3s ease;
49 |
50 | &:hover {
51 | color: $main;
52 | }
53 | }
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/components/BlogContent/BlogItem.jsx:
--------------------------------------------------------------------------------
1 | import { FaUser, FaCalendarAlt } from "react-icons/fa";
2 | import { Link } from "react-router-dom";
3 |
4 | const BlogItem = (props) => {
5 | return (
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | By FitnessGym Team
14 |
15 |
16 | {props.month} 2023
17 |
18 |
19 |
20 |
{props.title}
21 |
{props.text}
22 |
23 | Read More
24 |
25 |
26 |
27 | );
28 | };
29 |
30 | export default BlogItem;
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2024 Dawid Olko
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/components/CartContent/CartModal.jsx:
--------------------------------------------------------------------------------
1 | import "./CartContent.scss";
2 | import { motion } from "framer-motion";
3 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
4 |
5 | const CartModal = ({ isOpen, closeModal }) => {
6 | return (
7 | isOpen && (
8 |
15 |
21 | Order Confirmed!
22 |
23 | Your order has been successfully placed.
24 |
25 |
26 | Close
27 |
28 |
29 |
30 | )
31 | );
32 | };
33 |
34 | export default CartModal;
35 |
--------------------------------------------------------------------------------
/src/components/AboutContent/AboutContent.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .about {
4 | padding: 4em 0;
5 |
6 | &__container {
7 | @include flexCenter(column);
8 | gap: 2em;
9 | max-width: 500px;
10 | padding: 0 0.5em;
11 | }
12 |
13 | &__img {
14 | object-fit: cover;
15 | height: 400px;
16 | }
17 |
18 | &__title {
19 | margin-bottom: 0.7em;
20 | font-size: 4rem;
21 | line-height: 1.2;
22 | }
23 |
24 | &__span {
25 | color: $main;
26 | }
27 |
28 | &__text {
29 | margin-bottom: 2em;
30 | line-height: 1.8;
31 | }
32 |
33 | &__marks {
34 | display: flex;
35 | gap: 0.3em;
36 | margin-bottom: 0.5em;
37 | color: #383737;
38 | }
39 |
40 | &__mark {
41 | color: #000;
42 | }
43 | }
44 |
45 | @media (min-width: 1024px) {
46 | .about {
47 | padding: 6em 0;
48 |
49 | &__container {
50 | flex-direction: row;
51 | gap: 3em;
52 | max-width: unset;
53 | }
54 |
55 | &__img {
56 | height: 100%;
57 | }
58 |
59 | &__img-container {
60 | height: 600px;
61 | }
62 |
63 | &__content {
64 | max-width: 500px;
65 | }
66 |
67 | &__title {
68 | font-size: 5rem;
69 | }
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/src/components/MainBackground/MainBackgroundData.js:
--------------------------------------------------------------------------------
1 | import bgc1 from "../../assets/bgc1.webp";
2 | import bgc2 from "../../assets/blog_big1.jpg";
3 | import bgc3 from "../../assets/bgc3.webp";
4 |
5 | const sliderItems = [
6 | {
7 | id: 1,
8 | img: bgc1,
9 | alt: "Man pushing his limits during a gym session",
10 | title: "KEEP PUSHING FORWARD",
11 | text: "Building strength and endurance requires dedication and hard work. We provide the tools and support to help you achieve your fitness goals.",
12 | },
13 | {
14 | id: 2,
15 | img: bgc2,
16 | alt: "Woman pushing her boundaries in a fitness class",
17 | title: "NO EXCUSES, JUST RESULTS",
18 | text: "A healthy body and mind come from consistent training. Let us guide you through your fitness journey with tailored programs and expert advice.",
19 | },
20 | {
21 | id: 3,
22 | img: bgc3,
23 | alt: "Woman receiving support during a workout",
24 | title: "TRAIN WITH CONFIDENCE",
25 | text: "Our gym provides not only top-notch equipment but also a supportive environment to help you conquer your fitness goals with ease.",
26 | },
27 | ];
28 |
29 | export default sliderItems;
30 |
--------------------------------------------------------------------------------
/src/components/Testimonials/Testimonials.jsx:
--------------------------------------------------------------------------------
1 | import "./Testimonials.scss";
2 | import TestimonialsItem from "./TestimonialsItem";
3 | import testimonialsData from "./TestimonialsData";
4 | import Slider from "react-slick";
5 | import "slick-carousel/slick/slick.css";
6 | import "slick-carousel/slick/slick-theme.css";
7 |
8 | const Testimonials = () => {
9 | const sliderSettings = {
10 | infinite: true,
11 | speed: 2000,
12 | slidesToShow: 3,
13 | slidesToScroll: 1,
14 | arrows: false,
15 | autoplay: true,
16 | autoplaySpeed: 4000,
17 |
18 | responsive: [
19 | {
20 | breakpoint: 1124,
21 | settings: {
22 | slidesToShow: 2,
23 | },
24 | },
25 | {
26 | breakpoint: 768,
27 | settings: {
28 | slidesToShow: 1,
29 | },
30 | },
31 | ],
32 | };
33 |
34 | return (
35 |
36 |
37 |
What Our Client Say's About Us
38 |
39 | {testimonialsData.map((item) => (
40 |
41 | ))}
42 |
43 |
44 |
45 | );
46 | };
47 |
48 | export default Testimonials;
49 |
--------------------------------------------------------------------------------
/src/components/NewProducts/NewProducts.jsx:
--------------------------------------------------------------------------------
1 | import shopData from "../ShopContent/ShopData";
2 | import ShopProduct from "../ShopContent/ShopProduct";
3 | import { useNavigate } from "react-router-dom";
4 | import { useRef } from "react";
5 | import { motion, useInView } from "framer-motion";
6 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
7 |
8 | const NewProducts = () => {
9 | const ref = useRef();
10 | const isInView = useInView(ref, { once: true });
11 | const navigate = useNavigate();
12 |
13 | return (
14 |
20 | Latest Arrivals
21 |
22 | {shopData
23 | .filter((product) => product.isNew)
24 | .map((product) => (
25 |
26 | ))}
27 |
28 | navigate("/shop")} className="shop__navigate">
29 | View All Products
30 |
31 |
32 | );
33 | };
34 |
35 | export default NewProducts;
36 |
--------------------------------------------------------------------------------
/src/components/Fitness/Fitness.jsx:
--------------------------------------------------------------------------------
1 | import AboutContent from "../AboutContent/AboutContent";
2 | import { motion, useInView } from "framer-motion";
3 | import { useRef } from "react";
4 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
5 | import fitness from "../../assets/fitness.webp";
6 |
7 | const Fitness = () => {
8 | const ref = useRef();
9 | const isInView = useInView(ref, { once: true });
10 |
11 | return (
12 |
17 |
25 |
26 | );
27 | };
28 |
29 | export default Fitness;
30 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
13 |
16 |
19 |
22 | FitnessGym
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/src/components/CartContent/CartProduct.jsx:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react";
2 | import { CartContext } from "../ShopContext/ShopContext";
3 | import { AiOutlinePlus, AiOutlineMinus } from "react-icons/ai";
4 |
5 | const CartProduct = (props) => {
6 | const { id, img, name, price } = props;
7 | const { items, addToCart, removeFromCart, singleProductAmount } =
8 | useContext(CartContext);
9 | const quantity = items[id];
10 |
11 | return (
12 |
13 |
14 |
15 |
16 | {name}
17 | ${parseFloat(price).toFixed(2)}
18 |
19 | removeFromCart(id)}>
20 |
21 |
22 | {quantity}
23 | addToCart(id)}>
24 |
25 |
26 |
27 |
28 | ${(singleProductAmount(id) || 0).toFixed(2)}
29 |
30 |
31 | );
32 | };
33 |
34 | export default CartProduct;
35 |
--------------------------------------------------------------------------------
/src/components/Counter/Counter.jsx:
--------------------------------------------------------------------------------
1 | import "./Counter.scss";
2 | import CountUp from "react-countup";
3 | import { useInView } from "react-intersection-observer";
4 |
5 | const Counter = () => {
6 | const [ref, inView] = useInView({
7 | triggerOnce: true,
8 | threshold: 0.5,
9 | });
10 |
11 | return (
12 |
13 | {inView && (
14 |
15 |
16 |
Total Member
17 |
18 | )}
19 | {inView && (
20 |
24 | )}
25 | {inView && (
26 |
27 |
28 |
Total Trainer
29 |
30 | )}
31 | {inView && (
32 |
33 |
34 |
Win Awards
35 |
36 | )}
37 |
38 | );
39 | };
40 |
41 | export default Counter;
42 |
--------------------------------------------------------------------------------
/src/components/MainBackground/MainBackground.jsx:
--------------------------------------------------------------------------------
1 | import "./MainBackground.scss";
2 | import sliderItems from "./MainBackgroundData";
3 | import MainBackgroundItem from "./MainBackgroundItem";
4 | import { useState } from "react";
5 | import { AiOutlineArrowLeft, AiOutlineArrowRight } from "react-icons/ai";
6 |
7 | const MainBackground = () => {
8 | const [currentSlide, setCurrentSlide] = useState(0);
9 |
10 | const prevSlide = () => {
11 | setCurrentSlide((prev) => (prev === 0 ? sliderItems.length - 1 : prev - 1));
12 | };
13 |
14 | const nextSlide = () => {
15 | setCurrentSlide((prev) => (prev === sliderItems.length - 1 ? 0 : prev + 1));
16 | };
17 |
18 | return (
19 |
39 | );
40 | };
41 |
42 | export default MainBackground;
43 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import { Route, Routes, useLocation } from "react-router-dom";
2 | import Navbar from "./components/Navbar/Navbar";
3 | import Home from "./pages/Home";
4 | import About from "./pages/About";
5 | import Faq from "./pages/Faq";
6 | import Blog from "./pages/Blog";
7 | import BlogId from "./components/BlogContent/Article/Article";
8 | import Contact from "./pages/Contact";
9 | import Footer from "./components/Footer/Footer";
10 | import NotFound from "./components/NotFound/NotFound";
11 | import Shop from "./pages/Shop";
12 | import Cart from "./pages/Cart";
13 | import ShopContext from "./components/ShopContext/ShopContext";
14 |
15 | function App() {
16 | const location = useLocation();
17 |
18 | return (
19 |
20 |
21 |
22 | } />
23 | } />
24 | } />
25 | } />
26 | } />
27 | } />
28 | } />
29 | } />
30 | } />
31 |
32 |
33 |
34 | );
35 | }
36 |
37 | export default App;
38 |
--------------------------------------------------------------------------------
/src/components/ShopContent/ShopContent.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import "./ShopContent.scss";
3 | import shopData from "./ShopData";
4 | import ShopProduct from "./ShopProduct";
5 |
6 | const ShopContent = () => {
7 | const [selectedCategory, setSelectedCategory] = useState("All");
8 |
9 | const categories = ["All", "Protein", "Creatine", "Pre-Workout"];
10 |
11 | const handleCategoryClick = (category) => {
12 | setSelectedCategory(category);
13 | };
14 |
15 | const filteredProducts =
16 | selectedCategory === "All"
17 | ? shopData
18 | : shopData.filter((product) => product.category === selectedCategory);
19 |
20 | return (
21 |
22 |
Our Products
23 |
24 | {categories.map((category) => (
25 | handleCategoryClick(category)}
28 | className={selectedCategory === category ? "shop__active" : ""}>
29 | {category}
30 |
31 | ))}
32 |
33 |
34 | {filteredProducts.map((product, index) => (
35 |
36 | ))}
37 |
38 |
39 | );
40 | };
41 |
42 | export default ShopContent;
43 |
--------------------------------------------------------------------------------
/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import AnimatedPage from "../components/AnimatedPage/AnimatedPage";
2 | import MainBackground from "../components/MainBackground/MainBackground";
3 | import Fitness from "../components/Fitness/Fitness";
4 | import FixedBg from "../components/FixedBg/FixedBg";
5 | import Pricing from "../components/Pricing/Pricing";
6 | import Counter from "../components/Counter/Counter";
7 | import Team from "../components/Team/Team";
8 | import Testimonials from "../components/Testimonials/Testimonials";
9 | import CallBack from "../components/CallBack/CallBack";
10 | import LogoSlider from "../components/LogoSlider/LogoSlider";
11 | import NewProducts from "../components/NewProducts/NewProducts";
12 |
13 | const Home = () => {
14 | return (
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
31 |
32 |
33 |
34 |
35 |
36 | );
37 | };
38 |
39 | export default Home;
40 |
--------------------------------------------------------------------------------
/src/components/CartContent/TotalAmount.jsx:
--------------------------------------------------------------------------------
1 | import { useContext } from "react";
2 | import { useNavigate } from "react-router-dom";
3 | import { CartContext } from "../ShopContext/ShopContext";
4 | import CartModal from "./CartModal";
5 | import { useState } from "react";
6 |
7 | const TotalAmount = () => {
8 | const { totalAmount, totalCartItems, resetCart } = useContext(CartContext);
9 | const navigate = useNavigate();
10 | const [isModalOpen, setIsModalOpen] = useState(false);
11 |
12 | const openModal = () => {
13 | setIsModalOpen(true);
14 | };
15 |
16 | const closeModal = () => {
17 | setIsModalOpen(false);
18 | resetCart();
19 | navigate("/FitnessGym/");
20 | };
21 |
22 | return (
23 |
24 |
Cart Total
25 |
26 | Total Price: ${totalAmount().toFixed(2)}
27 |
28 |
Total Items: {totalCartItems()}
29 |
30 | navigate("/shop")}>
31 | Continue Shopping
32 |
33 |
34 | Checkout
35 |
36 |
37 |
38 |
39 | );
40 | };
41 |
42 | export default TotalAmount;
43 |
--------------------------------------------------------------------------------
/src/components/Accordion/Accordion.jsx:
--------------------------------------------------------------------------------
1 | import "./Accordion.scss";
2 | import accordionData from "./AccordionData";
3 | import { useState } from "react";
4 | import { AiOutlinePlus, AiOutlineMinus } from "react-icons/ai";
5 | import faq from "../../assets/faq.webp";
6 |
7 | const Accordion = () => {
8 | const [activeIndex, setActiveIndex] = useState(null);
9 |
10 | const toggleAccordion = (index) => {
11 | setActiveIndex((prevIndex) => (prevIndex === index ? null : index));
12 | };
13 |
14 | return (
15 |
16 |
21 |
22 |
Frequently Asked Questions
23 | {accordionData.map((q, index) => (
24 |
25 |
toggleAccordion(index)}>
28 |
{q.question}
29 | {activeIndex === index ?
:
}
30 |
31 | {activeIndex === index && (
32 |
{q.answer}
33 | )}
34 |
35 | ))}
36 |
37 |
38 | );
39 | };
40 |
41 | export default Accordion;
42 |
--------------------------------------------------------------------------------
/src/components/Team/Team.jsx:
--------------------------------------------------------------------------------
1 | import "./Team.scss";
2 | import teamData from "./TeamData";
3 | import { useRef } from "react";
4 | import { motion, useInView } from "framer-motion";
5 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
6 | import { FaFacebookF, FaTwitter, FaInstagram } from "react-icons/fa";
7 |
8 | const Team = () => {
9 | const ref = useRef();
10 | const isInView = useInView(ref, { once: true });
11 |
12 | return (
13 |
20 | Meet With Expert Trainers
21 |
28 | {teamData.map((item) => (
29 |
30 |
31 |
32 |
{item.name}
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 | ))}
41 |
42 |
43 | );
44 | };
45 |
46 | export default Team;
47 |
--------------------------------------------------------------------------------
/src/components/AboutContent/AboutContent.jsx:
--------------------------------------------------------------------------------
1 | import "./AboutContent.scss";
2 | import { GiCheckMark } from "react-icons/gi";
3 |
4 | const AboutContent = (props) => {
5 | const { img, alt, title, span, text, showIcons = true } = props;
6 |
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | {title}
16 | {span}
17 |
18 |
{text}
19 | {showIcons && (
20 | <>
21 |
22 |
23 | Driven to Empower, Motivate, and Achieve Goals
24 |
25 |
26 |
27 | Our Mission: Inspire Fitness, Transform Lives
28 |
29 |
30 |
31 | Join a Community Built on Growth and Resilience
32 |
33 | >
34 | )}
35 |
36 |
37 |
38 | );
39 | };
40 |
41 | export default AboutContent;
42 |
--------------------------------------------------------------------------------
/src/components/Modal/ModalComponent.jsx:
--------------------------------------------------------------------------------
1 | import { motion } from "framer-motion";
2 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
3 | import FormComponent from "./FormComponent";
4 | import { AiOutlineClose } from "react-icons/ai";
5 |
6 | const ModalComponent = ({
7 | onClose,
8 | handleSubmit,
9 | setIsMessageSent,
10 | setMessage,
11 | isMessageSent,
12 | message,
13 | }) => {
14 | const handleClose = () => {
15 | setIsMessageSent(false);
16 | setMessage("");
17 | onClose();
18 | };
19 |
20 | return (
21 |
30 | e.stopPropagation()}
36 | className="modal"
37 | >
38 | REQUEST A CALLBACK
39 |
40 | We can call you in 30 seconds, just enter your number
41 |
42 |
49 |
50 |
51 |
52 |
53 |
54 | );
55 | };
56 |
57 | export default ModalComponent;
58 |
--------------------------------------------------------------------------------
/src/components/Modal/Modal.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .modal {
4 | @include flexCenter(column);
5 | gap: 0.5em;
6 | position: relative;
7 | padding: 3em 4em;
8 | background-color: rgb(14, 14, 14);
9 |
10 | &__overlay {
11 | @include flexCenter(row);
12 | position: fixed;
13 | top: 0;
14 | width: 100%;
15 | height: 100%;
16 | background-color: rgba(17, 17, 17, 0.863);
17 | z-index: 99;
18 | color: $white;
19 | }
20 |
21 | &__title {
22 | text-align: center;
23 | }
24 |
25 | &__text {
26 | margin-bottom: 1em;
27 | text-align: center;
28 | }
29 |
30 | &__form {
31 | @include flexCenter(column);
32 | gap: 1em;
33 | }
34 |
35 | &__input {
36 | padding: 0.5em;
37 | width: 100%;
38 | }
39 |
40 | &__error {
41 | font-size: 1.4rem;
42 | color: rgb(201, 10, 10);
43 | line-height: 0;
44 | }
45 |
46 | &__success {
47 | color: rgb(13, 139, 13);
48 | }
49 |
50 | &__btn {
51 | margin-top: 1em;
52 | padding: 0.8em 2.8em;
53 | width: fit-content;
54 | background-color: $main;
55 | border-radius: 8px;
56 | color: $white;
57 | }
58 |
59 | &__close {
60 | position: absolute;
61 | top: 10px;
62 | right: 10px;
63 | font-size: 2rem;
64 | color: $white;
65 | cursor: pointer;
66 | }
67 | }
68 |
69 | @media (min-width: 768px) {
70 | .modal {
71 | &__form {
72 | width: 550px;
73 | }
74 |
75 | &__btn {
76 | border: 1px solid transparent;
77 | transition: border 0.3s, background-color 0.3s;
78 |
79 | &:hover {
80 | background-color: #e4e3e117;
81 | border: 1px solid white;
82 | }
83 | }
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/components/FixedBg/FixedBg.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .fixed {
4 | height: 60vh;
5 | background: url("../../assets/fitnessClass.webp") rgba(0, 0, 0, 0.6);
6 | background-blend-mode: darken;
7 | background-size: cover;
8 | background-position: top;
9 |
10 | &__secondary {
11 | height: 75vh;
12 | background: url("../../assets/blog_big1.webp") rgba(0, 0, 0, 0.6);
13 | background-blend-mode: darken;
14 | background-size: cover;
15 | background-position: top;
16 | }
17 |
18 | &__content {
19 | @include flexCenter(column);
20 | height: 100%;
21 | color: $white;
22 | gap: 1em;
23 | }
24 |
25 | &__text {
26 | font-size: 2rem;
27 | font-style: italic;
28 | }
29 |
30 | &__title {
31 | max-width: 1100px;
32 | padding: 0 0.5em;
33 | font-size: 4rem;
34 | font-style: italic;
35 | text-align: center;
36 | line-height: 1.3;
37 | }
38 |
39 | &__link {
40 | padding: 0.7em 2.4em;
41 | background-color: $main;
42 | border-radius: 10px;
43 | color: $white;
44 | }
45 | }
46 |
47 | @media (min-width: 796px) {
48 | .fixed {
49 | background-attachment: fixed;
50 |
51 | &__secondary {
52 | background-attachment: fixed;
53 | }
54 | }
55 | }
56 |
57 | @media (min-width: 996px) {
58 | .fixed {
59 | height: 70vh;
60 |
61 | &__link {
62 | border: 1px solid transparent;
63 | transition: border 0.3s, background-color 0.3s;
64 |
65 | &:hover {
66 | background-color: #e4e3e117;
67 | border: 1px solid white;
68 | }
69 | }
70 |
71 | &__text {
72 | font-size: 3rem;
73 | }
74 |
75 | &__title {
76 | font-size: 8rem;
77 | }
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/components/AnimationVariants/AnimationVariants.jsx:
--------------------------------------------------------------------------------
1 | const AnimationVariants = {
2 | modalAnimation: {
3 | initial: {
4 | opacity: 0,
5 | y: 100,
6 | },
7 | animate: {
8 | opacity: 1,
9 | y: 0,
10 | transition: {
11 | duration: 0.4,
12 | ease: "easeOut",
13 | },
14 | },
15 | exit: {
16 | opacity: 0,
17 | y: -50,
18 | },
19 | },
20 |
21 | overlayAnimation: {
22 | initial: {
23 | opacity: 0,
24 | scale: 0.9,
25 | },
26 | animate: {
27 | opacity: 1,
28 | scale: 1,
29 | transition: {
30 | duration: 0.3,
31 | ease: "easeInOut",
32 | },
33 | },
34 | exit: {
35 | opacity: 0,
36 | scale: 0.95,
37 | },
38 | },
39 |
40 | fadeIn: {
41 | initial: {
42 | y: "-100px",
43 | opacity: 0,
44 | },
45 | animate: {
46 | y: 0,
47 | opacity: 1,
48 | transition: {
49 | duration: 0.5,
50 | ease: "easeOut",
51 | },
52 | },
53 | },
54 |
55 | fadeIn2: {
56 | initial: {
57 | opacity: 0,
58 | scale: 0.6,
59 | },
60 | animate: {
61 | scale: 1,
62 | opacity: 1,
63 | transition: {
64 | duration: 0.7,
65 | ease: "easeIn",
66 | },
67 | },
68 | },
69 |
70 | slideIn: {
71 | initial: {
72 | y: 150,
73 | opacity: 0,
74 | },
75 | animate: {
76 | y: 0,
77 | opacity: 1,
78 | transition: {
79 | duration: 0.7,
80 | ease: "easeInOut",
81 | },
82 | },
83 | },
84 | };
85 |
86 | export default AnimationVariants;
87 |
--------------------------------------------------------------------------------
/src/components/MainBackground/MainBackgroundItem.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from "react-router-dom";
2 | import { motion, useInView } from "framer-motion";
3 | import AnimationVariants from "../AnimationVariants/AnimationVariants";
4 | import { useRef } from "react";
5 |
6 | const MainBackgroundItem = ({ item, currentSlide }) => {
7 | const ref = useRef();
8 | const isInView = useInView(ref, { once: true });
9 |
10 | return (
11 |
15 |
16 |
17 |
18 |
19 |
26 | {item.title}
27 |
28 |
35 | {item.text}
36 |
37 |
43 |
44 | Join Us
45 |
46 |
47 |
48 |
49 | );
50 | };
51 |
52 | export default MainBackgroundItem;
53 |
--------------------------------------------------------------------------------
/src/components/Pricing/PricingItem.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from "react-router-dom";
2 | import { AiOutlineCheck, AiOutlineClose } from "react-icons/ai";
3 |
4 | const PricingItem = ({ title, price, yoga, fashion, swimming, bestOffer }) => {
5 | const items = [
6 | { label: "Gym & Fitness Access", included: true },
7 | { label: "Boxing Classes", included: true },
8 | { label: "Yoga Sessions", included: yoga },
9 | { label: "Fashion Yoga & Gym", included: fashion },
10 | { label: "Swimming Pool Access", included: swimming },
11 | ];
12 |
13 | return (
14 |
17 | {bestOffer &&
Top Pick }
18 |
{title}
19 |
20 | ${price} /month
21 |
22 |
23 |
24 | {items.map((item, index) => (
25 |
26 |
27 | {item.included ? (
28 |
29 | ) : (
30 |
31 | )}
32 |
33 | {item.label}
34 |
35 | ))}
36 |
37 |
38 | Join Now
39 |
40 |
41 | );
42 | };
43 |
44 | export default PricingItem;
45 |
--------------------------------------------------------------------------------
/src/components/CartContent/CartContent.jsx:
--------------------------------------------------------------------------------
1 | import "./CartContent.scss";
2 | import shopData from "../ShopContent/ShopData";
3 | import { useContext } from "react";
4 | import { CartContext } from "../ShopContext/ShopContext";
5 | import CartProduct from "./CartProduct";
6 | import TotalAmount from "./TotalAmount";
7 | import { useNavigate } from "react-router-dom";
8 |
9 | const CartContent = () => {
10 | const { items, totalAmount } = useContext(CartContext);
11 | const navigate = useNavigate();
12 |
13 | return (
14 |
15 | {totalAmount() > 0 ? (
16 |
17 |
18 |
19 |
20 | Product
21 | Name
22 | Price
23 | Quantity
24 | Total Price
25 |
26 |
27 |
28 | {shopData.map((product) => {
29 | if (items[product.id] && items[product.id] > 0) {
30 | return ;
31 | }
32 | return null;
33 | })}
34 |
35 |
36 |
37 |
38 | ) : (
39 |
40 |
Your cart is empty
41 | navigate("/shop")}>
42 | Go To Shopping
43 |
44 |
45 | )}
46 |
47 | );
48 | };
49 |
50 | export default CartContent;
51 |
--------------------------------------------------------------------------------
/src/components/LogoSlider/LogoSlider.jsx:
--------------------------------------------------------------------------------
1 | import "./LogoSlider.scss";
2 | import Slider from "react-slick";
3 | import logo1 from "../../assets/logo1.png";
4 | import logo2 from "../../assets/logo2.png";
5 | import logo3 from "../../assets/logo3.png";
6 | import logo4 from "../../assets/logo4.png";
7 |
8 | const LogoSlider = () => {
9 | const settings = {
10 | dots: false,
11 | infinite: true,
12 | speed: 3000,
13 | slidesToShow: 4,
14 | slidesToScroll: 1,
15 | autoplay: true,
16 | arrows: false,
17 | initialSlide: 0,
18 | autoplaySpeed: 4000,
19 |
20 | responsive: [
21 | {
22 | breakpoint: 1024,
23 | settings: {
24 | slidesToShow: 3,
25 | },
26 | },
27 | {
28 | breakpoint: 768,
29 | settings: {
30 | slidesToShow: 2,
31 | },
32 | },
33 | ],
34 | };
35 |
36 | return (
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | );
68 | };
69 |
70 | export default LogoSlider;
71 |
--------------------------------------------------------------------------------
/src/components/Accordion/AccordionData.js:
--------------------------------------------------------------------------------
1 | const accordionData = [
2 | {
3 | question: "HOW CAN I JOIN FITNESS CLASSES?",
4 | answer:
5 | "To join our fitness classes, simply choose a membership plan that suits your needs. For first-time visitors, we offer a free trial class every Saturday. Check our schedule and sign up through the website or at the reception desk.",
6 | },
7 | {
8 | question: "WHAT FITNESS PROGRAM IS BEST FOR BEGINNERS?",
9 | answer:
10 | "If you're new to fitness, we recommend starting with our introductory courses or personal training sessions. Additionally, you can take a free physical assessment to tailor the best program for your fitness level and goals.",
11 | },
12 | {
13 | question: "WHAT IS THE MINIMUM AGE FOR GYM MEMBERSHIP?",
14 | answer:
15 | "Our standard membership is available for individuals aged 18 and above. However, we offer specialized youth programs for teenagers aged 13-17 and group activities for children. Contact us for more details on these categories.",
16 | },
17 | {
18 | question: "CAN I INVITE FRIENDS TO TRY FITNESSGYM?",
19 | answer:
20 | "Yes! You can bring a friend for a trial session, and if they join, you’ll receive a discount on your next membership renewal. We believe fitness is more fun with friends!",
21 | },
22 | {
23 | question: "WHAT PAYMENT METHODS ARE ACCEPTED?",
24 | answer:
25 | "We accept Visa, MasterCard, and PayPal for online payments. Cash payments can be made at the gym. For group packages and memberships, card payments are preferred for convenience.",
26 | },
27 | {
28 | question: "CAN I PAUSE MY MEMBERSHIP?",
29 | answer:
30 | "Yes, you can freeze your membership for up to 12 months. During this period, all benefits will be preserved. You’ll receive reminders when your freeze period is nearing its end.",
31 | },
32 | ];
33 |
34 | export default accordionData;
35 |
--------------------------------------------------------------------------------
/src/components/Modal/FormComponent.jsx:
--------------------------------------------------------------------------------
1 | import { Formik, Form, ErrorMessage, Field } from "formik";
2 | import * as Yup from "yup";
3 |
4 | const FormComponent = ({
5 | handleSubmit,
6 | setIsMessageSent,
7 | setMessage,
8 | isMessageSent,
9 | message,
10 | }) => {
11 | const initialValues = {
12 | name: "",
13 | phone: "",
14 | };
15 |
16 | const validationSchema = Yup.object({
17 | name: Yup.string()
18 | .required("Name is required")
19 | .min(2, "Name must be at least 2 characters")
20 | .max(20, "Name can't be longer than 20 characters"),
21 | phone: Yup.string()
22 | .required("Phone number is required")
23 | .matches(/^[0-9]+$/, "Must be only digits")
24 | .min(10, "Phone number must be at least 10 characters")
25 | .max(15, "Phone number can't be longer than 15 characters"),
26 | });
27 |
28 | return (
29 | {
31 | handleSubmit(values, actions);
32 | setIsMessageSent(true);
33 | setMessage("Message sent successfully!");
34 | }}
35 | initialValues={initialValues}
36 | validationSchema={validationSchema}
37 | >
38 |
64 |
65 | );
66 | };
67 |
68 | export default FormComponent;
69 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fitnessgym",
3 | "version": "0.1.0",
4 | "private": true,
5 | "homepage": "https://fitnessgym.dawidolko.pl",
6 | "dependencies": {
7 | "@testing-library/jest-dom": "^5.17.0",
8 | "@testing-library/react": "^13.4.0",
9 | "@testing-library/user-event": "^13.5.0",
10 | "formik": "^2.4.5",
11 | "framer-motion": "^10.16.4",
12 | "icons": "^1.0.0",
13 | "input-mask": "^1.1.20",
14 | "react": "^18.2.0",
15 | "react-countup": "^6.4.2",
16 | "react-dom": "^18.2.0",
17 | "react-icons": "^4.11.0",
18 | "react-input-mask": "^2.0.4",
19 | "react-intersection-observer": "^9.5.2",
20 | "react-modal": "^3.16.1",
21 | "react-router-dom": "^6.17.0",
22 | "react-router-scroll-position": "^2.1.4",
23 | "react-router-scroll-to-top": "^1.2.1",
24 | "react-scripts": "5.0.1",
25 | "react-scroll-up": "^1.4.0",
26 | "react-scrollama": "^2.3.3",
27 | "react-slick": "^0.29.0",
28 | "react-spring": "^9.7.3",
29 | "sass": "^1.69.5",
30 | "slick-carousel": "^1.8.1",
31 | "web-vitals": "^2.1.4",
32 | "yup": "^1.3.2"
33 | },
34 | "scripts": {
35 | "start": "react-scripts start",
36 | "build": "react-scripts build",
37 | "test": "react-scripts test",
38 | "eject": "react-scripts eject",
39 | "predeploy": "npm run build",
40 | "deploy": "gh-pages -d build"
41 | },
42 | "eslintConfig": {
43 | "extends": [
44 | "react-app",
45 | "react-app/jest"
46 | ]
47 | },
48 | "browserslist": {
49 | "production": [
50 | ">0.2%",
51 | "not dead",
52 | "not op_mini all"
53 | ],
54 | "development": [
55 | "last 1 chrome version",
56 | "last 1 firefox version",
57 | "last 1 safari version"
58 | ]
59 | },
60 | "devDependencies": {
61 | "@babel/plugin-proposal-private-property-in-object": "^7.21.11",
62 | "gh-pages": "^6.3.0"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | /* Reset and Global Styles */
2 | *,
3 | *::before,
4 | *::after {
5 | box-sizing: inherit;
6 | margin: 0;
7 | padding: 0;
8 | }
9 |
10 | html {
11 | font-size: 60%;
12 | }
13 |
14 | body {
15 | font-size: 1.5rem;
16 | font-family: "Open Sans", sans-serif;
17 | line-height: 1.5;
18 | background-color: #f9f9f9;
19 | color: #333;
20 | }
21 |
22 | body::-webkit-scrollbar {
23 | width: 12px;
24 | background-color: #f9f9f9;
25 | }
26 |
27 | body::-webkit-scrollbar-thumb {
28 | background-color: #646566;
29 | border-radius: 6px;
30 | border: 3px solid #f9f9f9;
31 | transition: background-color 0.3s ease-in-out;
32 | }
33 |
34 | body::-webkit-scrollbar-thumb:hover {
35 | background-color: #939596;
36 | }
37 |
38 | body::-webkit-scrollbar-track {
39 | background-color: #e1e1e1;
40 | border-radius: 6px;
41 | }
42 |
43 | h1,
44 | h2,
45 | h3,
46 | h4 {
47 | font-family: "Lato", sans-serif;
48 | margin-bottom: 1.2rem;
49 | }
50 |
51 | a {
52 | text-decoration: none;
53 | color: inherit;
54 | transition: color 0.2s ease-in-out;
55 | }
56 |
57 | a:hover {
58 | color: #0077cc;
59 | }
60 |
61 | img {
62 | width: 100%;
63 | height: auto;
64 | display: block;
65 | object-fit: contain;
66 | }
67 |
68 | input,
69 | button,
70 | textarea,
71 | select {
72 | font-family: inherit;
73 | font-size: 1.6rem;
74 | }
75 |
76 | button {
77 | border: 1px solid transparent;
78 | border-radius: 4px;
79 | background-color: #0077cc;
80 | color: white;
81 | padding: 0.8rem 1.6rem;
82 | cursor: pointer;
83 | transition: background-color 0.3s ease;
84 | }
85 |
86 | button:hover {
87 | background-color: #005fa3;
88 | }
89 |
90 | ul {
91 | list-style: none;
92 | padding-left: 1rem;
93 | }
94 |
95 | .container {
96 | width: 90%;
97 | margin: 0 auto;
98 | padding: 2rem;
99 | }
100 |
101 | @media (min-width: 1200px) {
102 | .container {
103 | width: 1100px;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/components/Testimonials/Testimonials.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .testimonials {
4 | background: url("../../assets/testimonials.webp") rgba(0, 0, 0, 0.9);
5 | background-blend-mode: darken;
6 | background-size: cover;
7 | background-position: center;
8 |
9 | &__wrapper {
10 | width: 90%;
11 | margin: 0 auto;
12 | padding: 5em 0 7em;
13 | }
14 |
15 | &__title {
16 | margin-bottom: 1.5em;
17 | text-align: center;
18 | font-size: 5rem;
19 | font-style: italic;
20 | color: $white;
21 | font-weight: 500;
22 | }
23 |
24 | &__box {
25 | height: 350px;
26 | width: 100%;
27 | padding: 0.8em;
28 | margin-bottom: 1em;
29 | border-radius: 8px;
30 | overflow: hidden;
31 | background-color: rgb(235, 233, 233);
32 | }
33 |
34 | &__person {
35 | display: flex;
36 | align-items: center;
37 | gap: 1em;
38 | }
39 |
40 | &__img {
41 | width: 90px;
42 | height: 90px;
43 | margin: 1em 0 2em;
44 | padding: 0.2em;
45 | object-fit: cover;
46 | border-radius: 50%;
47 | border: 2px solid $main;
48 | }
49 |
50 | &__info {
51 | font-weight: 500;
52 | }
53 |
54 | &__name {
55 | font-size: 2rem;
56 | }
57 |
58 | &__client {
59 | color: $main;
60 | }
61 |
62 | &__review {
63 | font-style: italic;
64 | max-width: 400px;
65 | }
66 | }
67 |
68 | .slick-slide > div {
69 | margin: 0 10px;
70 | }
71 |
72 | .slick-list {
73 | margin: 0 -10px;
74 | }
75 |
76 | .slick-dots li button:before {
77 | font-size: 12px;
78 | background-color: #fff;
79 | border-radius: 50%;
80 | }
81 |
82 | .slick-dots li.slick-active button:before {
83 | background-color: rgb(255, 255, 255);
84 | }
85 |
86 | @media (min-width: 500px) {
87 | .testimonials {
88 | &__wrapper {
89 | width: 70%;
90 | }
91 | }
92 | }
93 |
94 | @media (min-width: 796px) {
95 | .testimonials {
96 | background-attachment: fixed;
97 | }
98 | }
99 |
100 | @media (min-width: 1300px) {
101 | .testimonials {
102 | &__box {
103 | height: 300px;
104 | }
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/src/components/BlogContent/BlogData.js:
--------------------------------------------------------------------------------
1 | import blog1 from "../../assets/blog1.webp";
2 | import blog2 from "../../assets/blog2.webp";
3 | import blog3 from "../../assets/blog3.webp";
4 | import blog4 from "../../assets/blog4.webp";
5 | import blog5 from "../../assets/blog5.webp";
6 | import blog6 from "../../assets/blog6.webp";
7 |
8 | const blogData = [
9 | {
10 | id: 1,
11 | img: blog5,
12 | alt: "Man working out in a fitness studio",
13 | month: "November",
14 | title: "TIPS TO OPTIMIZE YOUR GYM ROUTINE",
15 | text: "Enhance your workout efficiency with expert advice on maximizing gym time and achieving your fitness objectives.",
16 | },
17 | {
18 | id: 2,
19 | img: blog4,
20 | alt: "Woman performing strength exercises",
21 | month: "October",
22 | title: "THE ULTIMATE GUIDE TO FITNESS SUCCESS",
23 | text: "Uncover key strategies and insights with this comprehensive guide to conquering your fitness journey.",
24 | },
25 | {
26 | id: 3,
27 | img: blog6,
28 | alt: "Woman lifting weights at the gym",
29 | month: "October",
30 | title: "BOOST YOUR MIND AND BODY WITH FITNESS",
31 | text: "Explore how staying active can sharpen your mind and uplift your mood for a healthier lifestyle.",
32 | },
33 | {
34 | id: 4,
35 | img: blog2,
36 | alt: "Man engaged in endurance training",
37 | month: "September",
38 | title: "WHY TODAY IS PERFECT FOR FITNESS",
39 | text: "Don't wait for tomorrow—start your fitness transformation today and embrace a healthier you.",
40 | },
41 | {
42 | id: 5,
43 | img: blog1,
44 | alt: "Woman performing bodyweight exercises",
45 | month: "September",
46 | title: "PERSONAL TRAINING: GETTING STARTED",
47 | text: "Take the first step in your personal fitness journey with essential tips for beginners.",
48 | },
49 | {
50 | id: 6,
51 | img: blog3,
52 | alt: "Man training like a professional athlete",
53 | month: "August",
54 | title: "TRAIN LIKE A CHAMPION ATHLETE",
55 | text: "Adopt the training routines of elite athletes and unlock your peak performance potential.",
56 | },
57 | ];
58 |
59 | export default blogData;
60 |
--------------------------------------------------------------------------------
/src/components/ShopContext/ShopContext.jsx:
--------------------------------------------------------------------------------
1 | import { createContext, useEffect, useState } from "react";
2 | import shopData from "../ShopContent/ShopData";
3 |
4 | export const CartContext = createContext(null);
5 |
6 | const getDefaultCart = () => {
7 | let cart = {};
8 | for (let i = 1; i < shopData.length + 1; i++) {
9 | cart[i] = 0;
10 | }
11 | return cart;
12 | };
13 |
14 | const getStoredCart = () => {
15 | const storedCart = localStorage.getItem("cart");
16 | return storedCart ? JSON.parse(storedCart) : getDefaultCart();
17 | };
18 |
19 | const ShopContext = (props) => {
20 | const [items, setItems] = useState(getStoredCart());
21 |
22 | useEffect(() => {
23 | localStorage.setItem("cart", JSON.stringify(items));
24 | }, [items]);
25 |
26 | const addToCart = (itemId) => {
27 | setItems((prev) => ({ ...prev, [itemId]: prev[itemId] + 1 }));
28 | };
29 |
30 | const removeFromCart = (itemId) => {
31 | setItems((prev) => ({ ...prev, [itemId]: prev[itemId] - 1 }));
32 | };
33 |
34 | const totalAmount = () => {
35 | let total = 0;
36 | for (const itemId in items) {
37 | if (items[itemId] > 0) {
38 | const totalInfo = shopData.find(
39 | (product) => product.id === Number(itemId)
40 | );
41 | total += items[itemId] * totalInfo.price;
42 | }
43 | }
44 | return total;
45 | };
46 |
47 | const totalCartItems = () => {
48 | let totalItem = 0;
49 | for (const itemId in items) {
50 | if (items[itemId] > 0) {
51 | totalItem += items[itemId];
52 | }
53 | }
54 | return totalItem;
55 | };
56 |
57 | const singleProductAmount = (itemId) => {
58 | const priceInfo = shopData.find((product) => product.id === Number(itemId));
59 | return priceInfo ? items[itemId] * priceInfo.price : 0;
60 | };
61 |
62 | const resetCart = () => {
63 | setItems(getDefaultCart());
64 | };
65 |
66 | const contextValue = {
67 | items,
68 | addToCart,
69 | removeFromCart,
70 | totalAmount,
71 | totalCartItems,
72 | singleProductAmount,
73 | resetCart,
74 | };
75 |
76 | return (
77 |
78 | {props.children}
79 |
80 | );
81 | };
82 |
83 | export default ShopContext;
84 |
--------------------------------------------------------------------------------
/src/components/BlogContent/BlogContent.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .blog {
4 | padding: 3em 0;
5 | background-color: aliceblue;
6 |
7 | &__heading {
8 | margin-bottom: 1.5em;
9 | padding: 0 0.5em;
10 | font-size: 4rem;
11 | font-style: italic;
12 | text-align: center;
13 | }
14 |
15 | &__body {
16 | display: flex;
17 | gap: 3em;
18 | justify-content: center;
19 | flex-wrap: wrap;
20 | }
21 |
22 | &__box {
23 | height: 100%;
24 | max-width: 350px;
25 | padding: 1em;
26 | overflow: hidden;
27 | box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.2);
28 | }
29 |
30 | &__overflow {
31 | margin-bottom: 0.5em;
32 | overflow: hidden;
33 | }
34 |
35 | &__img {
36 | height: 220px;
37 | width: 100%;
38 | object-fit: cover;
39 | }
40 |
41 | &__content {
42 | padding: 0 0.5em 1em;
43 | }
44 |
45 | &__icons {
46 | display: flex;
47 | gap: 0.9em;
48 | margin-bottom: 0.5em;
49 | padding: 1em 0;
50 | font-size: 1.5rem;
51 | font-weight: 500;
52 | color: $dark;
53 | }
54 |
55 | &__span {
56 | display: flex;
57 | align-items: center;
58 | gap: 0.3em;
59 | }
60 |
61 | &__icon {
62 | color: $main;
63 | }
64 |
65 | &__line {
66 | height: 1px;
67 | margin: 0.5em;
68 | border: none;
69 | background-color: rgb(233, 232, 232);
70 | }
71 |
72 | &__title {
73 | margin-bottom: 0.5em;
74 | font-size: 2rem;
75 | color: $dark;
76 | }
77 |
78 | &__text {
79 | margin-bottom: 2em;
80 | color: rgb(85, 85, 85);
81 | }
82 |
83 | &__link {
84 | padding: 0.8em 1.8em;
85 | color: $white;
86 | background-color: $main;
87 | border-radius: 5px;
88 | }
89 | }
90 |
91 | @media (min-width: 768px) {
92 | .blog {
93 | padding: 5em 0;
94 |
95 | &__heading {
96 | margin-bottom: 2em;
97 | font-size: 5rem;
98 | }
99 |
100 | &__img {
101 | transition: transform 0.2s linear;
102 | }
103 |
104 | &__box {
105 | &:hover .blog__img {
106 | transform: scale(1.02);
107 | }
108 | }
109 |
110 | &__link {
111 | transition: background-color 0.3s ease;
112 |
113 | &:hover {
114 | background-color: $dark;
115 | }
116 | }
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/components/Team/Team.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .team {
4 | padding: 3em 0;
5 |
6 | &__title {
7 | font-size: 4rem;
8 | text-align: center;
9 | font-style: italic;
10 | }
11 |
12 | &__body {
13 | @include flexCenter(column);
14 | gap: 2em;
15 | padding: 3.5em 0;
16 | }
17 |
18 | &__card {
19 | position: relative;
20 | height: 450px;
21 | width: 100%;
22 | max-width: 450px;
23 | overflow: hidden;
24 | }
25 |
26 | &__img {
27 | height: 100%;
28 | width: 100%;
29 | overflow: hidden;
30 | object-fit: cover;
31 | border-radius: 3px;
32 | transition: 0.5s;
33 | }
34 |
35 | &__text {
36 | @include flexCenter(column);
37 | position: absolute;
38 | height: 70px;
39 | width: 100%;
40 | bottom: 0;
41 | background: rgba(0, 0, 0, 0.8);
42 | }
43 |
44 | &__name {
45 | margin-bottom: 0.2em;
46 | font-size: 2rem;
47 | font-weight: 500;
48 | color: $white;
49 | }
50 |
51 | &__icons {
52 | display: flex;
53 | gap: 0.3em;
54 | }
55 |
56 | &__icon {
57 | color: $white;
58 | }
59 | }
60 |
61 | @media (min-width: 768px) {
62 | .team {
63 | padding: 5em 0;
64 |
65 | &__title {
66 | font-size: 6rem;
67 | }
68 |
69 | &__body {
70 | display: flex;
71 | flex-direction: row;
72 | }
73 |
74 | &__card {
75 | height: 400px;
76 | }
77 |
78 | &__text {
79 | padding-top: 1em;
80 | transition: 0.5s;
81 | }
82 |
83 | &__name {
84 | margin-bottom: 0;
85 | }
86 |
87 | &__card:hover &__text {
88 | height: 100%;
89 | }
90 |
91 | &__card:hover &__icons {
92 | opacity: 1;
93 | }
94 |
95 | &__card:hover &__img {
96 | transform: scale(1.1);
97 | }
98 |
99 | &__icons {
100 | @include flexCenter(row);
101 | gap: 0.7em;
102 | margin-top: 0.3em;
103 | opacity: 0;
104 | font-size: 1.8rem;
105 | transition: 0.3s;
106 | }
107 |
108 | &__icon {
109 | transition: color 0.3s ease;
110 | &:hover {
111 | cursor: pointer;
112 | color: $main;
113 | }
114 | }
115 | }
116 | }
117 |
118 | @media (min-width: 996px) {
119 | .team {
120 | &__card {
121 | height: 450px;
122 | }
123 | }
124 | }
125 |
--------------------------------------------------------------------------------
/src/components/Testimonials/TestimonialsData.js:
--------------------------------------------------------------------------------
1 | import client1 from "../../assets/client1.webp";
2 | import client2 from "../../assets/client2.webp";
3 | import client3 from "../../assets/client3.webp";
4 | import client4 from "../../assets/client4.webp";
5 | import client5 from "../../assets/client5.webp";
6 | import client6 from "../../assets/client6.webp";
7 |
8 | const testimonialsData = [
9 | {
10 | id: 1,
11 | img: client4,
12 | alt: "Motivated man working out at the gym.",
13 | name: "James Anderson",
14 | review:
15 | "The atmosphere in this gym is unmatched. Skilled trainers, high-quality equipment, and a welcoming community have helped me exceed my fitness goals.",
16 | },
17 | {
18 | id: 2,
19 | img: client1,
20 | alt: "Motivated woman working out at the gym.",
21 | name: "Sophia Martinez",
22 | review:
23 | "Joining this gym has been life-changing. The trainers are incredibly supportive, and the environment is perfect for achieving results.",
24 | },
25 | {
26 | id: 3,
27 | img: client5,
28 | alt: "Focused man working out at the gym.",
29 | name: "Liam Scott",
30 | review:
31 | "This gym provides a transformative experience. With tailored guidance and a motivational setting, I've reached milestones I never thought possible.",
32 | },
33 | {
34 | id: 4,
35 | img: client3,
36 | alt: "Focused woman working out at the gym.",
37 | name: "Olivia Wilson",
38 | review:
39 | "The dedication of the team here is unparalleled. The community and expertise have helped me become stronger both mentally and physically.",
40 | },
41 | {
42 | id: 5,
43 | img: client2,
44 | alt: "Determined woman working out at the gym.",
45 | name: "Ava Thompson",
46 | review:
47 | "This is more than a gym; it's a place where determination and support come together. I’ve found the motivation and tools to thrive in my fitness journey.",
48 | },
49 | {
50 | id: 6,
51 | img: client6,
52 | alt: "Determined man working out at the gym.",
53 | name: "Noah Brown",
54 | review:
55 | "This gym has exceeded my expectations. The staff’s guidance and the supportive atmosphere have made every workout an enjoyable challenge.",
56 | },
57 | ];
58 |
59 | export default testimonialsData;
60 |
--------------------------------------------------------------------------------
/src/components/Footer/Footer.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .footer {
4 | display: flex;
5 | padding: 3em 0.5em 1em;
6 | color: $white;
7 | background-color: $darker;
8 |
9 | &__content {
10 | @include flexCenter(column);
11 | gap: 3em;
12 | }
13 |
14 | &__box,
15 | &__links {
16 | flex: 1;
17 | display: flex;
18 | flex-direction: column;
19 | align-items: center;
20 | gap: 0.5em;
21 | max-width: 300px;
22 | }
23 |
24 | &__logo {
25 | @include flexCenter(row);
26 | gap: 0.2em;
27 | color: $white;
28 | font-size: 2.5rem;
29 | font-family: "Montserrat", sans-serif;
30 | }
31 |
32 | &__desc {
33 | font-size: 1.4rem;
34 | text-align: center;
35 | }
36 |
37 | &__title {
38 | color: $main;
39 | font-size: 2rem;
40 | }
41 |
42 | &__link {
43 | color: $white;
44 | }
45 |
46 | &__contact {
47 | display: flex;
48 | gap: 0.3em;
49 | }
50 |
51 | &__line {
52 | height: 2px;
53 | margin: 2em 0 1em;
54 | border: none;
55 | background-color: rgba(56, 56, 56, 0.315);
56 | }
57 |
58 | &__date {
59 | @include flexCenter(column);
60 | gap: 1em;
61 | padding: 1em 0.5em;
62 | text-align: center;
63 | }
64 |
65 | &__logo-name {
66 | color: $main;
67 | font-weight: 500;
68 | }
69 |
70 | &__icons {
71 | display: flex;
72 | gap: 0.5em;
73 | }
74 |
75 | &__icon-bg {
76 | @include flexCenter(row);
77 | padding: 5px;
78 | background-color: $white;
79 | border-radius: 50%;
80 | }
81 |
82 | &__icon {
83 | color: $main;
84 | }
85 | }
86 |
87 | @media (min-width: 768px) {
88 | .footer {
89 | &__content {
90 | flex-direction: row;
91 | gap: 4em;
92 | align-items: start;
93 | }
94 |
95 | &__logo {
96 | font-size: 3rem;
97 | }
98 |
99 | &__box,
100 | &__links,
101 | &__desc {
102 | align-items: start;
103 | }
104 |
105 | &__desc {
106 | text-align: start;
107 | }
108 |
109 | &__link {
110 | transition: color 0.3s ease;
111 |
112 | &:hover {
113 | color: $main;
114 | }
115 | }
116 |
117 | &__icon-bg {
118 | transition: background-color 0.3s ease;
119 |
120 | &:hover {
121 | background-color: inherit;
122 | cursor: pointer;
123 | }
124 | }
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/components/Pricing/Pricing.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .pricing {
4 | padding: 4em 0 8em;
5 |
6 | &__title {
7 | margin-bottom: 1em;
8 | padding: 0.5em;
9 | text-align: center;
10 | font-size: 4rem;
11 | font-style: italic;
12 | }
13 |
14 | &__container {
15 | @include flexCenter(column);
16 | gap: 2em;
17 | padding: 0 0.5em;
18 | }
19 |
20 | &__box {
21 | position: relative;
22 | width: 300px;
23 | padding: 2em;
24 | background-color: #222222;
25 | color: $white;
26 | overflow: hidden;
27 | }
28 |
29 | &__best-offer {
30 | position: absolute;
31 | background-color: $main;
32 | top: 10px;
33 | right: -70px;
34 | width: 200px;
35 | text-align: center;
36 | padding: 0.4em;
37 | font-size: 1.4rem;
38 | transform: rotate(35deg); // Adjust the angle as needed
39 | // transform-origin: bottom right; // Set the origin to the bottom right corner
40 | }
41 |
42 | &__box-title {
43 | margin-bottom: 0.5em;
44 | font-weight: 500;
45 | font-size: 3rem;
46 | }
47 |
48 | &__price {
49 | color: $main;
50 | font-size: 5rem;
51 | font-weight: 600;
52 | }
53 |
54 | &__month {
55 | color: $white;
56 | font-size: 1.4rem;
57 | font-weight: normal;
58 | }
59 |
60 | &__line {
61 | height: 1px;
62 | margin: 1em 0;
63 | border: none;
64 | background-color: rgb(59, 59, 59);
65 | }
66 |
67 | &__item {
68 | display: flex;
69 | align-items: center;
70 | gap: 0.5em;
71 | margin-bottom: 1em;
72 | &:last-of-type {
73 | margin-bottom: 2em;
74 | }
75 | }
76 |
77 | &__icon {
78 | font-size: 1.8rem;
79 | &--close {
80 | color: red;
81 | }
82 | }
83 |
84 | &__link {
85 | display: flex;
86 | align-items: center;
87 | gap: 0.3em;
88 | width: fit-content;
89 | padding: 0.8em 1.8em;
90 | background-color: $main;
91 | font-size: 1.4rem;
92 | color: $white;
93 | font-weight: 600;
94 | }
95 | }
96 |
97 | @media (min-width: 768px) {
98 | .pricing {
99 | &__link {
100 | transition: background-color 0.3s ease, color 0.3s ease;
101 |
102 | &:hover {
103 | background-color: $white;
104 | color: $main;
105 | }
106 | }
107 |
108 | &__box {
109 | width: 350px;
110 | transition: background-color 0.3s ease;
111 |
112 | &:hover {
113 | background-color: $dark;
114 | }
115 | }
116 | }
117 | }
118 |
119 | @media (min-width: 996px) {
120 | .pricing {
121 | &__container {
122 | flex-direction: row;
123 | }
124 |
125 | &__title {
126 | font-size: 6rem;
127 | }
128 | }
129 | }
130 |
--------------------------------------------------------------------------------
/src/components/ShopContent/ShopContent.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .shop {
4 | @include flexCenter(column);
5 | padding: 5em 1em;
6 |
7 | &__title {
8 | margin-bottom: 1em;
9 | font-size: 3rem;
10 | text-align: center;
11 | }
12 |
13 | &__buttons {
14 | @include flexCenter(row);
15 | flex-wrap: wrap;
16 | gap: 0.5em;
17 | margin-bottom: 4em;
18 | }
19 |
20 | &__buttons > *,
21 | &__btn,
22 | &__navigate {
23 | padding: 0.5em 1em;
24 | border-radius: 12px;
25 | background-color: $dark;
26 | color: $white;
27 | }
28 |
29 | &__navigate {
30 | margin-top: 4em;
31 | background-color: $main;
32 | font-size: inherit;
33 | }
34 |
35 | &__products {
36 | @include flexCenter(row);
37 | flex-wrap: wrap;
38 | gap: 3em;
39 | }
40 |
41 | &__product {
42 | @include flexCenter(column);
43 | position: relative;
44 | padding: 1.5em;
45 | box-shadow: 0 0 9px rgba(0, 0, 0, 0.185);
46 | }
47 |
48 | &__label {
49 | position: absolute;
50 | left: 0;
51 | top: 0;
52 | padding: 0.3em 0.6em;
53 | background-color: $main;
54 | color: $white;
55 | font-size: 1.4rem;
56 | }
57 |
58 | &__img {
59 | max-width: 250px;
60 | width: 100%;
61 | margin-bottom: 1em;
62 | object-fit: cover;
63 | }
64 |
65 | &__content {
66 | @include flexCenter(column);
67 | gap: 0.5em;
68 | }
69 |
70 | &__name {
71 | text-align: center;
72 | font-weight: 500;
73 | }
74 |
75 | &__price {
76 | font-weight: 500;
77 | margin-bottom: 0.5em;
78 | }
79 |
80 | &__active {
81 | background-color: $main;
82 | }
83 | }
84 |
85 | @media (min-width: 600px) {
86 | .shop {
87 | &__title {
88 | font-size: 4rem;
89 | }
90 |
91 | &__buttons > *,
92 | &__btn,
93 | &__navigate {
94 | padding: 0.8em 1.6em;
95 | }
96 | }
97 | }
98 |
99 | @media (min-width: 768px) {
100 | .shop {
101 | &__title {
102 | font-size: 5rem;
103 | }
104 |
105 | &__buttons {
106 | gap: 1em;
107 | }
108 |
109 | &__buttons > *,
110 | &__btn,
111 | &__navigate {
112 | transition: background-color 0.3s ease;
113 | }
114 |
115 | &__buttons > *:hover,
116 | &__btn:hover {
117 | background-color: $main;
118 | }
119 |
120 | &__navigate {
121 | &:hover {
122 | background-color: $dark;
123 | }
124 | }
125 |
126 | &__img {
127 | height: 250px;
128 | transition: transform 0.3s ease;
129 | }
130 |
131 | &__product {
132 | &:hover .shop__img {
133 | transform: scale(1.03);
134 | }
135 | }
136 |
137 | &__name {
138 | font-size: 1.8rem;
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/components/Navbar/Navbar.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .navbar {
4 | position: fixed;
5 | width: 100%;
6 | height: 8vh;
7 | z-index: 10;
8 | color: $white;
9 | transition: background-color 0.3s ease;
10 | background-color: #0a0a0a;
11 |
12 | &__container {
13 | display: flex;
14 | justify-content: space-between;
15 | align-items: center;
16 | height: 100%;
17 | padding: 0 0.5em;
18 | }
19 |
20 | &__logo {
21 | font-size: 2.5rem;
22 | color: $white;
23 | font-family: "Montserrat", sans-serif;
24 | }
25 |
26 | &__links {
27 | @include flexCenter(column);
28 | gap: 1em;
29 | position: absolute;
30 | top: 8vh;
31 | left: 0;
32 | height: 45vh;
33 | width: 100%;
34 | left: -100%;
35 | background-color: #111;
36 | transition: 0.3s ease;
37 | z-index: 10;
38 | }
39 |
40 | &__link,
41 | &__cart-link {
42 | padding: 0.4em;
43 | color: $white;
44 | }
45 |
46 | &__link {
47 | &.active {
48 | color: $main;
49 | font-weight: 500;
50 | }
51 | }
52 |
53 | &__cart-link {
54 | &.active {
55 | color: unset;
56 | }
57 | }
58 |
59 | &__cart {
60 | position: relative;
61 | }
62 |
63 | &__quantity {
64 | @include flexCenter(row);
65 | position: absolute;
66 | width: 20px;
67 | height: 20px;
68 | top: -10px;
69 | left: 6px;
70 | border-radius: 50%;
71 | font-size: 1.2rem;
72 | background-color: rgb(202, 10, 10);
73 | }
74 |
75 | &__basket {
76 | font-size: 2.4rem;
77 | }
78 |
79 | &__links-active {
80 | left: 0;
81 | }
82 |
83 | &__hamburger {
84 | padding: 0.3em;
85 | }
86 | }
87 |
88 | @media (min-width: 768px) {
89 | .navbar {
90 | background-color: unset;
91 |
92 | &__bgc {
93 | background-color: $darker;
94 | }
95 |
96 | &__logo {
97 | font-size: 3.2rem;
98 | }
99 |
100 | &__links {
101 | flex-direction: row;
102 | gap: 1em;
103 | position: relative;
104 | top: 0;
105 | left: unset;
106 | height: unset;
107 | width: unset;
108 | background-color: inherit;
109 | transform: translateX(0);
110 | }
111 |
112 | &__link {
113 | transition: color 0.3s ease;
114 |
115 | &:hover {
116 | color: $main;
117 | }
118 | }
119 |
120 | &__hamburger {
121 | display: none;
122 | }
123 | }
124 | }
125 |
126 | @media (min-width: 1024px) {
127 | .navbar {
128 | &__logo {
129 | font-size: 3.5rem;
130 | }
131 | }
132 | }
133 |
--------------------------------------------------------------------------------
/src/components/MainBackground/MainBackground.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .mainBackground {
4 | position: relative;
5 | height: 100vh;
6 | width: 100%;
7 | display: flex;
8 | overflow: hidden;
9 |
10 | :hover &__arrow {
11 | opacity: 1;
12 | }
13 |
14 | &__arrow {
15 | display: none;
16 | align-items: center;
17 | justify-content: center;
18 | position: absolute;
19 | top: 0;
20 | bottom: 0;
21 | width: 40px;
22 | height: 40px;
23 | background-color: #ffffff15;
24 | border-radius: 50%;
25 | margin: auto;
26 | opacity: 0;
27 | z-index: 2;
28 | cursor: pointer;
29 | transition: opacity 0.3s ease;
30 | }
31 |
32 | &__arrows {
33 | font-size: 20px;
34 | color: $white;
35 | }
36 |
37 | &__arrow-right {
38 | position: absolute;
39 | right: 0px;
40 | }
41 |
42 | &__container {
43 | display: flex;
44 | height: 100%;
45 | }
46 |
47 | &__slider {
48 | width: 100vw;
49 | height: 100vh;
50 | transition: all 1s ease;
51 | }
52 |
53 | &__img {
54 | position: relative;
55 | }
56 |
57 | &__img::before {
58 | content: "";
59 | position: absolute;
60 | top: 0;
61 | left: 0;
62 | width: 100%;
63 | height: 100%;
64 | background: rgba(0, 0, 0, 0.7);
65 | }
66 |
67 | &__image {
68 | width: 100%;
69 | height: 100vh;
70 | object-fit: cover;
71 | object-position: top;
72 | }
73 |
74 | &__content {
75 | @include flexCenter(column);
76 | gap: 1em;
77 | position: absolute;
78 | top: 50%;
79 | left: 50%;
80 | width: 100%;
81 | max-width: 600px;
82 | transform: translate(-50%, -50%);
83 | color: $white;
84 | }
85 |
86 | &__title {
87 | font-size: 5rem;
88 | padding: 0 0.5em;
89 | text-align: center;
90 | font-style: italic;
91 | margin-bottom: 0.5em;
92 | }
93 |
94 | &__text {
95 | display: none;
96 | margin-bottom: 1.5em;
97 | text-align: center;
98 | }
99 |
100 | &__link {
101 | padding: 0.8em 2.4em;
102 | background-color: $main;
103 | color: $white;
104 | border-radius: 8px;
105 | text-transform: uppercase;
106 | }
107 | }
108 |
109 | @media (min-width: 768px) {
110 | .mainBackground {
111 | &__arrow {
112 | display: flex;
113 | transition: background-color 0.3s ease;
114 |
115 | &:hover {
116 | background-color: $main;
117 | }
118 | }
119 |
120 | &__title {
121 | font-size: 6rem;
122 | margin-bottom: unset;
123 | }
124 |
125 | &__text {
126 | display: block;
127 | font-size: 2rem;
128 | }
129 |
130 | &__link {
131 | border: 1px solid transparent;
132 | transition: border 0.3s, background-color 0.3s;
133 |
134 | &:hover {
135 | background-color: #e4e3e117;
136 | border: 1px solid white;
137 | }
138 | }
139 | }
140 | }
141 |
142 | @media (min-width: 1024px) {
143 | .mainBackground {
144 | &__title {
145 | font-size: 9rem;
146 | }
147 |
148 | &__content {
149 | max-width: 800px;
150 | }
151 |
152 | &__text {
153 | display: block;
154 | font-size: 2.2rem;
155 | }
156 | }
157 | }
158 |
--------------------------------------------------------------------------------
/src/components/ContactContent/ContactContent.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .contact {
4 | padding: 6em 0;
5 | background-color: aliceblue;
6 |
7 | &__boxes {
8 | @include flexCenter(column);
9 | gap: 4em;
10 | margin-bottom: 6em;
11 | }
12 |
13 | &__box {
14 | @include flexCenter(column);
15 | gap: 0.5em;
16 | width: 250px;
17 | height: 250px;
18 | padding: 2em;
19 | box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.2);
20 | background-color: rgb(255, 255, 255);
21 | border-bottom: 4px solid $main;
22 | }
23 |
24 | &__link {
25 | @include flexCenter(column);
26 | color: $dark;
27 | }
28 |
29 | &__icon {
30 | font-size: 4rem;
31 | }
32 |
33 | &__box-title {
34 | margin-bottom: 0.2em;
35 | }
36 |
37 | &__wrapper {
38 | @include flexCenter(column);
39 | gap: 2em;
40 | box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.2);
41 | }
42 |
43 | &__img {
44 | width: 500px;
45 | max-height: 600px;
46 | object-fit: cover;
47 | }
48 |
49 | &__info {
50 | display: flex;
51 | flex-direction: column;
52 | gap: 1em;
53 | height: auto;
54 | max-width: 600px;
55 | padding: 0 1em 1.5em;
56 | }
57 |
58 | &__form {
59 | display: flex;
60 | flex-direction: column;
61 | gap: 1em;
62 | }
63 |
64 | &__title {
65 | font-size: 3rem;
66 | text-transform: capitalize;
67 | }
68 |
69 | &__text {
70 | color: rgb(26, 26, 26);
71 | }
72 |
73 | &__input {
74 | width: 100%;
75 | padding: 1em;
76 | outline: none;
77 | border: 1px solid rgb(134, 134, 134);
78 | }
79 |
80 | &__error {
81 | display: block;
82 | height: 0.8em;
83 | padding: 0.1em 0;
84 | margin-left: 0.1em;
85 | font-size: 1.4rem;
86 | color: rgb(177, 14, 14);
87 |
88 | &-line {
89 | line-height: 0.8;
90 | }
91 | }
92 |
93 | &__area {
94 | width: 100%;
95 | padding: 1em;
96 | min-height: 130px;
97 | max-height: 170px;
98 | resize: vertical;
99 | outline: none;
100 | }
101 |
102 | &__sent {
103 | color: rgb(11, 151, 11);
104 | }
105 |
106 | &__btn {
107 | padding: 0.8em 1.8em;
108 | width: fit-content;
109 | background-color: $main;
110 | color: $white;
111 | }
112 | }
113 |
114 | @media (min-width: 500px) {
115 | .contact {
116 | &__info {
117 | padding-bottom: 2em;
118 | }
119 | }
120 | }
121 |
122 | @media (min-width: 1024px) {
123 | .contact {
124 | flex-direction: row;
125 |
126 | &__boxes {
127 | flex-direction: row;
128 | }
129 |
130 | &__box {
131 | transition: background-color 0.3s ease;
132 |
133 | &:hover {
134 | background-color: $main;
135 | }
136 | }
137 |
138 | &__link {
139 | transition: color 0.3s ease;
140 |
141 | &:hover {
142 | color: $white;
143 | }
144 | }
145 |
146 | &__wrapper {
147 | flex-direction: row;
148 | }
149 |
150 | &__info {
151 | height: 650px;
152 | padding: 2em;
153 | }
154 |
155 | &__btn {
156 | transition: background-color 0.3s ease;
157 | margin-top: 0.5em;
158 |
159 | &:hover {
160 | background-color: $dark;
161 | }
162 | }
163 | }
164 | }
165 |
--------------------------------------------------------------------------------
/src/components/Navbar/Navbar.jsx:
--------------------------------------------------------------------------------
1 | import "./Navbar.scss";
2 | import { Link, NavLink } from "react-router-dom";
3 | import { useEffect, useState, useContext } from "react";
4 | import { GiHamburgerMenu } from "react-icons/gi";
5 | import { AiOutlineClose } from "react-icons/ai";
6 | import { FaShoppingCart } from "react-icons/fa";
7 | import { CartContext } from "../ShopContext/ShopContext";
8 |
9 | const Navbar = () => {
10 | const { totalCartItems } = useContext(CartContext);
11 | const [isOpen, setIsOpen] = useState(false);
12 |
13 | const handleClick = () => {
14 | setIsOpen(!isOpen);
15 | };
16 |
17 | const closeNav = () => {
18 | setIsOpen(false);
19 | };
20 |
21 | const [navBgc, setNavBgc] = useState(false);
22 |
23 | useEffect(() => {
24 | const changeBgc = () => {
25 | setNavBgc(window.scrollY > 10);
26 | };
27 | window.addEventListener("scroll", changeBgc);
28 |
29 | return () => {
30 | window.removeEventListener("scroll", changeBgc);
31 | };
32 | }, []);
33 |
34 | return (
35 |
36 |
37 |
38 |
FitnessGym
39 |
40 |
44 |
45 |
46 | HOME
47 |
48 |
49 |
50 |
51 | ABOUT
52 |
53 |
54 |
55 |
56 | SHOP
57 |
58 |
59 |
60 |
61 | FAQ
62 |
63 |
64 |
65 |
66 | BLOG
67 |
68 |
69 |
70 |
71 | CONTACT
72 |
73 |
74 |
75 |
79 |
80 | {totalCartItems()}
81 |
82 |
83 |
84 |
85 |
86 |
89 |
90 |
91 | );
92 | };
93 |
94 | export default Navbar;
95 |
--------------------------------------------------------------------------------
/src/components/ContactContent/ContactForm.jsx:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import { Formik, Form, ErrorMessage, Field } from "formik";
3 | import * as Yup from "yup";
4 | import contact from "../../assets/contact.webp";
5 |
6 | const ContactForm = () => {
7 | const [formSubmitted, setFormSubmitted] = useState(false);
8 |
9 | const initialValues = {
10 | name: "",
11 | email: "",
12 | subject: "",
13 | textarea: "",
14 | };
15 |
16 | const validationSchema = Yup.object({
17 | name: Yup.string().required("Name is required").max(20),
18 | email: Yup.string()
19 | .required("Email is required")
20 | .email("Invalid email address"),
21 | subject: Yup.string()
22 | .required("Subject is required")
23 | .min(5, "Subject must be at least 5 characters"),
24 | textarea: Yup.string()
25 | .required("Message is required")
26 | .min(15, "Textarea must be at least 15 characters"),
27 | });
28 |
29 | const handleSubmit = (_, { resetForm }) => {
30 | setFormSubmitted(true);
31 | resetForm();
32 |
33 | setTimeout(() => {
34 | setFormSubmitted(false);
35 | }, 2000);
36 | };
37 |
38 | return (
39 | <>
40 |
45 |
46 |
get in touch
47 |
48 | Get in touch with us! We're ready to assist and chat about your
49 | questions and needs.
50 |
51 |
56 |
118 |
119 |
120 | >
121 | );
122 | };
123 |
124 | export default ContactForm;
125 |
--------------------------------------------------------------------------------
/src/components/CartContent/CartContent.scss:
--------------------------------------------------------------------------------
1 | @import "../../global.scss";
2 |
3 | .cart {
4 | padding: 6em 0;
5 |
6 | &__table {
7 | width: 100%;
8 | margin-bottom: 3em;
9 | border-collapse: collapse;
10 | }
11 |
12 | &__thead {
13 | box-shadow: 0 0 6px rgba(0, 0, 0, 0.185);
14 | }
15 |
16 | &__row > * {
17 | padding: 0.3em;
18 | font-size: 1.2rem;
19 | }
20 |
21 | &__tr > * {
22 | padding: 0.3em;
23 | font-size: 1.2rem;
24 | border-bottom: 1px solid #ddd;
25 | }
26 |
27 | .cart__img {
28 | width: 50px;
29 | object-fit: cover;
30 | }
31 |
32 | &__action-btn {
33 | padding: 0.15em;
34 | background-color: #4caf50;
35 | border-radius: 3px;
36 | }
37 |
38 | &__action-icon {
39 | @include flexCenter(row);
40 | font-size: 1rem;
41 | color: $white;
42 | }
43 |
44 | &__action-quantity {
45 | margin: 0 0.5em;
46 | font-weight: bold;
47 | }
48 |
49 | &__total {
50 | font-weight: bold;
51 | color: $main;
52 | }
53 |
54 | &__info {
55 | padding: 2em;
56 | max-width: 500px;
57 | box-shadow: 0 0 6px rgba(0, 0, 0, 0.24);
58 | }
59 |
60 | &__info-title {
61 | margin-bottom: 1em;
62 | text-align: center;
63 | font-size: 2rem;
64 | }
65 |
66 | &__total-amount {
67 | margin-bottom: 1em;
68 | font-size: 1.6rem;
69 | border-bottom: 1px solid rgba(0, 0, 0, 0.144);
70 | }
71 |
72 | &__buttons {
73 | display: flex;
74 | gap: 1em;
75 | }
76 |
77 | &__btn {
78 | margin-top: 1.5em;
79 | padding: 0.8em 1.4em;
80 | border-radius: 12px;
81 | background-color: $dark;
82 | color: $white;
83 | }
84 |
85 | &__empty {
86 | @include flexCenter(column);
87 | gap: 2em;
88 | padding: 4em;
89 | }
90 |
91 | &__empty-title {
92 | font-size: 5rem;
93 | }
94 |
95 | &__empty-btn {
96 | padding: 0.9em 1.8em;
97 | background-color: $dark;
98 | color: $white;
99 | border-radius: 12px;
100 | font-size: inherit;
101 | }
102 |
103 | &__modal-overlay {
104 | position: fixed;
105 | top: 0;
106 | left: 0;
107 | width: 100%;
108 | height: 100%;
109 | background: rgba(0, 0, 0, 0.5);
110 | display: flex;
111 | justify-content: center;
112 | align-items: center;
113 | }
114 |
115 | &__modal {
116 | @include flexCenter(column);
117 | gap: 1em;
118 | width: 90%;
119 | max-width: 550px;
120 | padding: 5em;
121 | background-color: $dark;
122 | color: $white;
123 | border-radius: 5px;
124 | box-shadow: 0 0 7px rgba(0, 0, 0, 0.3);
125 | }
126 |
127 | &__modal-title {
128 | font-size: 3.5rem;
129 | text-align: center;
130 | }
131 |
132 | &__modal-text {
133 | text-align: center;
134 | }
135 |
136 | &__modal-btn {
137 | padding: 0.8em 2.4em;
138 | background: $main;
139 | color: $white;
140 | border-radius: 5px;
141 | border: 1px solid $dark;
142 | }
143 | }
144 |
145 | @media (min-width: 520px) {
146 | .cart {
147 | &__row > * {
148 | padding: 1em;
149 | font-size: 1.4rem;
150 | text-align: left;
151 | }
152 |
153 | &__tr > * {
154 | padding: 0.8em;
155 | font-size: 1.4rem;
156 | }
157 |
158 | .cart__img {
159 | width: 70px;
160 | }
161 |
162 | &__info-title {
163 | font-size: 2.5rem;
164 | }
165 |
166 | &__action-btn {
167 | padding: 0.3em;
168 | }
169 | }
170 | }
171 |
172 | @media (min-width: 760px) {
173 | .cart {
174 | &__btn {
175 | padding: 0.8em 1.6em;
176 | transition: background-color 0.3s ease;
177 | font-size: inherit;
178 |
179 | &:hover {
180 | background-color: $main;
181 | }
182 | }
183 |
184 | &__action-btn {
185 | padding: 0.4em;
186 | }
187 |
188 | &__info-title {
189 | font-size: 3rem;
190 | }
191 |
192 | &__total-amount {
193 | font-size: 2rem;
194 | }
195 |
196 | &__empty-btn {
197 | transition: background-color 0.3s ease;
198 | }
199 |
200 | &__empty-btn:hover {
201 | background-color: $main;
202 | }
203 |
204 | &__modal-btn {
205 | transition: border 0.3s ease, background-color 0.3s ease;
206 |
207 | &:hover {
208 | border: 1px solid white;
209 | background-color: inherit;
210 | }
211 | }
212 | }
213 | }
214 |
--------------------------------------------------------------------------------
/src/components/ShopContent/ShopData.js:
--------------------------------------------------------------------------------
1 | import protein1 from "../../assets/protein1.png";
2 | import protein2 from "../../assets/protein2.png";
3 | import protein3 from "../../assets/protein3.png";
4 | import protein4 from "../../assets/protein4.png";
5 | import protein5 from "../../assets/protein5.png";
6 | import protein6 from "../../assets/protein6.png";
7 | import protein7 from "../../assets/protein7.png";
8 |
9 | import creatine1 from "../../assets/creatine1.png";
10 | import creatine2 from "../../assets/creatine2.png";
11 | import creatine3 from "../../assets/creatine3.png";
12 | import creatine4 from "../../assets/creatine4.png";
13 | import creatine5 from "../../assets/creatine5.png";
14 | import creatine6 from "../../assets/creatine6.png";
15 |
16 | import preworkout1 from "../../assets/preworkout1.png";
17 | import preworkout2 from "../../assets/preworkout2.png";
18 | import preworkout3 from "../../assets/preworkout3.png";
19 | import preworkout4 from "../../assets/preworkout4.png";
20 | import preworkout5 from "../../assets/preworkout5.png";
21 |
22 | const shopData = [
23 | {
24 | id: 1,
25 | img: protein1,
26 | name: "Advanced Whey Protein 750g",
27 | price: "23.99",
28 | category: "Protein",
29 | isNew: true,
30 | },
31 | {
32 | id: 2,
33 | img: protein2,
34 | name: "Protein Max 850g",
35 | price: "16.49",
36 | category: "Protein",
37 | isNew: true,
38 | },
39 | {
40 | id: 3,
41 | img: protein3,
42 | name: "Whey Pro Elite 2100g",
43 | price: "51.99",
44 | category: "Protein",
45 | },
46 | {
47 | id: 4,
48 | img: protein4,
49 | name: "PureIsolate Protein 550g",
50 | price: "9.99",
51 | category: "Protein",
52 | },
53 | {
54 | id: 5,
55 | img: protein5,
56 | name: "Deluxe Protein Blend 750g",
57 | price: "18.49",
58 | category: "Protein",
59 | },
60 | {
61 | id: 6,
62 | img: protein6,
63 | name: "NitroFuel Protein 1900g",
64 | price: "39.99",
65 | category: "Protein",
66 | },
67 | {
68 | id: 7,
69 | img: protein7,
70 | name: "OrganicWhey Protein 950g",
71 | price: "29.99",
72 | category: "Protein",
73 | },
74 | {
75 | id: 8,
76 | img: creatine1,
77 | name: "Platinum Micronized Creatine 450g",
78 | price: "10.99",
79 | category: "Creatine",
80 | isNew: true,
81 | },
82 | {
83 | id: 9,
84 | img: creatine2,
85 | name: "Ultra Creatine 350g",
86 | price: "7.99",
87 | category: "Creatine",
88 | isNew: true,
89 | },
90 | {
91 | id: 10,
92 | img: creatine3,
93 | name: "Explosive Creatine 550g",
94 | price: "15.99",
95 | category: "Creatine",
96 | },
97 | {
98 | id: 11,
99 | img: creatine4,
100 | name: "Swedish Pure Creatine 350g",
101 | price: "10.49",
102 | category: "Creatine",
103 | },
104 | {
105 | id: 12,
106 | img: creatine5,
107 | name: "CellFusion Creatine 2800g",
108 | price: "62.99",
109 | category: "Creatine",
110 | },
111 | {
112 | id: 13,
113 | img: creatine6,
114 | name: "MuscleBoost Creatine 450g",
115 | price: "14.99",
116 | category: "Creatine",
117 | },
118 | {
119 | id: 14,
120 | img: preworkout1,
121 | name: "Intensity Pre-Workout 300g",
122 | price: "15.99",
123 | category: "Pre-Workout",
124 | isNew: true,
125 | },
126 | {
127 | id: 15,
128 | img: preworkout2,
129 | name: "C4 Ultimate Pre-Workout 350g",
130 | price: "19.99",
131 | category: "Pre-Workout",
132 | isNew: true,
133 | },
134 | {
135 | id: 16,
136 | img: preworkout3,
137 | name: "Explosive Pre-Workout 600g",
138 | price: "16.99",
139 | category: "Pre-Workout",
140 | },
141 | {
142 | id: 17,
143 | img: preworkout4,
144 | name: "PumpMax Pre-Workout 320g",
145 | price: "18.79",
146 | category: "Pre-Workout",
147 | },
148 | {
149 | id: 18,
150 | img: preworkout5,
151 | name: "Extreme Assault Pre-Workout 420g",
152 | price: "22.99",
153 | category: "Pre-Workout",
154 | },
155 | ];
156 |
157 | export default shopData;
158 |
--------------------------------------------------------------------------------
/src/components/Footer/Footer.jsx:
--------------------------------------------------------------------------------
1 | import "./Footer.scss";
2 | import { Link } from "react-router-dom";
3 | import { AiFillPhone, AiFillMail } from "react-icons/ai";
4 | import {
5 | FaFacebookF,
6 | FaTwitter,
7 | FaInstagram,
8 | FaYoutube,
9 | FaLocationArrow,
10 | } from "react-icons/fa";
11 |
12 | const Footer = () => {
13 | return (
14 |
15 |
16 |
17 |
18 |
19 |
FitnessGym
20 |
21 |
22 | Join our gym to strengthen your body, improve fitness, and achieve
23 | your fitness goals. Get started today!
24 |
25 |
26 |
27 |
Useful Links
28 |
29 |
30 |
31 | About
32 |
33 |
34 |
35 |
36 | FAQ
37 |
38 |
39 |
40 |
41 | Blog
42 |
43 |
44 |
45 |
46 | Contact
47 |
48 |
49 |
50 |
51 |
52 |
Opening Hours
53 |
Mon To Fri
54 |
07:00 AM - 11:00 PM
55 |
Sat To Sun
56 |
09:00 AM - 10:00 PM
57 |
58 |
59 |
Contact
60 |
70 |
76 |
82 |
83 |
84 |
85 |
86 |
87 | © Copyright {new Date().getFullYear()}
88 | FitnessGym
89 | All Rights Reserved.
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 | );
109 | };
110 |
111 | export default Footer;
112 |
--------------------------------------------------------------------------------
/src/components/BlogContent/Article/ArticleData.js:
--------------------------------------------------------------------------------
1 | import blog1 from "../../../assets/blog1.webp";
2 | import blog2 from "../../../assets/blog2.webp";
3 | import blog3 from "../../../assets/blog3.webp";
4 | import blog4 from "../../../assets/blog4.webp";
5 | import blog5 from "../../../assets/blog5.webp";
6 | import blog6 from "../../../assets/blog6.webp";
7 |
8 | const articleData = [
9 | {
10 | id: 1,
11 | img: blog1,
12 | alt: "Man performing strength training at the gym",
13 | title: "MAXIMIZE YOUR GYM TIME EFFECTIVELY",
14 | text: "Making the most of your gym time is essential to achieving your fitness goals. Plan your sessions carefully, set clear objectives, and focus on exercises that align with your targets, whether it's building strength or improving endurance. Incorporate a proper warm-up and cooldown to avoid injuries and boost recovery. Stay consistent, eat a balanced diet, and prioritize rest for optimal results. Fitness success is built on daily effort and dedication.",
15 | highlight:
16 | "Success is a journey, not a destination—embrace every workout as a step forward.",
17 | text2:
18 | "Begin your fitness journey with clear objectives, proper planning, and tailored exercises. Remember to warm up and cool down to prevent injuries and enhance performance. Nutrition and recovery play a pivotal role in your progress, so don't overlook these factors. Stay patient, persistent, and celebrate small wins on your way to achieving your fitness aspirations.",
19 | },
20 | {
21 | id: 2,
22 | img: blog2,
23 | alt: "Woman focused during a workout",
24 | title: "ALL YOU NEED TO KNOW ABOUT FITNESS",
25 | text: "Understanding the fundamentals of fitness is the first step toward a healthier lifestyle. From workout routines to nutrition and wellness trends, this guide provides you with the knowledge needed to make informed decisions. Equip yourself with the tools to succeed and create a fitness journey that's tailored to your needs.",
26 | highlight:
27 | "Consistency and knowledge are the cornerstones of fitness success.",
28 | text2:
29 | "Explore the key aspects of fitness, including tailored workout plans and smart dietary choices. Stay informed about the latest trends and techniques to maximize your results. With consistency and dedication, you'll pave the way for a healthier, more active life.",
30 | },
31 | {
32 | id: 3,
33 | img: blog3,
34 | alt: "Woman lifting weights",
35 | title: "FITNESS: A PATH TO A SHARPER MIND",
36 | text: "Regular physical activity does wonders for your mental and emotional well-being. It reduces stress, enhances mood, and boosts cognitive functions. Discover how making fitness a part of your lifestyle can transform not just your body, but also your mind.",
37 | highlight: "Fitness is not just physical—it's mental and emotional too.",
38 | text2:
39 | "Incorporate regular workouts into your routine to benefit both your body and mind. Exercise releases endorphins that elevate your mood and sharpen cognitive abilities, helping you approach challenges with clarity and positivity.",
40 | },
41 | {
42 | id: 4,
43 | img: blog4,
44 | alt: "Man starting his fitness journey",
45 | title: "START YOUR FITNESS JOURNEY TODAY",
46 | text: "There’s no better time than today to take the first step toward a healthier you. Procrastination holds you back from reaping the benefits of fitness. Start small, stay consistent, and watch as your life transforms.",
47 | highlight:
48 | "Today is the perfect day to make fitness a priority—don't wait for tomorrow.",
49 | text2:
50 | "Delaying your fitness journey only postpones your progress. Begin today, and set the foundation for a healthier, more fulfilling future. Small steps lead to significant results.",
51 | },
52 | {
53 | id: 5,
54 | img: blog5,
55 | alt: "Woman performing bodyweight exercises",
56 | title: "PERSONAL TRAINING: WHERE TO BEGIN",
57 | text: "Starting your personal fitness journey can be daunting, but this guide simplifies the process. Learn how to set realistic goals, create effective workout plans, and build a foundation for long-term success.",
58 | highlight:
59 | "Your fitness journey begins with a single step in the direction of your goals.",
60 | text2:
61 | "Tailor your fitness plan to your needs and preferences. Understand the basics, focus on consistency, and prioritize your health. This is your guide to a sustainable and rewarding fitness journey.",
62 | },
63 | {
64 | id: 6,
65 | img: blog6,
66 | alt: "Man training like a pro athlete",
67 | title: "TRAIN LIKE A CHAMPION",
68 | text: "Discover the rigorous training, disciplined nutrition, and mental focus that define champions. Adopting these habits can elevate your fitness routine and help you achieve peak performance.",
69 | highlight: "To train like a champion, think like one first.",
70 | text2:
71 | "Understand the mindset and habits of elite athletes. Embrace disciplined training, balanced nutrition, and mental resilience to push your limits and achieve your goals.",
72 | },
73 | ];
74 |
75 | export default articleData;
76 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # FitnessGym-Website
2 |
3 | > 🚀 **Modern Fitness Website with React** - Build dynamic fitness platforms with interactive features and responsive design
4 |
5 | ## 📋 Description
6 |
7 | Welcome to the **FitnessGym-Website** repository! This project showcases a modern and fully responsive fitness website built with React, offering dynamic features such as a product shop, trainer profiles, gym services, and interactive schedules. The platform delivers an engaging experience for fitness enthusiasts with cutting-edge frontend technologies.
8 |
9 | This repository demonstrates best practices in React development, component-based architecture, and modern web design patterns for fitness and wellness platforms.
10 |
11 | ## 📁 Repository Structure
12 |
13 | ```
14 | FitnessGym-Website/
15 | ├── 📁 public/ # Static public files and assets
16 | ├── 📁 src/
17 | │ ├── 🖼️ assets/ # Images, media, and graphic resources
18 | │ ├── ⚛️ components/ # Reusable React components
19 | │ ├── 📄 pages/ # Main page components (Home, Shop, Trainers)
20 | │ ├── 🎨 styles/ # Global and modular SCSS styles
21 | │ └── 💻 App.js # Main application entry point
22 | ├── 📦 package.json # Project dependencies and metadata
23 | └── 📖 README.md # Project documentation
24 | ```
25 |
26 | ## 🚀 Getting Started
27 |
28 | ### 1. Clone the Repository
29 |
30 | ```bash
31 | git clone https://github.com/dawidolko/FitnessGym-Website.git
32 | cd FitnessGym-Website
33 | ```
34 |
35 | ### 2. Install Dependencies
36 |
37 | ```bash
38 | npm install
39 | ```
40 |
41 | ### 3. Start Development Server
42 |
43 | ```bash
44 | npm start
45 | ```
46 |
47 | - Open your browser and navigate to [http://localhost:3000](http://localhost:3000)
48 |
49 | ## ⚙️ System Requirements
50 |
51 | ### **Essential Tools:**
52 |
53 | - **Node.js** (version 14.0 or higher)
54 | - **npm** or **yarn** package manager
55 | - **Modern Web Browser** (Chrome, Firefox, Safari, Edge)
56 | - **Git** for version control
57 |
58 | ### **Development Environment:**
59 |
60 | - **Code Editor** (VS Code, WebStorm, Sublime Text)
61 | - **React Developer Tools** browser extension
62 | - **Node.js debugging tools**
63 |
64 | ### **Recommended Extensions:**
65 |
66 | - **ES6/React** syntax highlighting
67 | - **Sass/SCSS** support
68 | - **Prettier** for code formatting
69 | - **ESLint** for code quality
70 | - **Auto Rename Tag** for JSX editing
71 |
72 | ### **React Ecosystem:**
73 |
74 | - **React** (latest version)
75 | - **React DOM** for rendering
76 | - **React Scripts** for build configuration
77 | - **SCSS/SASS** for styling
78 |
79 | ## ✨ Key Features
80 |
81 | ### **🛒 Interactive Product Shop**
82 |
83 | - Browse fitness supplements: proteins, creatine, pre-workouts
84 | - Detailed product descriptions with pricing and high-quality images
85 | - Dynamic shopping cart functionality with add/remove capabilities
86 |
87 | ### **🏋️ Gym Services Section**
88 |
89 | - Comprehensive gym facilities and available classes
90 | - Interactive schedules and booking system
91 | - Trainer profiles showcasing specialties and certifications
92 |
93 | ### **📱 Responsive Design**
94 |
95 | - Flawless experience across mobile, tablet, and desktop devices
96 | - Modern React responsive patterns and CSS Grid/Flexbox
97 |
98 | ### **⚡ Dynamic Frontend**
99 |
100 | - Advanced search functionality and product category filtering
101 | - Interactive UI components with smooth animations
102 | - Real-time state management for cart and user interactions
103 |
104 | ### **🎨 Modular Architecture**
105 |
106 | - Component-based React structure for scalability
107 | - Clean, reusable SCSS/SASS styling system
108 | - Organized file structure following React best practices
109 |
110 | ## 🛠️ Technologies Used
111 |
112 | - **React** - Component-based frontend framework
113 | - **JavaScript (ES6+)** - Modern JavaScript features and logic
114 | - **SCSS/SASS** - Advanced CSS preprocessing and styling
115 | - **Git** - Version control and collaboration
116 | - **NPM** - Package management and dependency handling
117 |
118 | ## 🌍 Live Demo
119 |
120 | The project is deployed and available at: **[https://fitnessgym.dawidolko.pl](https://fitnessgym.dawidolko.pl)**
121 |
122 | ## 🖼️ Preview
123 |
124 | [ ](src/assets/fitnessgym.dawidolko.pl_.png)
125 |
126 | ## 🤝 Contributing
127 |
128 | Contributions are highly welcomed! Here's how you can help:
129 |
130 | - 🐛 **Report bugs** - Found an issue? Let us know!
131 | - 💡 **Suggest improvements** - Have ideas for better features?
132 | - 🔧 **Submit pull requests** - Share your enhancements and solutions
133 | - 📖 **Improve documentation** - Help make the project clearer
134 |
135 | Feel free to open issues or reach out through GitHub for any questions or suggestions.
136 |
137 | ## 👨💻 Author
138 |
139 | Created by **Dawid Olko** - Part of the **FitnessGym** project series.
140 |
141 | ## 📄 License
142 |
143 | This project is open source and available under the [MIT License](LICENSE).
144 |
145 | ---
146 |
147 | ⭐ **Found this helpful?** Give it a star and share with fellow React developers!
148 |
--------------------------------------------------------------------------------