├── src
├── assets
│ ├── 1.png
│ ├── 2.png
│ ├── 3.png
│ ├── 4.png
│ └── 5.png
├── store
│ ├── reducers
│ │ ├── rootReducer.js
│ │ ├── nowPlaying.js
│ │ └── movieReducer.js
│ ├── constans
│ │ └── index.js
│ ├── configureStore.js
│ └── actions
│ │ ├── nowPlaying.js
│ │ └── movie.js
├── index.js
├── pages
│ ├── Home.jsx
│ └── MovieDetail.jsx
├── components
│ ├── CategoryItem.jsx
│ ├── Category.jsx
│ ├── Popular.jsx
│ ├── Header.jsx
│ ├── NowShowing.jsx
│ ├── MovieList.jsx
│ ├── MovieCard.jsx
│ └── Search.jsx
├── App.js
└── style.css
├── public
├── favicon.ico
├── logo192.png
├── logo512.png
├── robots.txt
├── manifest.json
└── index.html
├── tailwind.config.js
├── .gitignore
├── tailwind.css
├── package.json
└── README.md
/src/assets/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/src/assets/1.png
--------------------------------------------------------------------------------
/src/assets/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/src/assets/2.png
--------------------------------------------------------------------------------
/src/assets/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/src/assets/3.png
--------------------------------------------------------------------------------
/src/assets/4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/src/assets/4.png
--------------------------------------------------------------------------------
/src/assets/5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/src/assets/5.png
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ysnbyzli/the-movies/HEAD/public/logo512.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/store/reducers/rootReducer.js:
--------------------------------------------------------------------------------
1 | import { combineReducers } from "redux";
2 | import nowPlaying from './nowPlaying'
3 | import movieReducer from "./movieReducer";
4 |
5 |
6 | export default combineReducers({
7 | nowPlaying,
8 | movie: movieReducer
9 | })
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | mode: "jit",
3 | purge: ['./src/**/*.{js,jsx,ts,tsx}', './public/index.html'],
4 | darkMode: 'class', // or 'media' or 'class'
5 | theme: {
6 | extend: {},
7 | },
8 | variants: {
9 | extend: {},
10 | },
11 | plugins: [],
12 | }
13 |
--------------------------------------------------------------------------------
/src/store/constans/index.js:
--------------------------------------------------------------------------------
1 | // NOW PLAYING
2 | export const FETCH_MOVIES_NOW_PLAYING = "FETCH_MOVIES_NOW_PLAYING";
3 |
4 | // MOVIE
5 | export const CHANGE_CURRENT_CATEGORY = "CHANGE_CURRENT_CATEGORY"
6 | export const CHANGE_CURRENT_CATEGORY_MOVIES = "CHANGE_CURRENT_CATEGORY_MOVIES"
7 | export const FETCH_MOVIES_BY_POPULAR = "FETCH_MOVIES_BY_POPULAR"
--------------------------------------------------------------------------------
/src/store/configureStore.js:
--------------------------------------------------------------------------------
1 | import { applyMiddleware, createStore } from "redux";
2 | import { composeWithDevTools } from 'redux-devtools-extension';
3 | import thunk from "redux-thunk";
4 | import rootReducer from "./reducers/rootReducer";
5 |
6 | export function configureStore() {
7 | return createStore(rootReducer, composeWithDevTools(
8 | applyMiddleware(thunk)));
9 | }
--------------------------------------------------------------------------------
/.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 | .env
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/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './style.css'
4 | import App from './App';
5 | import { Provider } from 'react-redux';
6 | import { configureStore } from './store/configureStore';
7 |
8 |
9 | const store = configureStore();
10 |
11 | ReactDOM.render(
12 |
13 |
14 |
15 |
16 | ,
17 | document.getElementById('root')
18 | );
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/pages/Home.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import Category from '../components/Category'
3 | import MovieList from '../components/MovieList'
4 | import NowShowing from '../components/NowShowing'
5 | import Popular from '../components/Popular'
6 |
7 | const Home = () => {
8 | return (
9 |
15 | )
16 | }
17 |
18 | export default Home
19 |
--------------------------------------------------------------------------------
/src/store/actions/nowPlaying.js:
--------------------------------------------------------------------------------
1 | import axios from "axios";
2 | import { FETCH_MOVIES_NOW_PLAYING } from "../constans";
3 |
4 | export const fetchNowPlayingList = () => {
5 | return async dispatch => {
6 | await axios.get(`https://api.themoviedb.org/3/movie/upcoming?api_key=${process.env.REACT_APP_API_KEY}&language=en-US&page=1`).then(value => dispatch({
7 | type: FETCH_MOVIES_NOW_PLAYING,
8 | payload: value.data.results
9 | }))
10 | }
11 | }
12 |
13 | /*https://api.themoviedb.org/3/movie/now_playing?api_key=${process.env.REACT_APP_API_KEY}&language=en-US&page=1 */
--------------------------------------------------------------------------------
/src/store/reducers/nowPlaying.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable default-case */
2 | /* eslint-disable import/no-anonymous-default-export */
3 |
4 | import { FETCH_MOVIES_NOW_PLAYING } from "../constans";
5 |
6 | const initialState = {
7 | nowPlayingMovies: []
8 | }
9 |
10 |
11 | export default (state = initialState, action) => {
12 | switch (action.type) {
13 | case FETCH_MOVIES_NOW_PLAYING:
14 | return {
15 | nowPlayingMovies: [
16 | action.payload
17 | ]
18 | }
19 | default:
20 | return state;
21 | }
22 | }
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/src/components/CategoryItem.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useDispatch, useSelector } from 'react-redux'
3 | import { changeCurrentCategory } from '../store/actions/movie';
4 |
5 | const CategoryItem = ({ category: { id, name } }) => {
6 |
7 |
8 | const currentCategory = useSelector(state => state.movie.currentCategory)
9 |
10 | const dispatch = useDispatch();
11 |
12 | const handleChangeCategory = (id) => {
13 | dispatch(changeCurrentCategory(id))
14 | }
15 |
16 | return (
17 | handleChangeCategory(id)}>{name}
18 | )
19 | }
20 |
21 | export default CategoryItem
22 |
--------------------------------------------------------------------------------
/src/components/Category.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import CategoryItem from './CategoryItem'
3 |
4 | const categories = [
5 | { id: 28, name: "Aksiyon" },
6 | { id: 12, name: "Macera" },
7 | { id: 16, name: "Animasyon" },
8 | { id: 35, name: "Komedi" },
9 | { id: 18, name: "Drama" },
10 | ]
11 |
12 |
13 | const Category = () => {
14 |
15 |
16 | return (
17 | <>
18 |
19 |
Kategoriler
20 |
21 | {
22 | categories.map(category => (
23 |
24 | ))
25 | }
26 |
27 |
28 | >
29 | )
30 | }
31 |
32 | export default Category
33 |
--------------------------------------------------------------------------------
/src/store/reducers/movieReducer.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable default-case */
2 | /* eslint-disable import/no-anonymous-default-export */
3 |
4 | import { CHANGE_CURRENT_CATEGORY, CHANGE_CURRENT_CATEGORY_MOVIES, FETCH_MOVIES_BY_POPULAR } from "../constans";
5 |
6 |
7 | const initialState = {
8 | currentCategory: 28,
9 | currentCategoryMovies: [],
10 | popularMovies: []
11 | }
12 |
13 | export default (state = initialState, action) => {
14 | switch (action.type) {
15 | case CHANGE_CURRENT_CATEGORY:
16 | return {
17 | ...state,
18 | currentCategory: action.payload
19 | }
20 | case CHANGE_CURRENT_CATEGORY_MOVIES:
21 | return {
22 | ...state,
23 | currentCategoryMovies: action.payload
24 | }
25 | case FETCH_MOVIES_BY_POPULAR:
26 | return {
27 | ...state,
28 | popularMovies: action.payload
29 | }
30 | default:
31 | return state;
32 | }
33 | }
--------------------------------------------------------------------------------
/tailwind.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | @import url("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css");
6 | @import url("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css");
7 | @import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;500;600;700&display=swap');
8 |
9 | @layer base {
10 | html, body{
11 | font-family: 'Oswald', sans-serif;
12 | overflow-x: hidden;
13 | height: 100%;
14 | width: 100%;
15 | overflow-x: hidden;
16 | }
17 | }
18 |
19 | .toggle-checkbox:checked {
20 | @apply: right-0 border-green-400;
21 | right: 0;
22 | border-color: #68D391;
23 | }
24 | .toggle-checkbox:checked + .toggle-label {
25 | @apply: bg-green-400;
26 | background-color: #68D391;
27 | }
28 |
29 | .category-active{
30 | @apply rounded-2xl bg-red-200 text-red-400 dark:bg-red-400 dark:text-red-100 dark:hover:text-red-100
31 | }
32 |
33 | .slick-list{
34 | height: 100%;
35 | }
--------------------------------------------------------------------------------
/src/components/Popular.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useEffect } from 'react';
3 | import { useDispatch, useSelector } from 'react-redux'
4 | import { fecthMoviesByPopular } from '../store/actions/movie';
5 | import MovieCard from './MovieCard';
6 |
7 | const Popular = () => {
8 |
9 | const movies = useSelector(state => state.movie.popularMovies);
10 |
11 | const dispatch = useDispatch();
12 |
13 | useEffect(() => {
14 | dispatch(fecthMoviesByPopular())
15 | }, [dispatch])
16 |
17 | return (
18 |
19 |
Popüler
20 |
21 | {
22 | movies && movies.map(movie => (
23 |
24 | ))
25 | }
26 |
27 |
28 | )
29 | }
30 |
31 | export default Popular
32 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import Header from "./components/Header";
3 | import Home from "./pages/Home";
4 | import {
5 | BrowserRouter as Router,
6 | Switch,
7 | Route,
8 | } from "react-router-dom";
9 | import MovieDetail from "./pages/MovieDetail";
10 |
11 | function App() {
12 |
13 | const [isDarkMode, setIsDarkMode] = useState(false);
14 |
15 | const handleChangeDarkMode = () => {
16 | setIsDarkMode(!isDarkMode);
17 |
18 | if (!isDarkMode) {
19 | document.body.classList.add('dark')
20 | } else {
21 | document.body.classList.remove('dark')
22 | }
23 | }
24 |
25 |
26 | return (
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 | );
44 | }
45 |
46 | export default App;
47 |
--------------------------------------------------------------------------------
/src/store/actions/movie.js:
--------------------------------------------------------------------------------
1 | import axios from "axios"
2 | import { CHANGE_CURRENT_CATEGORY, CHANGE_CURRENT_CATEGORY_MOVIES, FETCH_MOVIES_BY_POPULAR } from "../constans"
3 |
4 | export const changeCurrentCategory = (category) => {
5 | return async dispatch => {
6 | dispatch({
7 | type: CHANGE_CURRENT_CATEGORY,
8 | payload: category
9 | })
10 | }
11 | }
12 |
13 | export const changeCurrentCategoryMovies = (category_id) => {
14 | return async dispatch => {
15 | await axios.get(`https://api.themoviedb.org/3/discover/movie?api_key=${process.env.REACT_APP_API_KEY}&with_genres=${category_id}`).then(value => dispatch({
16 | type: CHANGE_CURRENT_CATEGORY_MOVIES,
17 | payload: value.data.results
18 | }))
19 | }
20 | }
21 |
22 | export const fecthMoviesByPopular = () => {
23 | return async dispatch => {
24 | await axios.get(`https://api.themoviedb.org/3/movie/popular?api_key=${process.env.REACT_APP_API_KEY}&language=tr-TR&page=1`).then(value => dispatch({
25 | type: FETCH_MOVIES_BY_POPULAR,
26 | payload: value.data.results
27 | }))
28 | }
29 | }
--------------------------------------------------------------------------------
/src/components/Header.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from 'react-router-dom';
2 | import Search from './Search';
3 |
4 | const Header = ({ handleChangeDarkMode }) => {
5 |
6 | return (
7 |
8 |
9 |
10 | The Movies
11 |
12 |
13 |
14 |
15 | handleChangeDarkMode()} />
16 |
17 |
18 |
19 |
20 |
21 | )
22 | }
23 |
24 | export default Header
25 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "the-movies",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.11.4",
7 | "@testing-library/react": "^11.1.0",
8 | "@testing-library/user-event": "^12.1.10",
9 | "axios": "^0.21.1",
10 | "hoek": "^6.1.3",
11 | "react": "^17.0.2",
12 | "react-dom": "^17.0.2",
13 | "react-icons": "^4.2.0",
14 | "react-player": "^2.9.0",
15 | "react-redux": "^7.2.4",
16 | "react-router-dom": "^5.2.1",
17 | "react-scripts": "^4.0.3",
18 | "react-slick": "^0.28.1",
19 | "redux": "^4.1.1",
20 | "redux-devtools-extension": "^2.13.9",
21 | "redux-thunk": "^2.3.0",
22 | "web-vitals": "^1.0.1"
23 | },
24 | "scripts": {
25 | "start": "react-scripts start",
26 | "build": "react-scripts build",
27 | "test": "react-scripts test",
28 | "eject": "react-scripts eject",
29 | "watch": "npx tailwindcss -i tailwind.css -o src/style.css --watch"
30 | },
31 | "eslintConfig": {
32 | "extends": [
33 | "react-app",
34 | "react-app/jest"
35 | ]
36 | },
37 | "browserslist": {
38 | "production": [
39 | ">0.2%",
40 | "not dead",
41 | "not op_mini all"
42 | ],
43 | "development": [
44 | "last 1 chrome version",
45 | "last 1 firefox version",
46 | "last 1 safari version"
47 | ]
48 | },
49 | "devDependencies": {
50 | "autoprefixer": "^10.3.3",
51 | "postcss": "^8.3.6",
52 | "tailwindcss": "^2.2.8"
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/src/components/NowShowing.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useEffect } from 'react';
3 | import { useDispatch, useSelector } from 'react-redux';
4 | import Slider from 'react-slick';
5 | import MovieCard from './MovieCard';
6 | import { fetchNowPlayingList } from '../store/actions/nowPlaying'
7 |
8 |
9 | const settings = {
10 | infinite: false,
11 | speed: 500,
12 | slidesToShow: 4,
13 | slidesToScroll: 4,
14 | initialSlide: 0,
15 | arrows: false,
16 | responsive: [
17 | {
18 | breakpoint: 1024,
19 | settings: {
20 | slidesToShow: 3,
21 | slidesToScroll: 3,
22 | infinite: true,
23 | }
24 | },
25 | {
26 | breakpoint: 600,
27 | settings: {
28 | slidesToShow: 2,
29 | slidesToScroll: 2,
30 | initialSlide: 2
31 | }
32 | },
33 | {
34 | breakpoint: 480,
35 | settings: {
36 | slidesToShow: 1,
37 | slidesToScroll: 1
38 | }
39 | }
40 | ]
41 | }
42 |
43 |
44 | const NowShowing = () => {
45 |
46 | const movies = useSelector(state => state.nowPlaying.nowPlayingMovies)
47 |
48 |
49 | const dispatch = useDispatch();
50 |
51 | useEffect(() => {
52 | dispatch(fetchNowPlayingList())
53 | }, [dispatch])
54 |
55 | return (
56 |
57 |
58 |
Sinemalarda
59 |
60 |
61 | {movies[0]?.map(movie => (
))}
62 |
63 |
64 | )
65 | }
66 |
67 | export default NowShowing
68 |
--------------------------------------------------------------------------------
/src/components/MovieList.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { useEffect } from 'react'
3 | import { useDispatch, useSelector } from 'react-redux'
4 | import Slider from 'react-slick'
5 | import { changeCurrentCategoryMovies } from '../store/actions/movie'
6 | import MovieCard from './MovieCard'
7 |
8 | const settings = {
9 | infinite: false,
10 | speed: 500,
11 | slidesToShow: 6,
12 | slidesToScroll: 6,
13 | initialSlide: 0,
14 | arrows: false,
15 | responsive: [
16 | {
17 | breakpoint: 1440,
18 | settings: {
19 | slidesToShow: 5,
20 | slidesToScroll: 5,
21 | infinite: true,
22 | }
23 | },
24 | {
25 | breakpoint: 1024,
26 | settings: {
27 | slidesToShow: 3,
28 | slidesToScroll: 3,
29 | infinite: true,
30 | }
31 | },
32 | {
33 | breakpoint: 600,
34 | settings: {
35 | slidesToShow: 2,
36 | slidesToScroll: 2,
37 | initialSlide: 2
38 | }
39 | },
40 | {
41 | breakpoint: 480,
42 | settings: {
43 | slidesToShow: 1,
44 | slidesToScroll: 1
45 | }
46 | }
47 | ]
48 | }
49 |
50 | const MovieList = () => {
51 |
52 | const currentCategoryId = useSelector(state => state.movie.currentCategory)
53 | const currentCategoryMovies = useSelector(state => state.movie.currentCategoryMovies)
54 |
55 | const dispatch = useDispatch();
56 |
57 | useEffect(() => {
58 | dispatch(changeCurrentCategoryMovies(currentCategoryId));
59 | }, [currentCategoryId, dispatch])
60 |
61 |
62 |
63 | return (
64 |
65 |
66 | {currentCategoryMovies && currentCategoryMovies.map(movie => (
67 |
68 | ))}
69 |
70 |
71 | )
72 | }
73 |
74 | export default MovieList
75 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # THE MOVIES
3 |
4 | Bu projede [themovie.db](https://www.themoviedb.org/?language=tr) api kullanarak film
5 | bilgileri ile bir proje ortaya çıkardım. Proje kapsamında redux kullanımı pekiştirmek için
6 | bir çok fırsatta kullanmaya çalıştım.
7 |
8 | ## DEMO
9 | https://heuristic-sinoussi-e1e26e.netlify.app/
10 |
11 | ## Kullanılan Teknolojiler
12 | [](https://tr.reactjs.org/)
13 | [](https://reactrouter.com/)
14 | [](https://redux.js.org/)
15 | [](https://tailwindcss.com/)
16 |
17 | ## Ekran Görüntüleri
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | ## Özellikler
27 |
28 | - [x] Açık/koyu mod geçişi
29 | - [x] Responsive tasarım
30 | - [x] Sinemalarda olan filmlerin listelenmesi
31 | - [x] Kategoriye göre filtreleme
32 | - [x] Popüler filmleri listeleme
33 | - [x] Filme ait detay sayfası
34 | - [x] Film arama
35 |
36 |
37 |
38 | ## Ortam Değişkenleri
39 |
40 | Bu projeyi çalıştırmak için aşağıdaki ortam değişkenlerini .env dosyanıza eklemeniz gerekecek
41 |
42 | | Parametre | Açıklama |
43 | | :-------- | :------------------------- |
44 | | `REACT_APP_API_KEY` | **Gerekli**. API anahtarınız. |
45 |
46 |
47 | ## Bilgisayarınızda Çalıştırın
48 |
49 | Projeyi klonlayın
50 |
51 | ```bash
52 | git clone https://link-to-project
53 | ```
54 |
55 | Proje dizinine gidin
56 |
57 | ```bash
58 | cd my-project
59 | ```
60 |
61 | Gerekli paketleri yükleyin
62 |
63 | ```bash
64 | npm install
65 | ```
66 |
67 | Sunucuyu çalıştırın
68 |
69 | ```bash
70 | npm run start
71 | ```
72 |
73 | ## Geri Bildirim
74 |
75 | Herhangi bir geri bildiriminiz varsa, lütfen yasinbeyazli29@gmail.com adresinden bana
76 | ulaşabilirsiniz.
77 |
78 |
--------------------------------------------------------------------------------
/src/components/MovieCard.jsx:
--------------------------------------------------------------------------------
1 | import axios from 'axios'
2 | import React from 'react'
3 | import { useState } from 'react'
4 | import { useEffect } from 'react'
5 | import { AiFillStar } from 'react-icons/ai'
6 | import { Link } from 'react-router-dom'
7 | const MovieCard = ({ movie: { id, original_title, vote_average, vote_count, poster_path }, small, collection }) => {
8 |
9 | const [detail, setDetails] = useState([]);
10 |
11 | useEffect(() => {
12 | fetchMovieDetail();
13 | }, [])
14 |
15 | const fetchMovieDetail = async () => {
16 | await axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=${process.env.REACT_APP_API_KEY}&language=tr-TR
17 | `).then(value => setDetails(value.data));
18 | }
19 |
20 | return (
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
{original_title}
30 |
{
31 | detail?.genres?.map(genre => genre.name + " ")
32 | }
33 |
{vote_average} ({vote_count})
34 |
35 | {
36 | !small ? (
37 |
38 | {detail.runtime} min
39 | {detail.release_date}
40 |
41 | ) : null
42 | }
43 |
44 |
45 | )
46 | }
47 |
48 | export default MovieCard
49 |
--------------------------------------------------------------------------------
/src/components/Search.jsx:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import React, { useState } from 'react'
3 | import { useEffect } from 'react';
4 | import { BiSearch } from 'react-icons/bi';
5 | import { Link } from 'react-router-dom';
6 |
7 | const Search = () => {
8 |
9 | const [search, setSearch] = useState("");
10 | const [movies, setMovies] = useState([])
11 |
12 |
13 | useEffect(() => {
14 | if (search && search.length >= 3) {
15 | axios.get(`https://api.themoviedb.org/3/search/movie?api_key=${process.env.REACT_APP_API_KEY}&language=en-US&query=${search}&page=1&include_adult=false`)
16 | .then(value => setMovies(value.data.results))
17 | } else {
18 | setMovies([])
19 | }
20 | }, [search])
21 |
22 |
23 | return (
24 |
25 |
setSearch(e.target.value)} />
27 |
30 |
48 |
49 | )
50 | }
51 |
52 | export default Search
53 |
--------------------------------------------------------------------------------
/src/pages/MovieDetail.jsx:
--------------------------------------------------------------------------------
1 | import axios from 'axios';
2 | import React from 'react'
3 | import { useState } from 'react';
4 | import { useEffect } from 'react';
5 | import ReactPlayer from 'react-player/youtube';
6 | import { Link, useParams } from 'react-router-dom'
7 | import { GoMute, GoUnmute } from 'react-icons/go'
8 | import { BsPlayFill } from 'react-icons/bs'
9 | import { AiOutlineArrowUp, AiOutlineArrowLeft } from 'react-icons/ai'
10 |
11 | const MovieDetail = () => {
12 |
13 | const [videos, setVideos] = useState(null);
14 | const [details, setDetails] = useState([]);
15 | const [isMuted, setIsMuted] = useState(true);
16 | const [isWatching, setIsWatching] = useState(false);
17 |
18 | const { id } = useParams();
19 |
20 |
21 |
22 | useEffect(() => {
23 | fetchMovieVideo()
24 | fetchMovieDetail()
25 | }, [id])
26 |
27 | const fetchMovieVideo = async () => {
28 | axios.get(`https://api.themoviedb.org/3/movie/${id}/videos?api_key=${process.env.REACT_APP_API_KEY}&language=tr-TR
29 | `).then(value => setVideos(value.data.results[0]?.key))
30 | }
31 |
32 | const fetchMovieDetail = async () => {
33 | await axios.get(`https://api.themoviedb.org/3/movie/${id}?api_key=${process.env.REACT_APP_API_KEY}&language=tr-TR
34 | `).then(value => setDetails(value.data));
35 | }
36 |
37 | const handleChangeMute = () => {
38 | setIsMuted(!isMuted);
39 | }
40 |
41 | const handleChangeIsWatching = () => {
42 | setIsWatching(!isWatching);
43 | }
44 |
45 | return (
46 |
47 |
55 | {
56 | isWatching ? (
57 |
handleChangeIsWatching()}
60 | >
61 |
62 |
63 | ) : (
64 |
65 | {
66 | videos ? (
67 |

68 |
) : (
69 |

70 | )
71 | }
72 |
73 |
74 |
75 |
76 |
77 | {details.original_title}
78 |
79 |
80 | {details.genres?.map(genre => (
81 | - • {genre.name}
82 | ))}
83 |
84 |
85 |
86 | {details.release_date}
87 |
88 |
89 | {
90 | details.overview && (
91 |
ÖZET
92 | {details.overview}
93 | )
94 | }
95 |
96 |
97 | {
98 | videos && (
99 |
100 | -
101 | handleChangeIsWatching()}>{
102 |
103 | }
104 |
105 | - handleChangeMute()}>
106 | {
107 | isMuted ? () : ()
108 | }
109 |
110 |
111 | )
112 | }
113 |
114 |
115 |
116 | )
117 | }
118 |
119 |
120 |
121 |
122 | )
123 | }
124 |
125 | export default MovieDetail
126 |
--------------------------------------------------------------------------------
/src/style.css:
--------------------------------------------------------------------------------
1 | /*! tailwindcss v2.2.8 | MIT License | https://tailwindcss.com */
2 |
3 | /*! modern-normalize v1.1.0 | MIT License | https://github.com/sindresorhus/modern-normalize */
4 |
5 | /*
6 | Document
7 | ========
8 | */
9 |
10 | /**
11 | Use a better box model (opinionated).
12 | */
13 |
14 | *,
15 | ::before,
16 | ::after {
17 | box-sizing: border-box;
18 | }
19 |
20 | /**
21 | Use a more readable tab size (opinionated).
22 | */
23 |
24 | html {
25 | -moz-tab-size: 4;
26 | tab-size: 4;
27 | }
28 |
29 | /**
30 | 1. Correct the line height in all browsers.
31 | 2. Prevent adjustments of font size after orientation changes in iOS.
32 | */
33 |
34 | html {
35 | line-height: 1.15;
36 | /* 1 */
37 | -webkit-text-size-adjust: 100%;
38 | /* 2 */
39 | }
40 |
41 | /*
42 | Sections
43 | ========
44 | */
45 |
46 | /**
47 | Remove the margin in all browsers.
48 | */
49 |
50 | body {
51 | margin: 0;
52 | }
53 |
54 | /**
55 | Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
56 | */
57 |
58 | body {
59 | font-family:
60 | system-ui,
61 | -apple-system, /* Firefox supports this but not yet `system-ui` */
62 | 'Segoe UI',
63 | Roboto,
64 | Helvetica,
65 | Arial,
66 | sans-serif,
67 | 'Apple Color Emoji',
68 | 'Segoe UI Emoji';
69 | }
70 |
71 | /*
72 | Grouping content
73 | ================
74 | */
75 |
76 | /**
77 | 1. Add the correct height in Firefox.
78 | 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
79 | */
80 |
81 | hr {
82 | height: 0;
83 | /* 1 */
84 | color: inherit;
85 | /* 2 */
86 | }
87 |
88 | /*
89 | Text-level semantics
90 | ====================
91 | */
92 |
93 | /**
94 | Add the correct text decoration in Chrome, Edge, and Safari.
95 | */
96 |
97 | abbr[title] {
98 | -webkit-text-decoration: underline dotted;
99 | text-decoration: underline dotted;
100 | }
101 |
102 | /**
103 | Add the correct font weight in Edge and Safari.
104 | */
105 |
106 | b,
107 | strong {
108 | font-weight: bolder;
109 | }
110 |
111 | /**
112 | 1. Improve consistency of default fonts in all browsers. (https://github.com/sindresorhus/modern-normalize/issues/3)
113 | 2. Correct the odd 'em' font sizing in all browsers.
114 | */
115 |
116 | code,
117 | kbd,
118 | samp,
119 | pre {
120 | font-family:
121 | ui-monospace,
122 | SFMono-Regular,
123 | Consolas,
124 | 'Liberation Mono',
125 | Menlo,
126 | monospace;
127 | /* 1 */
128 | font-size: 1em;
129 | /* 2 */
130 | }
131 |
132 | /**
133 | Add the correct font size in all browsers.
134 | */
135 |
136 | small {
137 | font-size: 80%;
138 | }
139 |
140 | /**
141 | Prevent 'sub' and 'sup' elements from affecting the line height in all browsers.
142 | */
143 |
144 | sub,
145 | sup {
146 | font-size: 75%;
147 | line-height: 0;
148 | position: relative;
149 | vertical-align: baseline;
150 | }
151 |
152 | sub {
153 | bottom: -0.25em;
154 | }
155 |
156 | sup {
157 | top: -0.5em;
158 | }
159 |
160 | /*
161 | Tabular data
162 | ============
163 | */
164 |
165 | /**
166 | 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
167 | 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
168 | */
169 |
170 | table {
171 | text-indent: 0;
172 | /* 1 */
173 | border-color: inherit;
174 | /* 2 */
175 | }
176 |
177 | /*
178 | Forms
179 | =====
180 | */
181 |
182 | /**
183 | 1. Change the font styles in all browsers.
184 | 2. Remove the margin in Firefox and Safari.
185 | */
186 |
187 | button,
188 | input,
189 | optgroup,
190 | select,
191 | textarea {
192 | font-family: inherit;
193 | /* 1 */
194 | font-size: 100%;
195 | /* 1 */
196 | line-height: 1.15;
197 | /* 1 */
198 | margin: 0;
199 | /* 2 */
200 | }
201 |
202 | /**
203 | Remove the inheritance of text transform in Edge and Firefox.
204 | 1. Remove the inheritance of text transform in Firefox.
205 | */
206 |
207 | button,
208 | select {
209 | /* 1 */
210 | text-transform: none;
211 | }
212 |
213 | /**
214 | Correct the inability to style clickable types in iOS and Safari.
215 | */
216 |
217 | button,
218 | [type='button'],
219 | [type='reset'],
220 | [type='submit'] {
221 | -webkit-appearance: button;
222 | }
223 |
224 | /**
225 | Remove the inner border and padding in Firefox.
226 | */
227 |
228 | ::-moz-focus-inner {
229 | border-style: none;
230 | padding: 0;
231 | }
232 |
233 | /**
234 | Restore the focus styles unset by the previous rule.
235 | */
236 |
237 | :-moz-focusring {
238 | outline: 1px dotted ButtonText;
239 | }
240 |
241 | /**
242 | Remove the additional ':invalid' styles in Firefox.
243 | See: https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737
244 | */
245 |
246 | :-moz-ui-invalid {
247 | box-shadow: none;
248 | }
249 |
250 | /**
251 | Remove the padding so developers are not caught out when they zero out 'fieldset' elements in all browsers.
252 | */
253 |
254 | legend {
255 | padding: 0;
256 | }
257 |
258 | /**
259 | Add the correct vertical alignment in Chrome and Firefox.
260 | */
261 |
262 | progress {
263 | vertical-align: baseline;
264 | }
265 |
266 | /**
267 | Correct the cursor style of increment and decrement buttons in Safari.
268 | */
269 |
270 | ::-webkit-inner-spin-button,
271 | ::-webkit-outer-spin-button {
272 | height: auto;
273 | }
274 |
275 | /**
276 | 1. Correct the odd appearance in Chrome and Safari.
277 | 2. Correct the outline style in Safari.
278 | */
279 |
280 | [type='search'] {
281 | -webkit-appearance: textfield;
282 | /* 1 */
283 | outline-offset: -2px;
284 | /* 2 */
285 | }
286 |
287 | /**
288 | Remove the inner padding in Chrome and Safari on macOS.
289 | */
290 |
291 | ::-webkit-search-decoration {
292 | -webkit-appearance: none;
293 | }
294 |
295 | /**
296 | 1. Correct the inability to style clickable types in iOS and Safari.
297 | 2. Change font properties to 'inherit' in Safari.
298 | */
299 |
300 | ::-webkit-file-upload-button {
301 | -webkit-appearance: button;
302 | /* 1 */
303 | font: inherit;
304 | /* 2 */
305 | }
306 |
307 | /*
308 | Interactive
309 | ===========
310 | */
311 |
312 | /*
313 | Add the correct display in Chrome and Safari.
314 | */
315 |
316 | summary {
317 | display: list-item;
318 | }
319 |
320 | /**
321 | * Manually forked from SUIT CSS Base: https://github.com/suitcss/base
322 | * A thin layer on top of normalize.css that provides a starting point more
323 | * suitable for web applications.
324 | */
325 |
326 | /**
327 | * Removes the default spacing and border for appropriate elements.
328 | */
329 |
330 | blockquote,
331 | dl,
332 | dd,
333 | h1,
334 | h2,
335 | h3,
336 | h4,
337 | h5,
338 | h6,
339 | hr,
340 | figure,
341 | p,
342 | pre {
343 | margin: 0;
344 | }
345 |
346 | button {
347 | background-color: transparent;
348 | background-image: none;
349 | }
350 |
351 | fieldset {
352 | margin: 0;
353 | padding: 0;
354 | }
355 |
356 | ol,
357 | ul {
358 | list-style: none;
359 | margin: 0;
360 | padding: 0;
361 | }
362 |
363 | /**
364 | * Tailwind custom reset styles
365 | */
366 |
367 | /**
368 | * 1. Use the user's configured `sans` font-family (with Tailwind's default
369 | * sans-serif font stack as a fallback) as a sane default.
370 | * 2. Use Tailwind's default "normal" line-height so the user isn't forced
371 | * to override it to ensure consistency even when using the default theme.
372 | */
373 |
374 | html {
375 | font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
376 | /* 1 */
377 | line-height: 1.5;
378 | /* 2 */
379 | }
380 |
381 | /**
382 | * Inherit font-family and line-height from `html` so users can set them as
383 | * a class directly on the `html` element.
384 | */
385 |
386 | body {
387 | font-family: inherit;
388 | line-height: inherit;
389 | }
390 |
391 | /**
392 | * 1. Prevent padding and border from affecting element width.
393 | *
394 | * We used to set this in the html element and inherit from
395 | * the parent element for everything else. This caused issues
396 | * in shadow-dom-enhanced elements like where the content
397 | * is wrapped by a div with box-sizing set to `content-box`.
398 | *
399 | * https://github.com/mozdevs/cssremedy/issues/4
400 | *
401 | *
402 | * 2. Allow adding a border to an element by just adding a border-width.
403 | *
404 | * By default, the way the browser specifies that an element should have no
405 | * border is by setting it's border-style to `none` in the user-agent
406 | * stylesheet.
407 | *
408 | * In order to easily add borders to elements by just setting the `border-width`
409 | * property, we change the default border-style for all elements to `solid`, and
410 | * use border-width to hide them instead. This way our `border` utilities only
411 | * need to set the `border-width` property instead of the entire `border`
412 | * shorthand, making our border utilities much more straightforward to compose.
413 | *
414 | * https://github.com/tailwindcss/tailwindcss/pull/116
415 | */
416 |
417 | *,
418 | ::before,
419 | ::after {
420 | box-sizing: border-box;
421 | /* 1 */
422 | border-width: 0;
423 | /* 2 */
424 | border-style: solid;
425 | /* 2 */
426 | border-color: currentColor;
427 | /* 2 */
428 | }
429 |
430 | /*
431 | * Ensure horizontal rules are visible by default
432 | */
433 |
434 | hr {
435 | border-top-width: 1px;
436 | }
437 |
438 | /**
439 | * Undo the `border-style: none` reset that Normalize applies to images so that
440 | * our `border-{width}` utilities have the expected effect.
441 | *
442 | * The Normalize reset is unnecessary for us since we default the border-width
443 | * to 0 on all elements.
444 | *
445 | * https://github.com/tailwindcss/tailwindcss/issues/362
446 | */
447 |
448 | img {
449 | border-style: solid;
450 | }
451 |
452 | textarea {
453 | resize: vertical;
454 | }
455 |
456 | input::-webkit-input-placeholder, textarea::-webkit-input-placeholder {
457 | opacity: 1;
458 | color: #9ca3af;
459 | }
460 |
461 | input:-ms-input-placeholder, textarea:-ms-input-placeholder {
462 | opacity: 1;
463 | color: #9ca3af;
464 | }
465 |
466 | input::placeholder,
467 | textarea::placeholder {
468 | opacity: 1;
469 | color: #9ca3af;
470 | }
471 |
472 | button,
473 | [role="button"] {
474 | cursor: pointer;
475 | }
476 |
477 | /**
478 | * Override legacy focus reset from Normalize with modern Firefox focus styles.
479 | *
480 | * This is actually an improvement over the new defaults in Firefox in our testing,
481 | * as it triggers the better focus styles even for links, which still use a dotted
482 | * outline in Firefox by default.
483 | */
484 |
485 | :-moz-focusring {
486 | outline: auto;
487 | }
488 |
489 | table {
490 | border-collapse: collapse;
491 | }
492 |
493 | h1,
494 | h2,
495 | h3,
496 | h4,
497 | h5,
498 | h6 {
499 | font-size: inherit;
500 | font-weight: inherit;
501 | }
502 |
503 | /**
504 | * Reset links to optimize for opt-in styling instead of
505 | * opt-out.
506 | */
507 |
508 | a {
509 | color: inherit;
510 | text-decoration: inherit;
511 | }
512 |
513 | /**
514 | * Reset form element properties that are easy to forget to
515 | * style explicitly so you don't inadvertently introduce
516 | * styles that deviate from your design system. These styles
517 | * supplement a partial reset that is already applied by
518 | * normalize.css.
519 | */
520 |
521 | button,
522 | input,
523 | optgroup,
524 | select,
525 | textarea {
526 | padding: 0;
527 | line-height: inherit;
528 | color: inherit;
529 | }
530 |
531 | /**
532 | * Use the configured 'mono' font family for elements that
533 | * are expected to be rendered with a monospace font, falling
534 | * back to the system monospace stack if there is no configured
535 | * 'mono' font family.
536 | */
537 |
538 | pre,
539 | code,
540 | kbd,
541 | samp {
542 | font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
543 | }
544 |
545 | /**
546 | * 1. Make replaced elements `display: block` by default as that's
547 | * the behavior you want almost all of the time. Inspired by
548 | * CSS Remedy, with `svg` added as well.
549 | *
550 | * https://github.com/mozdevs/cssremedy/issues/14
551 | *
552 | * 2. Add `vertical-align: middle` to align replaced elements more
553 | * sensibly by default when overriding `display` by adding a
554 | * utility like `inline`.
555 | *
556 | * This can trigger a poorly considered linting error in some
557 | * tools but is included by design.
558 | *
559 | * https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210
560 | */
561 |
562 | img,
563 | svg,
564 | video,
565 | canvas,
566 | audio,
567 | iframe,
568 | embed,
569 | object {
570 | display: block;
571 | /* 1 */
572 | vertical-align: middle;
573 | /* 2 */
574 | }
575 |
576 | /**
577 | * Constrain images and videos to the parent width and preserve
578 | * their intrinsic aspect ratio.
579 | *
580 | * https://github.com/mozdevs/cssremedy/issues/14
581 | */
582 |
583 | img,
584 | video {
585 | max-width: 100%;
586 | height: auto;
587 | }
588 |
589 | /**
590 | * Ensure the default browser behavior of the `hidden` attribute.
591 | */
592 |
593 | [hidden] {
594 | display: none;
595 | }
596 |
597 | *, ::before, ::after {
598 | --tw-translate-x: 0;
599 | --tw-translate-y: 0;
600 | --tw-rotate: 0;
601 | --tw-skew-x: 0;
602 | --tw-skew-y: 0;
603 | --tw-scale-x: 1;
604 | --tw-scale-y: 1;
605 | --tw-transform: translateX(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
606 | --tw-border-opacity: 1;
607 | border-color: rgba(229, 231, 235, var(--tw-border-opacity));
608 | --tw-ring-offset-shadow: 0 0 #0000;
609 | --tw-ring-shadow: 0 0 #0000;
610 | --tw-shadow: 0 0 #0000;
611 | }
612 |
613 | html, body{
614 | font-family: 'Oswald', sans-serif;
615 | overflow-x: hidden;
616 | height: 100%;
617 | width: 100%;
618 | overflow-x: hidden;
619 | }
620 |
621 | .container {
622 | width: 100%;
623 | }
624 |
625 | @media (min-width: 640px) {
626 | .container {
627 | max-width: 640px;
628 | }
629 | }
630 |
631 | @media (min-width: 768px) {
632 | .container {
633 | max-width: 768px;
634 | }
635 | }
636 |
637 | @media (min-width: 1024px) {
638 | .container {
639 | max-width: 1024px;
640 | }
641 | }
642 |
643 | @media (min-width: 1280px) {
644 | .container {
645 | max-width: 1280px;
646 | }
647 | }
648 |
649 | @media (min-width: 1536px) {
650 | .container {
651 | max-width: 1536px;
652 | }
653 | }
654 |
655 | .invisible {
656 | visibility: hidden;
657 | }
658 |
659 | .absolute {
660 | position: absolute;
661 | }
662 |
663 | .relative {
664 | position: relative;
665 | }
666 |
667 | .inset-0 {
668 | top: 0px;
669 | right: 0px;
670 | bottom: 0px;
671 | left: 0px;
672 | }
673 |
674 | .right-0 {
675 | right: 0px;
676 | }
677 |
678 | .top-0 {
679 | top: 0px;
680 | }
681 |
682 | .bottom-14 {
683 | bottom: 3.5rem;
684 | }
685 |
686 | .left-1\/2 {
687 | left: 50%;
688 | }
689 |
690 | .top-14 {
691 | top: 3.5rem;
692 | }
693 |
694 | .left-14 {
695 | left: 3.5rem;
696 | }
697 |
698 | .z-20 {
699 | z-index: 20;
700 | }
701 |
702 | .mx-auto {
703 | margin-left: auto;
704 | margin-right: auto;
705 | }
706 |
707 | .mx-4 {
708 | margin-left: 1rem;
709 | margin-right: 1rem;
710 | }
711 |
712 | .mt-6 {
713 | margin-top: 1.5rem;
714 | }
715 |
716 | .mt-4 {
717 | margin-top: 1rem;
718 | }
719 |
720 | .ml-5 {
721 | margin-left: 1.25rem;
722 | }
723 |
724 | .mb-8 {
725 | margin-bottom: 2rem;
726 | }
727 |
728 | .mt-5 {
729 | margin-top: 1.25rem;
730 | }
731 |
732 | .mr-4 {
733 | margin-right: 1rem;
734 | }
735 |
736 | .mt-10 {
737 | margin-top: 2.5rem;
738 | }
739 |
740 | .mb-2 {
741 | margin-bottom: 0.5rem;
742 | }
743 |
744 | .block {
745 | display: block;
746 | }
747 |
748 | .inline-block {
749 | display: inline-block;
750 | }
751 |
752 | .flex {
753 | display: flex;
754 | }
755 |
756 | .grid {
757 | display: grid;
758 | }
759 |
760 | .hidden {
761 | display: none;
762 | }
763 |
764 | .h-6 {
765 | height: 1.5rem;
766 | }
767 |
768 | .h-96 {
769 | height: 24rem;
770 | }
771 |
772 | .h-3\/4 {
773 | height: 75%;
774 | }
775 |
776 | .h-\[500px\] {
777 | height: 500px;
778 | }
779 |
780 | .h-full {
781 | height: 100%;
782 | }
783 |
784 | .h-\[530px\] {
785 | height: 530px;
786 | }
787 |
788 | .h-10 {
789 | height: 2.5rem;
790 | }
791 |
792 | .h-1\/2 {
793 | height: 50%;
794 | }
795 |
796 | .h-11 {
797 | height: 2.75rem;
798 | }
799 |
800 | .max-h-36 {
801 | max-height: 9rem;
802 | }
803 |
804 | .max-h-64 {
805 | max-height: 16rem;
806 | }
807 |
808 | .max-h-72 {
809 | max-height: 18rem;
810 | }
811 |
812 | .min-h-\[200px\] {
813 | min-height: 200px;
814 | }
815 |
816 | .min-h-\[100px\] {
817 | min-height: 100px;
818 | }
819 |
820 | .min-h-\[50px\] {
821 | min-height: 50px;
822 | }
823 |
824 | .w-10 {
825 | width: 2.5rem;
826 | }
827 |
828 | .w-6 {
829 | width: 1.5rem;
830 | }
831 |
832 | .w-full {
833 | width: 100%;
834 | }
835 |
836 | .w-1\/2 {
837 | width: 50%;
838 | }
839 |
840 | .w-64 {
841 | width: 16rem;
842 | }
843 |
844 | .w-\[700px\] {
845 | width: 700px;
846 | }
847 |
848 | .w-11 {
849 | width: 2.75rem;
850 | }
851 |
852 | .w-16 {
853 | width: 4rem;
854 | }
855 |
856 | .w-1\/4 {
857 | width: 25%;
858 | }
859 |
860 | .w-48 {
861 | width: 12rem;
862 | }
863 |
864 | .w-96 {
865 | width: 24rem;
866 | }
867 |
868 | .w-1\/3 {
869 | width: 33.333333%;
870 | }
871 |
872 | .w-56 {
873 | width: 14rem;
874 | }
875 |
876 | .min-w-\[450px\] {
877 | min-width: 450px;
878 | }
879 |
880 | .flex-1 {
881 | flex: 1 1 0%;
882 | }
883 |
884 | .-translate-x-1\/2 {
885 | --tw-translate-x: -50%;
886 | -webkit-transform: var(--tw-transform);
887 | transform: var(--tw-transform);
888 | }
889 |
890 | .transform {
891 | -webkit-transform: var(--tw-transform);
892 | transform: var(--tw-transform);
893 | }
894 |
895 | @-webkit-keyframes bounce {
896 | 0%, 100% {
897 | -webkit-transform: translateY(-25%);
898 | transform: translateY(-25%);
899 | -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);
900 | animation-timing-function: cubic-bezier(0.8,0,1,1);
901 | }
902 |
903 | 50% {
904 | -webkit-transform: none;
905 | transform: none;
906 | -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);
907 | animation-timing-function: cubic-bezier(0,0,0.2,1);
908 | }
909 | }
910 |
911 | @keyframes bounce {
912 | 0%, 100% {
913 | -webkit-transform: translateY(-25%);
914 | transform: translateY(-25%);
915 | -webkit-animation-timing-function: cubic-bezier(0.8,0,1,1);
916 | animation-timing-function: cubic-bezier(0.8,0,1,1);
917 | }
918 |
919 | 50% {
920 | -webkit-transform: none;
921 | transform: none;
922 | -webkit-animation-timing-function: cubic-bezier(0,0,0.2,1);
923 | animation-timing-function: cubic-bezier(0,0,0.2,1);
924 | }
925 | }
926 |
927 | .animate-bounce {
928 | -webkit-animation: bounce 1s infinite;
929 | animation: bounce 1s infinite;
930 | }
931 |
932 | .cursor-pointer {
933 | cursor: pointer;
934 | }
935 |
936 | .select-none {
937 | -webkit-user-select: none;
938 | -ms-user-select: none;
939 | user-select: none;
940 | }
941 |
942 | .appearance-none {
943 | -webkit-appearance: none;
944 | appearance: none;
945 | }
946 |
947 | .grid-cols-2 {
948 | grid-template-columns: repeat(2, minmax(0, 1fr));
949 | }
950 |
951 | .flex-col {
952 | flex-direction: column;
953 | }
954 |
955 | .items-center {
956 | align-items: center;
957 | }
958 |
959 | .justify-center {
960 | justify-content: center;
961 | }
962 |
963 | .justify-between {
964 | justify-content: space-between;
965 | }
966 |
967 | .gap-5 {
968 | gap: 1.25rem;
969 | }
970 |
971 | .gap-x-4 {
972 | -webkit-column-gap: 1rem;
973 | column-gap: 1rem;
974 | }
975 |
976 | .gap-y-1 {
977 | row-gap: 0.25rem;
978 | }
979 |
980 | .gap-x-1 {
981 | -webkit-column-gap: 0.25rem;
982 | column-gap: 0.25rem;
983 | }
984 |
985 | .gap-x-3 {
986 | -webkit-column-gap: 0.75rem;
987 | column-gap: 0.75rem;
988 | }
989 |
990 | .gap-y-5 {
991 | row-gap: 1.25rem;
992 | }
993 |
994 | .gap-x-2 {
995 | -webkit-column-gap: 0.5rem;
996 | column-gap: 0.5rem;
997 | }
998 |
999 | .overflow-hidden {
1000 | overflow: hidden;
1001 | }
1002 |
1003 | .overflow-x-hidden {
1004 | overflow-x: hidden;
1005 | }
1006 |
1007 | .overflow-y-scroll {
1008 | overflow-y: scroll;
1009 | }
1010 |
1011 | .whitespace-nowrap {
1012 | white-space: nowrap;
1013 | }
1014 |
1015 | .rounded-full {
1016 | border-radius: 9999px;
1017 | }
1018 |
1019 | .rounded-lg {
1020 | border-radius: 0.5rem;
1021 | }
1022 |
1023 | .rounded-2xl {
1024 | border-radius: 1rem;
1025 | }
1026 |
1027 | .rounded-md {
1028 | border-radius: 0.375rem;
1029 | }
1030 |
1031 | .rounded-t-lg {
1032 | border-top-left-radius: 0.5rem;
1033 | border-top-right-radius: 0.5rem;
1034 | }
1035 |
1036 | .rounded-b-lg {
1037 | border-bottom-right-radius: 0.5rem;
1038 | border-bottom-left-radius: 0.5rem;
1039 | }
1040 |
1041 | .border-4 {
1042 | border-width: 4px;
1043 | }
1044 |
1045 | .border-2 {
1046 | border-width: 2px;
1047 | }
1048 |
1049 | .border-gray-300 {
1050 | --tw-border-opacity: 1;
1051 | border-color: rgba(209, 213, 219, var(--tw-border-opacity));
1052 | }
1053 |
1054 | .bg-white {
1055 | --tw-bg-opacity: 1;
1056 | background-color: rgba(255, 255, 255, var(--tw-bg-opacity));
1057 | }
1058 |
1059 | .bg-gray-300 {
1060 | --tw-bg-opacity: 1;
1061 | background-color: rgba(209, 213, 219, var(--tw-bg-opacity));
1062 | }
1063 |
1064 | .bg-gray-900 {
1065 | --tw-bg-opacity: 1;
1066 | background-color: rgba(17, 24, 39, var(--tw-bg-opacity));
1067 | }
1068 |
1069 | .bg-black {
1070 | --tw-bg-opacity: 1;
1071 | background-color: rgba(0, 0, 0, var(--tw-bg-opacity));
1072 | }
1073 |
1074 | .bg-purple-300 {
1075 | --tw-bg-opacity: 1;
1076 | background-color: rgba(196, 181, 253, var(--tw-bg-opacity));
1077 | }
1078 |
1079 | .bg-gray-100 {
1080 | --tw-bg-opacity: 1;
1081 | background-color: rgba(243, 244, 246, var(--tw-bg-opacity));
1082 | }
1083 |
1084 | .bg-red-500 {
1085 | --tw-bg-opacity: 1;
1086 | background-color: rgba(239, 68, 68, var(--tw-bg-opacity));
1087 | }
1088 |
1089 | .bg-opacity-70 {
1090 | --tw-bg-opacity: 0.7;
1091 | }
1092 |
1093 | .object-cover {
1094 | object-fit: cover;
1095 | }
1096 |
1097 | .object-center {
1098 | object-position: center;
1099 | }
1100 |
1101 | .p-3 {
1102 | padding: 0.75rem;
1103 | }
1104 |
1105 | .py-1 {
1106 | padding-top: 0.25rem;
1107 | padding-bottom: 0.25rem;
1108 | }
1109 |
1110 | .px-4 {
1111 | padding-left: 1rem;
1112 | padding-right: 1rem;
1113 | }
1114 |
1115 | .py-3 {
1116 | padding-top: 0.75rem;
1117 | padding-bottom: 0.75rem;
1118 | }
1119 |
1120 | .px-8 {
1121 | padding-left: 2rem;
1122 | padding-right: 2rem;
1123 | }
1124 |
1125 | .px-3 {
1126 | padding-left: 0.75rem;
1127 | padding-right: 0.75rem;
1128 | }
1129 |
1130 | .py-7 {
1131 | padding-top: 1.75rem;
1132 | padding-bottom: 1.75rem;
1133 | }
1134 |
1135 | .px-5 {
1136 | padding-left: 1.25rem;
1137 | padding-right: 1.25rem;
1138 | }
1139 |
1140 | .px-48 {
1141 | padding-left: 12rem;
1142 | padding-right: 12rem;
1143 | }
1144 |
1145 | .py-4 {
1146 | padding-top: 1rem;
1147 | padding-bottom: 1rem;
1148 | }
1149 |
1150 | .px-1 {
1151 | padding-left: 0.25rem;
1152 | padding-right: 0.25rem;
1153 | }
1154 |
1155 | .py-2 {
1156 | padding-top: 0.5rem;
1157 | padding-bottom: 0.5rem;
1158 | }
1159 |
1160 | .pl-9 {
1161 | padding-left: 2.25rem;
1162 | }
1163 |
1164 | .pl-3 {
1165 | padding-left: 0.75rem;
1166 | }
1167 |
1168 | .pr-6 {
1169 | padding-right: 1.5rem;
1170 | }
1171 |
1172 | .pt-5 {
1173 | padding-top: 1.25rem;
1174 | }
1175 |
1176 | .pt-\[6px\] {
1177 | padding-top: 6px;
1178 | }
1179 |
1180 | .pt-7 {
1181 | padding-top: 1.75rem;
1182 | }
1183 |
1184 | .pb-9 {
1185 | padding-bottom: 2.25rem;
1186 | }
1187 |
1188 | .pt-4 {
1189 | padding-top: 1rem;
1190 | }
1191 |
1192 | .pt-2 {
1193 | padding-top: 0.5rem;
1194 | }
1195 |
1196 | .pr-16 {
1197 | padding-right: 4rem;
1198 | }
1199 |
1200 | .pr-10 {
1201 | padding-right: 2.5rem;
1202 | }
1203 |
1204 | .pb-5 {
1205 | padding-bottom: 1.25rem;
1206 | }
1207 |
1208 | .pb-2 {
1209 | padding-bottom: 0.5rem;
1210 | }
1211 |
1212 | .pl-5 {
1213 | padding-left: 1.25rem;
1214 | }
1215 |
1216 | .align-middle {
1217 | vertical-align: middle;
1218 | }
1219 |
1220 | .text-2xl {
1221 | font-size: 1.5rem;
1222 | line-height: 2rem;
1223 | }
1224 |
1225 | .text-lg {
1226 | font-size: 1.125rem;
1227 | line-height: 1.75rem;
1228 | }
1229 |
1230 | .text-xs {
1231 | font-size: 0.75rem;
1232 | line-height: 1rem;
1233 | }
1234 |
1235 | .text-sm {
1236 | font-size: 0.875rem;
1237 | line-height: 1.25rem;
1238 | }
1239 |
1240 | .font-semibold {
1241 | font-weight: 600;
1242 | }
1243 |
1244 | .font-light {
1245 | font-weight: 300;
1246 | }
1247 |
1248 | .font-bold {
1249 | font-weight: 700;
1250 | }
1251 |
1252 | .uppercase {
1253 | text-transform: uppercase;
1254 | }
1255 |
1256 | .tracking-wider {
1257 | letter-spacing: 0.05em;
1258 | }
1259 |
1260 | .text-gray-600 {
1261 | --tw-text-opacity: 1;
1262 | color: rgba(75, 85, 99, var(--tw-text-opacity));
1263 | }
1264 |
1265 | .text-gray-500 {
1266 | --tw-text-opacity: 1;
1267 | color: rgba(107, 114, 128, var(--tw-text-opacity));
1268 | }
1269 |
1270 | .text-yellow-300 {
1271 | --tw-text-opacity: 1;
1272 | color: rgba(252, 211, 77, var(--tw-text-opacity));
1273 | }
1274 |
1275 | .text-gray-400 {
1276 | --tw-text-opacity: 1;
1277 | color: rgba(156, 163, 175, var(--tw-text-opacity));
1278 | }
1279 |
1280 | .text-white {
1281 | --tw-text-opacity: 1;
1282 | color: rgba(255, 255, 255, var(--tw-text-opacity));
1283 | }
1284 |
1285 | .shadow-md {
1286 | --tw-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
1287 | box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
1288 | }
1289 |
1290 | .transition {
1291 | transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, -webkit-transform, -webkit-filter, -webkit-backdrop-filter;
1292 | transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter;
1293 | transition-property: background-color, border-color, color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter, -webkit-transform, -webkit-filter, -webkit-backdrop-filter;
1294 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1295 | transition-duration: 150ms;
1296 | }
1297 |
1298 | .transition-colors {
1299 | transition-property: background-color, border-color, color, fill, stroke;
1300 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1301 | transition-duration: 150ms;
1302 | }
1303 |
1304 | .duration-200 {
1305 | transition-duration: 200ms;
1306 | }
1307 |
1308 | .duration-1000 {
1309 | transition-duration: 1000ms;
1310 | }
1311 |
1312 | .duration-300 {
1313 | transition-duration: 300ms;
1314 | }
1315 |
1316 | .duration-500 {
1317 | transition-duration: 500ms;
1318 | }
1319 |
1320 | .ease-in {
1321 | transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
1322 | }
1323 |
1324 | .ease-in-out {
1325 | transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
1326 | }
1327 |
1328 | @import url("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick.min.css");
1329 |
1330 | @import url("https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.6.0/slick-theme.min.css");
1331 |
1332 | @import url('https://fonts.googleapis.com/css2?family=Oswald:wght@200;300;400;500;600;700&display=swap');
1333 |
1334 | .toggle-checkbox:checked {
1335 | @apply: right-0 border-green-400;
1336 | right: 0;
1337 | border-color: #68D391;
1338 | }
1339 |
1340 | .toggle-checkbox:checked + .toggle-label {
1341 | @apply: bg-green-400;
1342 | background-color: #68D391;
1343 | }
1344 |
1345 | .category-active {
1346 | border-radius: 1rem;
1347 | --tw-bg-opacity: 1;
1348 | background-color: rgba(254, 202, 202, var(--tw-bg-opacity));
1349 | --tw-text-opacity: 1;
1350 | color: rgba(248, 113, 113, var(--tw-text-opacity));
1351 | }
1352 |
1353 | .dark .category-active {
1354 | --tw-bg-opacity: 1;
1355 | background-color: rgba(248, 113, 113, var(--tw-bg-opacity));
1356 | --tw-text-opacity: 1;
1357 | color: rgba(254, 226, 226, var(--tw-text-opacity));
1358 | }
1359 |
1360 | .dark .category-active:hover {
1361 | --tw-text-opacity: 1;
1362 | color: rgba(254, 226, 226, var(--tw-text-opacity));
1363 | }
1364 |
1365 | .slick-list{
1366 | height: 100%;
1367 | }
1368 |
1369 | .hover\:bg-opacity-20:hover {
1370 | --tw-bg-opacity: 0.2;
1371 | }
1372 |
1373 | .hover\:text-red-400:hover {
1374 | --tw-text-opacity: 1;
1375 | color: rgba(248, 113, 113, var(--tw-text-opacity));
1376 | }
1377 |
1378 | .hover\:text-opacity-90:hover {
1379 | --tw-text-opacity: 0.9;
1380 | }
1381 |
1382 | .focus\:outline-none:focus {
1383 | outline: 2px solid transparent;
1384 | outline-offset: 2px;
1385 | }
1386 |
1387 | .dark .dark\:border-black {
1388 | --tw-border-opacity: 1;
1389 | border-color: rgba(0, 0, 0, var(--tw-border-opacity));
1390 | }
1391 |
1392 | .dark .dark\:border-gray-600 {
1393 | --tw-border-opacity: 1;
1394 | border-color: rgba(75, 85, 99, var(--tw-border-opacity));
1395 | }
1396 |
1397 | .dark .dark\:border-gray-800 {
1398 | --tw-border-opacity: 1;
1399 | border-color: rgba(31, 41, 55, var(--tw-border-opacity));
1400 | }
1401 |
1402 | .dark .dark\:border-gray-500 {
1403 | --tw-border-opacity: 1;
1404 | border-color: rgba(107, 114, 128, var(--tw-border-opacity));
1405 | }
1406 |
1407 | .dark .dark\:border-gray-700 {
1408 | --tw-border-opacity: 1;
1409 | border-color: rgba(55, 65, 81, var(--tw-border-opacity));
1410 | }
1411 |
1412 | .dark .dark\:bg-gray-900 {
1413 | --tw-bg-opacity: 1;
1414 | background-color: rgba(17, 24, 39, var(--tw-bg-opacity));
1415 | }
1416 |
1417 | .dark .dark\:bg-gray-700 {
1418 | --tw-bg-opacity: 1;
1419 | background-color: rgba(55, 65, 81, var(--tw-bg-opacity));
1420 | }
1421 |
1422 | .dark .dark\:bg-gray-500 {
1423 | --tw-bg-opacity: 1;
1424 | background-color: rgba(107, 114, 128, var(--tw-bg-opacity));
1425 | }
1426 |
1427 | .dark .dark\:bg-gray-800 {
1428 | --tw-bg-opacity: 1;
1429 | background-color: rgba(31, 41, 55, var(--tw-bg-opacity));
1430 | }
1431 |
1432 | .dark .dark\:text-white {
1433 | --tw-text-opacity: 1;
1434 | color: rgba(255, 255, 255, var(--tw-text-opacity));
1435 | }
1436 |
1437 | .dark .dark\:text-gray-300 {
1438 | --tw-text-opacity: 1;
1439 | color: rgba(209, 213, 219, var(--tw-text-opacity));
1440 | }
1441 |
1442 | .dark .dark\:text-gray-200 {
1443 | --tw-text-opacity: 1;
1444 | color: rgba(229, 231, 235, var(--tw-text-opacity));
1445 | }
1446 |
1447 | .dark .dark\:text-gray-100 {
1448 | --tw-text-opacity: 1;
1449 | color: rgba(243, 244, 246, var(--tw-text-opacity));
1450 | }
1451 |
1452 | @media (min-width: 768px) {
1453 | .md\:grid-cols-3 {
1454 | grid-template-columns: repeat(3, minmax(0, 1fr));
1455 | }
1456 | }
1457 |
1458 | @media (min-width: 1024px) {
1459 | .lg\:flex {
1460 | display: flex;
1461 | }
1462 |
1463 | .lg\:w-96 {
1464 | width: 24rem;
1465 | }
1466 |
1467 | .lg\:grid-cols-4 {
1468 | grid-template-columns: repeat(4, minmax(0, 1fr));
1469 | }
1470 |
1471 | .lg\:justify-between {
1472 | justify-content: space-between;
1473 | }
1474 | }
1475 |
1476 | @media (min-width: 1280px) {
1477 | .xl\:visible {
1478 | visibility: visible;
1479 | }
1480 |
1481 | .xl\:grid-cols-5 {
1482 | grid-template-columns: repeat(5, minmax(0, 1fr));
1483 | }
1484 | }
1485 |
1486 | @media (min-width: 1536px) {
1487 | .\32xl\:grid-cols-6 {
1488 | grid-template-columns: repeat(6, minmax(0, 1fr));
1489 | }
1490 | }
--------------------------------------------------------------------------------