diff --git a/.eslintrc.js b/.eslintrc.js index 4b43ed4..79b4857 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,5 +24,9 @@ module.exports = { 'import/no-unresolved': 0, camelcase: 0, 'prettier/prettier': 0, + 'no-use-before-define': 0, + 'import/prefer-default-export': 0, + 'jsx-a11y/click-events-have-key-events': 0, + 'jsx-a11y/no-static-element-interactions': 0, }, }; diff --git a/.gitignore b/.gitignore index c9281e0..2b8488b 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,4 @@ firebase.json /storybook-static yarn.lock +.eslintcache diff --git a/README.md b/README.md index ac69cab..5fe6424 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

- +


@@ -18,19 +18,18 @@ Project   |    Techs   |    Installation   |    - Test   |    + Start   |    Contributing   |    License

## -
-

+
## Project :star2: @@ -38,7 +37,7 @@ This repo contains an UI clone from Tesla homepage.
-Deployed [here](https://tesla-homepage-ui-clone.web.app/). +Deployed [here](https://tesla.ui-clone.ronne.dev/).
@@ -58,17 +57,20 @@ Deployed [here](https://tesla-homepage-ui-clone.web.app/). - [x] [ReactJS](https://reactjs.org); - [x] [TypeScript](https://www.typescriptlang.org/); +- [x] [Framer Motion](https://www.framer.com/motion/); - [x] [Styled Components](https://styled-components.com/).
## Installation :wrench: +First you need to clone the project using `git clone https://github.com/leoronne/tesla-homepage-ui-clone.git`. + You can install the application using `npm install` or `yarn install` on the root dir.
-## Test :heavy_check_mark: +## Start :on: To start the application interface just run `npm start` or `yarn start` on the root dir. diff --git a/package.json b/package.json index 23c2ad0..ab29682 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,28 @@ { "name": "tesla-homepage-ui-clone", + "description": "This app contains an UI clone (partial) from Tesla Homepage website", "version": "1.0.0", + "main": "index.tsx", "repository": "https://github.com/leoronne/tesla-homepage-ui-clone", - "author": "Leonardo Ronne", - "description": "This app contains an UI clone (partial) from Tesla Homepage website", + "author": "Leonardo Ronne ", "license": "MIT", "dependencies": { - "@material-ui/core": "^4.11.0", - "@testing-library/jest-dom": "^4.2.4", - "@testing-library/react": "^9.3.2", - "@testing-library/user-event": "^7.1.2", - "@types/jest": "^24.0.0", - "@types/node": "^12.0.0", - "@types/react": "^16.9.0", - "@types/react-dom": "^16.9.0", + "@material-ui/core": "^4.11.2", + "@testing-library/jest-dom": "^5.11.6", + "@testing-library/react": "^11.2.2", + "@testing-library/user-event": "^12.6.0", + "@types/jest": "^26.0.19", + "@types/node": "^14.14.14", + "@types/react": "^17.0.0", + "@types/react-dom": "^17.0.0", "clsx": "^1.1.1", - "framer-motion": "^2.7.6", - "react": "^16.13.1", - "react-dom": "^16.13.1", - "react-scripts": "3.4.3", - "styled-components": "^5.2.0", - "typescript": "~3.7.2" + "framer-motion": "^3.1.1", + "react": "^17.0.1", + "react-cookie-consent": "^6.2.1", + "react-dom": "^17.0.1", + "react-scripts": "^4.0.1", + "styled-components": "^5.2.1", + "typescript": "^4.1.3" }, "scripts": { "start": "react-app-rewired start", @@ -45,24 +47,24 @@ }, "devDependencies": { "@types/react-icons": "^3.0.0", - "@types/react-router-dom": "^5.1.5", - "@types/styled-components": "^5.1.3", - "@typescript-eslint/eslint-plugin": "^4.3.0", - "@typescript-eslint/parser": "^3.6.0", + "@types/react-router-dom": "^5.1.6", + "@types/styled-components": "^5.1.7", + "@typescript-eslint/eslint-plugin": "^4.11.0", + "@typescript-eslint/parser": "^4.11.0", "babel-eslint": "^10.0.3", - "babel-plugin-root-import": "^6.4.1", - "customize-cra": "^0.9.1", - "eslint": "^6.8.0", - "eslint-config-airbnb": "^18.1.0", - "eslint-config-prettier": "^6.11.0", + "babel-plugin-root-import": "^6.6.0", + "customize-cra": "^1.0.0", + "eslint": "^7.16.0", + "eslint-config-airbnb": "^18.2.1", + "eslint-config-prettier": "^7.1.0", "eslint-import-resolver-babel-plugin-root-import": "^1.1.1", "eslint-plugin-import": "^2.20.2", "eslint-plugin-import-helpers": "^1.0.2", - "eslint-plugin-jsx-a11y": "^6.2.3", - "eslint-plugin-prettier": "^3.1.4", - "eslint-plugin-react": "^7.19.0", - "eslint-plugin-react-hooks": "^2.5.1", - "prettier": "^2.0.5", - "react-app-rewired": "^2.1.6" + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-prettier": "^3.3.0", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4.2.0", + "prettier": "^2.2.1", + "react-app-rewired": "^2.1.8" } } diff --git a/public/index.html b/public/index.html index a439f08..1228e2c 100644 --- a/public/index.html +++ b/public/index.html @@ -2,12 +2,12 @@ - + - + @@ -16,13 +16,13 @@ - + - - + + - + @@ -31,8 +31,8 @@ - - + + diff --git a/public/locales/en/translation.json b/public/locales/en/translation.json new file mode 100644 index 0000000..5d1a7d1 --- /dev/null +++ b/public/locales/en/translation.json @@ -0,0 +1,35 @@ +{ + "custom-order": "Custom Order", + "existing-inventory": "Existing Inventory", + "learn-more": "Learn More", + "order-now": "Order Now", + "shop-now": "Shop Now", + "shop": "Shop", + "tesla-account": "Tesla Account", + "solar-panels": "Solar Panels", + "model-s": "Model S", + "model-3": "Model 3", + "model-x": "Model X", + "model-y": "Model Y", + "solar-roof": "Solar Roof", + "order-online": "Order Online for", + "touchless-delivery": "Touchless Delivery", + "solar-new-roofs": "Solar for New Roofs", + "solar-existing-roofs": "Only $1.49/Watt for Solar on Existing Roofs", + "accessories": "Accessories", + "lowest-costs-america": "Lowest Cost in America - Money-back guarantee", + "solar-roof-costs": "Solar Roof Costs Less Than a New Roof Plus Solar Panels", + + "used-inventory": "USED INVENTORY", + "trade-in": "TRADE-IN", + "cybertruck": "CYBERTRUCK", + "roadster": "ROADSTER", + "semi": "SEMI", + "powerwall": "POWERWALL", + "commercial-solar": "COMMERCIAL SOLAR", + "test-drive": "TEST DRIVE", + "charging": "CHARGING", + "find-us": "FIND US", + "support": "SUPPORT", + "united-states": "UNITED STATES" +} diff --git a/public/logo1024.png b/public/logo1024.png new file mode 100644 index 0000000..7169b8e Binary files /dev/null and b/public/logo1024.png differ diff --git a/public/manifest.json b/public/manifest.json index 992e03a..29a72f7 100644 --- a/public/manifest.json +++ b/public/manifest.json @@ -7,7 +7,7 @@ "name": "Leonardo Ronne", "url": "https://github.com/leoronne" }, - "homepage_url": "https://tesla-homepage-ui-clone.web.app", + "homepage_url": "https://tesla.ui-clone.ronne.dev", "icons": [ { "src": "favicon.ico", @@ -28,6 +28,11 @@ "src": "logo512.png", "type": "image/png", "sizes": "512x512" + }, + { + "src": "logo1024.png", + "type": "image/png", + "sizes": "1024x1024" } ], "start_url": "/", diff --git a/src/components/LoaderSpinner/index.tsx b/src/components/LoaderSpinner/index.tsx index 07a0fe5..2b14de2 100644 --- a/src/components/LoaderSpinner/index.tsx +++ b/src/components/LoaderSpinner/index.tsx @@ -3,10 +3,10 @@ import { CircularProgress } from '@material-ui/core'; import { Container } from './styles'; -const Loader: React.FC = () => { +const Loader: React.FC<{ color: string }> = ({ color = '#e82127' }) => { return ( - + ); }; diff --git a/src/components/UniqueOverlay/Header/Drawer/styles.ts b/src/components/UniqueOverlay/Header/Drawer/styles.ts index a72f3a5..8cdb625 100644 --- a/src/components/UniqueOverlay/Header/Drawer/styles.ts +++ b/src/components/UniqueOverlay/Header/Drawer/styles.ts @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { BurgerSVG, CloseSVG } from '../../IconSVG'; +import { BurgerSVG, CloseSVG } from '../../../../styles/Icons'; export const Burger = styled(BurgerSVG)` width: 24px; diff --git a/src/components/UniqueOverlay/Header/styles.ts b/src/components/UniqueOverlay/Header/styles.ts index 88c875e..838bcf6 100644 --- a/src/components/UniqueOverlay/Header/styles.ts +++ b/src/components/UniqueOverlay/Header/styles.ts @@ -1,5 +1,5 @@ import styled from 'styled-components'; -import { LogoSVG, GitHubSVG } from '../IconSVG'; +import { LogoSVG, GitHubSVG } from '../../../styles/Icons'; export const Container = styled.header` position: fixed; diff --git a/src/components/index.ts b/src/components/index.ts new file mode 100644 index 0000000..21abb8d --- /dev/null +++ b/src/components/index.ts @@ -0,0 +1 @@ +export { default as LoaderSpinner } from './LoaderSpinner'; diff --git a/src/index.tsx b/src/index.tsx index c96f313..328d14f 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,19 +1,15 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import LoaderSpinner from './components/LoaderSpinner'; +import { LoaderSpinner } from './components'; import App from './App'; -import * as serviceWorker from './serviceWorker'; - ReactDOM.render( - }> + }> , document.getElementById('root') ); - -serviceWorker.unregister(); diff --git a/src/serviceWorker.ts b/src/serviceWorker.ts deleted file mode 100644 index 58e2f3d..0000000 --- a/src/serviceWorker.ts +++ /dev/null @@ -1,133 +0,0 @@ -// 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}$/) -); - -type Config = { - onSuccess?: (registration: ServiceWorkerRegistration) => void; - onUpdate?: (registration: ServiceWorkerRegistration) => void; -}; - -export function register(config?: 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: string, config?: 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: string, config?: 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/src/components/UniqueOverlay/IconSVG.tsx b/src/styles/Icons/index.tsx similarity index 100% rename from src/components/UniqueOverlay/IconSVG.tsx rename to src/styles/Icons/index.tsx diff --git a/tsconfig.json b/tsconfig.json index f2850b7..e18c413 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,8 @@ "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, - "jsx": "react" + "jsx": "react-jsx", + "noFallthroughCasesInSwitch": true }, "include": [ "src"