Skip to content

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

Notifications You must be signed in to change notification settings

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

Watchers

Forks

Releases

No releases published

Packages

No packages published