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"