From 6d57d8afe61d733abe657f3c52d7f0e8b3869eb3 Mon Sep 17 00:00:00 2001 From: riship99 <40177825+riship99@users.noreply.github.com> Date: Sat, 31 Oct 2020 14:01:05 +0530 Subject: [PATCH] All The reaquired files for the amazon-clone project --- Amazon-clone/App.css | 42 +++++++++ Amazon-clone/App.js | 60 +++++++++++++ Amazon-clone/App.test.js | 9 ++ Amazon-clone/Checkout.css | 17 ++++ Amazon-clone/Checkout.js | 43 ++++++++++ Amazon-clone/CheckoutProduct.css | 33 ++++++++ Amazon-clone/CheckoutProduct.js | 41 +++++++++ Amazon-clone/Header.css | 69 +++++++++++++++ Amazon-clone/Header.js | 67 +++++++++++++++ Amazon-clone/Home.css | 20 +++++ Amazon-clone/Home.js | 117 +++++++++++++++++++++++++ Amazon-clone/Login.css | 66 +++++++++++++++ Amazon-clone/Login.js | 68 +++++++++++++++ Amazon-clone/Product.css | 41 +++++++++ Amazon-clone/Product.js | 48 +++++++++++ Amazon-clone/StateProvider.js | 14 +++ Amazon-clone/Subtotal.css | 31 +++++++ Amazon-clone/Subtotal.js | 38 +++++++++ Amazon-clone/index.css | 31 +++++++ Amazon-clone/index.js | 22 +++++ Amazon-clone/logo.svg | 7 ++ Amazon-clone/reducer.js | 56 ++++++++++++ Amazon-clone/serviceWorker.js | 141 +++++++++++++++++++++++++++++++ Amazon-clone/setupTests.js | 5 ++ 24 files changed, 1086 insertions(+) create mode 100644 Amazon-clone/App.css create mode 100644 Amazon-clone/App.js create mode 100644 Amazon-clone/App.test.js create mode 100644 Amazon-clone/Checkout.css create mode 100644 Amazon-clone/Checkout.js create mode 100644 Amazon-clone/CheckoutProduct.css create mode 100644 Amazon-clone/CheckoutProduct.js create mode 100644 Amazon-clone/Header.css create mode 100644 Amazon-clone/Header.js create mode 100644 Amazon-clone/Home.css create mode 100644 Amazon-clone/Home.js create mode 100644 Amazon-clone/Login.css create mode 100644 Amazon-clone/Login.js create mode 100644 Amazon-clone/Product.css create mode 100644 Amazon-clone/Product.js create mode 100644 Amazon-clone/StateProvider.js create mode 100644 Amazon-clone/Subtotal.css create mode 100644 Amazon-clone/Subtotal.js create mode 100644 Amazon-clone/index.css create mode 100644 Amazon-clone/index.js create mode 100644 Amazon-clone/logo.svg create mode 100644 Amazon-clone/reducer.js create mode 100644 Amazon-clone/serviceWorker.js create mode 100644 Amazon-clone/setupTests.js diff --git a/Amazon-clone/App.css b/Amazon-clone/App.css new file mode 100644 index 0000000..63518fd --- /dev/null +++ b/Amazon-clone/App.css @@ -0,0 +1,42 @@ +*{ + margin: 0; + padding: 0; + } + .App { + text-align: center; +} + +.App-logo { + height: 40vmin; + pointer-events: none; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +.App-link { + color: #61dafb; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} diff --git a/Amazon-clone/App.js b/Amazon-clone/App.js new file mode 100644 index 0000000..0ac6b4f --- /dev/null +++ b/Amazon-clone/App.js @@ -0,0 +1,60 @@ + +import React, { useEffect } from "react"; +import "./App.css"; +import Header from "./Header"; +import Home from "./Home"; +import { BrowserRouter as Router, Switch, Route } from "react-router-dom"; +import Checkout from "./Checkout"; +import Login from "./Login"; +import { auth } from "./firebase"; +import { useStateValue } from "./StateProvider"; + +function App() { + const [{}, dispatch] = useStateValue(); +useEffect(() => { + + auth.onAuthStateChanged((authUser) => { + console.log("THE USER IS >>> ", authUser); + + if (authUser) { + // the user logged in + dispatch({ + type: "SET_USER", + user: authUser, + }); + } else { + // the user is logged out + dispatch({ + type: "SET_USER", + user: null, + }); + } + }); +}, []); + + +return ( +
+ +
+ + + + + + +
+ + + + +
+ + + +
+
+
+); +} +export default App; \ No newline at end of file diff --git a/Amazon-clone/App.test.js b/Amazon-clone/App.test.js new file mode 100644 index 0000000..4db7ebc --- /dev/null +++ b/Amazon-clone/App.test.js @@ -0,0 +1,9 @@ +import React from 'react'; +import { render } from '@testing-library/react'; +import App from './App'; + +test('renders learn react link', () => { + const { getByText } = render(); + const linkElement = getByText(/learn react/i); + expect(linkElement).toBeInTheDocument(); +}); diff --git a/Amazon-clone/Checkout.css b/Amazon-clone/Checkout.css new file mode 100644 index 0000000..10bbcc4 --- /dev/null +++ b/Amazon-clone/Checkout.css @@ -0,0 +1,17 @@ +.checkout { + display: flex; + padding: 20px; + background-color: white; + height: max-content; + } + + .checkout__ad { + width: 100%; + margin-bottom: 10px; + } + + .checkout__title { + margin-right: 10px; + padding: 10px; + border-bottom: 1px solid lightgray; + } \ No newline at end of file diff --git a/Amazon-clone/Checkout.js b/Amazon-clone/Checkout.js new file mode 100644 index 0000000..3368552 --- /dev/null +++ b/Amazon-clone/Checkout.js @@ -0,0 +1,43 @@ +import React from "react"; +import "./Checkout.css"; +import Subtotal from "./Subtotal"; +import { useStateValue } from "./StateProvider"; +import CheckoutProduct from "./CheckoutProduct"; + +function Checkout() { + const [{ basket, user }, dispatch] = useStateValue(); + + return ( +
+
+ + +
+

Hello, {user?.email}

+

Your shopping Basket

+ + {basket.map(item => ( + + ))} + +
+
+ +
+ +
+
+ ); +} + +export default Checkout; \ No newline at end of file diff --git a/Amazon-clone/CheckoutProduct.css b/Amazon-clone/CheckoutProduct.css new file mode 100644 index 0000000..84585c2 --- /dev/null +++ b/Amazon-clone/CheckoutProduct.css @@ -0,0 +1,33 @@ + +.checkoutProduct { + display: flex; + margin-top: 20px; + margin-bottom: 20px; +} + +.checkoutProduct__info { + padding-left: 20px +} + +.checkoutProduct__info > button { + background: #f0c14b; + border: 1px solid; + margin-top: 10px; + border-color: #a88734 #9c7e31 #846a29; + color: #111; +} + +.checkoutProduct__image { + object-fit: contain; + width: 180px; + height: 180px; + } + +.checkoutProduct__rating { + display: flex; + } + +.checkoutProduct__title { + font-size: 17px; + font-weight: 800; +} \ No newline at end of file diff --git a/Amazon-clone/CheckoutProduct.js b/Amazon-clone/CheckoutProduct.js new file mode 100644 index 0000000..32bfd3a --- /dev/null +++ b/Amazon-clone/CheckoutProduct.js @@ -0,0 +1,41 @@ +import React from 'react'; +import './CheckoutProduct.css' +import { useStateValue } from "./StateProvider"; + +function CheckoutProduct({ id, image, title, price, rating, hideButton }) { + const [{ basket }, dispatch] = useStateValue(); + + const removeFromBasket = () => { + // remove the item from the basket + dispatch({ + type: 'REMOVE_FROM_BASKET', + id: id, + }) + } + + return ( +
+ + +
+

{title}

+

+ $ + {price} +

+
+ {Array(rating) + .fill() + .map((_, i) => ( +

🌟

+ ))} +
+ {!hideButton && ( + + )} +
+
+ ) +} + +export default CheckoutProduct diff --git a/Amazon-clone/Header.css b/Amazon-clone/Header.css new file mode 100644 index 0000000..5291ffc --- /dev/null +++ b/Amazon-clone/Header.css @@ -0,0 +1,69 @@ +.header { + height: 60px; + display: flex; + align-items: center; + background-color: #131921; + position: sticky; + top: 0; + z-index: 100; + } + + .header__logo { + width: 100px; + object-fit: contain; + margin: 0 20px; + margin-top: 18px; + } + + .header__search { + display: flex; + flex: 1; + align-items: center; + border-radius: 24px; + } + + .header__searchInput { + height: 12px; + padding: 10px; + border: none; + width: 100%; + } + + .header__searchIcon { + padding: 5px; + height: 22px !important; + background-color: #cd9042; + } + + .header__optionLineOne { + font-size: 10px; + } + + .header__optionLineTwo { + font-size: 13px; + font-weight: 800; + } + + .header__optionBasket { + display: flex; + align-items: center; + color: white; + } + + .header__basketCount { + margin-left: 10px; + margin-right: 10px; + } + + .header__nav { + display: flex; + justify-content: space-evenly; + } + + .header__option { + display: flex; + flex-direction: column; + margin-left: 10px; + margin-right: 10px; + color: white; + } \ No newline at end of file diff --git a/Amazon-clone/Header.js b/Amazon-clone/Header.js new file mode 100644 index 0000000..de81213 --- /dev/null +++ b/Amazon-clone/Header.js @@ -0,0 +1,67 @@ +import React from "react"; +import "./Header.css"; +import SearchIcon from "@material-ui/icons/Search"; +import ShoppingBasketIcon from "@material-ui/icons/ShoppingBasket"; +import { Link } from "react-router-dom"; +import { useStateValue } from "./StateProvider"; +import { auth } from "./firebase"; +import Product from "./Product"; + +function Header() { + const [{ basket, user }, dispatch] = useStateValue(); + + const handleAuthenticaton = () => { + if (user) { + auth.signOut(); + } + } + + return ( +
+ + + + +
+ + +
+ +
+ +
+ Hello {!user ? 'Guest' : user.email} + {user ? 'Sign Out' : 'Sign In'} +
+ + + +
+ Returns + & Orders +
+ + + +
+ Your + Prime +
+ + +
+ + + {basket?.length} + +
+ +
+
+ ); +} + +export default Header; \ No newline at end of file diff --git a/Amazon-clone/Home.css b/Amazon-clone/Home.css new file mode 100644 index 0000000..c96edba --- /dev/null +++ b/Amazon-clone/Home.css @@ -0,0 +1,20 @@ +.home { + display: flex; + justify-content: center; + margin-left: auto; + margin-right: auto; + max-width: 1500px; + } + .home__image { + width: 100%; + z-index: -1; + margin-bottom: -150px; + mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0)); + } + .home__row { + display: flex; + z-index: 1; + margin-left: 5px; + margin-right: 5px; + padding-top: 0px; + } \ No newline at end of file diff --git a/Amazon-clone/Home.js b/Amazon-clone/Home.js new file mode 100644 index 0000000..c423825 --- /dev/null +++ b/Amazon-clone/Home.js @@ -0,0 +1,117 @@ +import React from "react"; +import "./Home.css"; +import Product from "./Product"; + +function Home() { + return ( +
+
+ + +
+ + +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ + +
+ + + + +
+
+
+
+
+ +
+
+
+ ); +} + +export default Home; \ No newline at end of file diff --git a/Amazon-clone/Login.css b/Amazon-clone/Login.css new file mode 100644 index 0000000..e54967b --- /dev/null +++ b/Amazon-clone/Login.css @@ -0,0 +1,66 @@ +.login { + background-color: white; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; +} + +.login__logo { + margin-top: 20px; + margin-bottom: 20px; + object-fit: contain; + width: 100px; + margin-right: auto; + margin-left: auto; + } + +.login__container { + width: 300px; + height: fit-content; + display: flex; + flex-direction: column; + border-radius: 5px; + border: 1px solid lightgray; + padding: 20px; +} + +.login__container > h1 { + font-weight: 500; + margin-bottom: 20px; + } + +.login__container > form > h5 { + margin-bottom: 5px; +} + +.login__container > form > input { + height: 30px; + margin-bottom: 10px; + background-color: white; + width: 98%; + } + +.login__container > p { + margin-top: 15px; + font-size: 12px; +} + +.login__signInButton { + background: #f0c14b; + border-radius: 2px; + width: 100%; + height: 30px; + border: 1px solid; + margin-top: 10px; + border-color: #a88734 #9c7e31 #846a29; + } + + .login__registerButton { + border-radius: 2px; + width: 100%; + height: 30px; + border: 1px solid; + margin-top: 10px; + border-color: darkgray; + } \ No newline at end of file diff --git a/Amazon-clone/Login.js b/Amazon-clone/Login.js new file mode 100644 index 0000000..f82ce0c --- /dev/null +++ b/Amazon-clone/Login.js @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; +import './Login.css' +import { Link, useHistory } from "react-router-dom"; +import { auth } from "./firebase"; + +function Login() { + const history = useHistory(); + const [email, setEmail] = useState(''); + const [password, setPassword] = useState(''); + + const signIn = e => { + e.preventDefault(); + + auth + .signInWithEmailAndPassword(email, password) + .then(auth => { + history.push('/') + }) + .catch(error => alert(error.message)) + } + + const register = e => { + e.preventDefault(); + + auth + .createUserWithEmailAndPassword(email, password) + .then((auth) => { + // it successfully created a new user with email and password + if (auth) { + history.push('/') + } + }) + .catch(error => alert(error.message)) + } + + return ( +
+ + + + +
+

Sign-in

+ +
+
E-mail
+ setEmail(e.target.value)} /> + +
Password
+ setPassword(e.target.value)} /> + + +
+ +

