├── .gitignore ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── robots.txt └── src ├── App.js ├── App.test.js ├── actions ├── games.js ├── movies.js └── search.js ├── assets ├── global.scss ├── images │ ├── arrow-left.svg │ ├── chevrons-up.svg │ ├── close.svg │ ├── logo.png │ ├── pause-circle.svg │ ├── play.svg │ ├── search.svg │ └── volume-x.svg └── scss │ ├── layout │ └── header.scss │ ├── product-detail.scss │ └── product-list.scss ├── components ├── contentLoaderDetail.jsx ├── createGame.jsx ├── createMovie.jsx ├── detail.jsx ├── editGame.jsx ├── editMovie.jsx ├── gameList.jsx ├── movieList.jsx └── search.jsx ├── index.js ├── layout └── header.jsx ├── logo.svg ├── pages ├── productCreate.jsx ├── productDetail.jsx ├── productEdit.jsx └── productPage.jsx ├── reducers ├── games.js ├── movies.js ├── rootReducer.js └── search.js ├── reportWebVitals.js └── setupTests.js /.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 17 | .eslintcache 18 | .env.local 19 | .env.development.local 20 | .env.test.local 21 | .env.production.local 22 | 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # REACT- REDUX MOVIE APP 2 | Canlı test linki: https://react-redux-advanced-movie-app-duz2oqzak.vercel.app/ 3 | 4 | Sevdiğiniz filmlerin veya oyunların ruhunu, onların fon müzikleriyle fazlasıyla hissedebilirsiniz, laptopun sesini çok açmayın :) 5 | Test sayfasından sizde sevdiğiniz film veya oyunları ekleyebilirsiniz. 6 | 7 | Klasik movie app'lerden daha çok, tasarımı özgün, yaratıcı, animasyonlarla süslediğim ve mobili bir app gibi olan bu proje, kod anlamıyla da içime sinen hoş bir proje oldu. 8 | 9 | React ve reduxu tam anlamıyla kullanabilmek adına projeye hep yeni özellikler eklemek istedim, özellikle redux tarafına çok yüklenmeye çalıştım. 10 | 11 | ## Build Setup 12 | 13 | ```bash 14 | # install dependencies 15 | $ npm install 16 | 17 | # serve with hot reload at localhost:3000 18 | $ npm start 19 | ``` 20 | 21 |
22 |
23 | 24 |

Developer by Şahin ZAYBAK

