From 9bc6fae2c48ec7c7f1cfb20bca9651475bd192ba Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 10 Aug 2021 12:50:47 +0200 Subject: [PATCH] First implementation of eslint/prettier --- .eslintrc.json | 52 + .estlintignore | 3 + .prettierrc.json | 5 + components/AuthText.js | 41 +- components/Avatar.js | 47 +- components/CardsLanding.js | 114 +- components/Contact.js | 81 +- components/Dashboard.js | 83 +- components/Footer.js | 20 +- components/Landing.js | 120 +- components/Layout.js | 69 +- components/MailingList.js | 42 +- components/Nav.js | 48 +- components/PaymentModal.js | 64 +- components/Pricing.js | 185 +- components/PrivacyPolicy.js | 274 +- components/SignUp.js | 10 +- components/Terms.js | 414 +- components/UI/CardLanding.js | 19 +- components/UI/KeyFeature.js | 18 +- components/UI/Login.js | 108 +- components/UI/SignUpPanel.js | 76 +- components/UI/ThemeToggle.js | 18 +- cypress/integration/basic.spec.js | 54 +- cypress/plugins/index.js | 2 +- cypress/support/index.js | 2 +- package-lock.json | 7462 ++++--------------- package.json | 18 +- pages/_app.js | 18 +- pages/_document.js | 2 +- pages/admin.js | 169 +- pages/api/auth.js | 2 +- pages/api/getUser.js | 4 +- pages/api/mailingList.js | 118 +- pages/api/sendgrid.js | 10 +- pages/api/stripe/create-checkout-session.js | 160 +- pages/api/stripe/customer-portal.js | 13 +- pages/api/stripe/stripe-webhook.js | 49 +- pages/contact.js | 30 +- pages/dashboard.js | 36 +- pages/index.js | 99 +- pages/login.js | 10 +- pages/pricing.js | 30 +- pages/privacy.js | 30 +- pages/signup.js | 38 +- pages/terms.js | 30 +- postcss.config.js | 2 +- tailwind.config.js | 90 +- utils/AuthContext.js | 20 +- utils/priceList.js | 36 +- utils/stripe.js | 2 +- utils/supabaseClient.js | 8 +- 52 files changed, 2780 insertions(+), 7675 deletions(-) create mode 100644 .eslintrc.json create mode 100644 .estlintignore create mode 100644 .prettierrc.json diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..1ce4521 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,52 @@ +{ + "env": { + "browser": true, + "es2021": true, + "node": true, + "cypress/globals": true + }, + "extends": [ + "plugin:react/recommended", + "airbnb", + "prettier" + ], + "parserOptions": { + "ecmaFeatures": { + "jsx": true + }, + "ecmaVersion": 12, + "sourceType": "module" + }, + "plugins": [ + "react", + "cypress", + "simple-import-sort", + "prettier" + ], + "rules": { + "no-console": "off", + "react/no-unescaped-entities": "off", + "prettier/prettier": "error", + "react/react-in-jsx-scope": "off", + "react/jsx-filename-extension": [ + 2, + { + "extensions": [ + ".js", + ".jsx", + ".ts", + ".tsx" + ] + } + ] + }, + "settings": { + "import/resolver": { + "node": { + "paths": [ + "." + ] + } + } + } +} \ No newline at end of file diff --git a/.estlintignore b/.estlintignore new file mode 100644 index 0000000..56eafb5 --- /dev/null +++ b/.estlintignore @@ -0,0 +1,3 @@ +.next +dist +node_modules/ \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..3181cc9 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "tabWidth": 2, + "semi": true +} \ No newline at end of file diff --git a/components/AuthText.js b/components/AuthText.js index 1e9ffd6..7fbe50f 100644 --- a/components/AuthText.js +++ b/components/AuthText.js @@ -1,26 +1,23 @@ -import Image from "next/image"; -import authImage from "public/auth.png"; +import Image from 'next/image'; +import authImage from 'public/auth.png'; -const AuthText = () => { - return ( -
-
- -
-

- Join SupaNexTail for free! -

-

- Create your website in a few minutes with our boilerplate. You can use - the login system, this will allow you to discover the sample dashboard - page. -

+const AuthText = () => ( +
+
+
- ); -}; +

+ Join SupaNexTail for free! +

+

+ Create your website in a few minutes with our boilerplate. You can use the + login system, this will allow you to discover the sample dashboard page. +

+
+); export default AuthText; diff --git a/components/Avatar.js b/components/Avatar.js index 95f55ee..75701a5 100644 --- a/components/Avatar.js +++ b/components/Avatar.js @@ -4,9 +4,9 @@ the upload. You can tweak the max size, line 47 */ -import { useEffect, useState } from "react"; +import { useEffect, useState } from 'react'; -import { supabase } from "utils/supabaseClient"; +import { supabase } from 'utils/supabaseClient'; const Avatar = ({ url, size, onUpload }) => { const [avatarUrl, setAvatarUrl] = useState(null); @@ -19,7 +19,7 @@ const Avatar = ({ url, size, onUpload }) => { async function downloadImage(path) { try { const { data, error } = await supabase.storage - .from("avatars") + .from('avatars') .download(path); if (error) { throw error; @@ -27,7 +27,7 @@ const Avatar = ({ url, size, onUpload }) => { const url = URL.createObjectURL(data); setAvatarUrl(url); } catch (error) { - console.log("Error downloading image: ", error.message); + console.log('Error downloading image: ', error.message); } } @@ -36,23 +36,23 @@ const Avatar = ({ url, size, onUpload }) => { setUploading(true); if (!event.target.files || event.target.files.length === 0) { - throw new Error("You must select an image to upload."); + throw new Error('You must select an image to upload.'); } const file = event.target.files[0]; - const fileExt = file.name.split(".").pop(); + const fileExt = file.name.split('.').pop(); const fileName = `${Math.random()}.${fileExt}`; const filePath = `${fileName}`; if (event.target.files[0].size > 150000) { - alert("File is too big!"); - event.target.value = ""; - setUploading(false) + alert('File is too big!'); + event.target.value = ''; + setUploading(false); return; } - let { error: uploadError } = await supabase.storage - .from("avatars") + const { error: uploadError } = await supabase.storage + .from('avatars') .upload(filePath, file); if (uploadError) { @@ -68,30 +68,31 @@ const Avatar = ({ url, size, onUpload }) => { } return ( -
+
{avatarUrl ? ( Avatar ) : ( -
+
)}
diff --git a/components/CardsLanding.js b/components/CardsLanding.js index 693b10e..b1f259e 100644 --- a/components/CardsLanding.js +++ b/components/CardsLanding.js @@ -1,62 +1,60 @@ -import CardLanding from "components/UI/CardLanding"; -import cardAuth from "public/landing/auth.svg"; -import cardFee from "public/landing/lifetime.svg"; -import cardPage from "public/landing/page.svg"; -import cardResponsive from "public/landing/responsive.svg"; -import cardServer from "public/landing/backend.svg"; -import cardStripe from "public/landing/stripe.svg"; -import cardTheme from "public/landing/theme.svg"; +import CardLanding from 'components/UI/CardLanding'; +import cardAuth from 'public/landing/auth.svg'; +import cardFee from 'public/landing/lifetime.svg'; +import cardPage from 'public/landing/page.svg'; +import cardResponsive from 'public/landing/responsive.svg'; +import cardServer from 'public/landing/backend.svg'; +import cardStripe from 'public/landing/stripe.svg'; +import cardTheme from 'public/landing/theme.svg'; -const CardsLanding = () => { - return ( -
-

- We've got you covered -

-

- Don’t waste your time and reinvent the wheel, we have provided you with - a maximum of features so that you only have one goal, to make your SaaS - a reality. -

-
- - - - - - - -
+const CardsLanding = () => ( +
+

+ We've got you covered +

+

+ Don’t waste your time and reinvent the wheel, we have provided you with a + maximum of features so that you only have one goal, to make your SaaS a + reality. +

+
+ + + + + + +
- ); -}; +
+); export default CardsLanding; diff --git a/components/Contact.js b/components/Contact.js index 6eac051..9c878ed 100644 --- a/components/Contact.js +++ b/components/Contact.js @@ -6,32 +6,32 @@ If you want to change the email provider, don't hesitate to create a new api rou the axios.post here, line 18. */ -import axios from "axios"; -import { toast } from "react-toastify"; +import axios from 'axios'; +import { toast } from 'react-toastify'; const Contact = () => { const sendEmail = () => { - const name = document.getElementById("name").value; - const email = document.getElementById("email").value; - const message = document.getElementById("message").value; + const name = document.getElementById('name').value; + const email = document.getElementById('email').value; + const message = document.getElementById('message').value; if (name && email && message) { axios - .post("/api/sendgrid", { email, name, message }) + .post('/api/sendgrid', { email, name, message }) .then((result) => { if (result.data.success === true) { toast.success(result.data.message); - document.getElementById("name").value = ""; - document.getElementById("email").value = ""; - document.getElementById("message").value = ""; + document.getElementById('name').value = ''; + document.getElementById('email').value = ''; + document.getElementById('message').value = ''; } }) .catch((err) => { console.log(err); }); } else { - toast.info("Please enter at least one URL", { - position: "top-center", + toast.info('Please enter at least one URL', { + position: 'top-center', autoClose: 2000, hideProgressBar: true, closeOnClick: true, @@ -42,51 +42,56 @@ const Contact = () => { } }; return ( -
+
-
-

+
+

Contact

-

+

Do you have a question about SupaNexTail? A cool feature you'd like us to integrate? A bug to report? Don't hesitate!

-
-
- + +
+

Your Name

+ id="name" + name="name" + placeholder="Enter your name" + className="input input-primary input-bordered" + />
-
- +
+

Your email

+ id="email" + name="email" + placeholder="Enter your email adress" + className="input input-primary input-bordered" + />
-
- +
+

Message

+ id="message" + name="message" + placeholder="Enter your message here..." + rows="5" + className="input input-primary input-bordered resize-none w-full h-32 pt-2" + />
diff --git a/components/Dashboard.js b/components/Dashboard.js index 786138f..515699b 100644 --- a/components/Dashboard.js +++ b/components/Dashboard.js @@ -5,16 +5,16 @@ function with your new elements. It also show you the current subscription plan */ -import { useEffect, useState } from "react"; +import { useEffect, useState } from 'react'; -import Avatar from "./Avatar"; -import Image from "next/image"; -import PaymentModal from "./PaymentModal"; -import Plan from "public/plan.svg"; -import { PriceIds } from "utils/priceList"; -import { supabase } from "../utils/supabaseClient"; -import { toast } from "react-toastify"; -import { useRouter } from "next/router"; +import Image from 'next/image'; +import Plan from 'public/plan.svg'; +import { PriceIds } from 'utils/priceList'; +import { toast } from 'react-toastify'; +import { useRouter } from 'next/router'; +import { supabase } from '../utils/supabaseClient'; +import PaymentModal from './PaymentModal'; +import Avatar from './Avatar'; export default function Dashboard(props) { const router = useRouter(); @@ -25,7 +25,7 @@ export default function Dashboard(props) { const [payment, setPayment] = useState(false); useEffect(() => { - if (router.query.session_id && router.query.session_id !== "canceled") { + if (router.query.session_id && router.query.session_id !== 'canceled') { setPayment(true); } }, []); @@ -43,8 +43,8 @@ export default function Dashboard(props) { updated_at: new Date(), }; - let { error } = await supabase.from("profiles").upsert(updates, { - returning: "minimal", // Don't return the value after inserting + const { error } = await supabase.from('profiles').upsert(updates, { + returning: 'minimal', // Don't return the value after inserting }); if (error) { @@ -54,14 +54,14 @@ export default function Dashboard(props) { alert(error.message); } finally { setLoading(false); - toast.success("Your profile has been updated"); + toast.success('Your profile has been updated'); } } return ( -
-
-

+
+
+

Dashboard

-
-