+ By signing in you are agreed to our terms and conditions of the website. +

+ + +
+
+ ) +} + +export default Login \ No newline at end of file diff --git a/Amazon-clone/Product.css b/Amazon-clone/Product.css new file mode 100644 index 0000000..58d34bd --- /dev/null +++ b/Amazon-clone/Product.css @@ -0,0 +1,41 @@ +.product { + display: flex; + flex-direction: column; + align-items: center; + justify-content: flex-end; + margin: 10px; + padding: 20px; + width: 100%; + max-height: 400px; + min-width: 100px; + background-color: white; + z-index: 1; + } + + .product__rating { + display: flex; + } + + .product > img { + max-height: 200px; + width: 100%; + object-fit: contain; + margin-bottom: 15px; + } + + .product > button { + background: #f0c14b; + border: 1px solid; + margin-top: 10px; + border-color: #a88734 #9c7e31 #846a29; + color: #111; + } + + .product__price { + margin-top: 5px; + } + + .product__info { + height: 100px; + margin-bottom: 15px; + } \ No newline at end of file diff --git a/Amazon-clone/Product.js b/Amazon-clone/Product.js new file mode 100644 index 0000000..2c516aa --- /dev/null +++ b/Amazon-clone/Product.js @@ -0,0 +1,48 @@ +import React from "react"; +import "./Product.css"; +import { useStateValue } from "./StateProvider"; + +function Product({ id, title, image, price, rating }) { + const [{ basket }, dispatch] = useStateValue(); + + const addToBasket = () => { + // dispatch the item into the data layer + (dispatch)({ + + + type: "ADD_TO_BASKET", + item: { + id: id, + title: title, + image: image, + price: price, + rating: rating, + }, + }); + }; + + return ( +
+
+

{title}

+

+ $ + {price} +

+
+ {Array(rating) + .fill() + .map((_, i) => ( +

🌟

+ ))} +
+
+ + + + +
+ ); +} + +export default Product; \ No newline at end of file diff --git a/Amazon-clone/StateProvider.js b/Amazon-clone/StateProvider.js new file mode 100644 index 0000000..5370a2f --- /dev/null +++ b/Amazon-clone/StateProvider.js @@ -0,0 +1,14 @@ +import React, { createContext, useContext, useReducer } from "react"; + +// Prepares the dataLayer +export const StateContext = createContext(); + +// Wrap our app and provide the Data layer +export const StateProvider = ({ reducer, initialState, children }) => ( + + {children} + +); + +// Pull information from the data layer +export const useStateValue = () => useContext(StateContext); \ No newline at end of file diff --git a/Amazon-clone/Subtotal.css b/Amazon-clone/Subtotal.css new file mode 100644 index 0000000..06b089e --- /dev/null +++ b/Amazon-clone/Subtotal.css @@ -0,0 +1,31 @@ +.subtotal { + display: flex; + flex-direction: column; + justify-content: space-between; + width: 300px; + height: 100px; + padding: 20px; + background-color: #f3f3f3; + border: 1px solid #dddddd; + border-radius: 3px; + } + + .subtotal__gift { + display: flex; + align-items: center; + } + + .subtotal__gift > input { + margin-right: 5px; + } + + .subtotal > button { + background: #f0c14b; + border-radius: 2px; + width: 100%; + height: 30px; + border: 1px solid; + margin-top: 10px; + border-color: #a88734 #9c7e31 #846a29; + color: #111; + } \ No newline at end of file diff --git a/Amazon-clone/Subtotal.js b/Amazon-clone/Subtotal.js new file mode 100644 index 0000000..df0afcb --- /dev/null +++ b/Amazon-clone/Subtotal.js @@ -0,0 +1,38 @@ +import React from "react"; +import "./Subtotal.css"; +import CurrencyFormat from "react-currency-format"; +import { useStateValue } from "./StateProvider"; +import { getBasketTotal } from "./reducer"; +import { useHistory } from "react-router-dom"; + +function Subtotal() { + const history = useHistory(); + const [{ basket }, dispatch] = useStateValue(); + + return ( +
+ ( + <> +

+ {/* Part of the homework */} + Subtotal ({basket.length} items): {value} +

+ + This order contains a gift + + + )} + decimalScale={2} + value={getBasketTotal(basket)} // Part of the homework + displayType={"text"} + thousandSeparator={true} + prefix={"$"} + /> + + +
+ ); +} + +export default Subtotal; diff --git a/Amazon-clone/index.css b/Amazon-clone/index.css new file mode 100644 index 0000000..b026f20 --- /dev/null +++ b/Amazon-clone/index.css @@ -0,0 +1,31 @@ +body { + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + monospace; +} +* { + margin: 0; +} + +body { + background-color: rgb(234, 237, 237); + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", + "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", + sans-serif; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +code { + font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", + monospace; +} \ No newline at end of file diff --git a/Amazon-clone/index.js b/Amazon-clone/index.js new file mode 100644 index 0000000..60f595d --- /dev/null +++ b/Amazon-clone/index.js @@ -0,0 +1,22 @@ + +import React from "react"; +import ReactDOM from "react-dom"; +import "./index.css"; +import App from "./App"; +import * as serviceWorker from "./serviceWorker"; +import reducer, { initialState } from "./reducer"; +import { StateProvider } from "./StateProvider"; + +ReactDOM.render( + + + + + , + document.getElementById("root") +); + +// If you want your app to work offline and load faster, you can change +// unregister() to register() below. Note this comes with some pitfalls. +// Learn more about service workers: https://bit.ly/CRA-PWA +serviceWorker.unregister(); \ No newline at end of file diff --git a/Amazon-clone/logo.svg b/Amazon-clone/logo.svg new file mode 100644 index 0000000..6b60c10 --- /dev/null +++ b/Amazon-clone/logo.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Amazon-clone/reducer.js b/Amazon-clone/reducer.js new file mode 100644 index 0000000..c509885 --- /dev/null +++ b/Amazon-clone/reducer.js @@ -0,0 +1,56 @@ +export const initialState = { + basket: [], + user: null + }; + + // Selector + export const getBasketTotal = (basket) => + basket?.reduce((amount, item) => item.price + amount, 0); + + const reducer = (state, action) => { + console.log(action); + switch (action.type) { + case "ADD_TO_BASKET": + return { + ...state, + basket: [...state.basket, action.item], + }; + + case 'EMPTY_BASKET': + return { + ...state, + basket: [] + } + + case "REMOVE_FROM_BASKET": + const index = state.basket.findIndex( + (basketItem) => basketItem.id === action.id + ); + let newBasket = [...state.basket]; + + if (index >= 0) { + newBasket.splice(index, 1); + + } else { + console.warn( + `Cant remove product (id: ${action.id}) as its not in basket!` + ) + } + + return { + ...state, + basket: newBasket + } + + case "SET_USER": + return { + ...state, + user: action.user + } + + default: + return state; + } + }; + + export default reducer; \ No newline at end of file diff --git a/Amazon-clone/serviceWorker.js b/Amazon-clone/serviceWorker.js new file mode 100644 index 0000000..b04b771 --- /dev/null +++ b/Amazon-clone/serviceWorker.js @@ -0,0 +1,141 @@ +// This optional code is used to register a service worker. +// register() is not called by default. + +// This lets the app load faster on subsequent visits in production, and gives +// it offline capabilities. However, it also means that developers (and users) +// will only see deployed updates on subsequent visits to a page, after all the +// existing tabs open on the page have been closed, since previously cached +// resources are updated in the background. + +// To learn more about the benefits of this model and instructions on how to +// opt-in, read https://bit.ly/CRA-PWA + +const isLocalhost = Boolean( + window.location.hostname === 'localhost' || + // [::1] is the IPv6 localhost address. + window.location.hostname === '[::1]' || + // 127.0.0.0/8 are considered localhost for IPv4. + window.location.hostname.match( + /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ + ) +); + +export function register(config) { + if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { + // The URL constructor is available in all browsers that support SW. + const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); + if (publicUrl.origin !== window.location.origin) { + // Our service worker won't work if PUBLIC_URL is on a different origin + // from what our page is served on. This might happen if a CDN is used to + // serve assets; see https://github.com/facebook/create-react-app/issues/2374 + return; + } + + window.addEventListener('load', () => { + const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; + + if (isLocalhost) { + // This is running on localhost. Let's check if a service worker still exists or not. + checkValidServiceWorker(swUrl, config); + + // Add some additional logging to localhost, pointing developers to the + // service worker/PWA documentation. + navigator.serviceWorker.ready.then(() => { + console.log( + 'This web app is being served cache-first by a service ' + + 'worker. To learn more, visit https://bit.ly/CRA-PWA' + ); + }); + } else { + // Is not localhost. Just register service worker + registerValidSW(swUrl, config); + } + }); + } +} + +function registerValidSW(swUrl, config) { + navigator.serviceWorker + .register(swUrl) + .then(registration => { + registration.onupdatefound = () => { + const installingWorker = registration.installing; + if (installingWorker == null) { + return; + } + installingWorker.onstatechange = () => { + if (installingWorker.state === 'installed') { + if (navigator.serviceWorker.controller) { + // At this point, the updated precached content has been fetched, + // but the previous service worker will still serve the older + // content until all client tabs are closed. + console.log( + 'New content is available and will be used when all ' + + 'tabs for this page are closed. See https://bit.ly/CRA-PWA.' + ); + + // Execute callback + if (config && config.onUpdate) { + config.onUpdate(registration); + } + } else { + // At this point, everything has been precached. + // It's the perfect time to display a + // "Content is cached for offline use." message. + console.log('Content is cached for offline use.'); + + // Execute callback + if (config && config.onSuccess) { + config.onSuccess(registration); + } + } + } + }; + }; + }) + .catch(error => { + console.error('Error during service worker registration:', error); + }); +} + +function checkValidServiceWorker(swUrl, config) { + // Check if the service worker can be found. If it can't reload the page. + fetch(swUrl, { + headers: { 'Service-Worker': 'script' }, + }) + .then(response => { + // Ensure service worker exists, and that we really are getting a JS file. + const contentType = response.headers.get('content-type'); + if ( + response.status === 404 || + (contentType != null && contentType.indexOf('javascript') === -1) + ) { + // No service worker found. Probably a different app. Reload the page. + navigator.serviceWorker.ready.then(registration => { + registration.unregister().then(() => { + window.location.reload(); + }); + }); + } else { + // Service worker found. Proceed as normal. + registerValidSW(swUrl, config); + } + }) + .catch(() => { + console.log( + 'No internet connection found. App is running in offline mode.' + ); + }); +} + +export function unregister() { + if ('serviceWorker' in navigator) { + navigator.serviceWorker.ready + .then(registration => { + registration.unregister(); + }) + .catch(error => { + console.error(error.message); + }); + } +} diff --git a/Amazon-clone/setupTests.js b/Amazon-clone/setupTests.js new file mode 100644 index 0000000..74b1a27 --- /dev/null +++ b/Amazon-clone/setupTests.js @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom/extend-expect';