25 |
26 |
27 | 28 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-movie-app", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@testing-library/jest-dom": "^5.11.9", 7 | "@testing-library/react": "^11.2.3", 8 | "@testing-library/user-event": "^12.6.2", 9 | "axios": "^0.21.1", 10 | "bootstrap": "^4.6.0", 11 | "node-sass": "^4.14.1", 12 | "react": "^17.0.1", 13 | "react-bootstrap": "^1.4.3", 14 | "react-circular-progressbar": "^2.0.3", 15 | "react-content-loader": "^6.0.1", 16 | "react-debounce-input": "^3.2.3", 17 | "react-dom": "^17.0.1", 18 | "react-modal-video": "^1.2.6", 19 | "react-player": "^2.8.2", 20 | "react-redux": "^7.2.2", 21 | "react-router-dom": "^5.2.0", 22 | "react-scripts": "4.0.1", 23 | "react-spotify-player": "^1.0.4", 24 | "react-thunk": "^1.0.0", 25 | "redux": "^4.0.5", 26 | "redux-devtools-extension": "^2.13.8", 27 | "redux-logger": "^3.0.6", 28 | "redux-promise-middleware": "^6.1.2", 29 | "redux-thunk": "^2.3.0", 30 | "web-vitals": "^0.2.4" 31 | }, 32 | "scripts": { 33 | "start": "react-scripts start", 34 | "build": "CI= react-scripts build", 35 | "test": "react-scripts test", 36 | "eject": "react-scripts eject" 37 | }, 38 | "eslintConfig": { 39 | "extends": [ 40 | "react-app", 41 | "react-app/jest" 42 | ] 43 | }, 44 | "browserslist": { 45 | "production": [ 46 | ">0.2%", 47 | "not dead", 48 | "not op_mini all" 49 | ], 50 | "development": [ 51 | "last 1 chrome version", 52 | "last 1 firefox version", 53 | "last 1 safari version" 54 | ] 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahinzaybak/react-redux-hooks-advanced-movie-app/7db43d7bca5a81c09a39f50d69fad9c69ed43358/public/favicon.ico -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahinzaybak/react-redux-hooks-advanced-movie-app/7db43d7bca5a81c09a39f50d69fad9c69ed43358/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahinzaybak/react-redux-hooks-advanced-movie-app/7db43d7bca5a81c09a39f50d69fad9c69ed43358/public/logo512.png -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import {Route} from 'react-router-dom'; 2 | import productPage from './pages/productPage.jsx' 3 | import productDetail from './pages/productDetail.jsx' 4 | import productCreate from './pages/productCreate.jsx' 5 | import productEdit from './pages/productEdit.jsx' 6 | 7 | import 'bootstrap/dist/css/bootstrap.css'; 8 | import './assets/global.scss' 9 | import './assets/scss/product-list.scss' 10 | import './assets/scss/product-detail.scss' 11 | 12 | function App() { 13 | return ( 14 |
15 | 16 | 17 | 18 | 19 |
20 | ); 21 | } 22 | 23 | export default App; 24 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import { render, screen } from '@testing-library/react'; 2 | import App from './App'; 3 | 4 | test('renders learn react link', () => { 5 | render(); 6 | const linkElement = screen.getByText(/learn react/i); 7 | expect(linkElement).toBeInTheDocument(); 8 | }); 9 | -------------------------------------------------------------------------------- /src/actions/games.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | const BASE_URL = process.env.REACT_APP_API_URL 3 | export function fetchGames() { 4 | return async dispatch => { 5 | await axios.get(`${BASE_URL}/games`).then(value => { 6 | dispatch({ 7 | type: "FETCH_GAMES", 8 | payload: value.data, 9 | }); 10 | }); 11 | }; 12 | } 13 | 14 | export function detail(platform, slug) { 15 | return async dispatch => { 16 | await axios.get(`${BASE_URL}/${platform}?slug=${slug}`).then(value => { 17 | dispatch({ 18 | type: "SET_DETAIL", 19 | payload: value.data[0], 20 | }); 21 | }); 22 | }; 23 | } 24 | 25 | export function saveGames(newGameInfo) { 26 | return async dispatch => { 27 | await axios.post(`${BASE_URL}/games`, { 28 | name: newGameInfo._name, 29 | title: newGameInfo._title, 30 | category: newGameInfo._category, 31 | slug: newGameInfo._slug, 32 | poster: newGameInfo._poster, 33 | music: newGameInfo._music, 34 | company: newGameInfo._company, 35 | trailer: newGameInfo._trailer, 36 | time: newGameInfo._time, 37 | year: newGameInfo._year, 38 | point: newGameInfo._point, 39 | platform: "games" 40 | }).then(value => { 41 | dispatch({ 42 | type: "NEW_GAME_RESULT", 43 | payload: value.statusText 44 | }); 45 | }) 46 | } 47 | } 48 | 49 | export function editGames(gameInfo) { 50 | return async dispatch => { 51 | await axios.put(`${BASE_URL}/${gameInfo._platform}/${gameInfo._id}`, { 52 | name: gameInfo._name, 53 | title: gameInfo._title, 54 | category: gameInfo._category, 55 | slug: gameInfo._slug, 56 | poster: gameInfo._poster, 57 | backdrop: gameInfo._backdrop, 58 | company: gameInfo._company, 59 | trailer: gameInfo._trailer, 60 | time: gameInfo._time, 61 | year: gameInfo._year, 62 | point: gameInfo._point, 63 | platform: "games" 64 | }).then(value => { 65 | dispatch({ 66 | type: "EDIT_RESULT", 67 | payload: value 68 | }); 69 | }) 70 | } 71 | } 72 | 73 | export function clearDetail() { 74 | return dispatch => { 75 | dispatch({ 76 | type: "CLEAR_DETAIL", 77 | payload: true 78 | }); 79 | } 80 | } -------------------------------------------------------------------------------- /src/actions/movies.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | const BASE_URL = process.env.REACT_APP_API_URL 3 | export function fetchMovies() { 4 | return async dispatch => { 5 | await axios.get(`${BASE_URL}/movies`).then(value => { 6 | dispatch({ 7 | type: "FETCH_MOVIES", 8 | payload: value.data, 9 | }); 10 | }); 11 | }; 12 | } 13 | 14 | export function saveMovie(newMovieInfo) { 15 | return async dispatch => { 16 | await axios.post(`${BASE_URL}/movies`, { 17 | name: newMovieInfo._name, 18 | title: newMovieInfo._title, 19 | category: newMovieInfo._category, 20 | slug: newMovieInfo._slug, 21 | poster: newMovieInfo._poster, 22 | music: newMovieInfo._music, 23 | director: newMovieInfo._director, 24 | writer: newMovieInfo._writer, 25 | trailer: newMovieInfo._trailer, 26 | time: newMovieInfo._time, 27 | year: newMovieInfo._year, 28 | point: newMovieInfo._point, 29 | platform: "movies" 30 | }).then(value => { 31 | dispatch({ 32 | type: "NEW_MOVIE_RESULT", 33 | payload: value.statusText 34 | }); 35 | }) 36 | } 37 | } 38 | 39 | 40 | export function editMovie(movieInfo) { 41 | return async dispatch => { 42 | await axios.put(`${BASE_URL}/${movieInfo._platform}/${movieInfo._id}`, { 43 | name: movieInfo._name, 44 | title: movieInfo._title, 45 | category: movieInfo._category, 46 | slug: movieInfo._slug, 47 | poster: movieInfo._poster, 48 | music: movieInfo._music, 49 | director: movieInfo._director, 50 | writer: movieInfo._writer, 51 | trailer: movieInfo._trailer, 52 | time: movieInfo._time, 53 | year: movieInfo._year, 54 | point: movieInfo._point, 55 | platform: "movies" 56 | }).then(value => { 57 | dispatch({ 58 | type: "EDIT_RESULT", 59 | payload: value 60 | }); 61 | }) 62 | } 63 | } -------------------------------------------------------------------------------- /src/actions/search.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | const BASE_URL = process.env.REACT_APP_API_URL 3 | export function searchGames(searchText) { 4 | return async dispatch => { 5 | await axios.get(`${BASE_URL}/games?name=${searchText}`).then(value => { 6 | dispatch({ 7 | type: "SEARCH_GAME_RESULT", 8 | payload: value.data 9 | }); 10 | }) 11 | } 12 | } 13 | 14 | export function searchMovies(searchText) { 15 | return async dispatch => { 16 | await axios.get(`${BASE_URL}/movies?name=${searchText}`).then(value => { 17 | dispatch({ 18 | type: "SEARCH_MOVIE_RESULT", 19 | payload: value.data 20 | }); 21 | }) 22 | } 23 | } 24 | 25 | export function searchActiveOverlay() { 26 | return dispatch => { 27 | dispatch({ 28 | type: "ACTIVE_SEARCH_OVERLAY", 29 | payload: "true" 30 | }); 31 | } 32 | } 33 | 34 | export function searchDisableOverlay() { 35 | return dispatch => { 36 | dispatch({ 37 | type: "DISABLED_SEARCH_OVERLAY", 38 | payload: "false" 39 | }); 40 | } 41 | } 42 | 43 | export function searchListClear() { 44 | return dispatch => { 45 | dispatch({ 46 | type: "SEARCH_LIST_CLEAR", 47 | }); 48 | } 49 | } -------------------------------------------------------------------------------- /src/assets/global.scss: -------------------------------------------------------------------------------- 1 | @import url('https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;600;700&display=swap'); 2 | @import url('https://fonts.googleapis.com/css2?family=Knewave&display=swap'); 3 | @import url('https://fonts.googleapis.com/css2?family=Hind+Siliguri:wght@400;500&display=swap'); 4 | 5 | * { 6 | 7 | &, 8 | &:before, 9 | &:after { 10 | box-sizing: border-box; 11 | } 12 | } 13 | 14 | *, 15 | *:focus { 16 | outline: none; 17 | } 18 | 19 | html { 20 | box-sizing: border-box; 21 | text-rendering: optimizeLegibility; 22 | } 23 | 24 | body { 25 | overflow-x: hidden !important; 26 | -webkit-font-smoothing: antialiased; 27 | -moz-osx-font-smoothing: grayscale; 28 | padding: 0; 29 | margin: 0; 30 | font-family: 'Montserrat'; 31 | font-weight: 500; 32 | letter-spacing: 0.2px; 33 | 34 | } 35 | 36 | 37 | blockquote, 38 | dl, 39 | dd, 40 | h1, 41 | h2, 42 | h3, 43 | h4, 44 | h5, 45 | h6, 46 | figure, 47 | p, 48 | pre, 49 | fieldset, 50 | ul, 51 | ol, 52 | menu, 53 | form { 54 | margin: 0; 55 | } 56 | 57 | button, 58 | fieldset, 59 | iframe { 60 | border: 0; 61 | } 62 | 63 | fieldset, 64 | ul, 65 | ol, 66 | button, 67 | menu { 68 | padding: 0; 69 | } 70 | 71 | ul { 72 | list-style: none; 73 | } 74 | 75 | textarea { 76 | resize: none; 77 | } 78 | 79 | table { 80 | width: 100%; 81 | border-collapse: collapse; 82 | border-spacing: 0; 83 | } 84 | 85 | td { 86 | padding: 0; 87 | } 88 | 89 | a, 90 | a:hover, 91 | a:focus, 92 | a:active { 93 | text-decoration: none; 94 | color: inherit; 95 | } 96 | 97 | a, 98 | a:focus, 99 | button, 100 | button:focus { 101 | outline: none !important; 102 | text-decoration: none; 103 | } 104 | 105 | a, 106 | button { 107 | user-select: none; 108 | transition: all .3s ease-in-out; 109 | } 110 | 111 | button { 112 | cursor: pointer; 113 | background: none; 114 | box-shadow: none; 115 | border: none; 116 | } 117 | 118 | img { 119 | max-width: 100%; 120 | } 121 | 122 | section { 123 | padding: 80px 0; 124 | } 125 | 126 | label { 127 | margin-bottom: 0; 128 | } 129 | 130 | 131 | .custom-container { 132 | position: relative; 133 | max-width: 1200px; 134 | width: 95%; 135 | margin: 0 auto; 136 | z-index: 99; 137 | &.product{ 138 | @media (max-width: 600px) { 139 | overflow: hidden; 140 | } 141 | } 142 | } 143 | 144 | .cursor-pointer { 145 | cursor: pointer; 146 | } 147 | 148 | .custom-switch { 149 | @media (max-width: 600px) { 150 | display: none; 151 | } 152 | } 153 | 154 | .dark { 155 | background-color: black; 156 | color: white; 157 | 158 | .header { 159 | background-color: black; 160 | } 161 | 162 | .movie-item__name { 163 | color: white; 164 | } 165 | 166 | .movie-create__form { 167 | input[type=text] { 168 | border: 1px solid #fdfdfd26; 169 | background-color: transparent; 170 | } 171 | } 172 | .search-result{ 173 | background-color: black !important; 174 | border-color: #131212 !important; 175 | } 176 | } 177 | 178 | .back-info { 179 | position: absolute; 180 | right: 0; 181 | left: 0; 182 | background-color: white; 183 | border-radius: 50px; 184 | width: 35px; 185 | height: 35px; 186 | display: flex; 187 | align-items: center; 188 | justify-content: center; 189 | margin: 0 auto; 190 | transform: scale(1.2); 191 | bottom: 46px; 192 | opacity: 0; 193 | transform: translateY(50px); 194 | transition: all .4s ease-in; 195 | cursor: pointer; 196 | z-index: 9; 197 | } 198 | 199 | .activeTrailer { 200 | .movie-detail__wrp { 201 | opacity: 0; 202 | transform: translateY(200px); 203 | padding-top: 0; 204 | } 205 | 206 | .back-info { 207 | opacity: 0.7; 208 | transform: none; 209 | } 210 | 211 | .movie-detail__backdrop { 212 | @media (max-width: 600px) { 213 | z-index: 1; 214 | } 215 | &:after { 216 | background-color: transparent; 217 | @media (max-width: 600px) { 218 | display: none; 219 | } 220 | } 221 | 222 | } 223 | } 224 | 225 | .status-message{ 226 | position: absolute; 227 | bottom: 5px; 228 | right: 0; 229 | left: 0; 230 | color: #95cc26; 231 | font-weight: 600; 232 | font-size: 17px; 233 | width: max-content; 234 | margin: 0 auto; 235 | &.yellow{ 236 | color:#ea8835; 237 | } 238 | } 239 | 240 | .load-skeleton-detail{ 241 | position: absolute; 242 | left: -4%; 243 | transform: translateY(-40%); 244 | @media (max-width: 650px) { 245 | top: -68px; 246 | position: absolute; 247 | left: 0; 248 | transform: none; 249 | overflow: hidden; 250 | } 251 | } 252 | 253 | .search-overlay{ 254 | position: fixed; 255 | width: 100%; 256 | height: 100vh; 257 | background-color: #000000e0; 258 | top: 80px; 259 | z-index: 9999; 260 | opacity: 0; 261 | transition: all .2s 0.2s ease; 262 | pointer-events: none; 263 | &.active{ 264 | opacity: 1; 265 | pointer-events: all; 266 | } 267 | } -------------------------------------------------------------------------------- /src/assets/images/arrow-left.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/chevrons-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/close.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sahinzaybak/react-redux-hooks-advanced-movie-app/7db43d7bca5a81c09a39f50d69fad9c69ed43358/src/assets/images/logo.png -------------------------------------------------------------------------------- /src/assets/images/pause-circle.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/play.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/search.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/images/volume-x.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/assets/scss/layout/header.scss: -------------------------------------------------------------------------------- 1 | .header { 2 | width: 100%; 3 | height: 80px; 4 | background-color: #151515; 5 | color: white; 6 | border-bottom: 1px solid transparent; 7 | opacity: 1; 8 | z-index: 99999; 9 | 10 | &-logo { 11 | width: 110px; 12 | } 13 | 14 | &-menu { 15 | &__link { 16 | color: white; 17 | margin-right: 30px; 18 | } 19 | 20 | &__search { 21 | position: relative; 22 | width: 480px; 23 | display: flex; 24 | align-items: center; 25 | 26 | .search { 27 | &-icon { 28 | position: absolute; 29 | opacity: 0.3; 30 | } 31 | 32 | &-item { 33 | input { 34 | width: 100%; 35 | border: 1px solid #ffffff17; 36 | border-radius: 6px; 37 | padding: 9px; 38 | text-indent: 60px; 39 | background-color: transparent; 40 | color: white; 41 | } 42 | &__platform{ 43 | font-size: 10px; 44 | background-color: #95cc26; 45 | padding: 2px 9px; 46 | border-radius: 6px; 47 | &.red{ 48 | background-color: #ea8835; 49 | } 50 | } 51 | .spinner-border{ 52 | left: 25px; 53 | width: 1.4em; 54 | height: 1.4em; 55 | } 56 | } 57 | 58 | &-result { 59 | position: absolute; 60 | width: 100%; 61 | background-color: #161616; 62 | z-index: 99999; 63 | padding: 23px; 64 | opacity: 0; 65 | pointer-events: none; 66 | transition: all .3s; 67 | border: 1px solid #2a2a2a; 68 | margin-top: -3px; 69 | border-bottom-left-radius: 6px; 70 | border-bottom-right-radius: 6px; 71 | 72 | &__name { 73 | font-size: 17px; 74 | opacity: 0.9; 75 | margin-bottom: 3px; 76 | } 77 | 78 | &__cat { 79 | font-size: 13px; 80 | opacity: 0.6; 81 | } 82 | 83 | &__item { 84 | display: flex; 85 | align-items: flex-start; 86 | padding-bottom: 10px; 87 | margin-bottom: 10px; 88 | border-bottom: 1px solid #f5f5f50f; 89 | justify-content: space-between; 90 | &:last-child{ 91 | margin-bottom: 0; 92 | padding-bottom: 0; 93 | border-bottom: 0; 94 | } 95 | 96 | img { 97 | width: 37px; 98 | height: 47px; 99 | border-radius: 6px; 100 | margin-right: 10px; 101 | } 102 | } 103 | 104 | &.active { 105 | pointer-events: all; 106 | opacity: 1; 107 | } 108 | } 109 | } 110 | } 111 | } 112 | } 113 | 114 | .header-nobg { 115 | overflow: hidden; 116 | height: 100vh; 117 | background-color: black; 118 | .header-menu{ 119 | opacity: 0; 120 | } 121 | 122 | @media (max-width: 600px) { 123 | overflow: auto; 124 | } 125 | .search{ 126 | opacity: 0; 127 | } 128 | 129 | &.overflow-hidden { 130 | .header { 131 | opacity: 0; 132 | @media (max-width: 600px) { 133 | display: none; 134 | } 135 | } 136 | 137 | .movie-detail__info { 138 | @media (max-width: 600px) { 139 | display: none; 140 | } 141 | } 142 | } 143 | 144 | .header { 145 | background-color: transparent; 146 | @media (max-width: 600px) { 147 | display: none; 148 | } 149 | } 150 | } -------------------------------------------------------------------------------- /src/assets/scss/product-detail.scss: -------------------------------------------------------------------------------- 1 | .movie { 2 | &-detail { 3 | 4 | &__wrp { 5 | position: absolute; 6 | width: 100%; 7 | top: 52%; 8 | transform: translateY(-50%); 9 | transition: all 0.4s ease-in; 10 | @media (max-width: 768px) { 11 | top:0; 12 | transform: none; 13 | width: 100%; 14 | overflow-x: hidden; 15 | background-color: black; 16 | height: -webkit-fill-available; 17 | } 18 | 19 | &.active-edit { 20 | padding-top: 0; 21 | } 22 | } 23 | 24 | &__content { 25 | transition: all .5s ease-in-out; 26 | 27 | &.active { 28 | opacity: 0; 29 | transform: translateY(200px); 30 | padding-top: 0; 31 | } 32 | } 33 | 34 | &__backdrop { 35 | position: absolute; 36 | width: 100%; 37 | height: 100vh; 38 | top: 0; 39 | z-index: -1; 40 | 41 | div { 42 | width: 100% !important; 43 | height: 100% !important; 44 | } 45 | 46 | img { 47 | width: 100%; 48 | height: 100%; 49 | object-fit: cover; 50 | } 51 | 52 | &:after { 53 | content: ''; 54 | position: absolute; 55 | width: 100%; 56 | height: 100%; 57 | transition: all .4s ease-in; 58 | background-color: #0a0a0ad1; 59 | top: 0; 60 | left: 0; 61 | } 62 | 63 | &.active { 64 | &:after { 65 | background-color: #0a0a0aed; 66 | } 67 | } 68 | } 69 | 70 | &__poster { 71 | position: relative; 72 | height: 414px; 73 | background-color: #b1b1b1; 74 | border-radius: 12px; 75 | img { 76 | box-shadow: 0 2px 8px #0000001a; 77 | border-radius: 12px; 78 | width: 100%; 79 | height: 100%; 80 | object-fit: cover; 81 | transition: all .8s ease; 82 | transform: scale(1); 83 | @media (max-width: 650px) { 84 | display: none; 85 | } 86 | } 87 | @media (max-width: 650px) { 88 | margin-top: 10px; 89 | } 90 | } 91 | 92 | &__title { 93 | font-weight: 700; 94 | 95 | @media (max-width: 768px) { 96 | font-size: 26px; 97 | margin-right: 18px; 98 | } 99 | 100 | span { 101 | font-weight: 100; 102 | color: #bdbdbd; 103 | } 104 | } 105 | 106 | &__top { 107 | position: relative; 108 | color: #bdbdbd; 109 | font-size: 15px; 110 | padding-left: 12px; 111 | 112 | &:before { 113 | content: ''; 114 | position: absolute; 115 | width: 5px; 116 | height: 5px; 117 | background-color: white; 118 | border-radius: 50px; 119 | left: 0; 120 | top: 9px; 121 | } 122 | } 123 | 124 | .CircularProgressbar { 125 | width: 60px; 126 | 127 | &-text { 128 | font-weight: 600; 129 | } 130 | 131 | &-path { 132 | stroke: #21d07a !important; 133 | } 134 | } 135 | 136 | &__icon { 137 | background-color: gainsboro; 138 | border-radius: 50px; 139 | padding: 3px; 140 | width: 40px; 141 | height: 40px; 142 | display: flex; 143 | align-items: center; 144 | justify-content: center; 145 | transition: all .4s; 146 | opacity: 0.4; 147 | 148 | img { 149 | width: 16px; 150 | } 151 | 152 | &:hover { 153 | opacity: 1; 154 | } 155 | 156 | &.opacity { 157 | opacity: 1; 158 | } 159 | } 160 | 161 | &__summary { 162 | font-size: 17px; 163 | color: #e4e4e4; 164 | line-height: 1.6; 165 | } 166 | 167 | .modal-video-body { 168 | max-width: 1200px; 169 | } 170 | 171 | &__spotify { 172 | position: absolute; 173 | width: 100%; 174 | height: 100%; 175 | bottom: 0; 176 | opacity: 0; 177 | border-bottom-left-radius: 12px; 178 | border-bottom-right-radius: 12px; 179 | right: 0; 180 | object-fit: cover; 181 | transform: scale(0); 182 | transition: all .6s ease-in-out; 183 | @media (max-width: 650px) { 184 | transform: none; 185 | opacity: 1; 186 | } 187 | 188 | div { 189 | width: 100% !important; 190 | height: 101% !important; 191 | } 192 | 193 | iframe { 194 | width: 100%; 195 | height: 100%; 196 | border-radius: 12px; 197 | } 198 | } 199 | 200 | &__edit { 201 | padding: 40px; 202 | top: 50%; 203 | border-radius: 9px; 204 | opacity: 0; 205 | position: absolute; 206 | width: 100%; 207 | transition: all 0.6s ease-in-out; 208 | transform: translateY(-20%); 209 | 210 | &.active { 211 | opacity: 1; 212 | transform: translateY(-50%); 213 | } 214 | 215 | .back-icon { 216 | position: absolute; 217 | right: 3%; 218 | transform: scale(1.8); 219 | z-index: 999; 220 | cursor: pointer; 221 | } 222 | 223 | @media (max-width: 650px) { 224 | padding: 0; 225 | top: 50px; 226 | transform: none !important; 227 | } 228 | } 229 | 230 | &__back{ 231 | position: absolute; 232 | top: -50px; 233 | cursor: pointer; 234 | img{ 235 | transform: scale(1.5); 236 | } 237 | @media (max-width: 650px) { 238 | top: 20px; 239 | z-index: 99; 240 | left: 6%; 241 | background-color: #79747440; 242 | padding: 5px 6px; 243 | border-radius: 50px; 244 | } 245 | } 246 | } 247 | } 248 | 249 | -------------------------------------------------------------------------------- /src/assets/scss/product-list.scss: -------------------------------------------------------------------------------- 1 | .movie { 2 | &-create { 3 | &__item { 4 | margin-bottom: 20px; 5 | 6 | input, 7 | textarea { 8 | width: 100%; 9 | padding: 9px 14px; 10 | border-radius: 5px; 11 | border: 0; 12 | border: 1px solid #313131; 13 | background-color: transparent; 14 | color: #c7c7c7; 15 | font-size: 15px; 16 | font-weight: 100; 17 | 18 | &:nth-child(3n) { 19 | margin-right: 0; 20 | } 21 | } 22 | } 23 | 24 | &__button { 25 | border: 0; 26 | padding: 8px 12px; 27 | border-radius: 5px; 28 | background-color: #94cc26; 29 | color: white; 30 | font-size: 14px; 31 | font-weight: 600; 32 | width: 100px; 33 | margin-left: auto; 34 | transition: all .3s; 35 | &:hover{ 36 | background-color: #7dad1f; 37 | color:white; 38 | } 39 | 40 | &.yellow { 41 | background-color: #ea8835; 42 | &:hover{ 43 | background-color: #d0762a; 44 | color:white; 45 | } 46 | } 47 | } 48 | 49 | &.edit { 50 | .movie-create__item { 51 | input { 52 | border: 1px solid #3e3e3e; 53 | background-color: #ffffff14; 54 | color: white; 55 | } 56 | } 57 | } 58 | 59 | &__form { 60 | p { 61 | font-size: 15px; 62 | color: #6f824a; 63 | margin-bottom: 5px; 64 | font-weight: 400; 65 | @media (max-width: 650px) { 66 | font-size: 10px; 67 | } 68 | } 69 | 70 | &.movie { 71 | p { 72 | color: #968136; 73 | } 74 | } 75 | } 76 | 77 | &__backdrop { 78 | position: absolute; 79 | height: 100vh; 80 | 81 | img { 82 | width: 100%; 83 | } 84 | } 85 | 86 | &.page { 87 | .movie-create__form{ 88 | background-color: #080808ba; 89 | padding: 20px 35px; 90 | border-radius: 9px; 91 | @media (max-width: 650px) { 92 | padding: 0; 93 | background-color: transparent; 94 | } 95 | } 96 | .movie-create__item { 97 | input, 98 | textarea { 99 | border: 1px solid #585858; 100 | } 101 | } 102 | } 103 | } 104 | 105 | &-add { 106 | position: relative; 107 | padding: 6px 24px; 108 | border-radius: 9px; 109 | color: white; 110 | text-align: center; 111 | z-index: 999; 112 | transition: all .3s; 113 | cursor: pointer; 114 | 115 | @media (max-width: 768px) { 116 | font-size: 12px; 117 | max-width: 146px; 118 | flex-shrink: 0; 119 | } 120 | 121 | &.green { 122 | background-color: #94cc26; 123 | &:hover{ 124 | background-color: #7dad1f; 125 | color:white; 126 | } 127 | } 128 | 129 | &.yellow { 130 | background-color: #ea8835; 131 | &:hover{ 132 | background-color: #d0762a; 133 | color:white; 134 | } 135 | } 136 | } 137 | 138 | &-item { 139 | &__img { 140 | width: 100%; 141 | height: 260px; 142 | object-fit: cover; 143 | box-shadow: 0 2px 8px #0000001a; 144 | border-radius: 12px; 145 | } 146 | 147 | &__name { 148 | color: black; 149 | font-size: 16px; 150 | font-weight: 700; 151 | transition: all 0.4s ease-in-out; 152 | } 153 | } 154 | 155 | .CircularProgressbar { 156 | width: 40px; 157 | margin-top: -30px; 158 | 159 | &-text { 160 | font-weight: 600; 161 | } 162 | 163 | &-path { 164 | stroke: #21d07a; 165 | } 166 | } 167 | } -------------------------------------------------------------------------------- /src/components/contentLoaderDetail.jsx: -------------------------------------------------------------------------------- 1 | import React, { PureComponent } from 'react' 2 | import ContentLoader from 'react-content-loader' 3 | 4 | class contentLoaderDetail extends PureComponent { 5 | render() { 6 | return ( 7 |
8 |
9 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 |
20 | 22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 |
30 | ) 31 | } 32 | } 33 | 34 | export default contentLoaderDetail; 35 | -------------------------------------------------------------------------------- /src/components/createGame.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react' 2 | import {connect} from 'react-redux' //redux ile bağlantı kurmak için connect gerekli. 3 | 4 | //Actions 5 | import {saveGames} from '../actions/games' 6 | 7 | //Class component 8 | class CreateGame extends Component { 9 | render(){ 10 | return ( 11 |
12 |
13 | 14 |
15 |
16 |

Oyun Ekle

17 |
18 |
19 |
20 |
21 |

Oyun Adı

22 | 23 |
24 |
25 |

Slug

26 | 27 |
28 |
29 |

Kategori

30 | 31 |
32 |
33 |
34 |
35 |

Poster URL

36 | 37 |
38 |
39 |

Müzik URL (Youtube)

40 | 41 |
42 |
43 |

Puan

44 | 45 |
46 |
47 |
48 |
49 |

Oyun Firması

50 | 51 |
52 |
53 |

Fragman URL (Youtube)

54 | 55 |
56 |
57 |

Oyun Süresi

58 | 59 |
60 |
61 |
62 |
63 |

Çıkış Yılı

64 | 65 |
66 |
67 |
68 |
69 |

Oyun Konusu

70 |