make it better
This commit is contained in:
1
src/actions/index.js
Normal file
1
src/actions/index.js
Normal file
@@ -0,0 +1 @@
|
||||
export * from './product';
|
||||
18
src/actions/product.js
Normal file
18
src/actions/product.js
Normal file
@@ -0,0 +1,18 @@
|
||||
import * as types from '../constants/types';
|
||||
|
||||
export function getProducts() {
|
||||
return dispatch => {
|
||||
fetch(`${process.env.REACT_APP_API_URL}/v1/api/products`)
|
||||
.then(response => response.json())
|
||||
.then(response => {
|
||||
dispatch({
|
||||
type: types.FETCH_PRODUCTS,
|
||||
payload: response
|
||||
});
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export function compare(product) {
|
||||
return {type: types.COMPARE_PRODUCT, product};
|
||||
}
|
||||
65
src/components/Compare/index.css
Normal file
65
src/components/Compare/index.css
Normal file
@@ -0,0 +1,65 @@
|
||||
.compare table {
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0px 13px 21px -5px rgba(0, 0, 0, 0.05);
|
||||
border: 1px solid #eee;
|
||||
font-size: 18px;
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.compare .thead-default th {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.compare table tr > td,
|
||||
.compare table tr > th {
|
||||
padding-top: 25px;
|
||||
padding-bottom: 25px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.compare table thead th {
|
||||
font-size: 20px;
|
||||
color: #393c45;
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.compare table th[scope="row"] {
|
||||
font-size: 20px;
|
||||
color: #393c45;
|
||||
font-weight: normal;
|
||||
background-color: #f9f9f9;
|
||||
border: 1px solid #eee;
|
||||
text-align: left;
|
||||
padding-left: 45px;
|
||||
}
|
||||
|
||||
.compare table tr.condition {
|
||||
color: #fff;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
.compare table tr.colors span {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
background-color: #000;
|
||||
display: inline-block;
|
||||
margin-right: 5px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.compare table td.red,
|
||||
.compare table tr.colors span.red {
|
||||
background-color: #ff715b;
|
||||
}
|
||||
|
||||
.compare table td.green,
|
||||
.compare table tr.colors span.green {
|
||||
background-color: #48cfad;
|
||||
}
|
||||
|
||||
.compare table td.blue,
|
||||
.compare table tr.colors span.blue {
|
||||
background-color: #0197F6;
|
||||
}
|
||||
140
src/components/Compare/index.js
Normal file
140
src/components/Compare/index.js
Normal file
@@ -0,0 +1,140 @@
|
||||
import React from 'react'
|
||||
import {Table} from 'reactstrap'
|
||||
import './index.css'
|
||||
|
||||
const Compare = ({products}) =>
|
||||
<div className="row compare">
|
||||
<div className="col-12 mt-5 text-center">
|
||||
<div className={(products.length < 2
|
||||
? 'hidden-xs-up'
|
||||
: '')}>
|
||||
<Table>
|
||||
<thead className="thead-default">
|
||||
<tr>
|
||||
<th></th>
|
||||
{products.map(product =>
|
||||
<th key={product.id}>
|
||||
{product.name}
|
||||
</th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr className="price">
|
||||
<th scope="row">Price</th>
|
||||
{products.map(product =>
|
||||
<td key={product.id} className="text-center">{product.price}</td>
|
||||
)}
|
||||
</tr>
|
||||
<tr className="colors">
|
||||
<th scope="row">Colors</th>
|
||||
{products.map(product =>
|
||||
<td key={product.id}>
|
||||
{product.colors.map((color, index) =>
|
||||
<span key={index} className={color}></span>
|
||||
)}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
<tr className="condition">
|
||||
<th scope="row">Condition</th>
|
||||
{products.map(product =>
|
||||
<td key={product.id} className={product.condition === "Used" ? "red" : "green"}>
|
||||
{product.condition}
|
||||
</td>
|
||||
)}
|
||||
</tr>
|
||||
</tbody>
|
||||
</Table>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
// const Compare = ({products}) =>
|
||||
// <div className="row">
|
||||
// <div className="col-12 mt-5">
|
||||
// <h3 className={"text-center " + (products.length > 1 ? 'hidden-xs-up' : '')}>
|
||||
// Select two or more products
|
||||
// </h3>
|
||||
//
|
||||
// <div className={(products.length < 2 ? 'hidden-xs-up' : '')}>
|
||||
// <Table>
|
||||
// <thead>
|
||||
// <tr>
|
||||
// <th></th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id}>
|
||||
// <img width="100%"
|
||||
// src={`${process.env.REACT_APP_API_URL}/v1/api/products/image/${product.img}`}
|
||||
// alt={product.name}/>
|
||||
// </td>
|
||||
// )}
|
||||
// </tr>
|
||||
// </thead>
|
||||
// <tbody>
|
||||
// <tr>
|
||||
// <th>Name</th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id} className="text-center">{product.name}</td>
|
||||
// )}
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <th>Categories</th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id}>
|
||||
// {product.categories.map((category, index) =>
|
||||
// <div className="text-center category" key={index}>{category}</div>
|
||||
// )}
|
||||
// </td>
|
||||
// )}
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <th>Balance Transfer Rates</th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id} className="text-center">
|
||||
// <div className="rate">{product.rates.balance.rate}% for up to</div>
|
||||
// <div className="period">{product.rates.balance.period} months</div>
|
||||
// <div className="fee">({product.rates.balance.fee}% handling fee)</div>
|
||||
// </td>
|
||||
// )}
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <th>Money Transfer Rates</th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id} className="text-center">
|
||||
// <div className="rate">{product.rates.money.rate}% for up to</div>
|
||||
// <div className="period">{product.rates.money.period} months</div>
|
||||
// <div className="fee">({product.rates.money.fee}% handling fee)</div>
|
||||
// </td>
|
||||
// )}
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <th>Card Purchases</th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id} className="text-center">
|
||||
// <div className="rate">{product.rates.purchases.rate}% for up to</div>
|
||||
// <div className="period">{product.rates.purchases.period} months</div>
|
||||
// <div className="fee">({product.rates.purchases.fee}% handling fee)</div>
|
||||
// </td>
|
||||
// )}
|
||||
// </tr>
|
||||
// <tr>
|
||||
// <th>Additional Info</th>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id} className="text-center">{product.info}</td>
|
||||
// )}
|
||||
// </tr>
|
||||
// <tr className="text-center">
|
||||
// <td></td>
|
||||
// {products.map(product =>
|
||||
// <td key={product.id}>
|
||||
// <Button color="primary">More info</Button>
|
||||
// </td>
|
||||
// )}
|
||||
// </tr>
|
||||
// </tbody>
|
||||
// </Table>
|
||||
// </div>
|
||||
// </div>
|
||||
// </div>;
|
||||
|
||||
export default Compare;
|
||||
3
src/components/Header/index.css
Normal file
3
src/components/Header/index.css
Normal file
@@ -0,0 +1,3 @@
|
||||
header {
|
||||
margin-top: 10vh;
|
||||
}
|
||||
17
src/components/Header/index.js
Normal file
17
src/components/Header/index.js
Normal file
@@ -0,0 +1,17 @@
|
||||
import React from 'react'
|
||||
import './index.css'
|
||||
|
||||
export default class Header extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="container">
|
||||
<header>
|
||||
<div className="row">
|
||||
<div className="col-12 text-center">
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
102
src/components/Product/index.css
Normal file
102
src/components/Product/index.css
Normal file
@@ -0,0 +1,102 @@
|
||||
.product {
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
padding-bottom: 100px;
|
||||
border-radius: 5px;
|
||||
overflow: hidden;
|
||||
-webkit-transition: all 500ms ease-out;
|
||||
-moz-transition: all 500ms ease-out;
|
||||
-o-transition: all 500ms ease-out;
|
||||
transition: all 500ms ease-out;
|
||||
}
|
||||
|
||||
.product:hover {
|
||||
box-shadow: 0px 13px 21px -5px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.product img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stats-container {
|
||||
background: #fff;
|
||||
padding: 25px 15px;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.stats-container .product_name {
|
||||
font-size: 22px;
|
||||
color: #393c45;
|
||||
}
|
||||
|
||||
.stats-container p {
|
||||
font-size: 16px;
|
||||
color: #b1b1b3;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.stats-container .product_price {
|
||||
float: right;
|
||||
color: #48cfad;
|
||||
font-size: 22px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.image_overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: #48cfad;
|
||||
opacity: 0;
|
||||
-webkit-transition: all 200ms ease-out;
|
||||
-moz-transition: all 200ms ease-out;
|
||||
-o-transition: all 200ms ease-out;
|
||||
transition: all 200ms ease-out;
|
||||
}
|
||||
|
||||
.product.compare .image_overlay,
|
||||
.product:hover .image_overlay {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.view_details {
|
||||
position: absolute;
|
||||
top: 112px;
|
||||
left: 50%;
|
||||
margin-left: -85px;
|
||||
border: 2px solid #fff;
|
||||
color: #fff;
|
||||
font-size: 19px;
|
||||
text-align: center;
|
||||
text-transform: uppercase;
|
||||
font-weight: 700;
|
||||
padding: 10px 0;
|
||||
width: 172px;
|
||||
opacity: 0;
|
||||
-webkit-transition: all 200ms ease-out;
|
||||
-moz-transition: all 200ms ease-out;
|
||||
-o-transition: all 200ms ease-out;
|
||||
transition: all 200ms ease-out;
|
||||
}
|
||||
|
||||
.view_details:hover {
|
||||
background: #fff;
|
||||
color: #48cfad;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.product:hover .view_details {
|
||||
opacity: 1;
|
||||
width: 152px;
|
||||
font-size: 15px;
|
||||
margin-left: -75px;
|
||||
top: 150px;
|
||||
-webkit-transition: all 200ms ease-out;
|
||||
-moz-transition: all 200ms ease-out;
|
||||
-o-transition: all 200ms ease-out;
|
||||
transition: all 200ms ease-out;
|
||||
}
|
||||
34
src/components/Product/index.js
Normal file
34
src/components/Product/index.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import React from 'react'
|
||||
import './index.css'
|
||||
|
||||
// const Product = ({product, compare}) =>
|
||||
// <div key={product.id} className="col-3 product-card">
|
||||
// <Card inverse
|
||||
// onClick={() => compare(product)}
|
||||
// color={product.compare ? "success" : "primary"}
|
||||
// >
|
||||
// <CardBlock>
|
||||
// <CardTitle>{product.name}</CardTitle>
|
||||
// </CardBlock>
|
||||
// </Card>
|
||||
// </div>;
|
||||
|
||||
const Product = ({product, compare}) =>
|
||||
<div key={product.id} className="col-3">
|
||||
<div className={"product " + (product.compare ? "compare" : "")} >
|
||||
<img src={product.image} alt={product.name} />
|
||||
<div className="image_overlay"></div>
|
||||
<div className="view_details" onClick={() => compare(product)}>
|
||||
{product.compare ? "Remove" : "Compare"}
|
||||
</div>
|
||||
<div className="stats">
|
||||
<div className="stats-container">
|
||||
<span className="product_price">{product.price}</span>
|
||||
<span className="product_name">{product.name}</span>
|
||||
<p>Men's running shirt</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
export default Product;
|
||||
13
src/components/ProductList/index.js
Normal file
13
src/components/ProductList/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import React from 'react'
|
||||
import Product from '../Product'
|
||||
|
||||
const ProductList = ({products, compare}) =>
|
||||
<div>
|
||||
<div className="row mt-3">
|
||||
{products.map(product =>
|
||||
<Product key={product.id} product={product} compare={compare} />
|
||||
)}
|
||||
</div>
|
||||
</div>;
|
||||
|
||||
export default ProductList;
|
||||
2
src/constants/types.js
Normal file
2
src/constants/types.js
Normal file
@@ -0,0 +1,2 @@
|
||||
export const FETCH_PRODUCTS = 'FETCH_PRODUCTS';
|
||||
export const COMPARE_PRODUCT = 'COMPARE_PRODUCT';
|
||||
25
src/containers/App/index.js
Normal file
25
src/containers/App/index.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import React, {Component} from 'react';
|
||||
import Header from '../../components/Header'
|
||||
import {Route, Switch} from 'react-router-dom'
|
||||
|
||||
import './style.css';
|
||||
|
||||
import Home from '../Home';
|
||||
import NotFound from '../NotFound';
|
||||
|
||||
export default class App extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div className="App">
|
||||
<Header />
|
||||
|
||||
<div className="container mt-4">
|
||||
<Switch>
|
||||
<Route exact path="/" component={Home}/>
|
||||
<Route component={NotFound}/>
|
||||
</Switch>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
0
src/containers/App/style.css
Normal file
0
src/containers/App/style.css
Normal file
42
src/containers/Home/index.js
Normal file
42
src/containers/Home/index.js
Normal file
@@ -0,0 +1,42 @@
|
||||
import React from 'react';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import ProductList from '../../components/ProductList';
|
||||
import Compare from '../../components/Compare';
|
||||
import * as productActions from '../../actions';
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
class Home extends React.Component {
|
||||
componentWillMount() {
|
||||
this.props.actions.getProducts();
|
||||
}
|
||||
|
||||
render() {
|
||||
|
||||
const {products, actions} = this.props;
|
||||
const compareProducts = products.filter(product => product.compare);
|
||||
|
||||
return (
|
||||
<div className="Home mt-5">
|
||||
<ProductList products={products} compare={actions.compare}/>
|
||||
<Compare products={compareProducts}/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return {
|
||||
products: state.product.products
|
||||
}
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return {
|
||||
actions: bindActionCreators(productActions, dispatch)
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(Home);
|
||||
12
src/containers/NotFound/index.js
Normal file
12
src/containers/NotFound/index.js
Normal file
@@ -0,0 +1,12 @@
|
||||
import React from 'react'
|
||||
|
||||
export default class NotFound extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h1>404</h1>
|
||||
<h3>Page not found</h3>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
7
src/index.css
Normal file
7
src/index.css
Normal file
@@ -0,0 +1,7 @@
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
font-family: sans-serif;
|
||||
background: #eaebec;
|
||||
color: #393c45;
|
||||
}
|
||||
31
src/index.js
Normal file
31
src/index.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import {BrowserRouter} from 'react-router-dom'
|
||||
import {createStore, applyMiddleware} from 'redux'
|
||||
import {Provider} from 'react-redux'
|
||||
import thunkMiddleware from 'redux-thunk'
|
||||
import { createLogger } from 'redux-logger'
|
||||
import reducer from './reducers'
|
||||
import App from './containers/App'
|
||||
|
||||
import 'bootstrap/dist/css/bootstrap.css'
|
||||
import './index.css'
|
||||
|
||||
const loggerMiddleware = createLogger()
|
||||
|
||||
const store = createStore(
|
||||
reducer,
|
||||
applyMiddleware(
|
||||
thunkMiddleware, // lets us dispatch() functions
|
||||
loggerMiddleware // neat middleware that logs actions
|
||||
)
|
||||
)
|
||||
|
||||
ReactDOM.render(
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<App />
|
||||
</BrowserRouter>
|
||||
</Provider>, document.getElementById('root'));
|
||||
registerServiceWorker();
|
||||
8
src/reducers/index.js
Normal file
8
src/reducers/index.js
Normal file
@@ -0,0 +1,8 @@
|
||||
import { combineReducers } from 'redux'
|
||||
import product from './product_reducer'
|
||||
|
||||
const compareApp = combineReducers({
|
||||
product
|
||||
})
|
||||
|
||||
export default compareApp
|
||||
26
src/reducers/product_reducer.js
Normal file
26
src/reducers/product_reducer.js
Normal file
@@ -0,0 +1,26 @@
|
||||
import * as types from '../constants/types';
|
||||
|
||||
const INITIAL_STATE = {
|
||||
products: []
|
||||
};
|
||||
|
||||
export default function (state = INITIAL_STATE, action) {
|
||||
switch (action.type) {
|
||||
case types.FETCH_PRODUCTS:
|
||||
return {
|
||||
...state, products: action.payload.map(product =>
|
||||
({...product, compare: false})
|
||||
)
|
||||
};
|
||||
case types.COMPARE_PRODUCT:
|
||||
return {
|
||||
...state, products: state.products.map(product =>
|
||||
product.id === action.product.id ?
|
||||
({...product, compare: !product.compare}) :
|
||||
product
|
||||
)
|
||||
};
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
108
src/registerServiceWorker.js
Normal file
108
src/registerServiceWorker.js
Normal file
@@ -0,0 +1,108 @@
|
||||
// In production, we register a service worker to serve assets from local cache.
|
||||
|
||||
// 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 the "N+1" visit to a page, since previously
|
||||
// cached resources are updated in the background.
|
||||
|
||||
// To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export default function register() {
|
||||
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);
|
||||
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/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (!isLocalhost) {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
} else {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.');
|
||||
} 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.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get('content-type').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);
|
||||
}
|
||||
})
|
||||
.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();
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user