Skip to content

satish-kumar75/Movix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

16 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation


Project Banner
react.js SASS redux toolkit vite

Movix

  1. ๐Ÿค– Introduction
  2. โš™๏ธ Tech Stack
  3. ๐Ÿ”‹ Features
  4. ๐Ÿคธ Quick Start
  5. ๐Ÿ•ธ๏ธ Snippets
  6. ๐Ÿ”— Links

I developed a stunning, fully responsive movie website using the TMDB API and React. It features a dynamic Home page for popular and trending movies, detailed movie pages with trailers and cast info, and an Explore section with infinite scrolling.

  • React.js
  • Redux Toolkit
  • Vite
  • SASS

๐Ÿ‘‰ Dynamic Home Page: Showcases popular and trending movies with lazy-loaded images and interactive carousels.

๐Ÿ‘‰ Detailed Movie Pages: Includes comprehensive information, cast details, trailers, and video clips using a React video player.

๐Ÿ‘‰ Cast Biographies and Filmographies: Users can explore detailed biographies and filmographies by clicking on cast images.

๐Ÿ‘‰ Explore Section: Allows users to discover movies and TV series with enhanced infinite scrolling using react-infinite-scroll-component.

๐Ÿ‘‰ Completely Responsive: Ensures consistent access and optimal viewing on any device with a fully responsive design.

๐Ÿ‘‰ Global State Management with Redux: Efficient state management across the entire application.

Follow these steps to set up the project locally on your machine.

Prerequisites

Make sure you have the following installed on your machine:

Cloning the Repository

git clone https://github.com/satish-kumar75/Movix.git
cd Movix

Installation

Install the project dependencies using npm:

npm install

Running the Project

npm run dev

Open http://localhost:5173 in your browser to view the project.

index.scss
:root {
  font-family: Inter, Avenir, Helvetica, Arial, sans-serif;
  font-size: 16px;
  line-height: 1;
  font-weight: 500;

  font-synthesis: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  -webkit-text-size-adjust: 100%;

  --black: #04152d;
  --black2: #041226;
  --black3: #020c1b;
  --black-lighter: #1c4b91;
  --black-light: #173d77;
  --pink: #da2f68;
  --orange: #f89e00;
  --gradient: linear-gradient(98.37deg, #f89e00 0.99%, #da2f68 100%);
}

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: var(--black);
}

::-webkit-scrollbar {
  display: none;
}

.skeleton {
  position: relative;
  overflow: hidden;
  background-color: #0a2955;
  &::after {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    transform: translateX(-100%);
    background-image: linear-gradient(
      90deg,
      rgba(#193763, 0) 0,
      rgba(#193763, 0.2) 20%,
      rgba(#193763, 0.5) 60%,
      rgba(#193763, 0)
    );
    animation: shimmer 2s infinite;
    content: "";
  }

  @keyframes shimmer {
    100% {
      transform: translateX(100%);
    }
  }
}
Img.jsx
import React from "react";
import { LazyLoadImage } from "react-lazy-load-image-component";
import "react-lazy-load-image-component/src/effects/blur.css";

const Img = ({ src, className }) => {
  return (
    <LazyLoadImage className={className || ""} alt="" effect="blur" src={src} />
  );
};

export default Img;
mixins.scss
@mixin sm {
  @media only screen and (min-width: 640px) {
    @content;
  }
}

@mixin md {
  @media only screen and (min-width: 768px) {
    @content;
  }
}

@mixin lg {
  @media only screen and (min-width: 1024px) {
    @content;
  }
}

@mixin xl {
  @media only screen and (min-width: 1280px) {
    @content;
  }
}

@mixin xxl {
  @media only screen and (min-width: 1536px) {
    @content;
  }
}

@mixin ellipsis($line: 2) {
  display: -webkit-box;
  -webkit-line-clamp: $line;
  -webkit-box-orient: vertical;
  overflow: hidden;
  text-overflow: ellipsis;
}
useFetch.jsx
import { useEffect, useState } from "react";
import { fetchDataFromApi } from "../utils/api";
const useFetch = (url) => {
  const [data, setData] = useState(null);
  const [loading, setLoading] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    setLoading("loading...");
    setData(null);
    setError(null);

    fetchDataFromApi(url)
      .then((res) => {
        setLoading(false);
        setData(res);
      })
      .catch((err) => {
        setLoading(false);
        setError("Something went wrong!");
      });
  }, [url]);

  return { data, loading, error };
};

export default useFetch;
package.json
"dependencies": {
    "@reduxjs/toolkit": "^1.9.1",
    "axios": "^1.2.2",
    "dayjs": "^1.11.7",
    "react": "^18.2.0",
    "react-circular-progressbar": "^2.1.0",
    "react-dom": "^18.2.0",
    "react-icons": "^4.7.1",
    "react-infinite-scroll-component": "^6.1.0",
    "react-lazy-load-image-component": "^1.5.6",
    "react-player": "^2.11.0",
    "react-redux": "^8.0.5",
    "react-router-dom": "^6.6.2",
    "react-select": "^5.7.0",
    "sass": "^1.57.1"
  }
PlayIcon.jsx
export const PlayIcon = () => {
  return (
    <svg
      version="1.1"
      xmlns="http://www.w3.org/2000/svg"
      xmlnsXlink="http://www.w3.org/1999/xlink"
      x="0px"
      y="0px"
      width="80px"
      height="80px"
      viewBox="0 0 213.7 213.7"
      enableBackground="new 0 0 213.7 213.7"
      xmlSpace="preserve"
    >
      <polygon
        className="triangle"
        fill="none"
        strokeWidth="7"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeMiterlimit="10"
        points="73.5,62.5 148.5,105.8 73.5,149.1 "
      ></polygon>
      <circle
        className="circle"
        fill="none"
        strokeWidth="7"
        strokeLinecap="round"
        strokeLinejoin="round"
        strokeMiterlimit="10"
        cx="106.8"
        cy="106.8"
        r="103.3"
      ></circle>
    </svg>
  );
};
Spinner.jsx
import React from "react";

import "./style.scss";

const Spinner = ({ initial }) => {
    return (
        <div className={`loadingSpinner ${initial ? "initial" : ""}`}>
            <svg className="spinner" viewBox="0 0 50 50">
                <circle
                    className="path"
                    cx="25"
                    cy="25"
                    r="20"
                    fill="none"
                    strokeWidth="5"
                ></circle>
            </svg>
        </div>
    );
};

export default Spinner;

// CSS
.loadingSpinner {
    width: 100%;
    height: 150px;
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    .spinner {
        animation: rotate 2s linear infinite;
        z-index: 2;
        width: 50px;
        height: 50px;
        & .path {
            stroke: hsl(210, 70, 75);
            stroke-linecap: round;
            animation: dash 1.5s ease-in-out infinite;
        }
    }

    &.initial {
        height: 700px;
    }

    @keyframes rotate {
        100% {
            transform: rotate(360deg);
        }
    }

    @keyframes dash {
        0% {
            stroke-dasharray: 1, 150;
            stroke-dashoffset: 0;
        }
        50% {
            stroke-dasharray: 90, 150;
            stroke-dashoffset: -35;
        }
        100% {
            stroke-dasharray: 90, 150;
            stroke-dashoffset: -124;
        }
    }
}

Public Assets used in the project can be found here

About

A simple movie website where you can explore different types of movies and tv shows and also watch it live.

Topics

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors