diff --git a/.eslintrc.json b/.eslintrc.json index e2f6d40..027b04a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -8,8 +8,7 @@ "extends": [ "next", "next/core-web-vitals", - "plugin:@typescript-eslint/recommended", - "prettier" + "plugin:@typescript-eslint/recommended-requiring-type-checking" ], "parserOptions": { "ecmaFeatures": { @@ -30,9 +29,18 @@ "prettier/prettier": [ "error", { - "endOfLine": "auto" + "semi": true, + "trailingComma": "es5", + "singleQuote": true, + "tabWidth": 2, + "useTabs": false, + "endOfLine": "auto", + "printWidth": 80, + "bracketSameLine": true, + "bracketSpacing": true } ], + "react/prop-types": "off", "react/react-in-jsx-scope": "off", "react/jsx-filename-extension": [ 2, @@ -44,6 +52,15 @@ ".tsx" ] } + ], + "@typescript-eslint/explicit-function-return-type": [ + "warn", + { + "allowExpressions": true, + "allowTypedFunctionExpressions": true, + "allowHigherOrderFunctions": true, + "allowConciseArrowFunctionExpressionsStartingWithVoid": true + } ] }, "settings": { diff --git a/.prettierrc.json b/.prettierrc.json index 3f7543a..c95bac3 100644 --- a/.prettierrc.json +++ b/.prettierrc.json @@ -3,7 +3,9 @@ "trailingComma": "es5", "singleQuote": true, "tabWidth": 2, - "useTabs": true, + "useTabs": false, "endOfLine": "auto", - "printWidth": 100 + "printWidth": 80, + "bracketSameLine": true, + "bracketSpacing": true } \ No newline at end of file diff --git a/components/AuthText.tsx b/components/AuthText.tsx index be85b16..95a234c 100644 --- a/components/AuthText.tsx +++ b/components/AuthText.tsx @@ -2,23 +2,23 @@ import Image from 'next/image'; import authImage from 'public/auth.png'; const AuthText = (): JSX.Element => ( -
-
- A rocketship -
-

- 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. -

-
+
+
+ A rocketship +
+

+ 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.tsx b/components/Avatar.tsx index 1db4804..be392f7 100644 --- a/components/Avatar.tsx +++ b/components/Avatar.tsx @@ -10,113 +10,116 @@ import Image from 'next/image'; import { supabase } from 'utils/supabaseClient'; type AvatarProps = { - url: string; - size: number; - onUpload: (filePath: string) => void; + url: string; + size: number; + onUpload: (filePath: string) => void; }; const Avatar = ({ url, size, onUpload }: AvatarProps): JSX.Element => { - const [avatarUrl, setAvatarUrl] = useState(''); - const [uploading, setUploading] = useState(false); - - const customImgLoader = ({ src }: { src: string }) => { - return `${src}`; - }; - - useEffect(() => { - if (url) downloadImage(url); - }, [url]); - - async function downloadImage(path: string) { - try { - const { data, error } = await supabase.storage.from('avatars').download(path); - if (error) { - throw error; - } - if (data) { - const url = URL.createObjectURL(data); - setAvatarUrl(url); - } - } catch (error: unknown) { - if (error instanceof Error) { - console.log('Error downloading image: ', error.message); - } - } - } - - async function uploadAvatar(event: React.ChangeEvent) { - try { - setUploading(true); - - if (!event.target.files || event.target.files.length === 0) { - throw new Error('You must select an image to upload.'); - } - - const file = event.target.files[0]; - 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); - return; - } - - const { error: uploadError } = await supabase.storage.from('avatars').upload(filePath, file); - - if (uploadError) { - throw uploadError; - } - - onUpload(filePath); - } catch (error: unknown) { - if (error instanceof Error) { - alert(error.message); - } - } finally { - setUploading(false); - } - } - - return ( -
- {avatarUrl ? ( -
- Avatar -
- ) : ( -
- )} -
- - -
-
- ); + const [avatarUrl, setAvatarUrl] = useState(''); + const [uploading, setUploading] = useState(false); + + const customImgLoader = ({ src }: { src: string }) => { + return `${src}`; + }; + + useEffect(() => { + if (url) downloadImage(url); + }, [url]); + + async function downloadImage(path: string) { + try { + const { data, error } = await supabase.storage + .from('avatars') + .download(path); + if (error) { + throw error; + } + if (data) { + const url = URL.createObjectURL(data); + setAvatarUrl(url); + } + } catch (error: unknown) { + if (error instanceof Error) { + console.log('Error downloading image: ', error.message); + } + } + } + + async function uploadAvatar(event: React.ChangeEvent) { + try { + setUploading(true); + + if (!event.target.files || event.target.files.length === 0) { + throw new Error('You must select an image to upload.'); + } + + const file = event.target.files[0]; + 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); + return; + } + + const { error: uploadError } = await supabase.storage + .from('avatars') + .upload(filePath, file); + + if (uploadError) { + throw uploadError; + } + + onUpload(filePath); + } catch (error: unknown) { + if (error instanceof Error) { + alert(error.message); + } + } finally { + setUploading(false); + } + } + + return ( +
+ {avatarUrl ? ( +
+ Avatar +
+ ) : ( +
+ )} +
+ + +
+
+ ); }; export default Avatar; diff --git a/components/CardsLanding.tsx b/components/CardsLanding.tsx index 26f772e..97a7bb6 100644 --- a/components/CardsLanding.tsx +++ b/components/CardsLanding.tsx @@ -8,48 +8,53 @@ import cardStripe from 'public/landing/stripe.svg'; import cardTheme from 'public/landing/theme.svg'; const CardsLanding = (): JSX.Element => ( -
-

- 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. -

-
- - - - - - - -
-
+
+

+ 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.tsx b/components/Contact.tsx index 4213ec4..acd2703 100644 --- a/components/Contact.tsx +++ b/components/Contact.tsx @@ -10,92 +10,92 @@ import axios from 'axios'; import { toast } from 'react-toastify'; const Contact = (): JSX.Element => { - const sendEmail = () => { - const name = (document.getElementById('name') as HTMLInputElement).value; - const email = (document.getElementById('email') as HTMLInputElement).value; - const message = (document.getElementById('message') as HTMLInputElement).value; + const sendEmail = () => { + const name = (document.getElementById('name') as HTMLInputElement).value; + const email = (document.getElementById('email') as HTMLInputElement).value; + const message = (document.getElementById('message') as HTMLInputElement) + .value; - if (name && email && message) { - axios - .post('/api/sendgrid', { email, name, message }) - .then((result) => { - if (result.data.success === true) { - toast.success(result.data.message); - (document.getElementById('name') as HTMLInputElement).value = ''; - (document.getElementById('email') as HTMLInputElement).value = ''; - (document.getElementById('message') as HTMLInputElement).value = ''; - } - }) - .catch((err) => { - console.log(err); - }); - } else { - toast.info('Please fill all the fields ', { - position: 'top-center', - autoClose: 2000, - hideProgressBar: true, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - }); - } - }; - 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

- -
-
-

Your email

- -
-
-

Message

-