Clean V2 - Add sonarjs and unicorn js

This commit is contained in:
Michael
2022-01-14 18:05:18 +01:00
parent 8579861f3b
commit e973cc5cd8
30 changed files with 590 additions and 310 deletions

View File

@@ -9,25 +9,25 @@ import React, { useEffect, useState } from 'react';
import Image from 'next/image';
import { supabase } from 'utils/supabaseClient';
type AvatarProps = {
type AvatarProperties = {
url: string;
size: number;
onUpload: (filePath: string) => void;
};
const Avatar = ({ url, size, onUpload }: AvatarProps): JSX.Element => {
const customImgLoader = ({ src }: { src: string }): string => {
return `${src}`;
};
const Avatar = ({ url, size, onUpload }: AvatarProperties): JSX.Element => {
const [avatarUrl, setAvatarUrl] = useState('');
const [uploading, setUploading] = useState(false);
const customImgLoader = ({ src }: { src: string }) => {
return `${src}`;
};
useEffect(() => {
if (url) downloadImage(url);
if (url) void downloadImage(url);
}, [url]);
async function downloadImage(path: string) {
async function downloadImage(path: string): Promise<void> {
try {
const { data, error } = await supabase.storage
.from('avatars')
@@ -41,12 +41,14 @@ const Avatar = ({ url, size, onUpload }: AvatarProps): JSX.Element => {
}
} catch (error: unknown) {
if (error instanceof Error) {
console.log('Error downloading image: ', error.message);
console.log('Error downloading image:', error.message);
}
}
}
async function uploadAvatar(event: React.ChangeEvent<HTMLInputElement>) {
async function uploadAvatar(
event: React.ChangeEvent<HTMLInputElement>
): Promise<void> {
try {
setUploading(true);
@@ -55,11 +57,11 @@ const Avatar = ({ url, size, onUpload }: AvatarProps): JSX.Element => {
}
const file = event.target.files[0];
const fileExt = file.name.split('.').pop();
const fileName = `${Math.random()}.${fileExt}`;
const fileExtension = file.name.split('.').pop();
const fileName = fileExtension ? `${Math.random()}.${fileExtension}` : '';
const filePath = `${fileName}`;
if (event.target.files[0].size > 150000) {
if (event.target.files[0].size > 150_000) {
alert('File is too big!');
event.target.value = '';
setUploading(false);

View File

@@ -9,39 +9,47 @@ the axios.post here, line 18.
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 = (): void => {
const name = (document.querySelector('#name') as HTMLInputElement).value;
const email = (document.querySelector('#email') as HTMLInputElement).value;
const message = (document.querySelector('#message') as HTMLInputElement)
.value;
if (name && email && message) {
axios
.post('/api/sendgrid', { email, name, message })
.then((result) => {
if (name && email && message) {
axios
.post('/api/sendgrid', { email, name, message })
.then(
(result: {
data: {
success: boolean;
message: string;
};
}) => {
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 = '';
(document.querySelector('#name') as HTMLInputElement).value = '';
(document.querySelector('#email') as HTMLInputElement).value = '';
(document.querySelector('#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,
}
)
.catch((error) => {
console.log(error);
});
}
};
} else {
toast.info('Please fill all the fields ', {
position: 'top-center',
autoClose: 2000,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
}
};
const Contact = (): JSX.Element => {
return (
<div className="max-w-xl px-5 py-10 m-auto">
<div>
@@ -87,8 +95,8 @@ const Contact = (): JSX.Element => {
<button
type="button"
className="btn btn-primary btn-sm"
onClick={(e) => {
e.preventDefault();
onClick={(event) => {
event.preventDefault();
sendEmail();
}}>
Submit{' '}

View File

@@ -16,7 +16,7 @@ import { supabase } from '../utils/supabaseClient';
import { toast } from 'react-toastify';
import { useRouter } from 'next/router';
type DashboardProps = {
type DashboardProperties = {
profile: { username: string; website: string; avatar_url: string };
session: Session;
planName: string;
@@ -26,7 +26,7 @@ const Dashboard = ({
profile,
session,
planName,
}: DashboardProps): JSX.Element => {
}: DashboardProperties): JSX.Element => {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [username, setUsername] = useState(profile?.username || '');
@@ -48,7 +48,7 @@ const Dashboard = ({
username: string;
website: string;
avatar_url: string;
}) {
}): Promise<void> {
try {
setLoading(true);
const user = supabase.auth.user();
@@ -89,7 +89,7 @@ const Dashboard = ({
size={150}
onUpload={(url) => {
setAvatarUrl(url);
updateProfile({ username, website, avatar_url: url });
void updateProfile({ username, website, avatar_url: url });
}}
/>
<div className="flex flex-col mb-5">
@@ -125,7 +125,7 @@ const Dashboard = ({
id="website"
type="website"
value={website || ''}
onChange={(e) => setWebsite(e.target.value)}
onChange={(event) => setWebsite(event.target.value)}
/>
</div>

View File

@@ -18,11 +18,11 @@ import Nav from './Nav';
import { ToastContainer } from 'react-toastify';
import { useAuth } from 'utils/AuthContext';
type LayoutProps = {
type LayoutProperties = {
children: JSX.Element;
};
const Layout = ({ children }: LayoutProps): JSX.Element => {
const Layout = ({ children }: LayoutProperties): JSX.Element => {
const { user, signOut } = useAuth();
return (

View File

@@ -17,7 +17,7 @@ const MailingList = (): JSX.Element => {
const validateEmail = () => {
// Regex patern for email validation
const regex =
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
/^(([^\s"(),.:;<>@[\\\]]+(\.[^\s"(),.:;<>@[\\\]]+)*)|(".+"))@((\[(?:\d{1,3}\.){3}\d{1,3}])|(([\dA-Za-z\-]+\.)+[A-Za-z]{2,}))$/;
if (regex.test(mail)) {
// this is a valid email address
@@ -42,8 +42,8 @@ const MailingList = (): JSX.Element => {
setLoading(false);
}
})
.catch((err) => {
console.log(err);
.catch((error) => {
console.log(error);
setLoading(false);
});
};

View File

@@ -8,12 +8,12 @@ import Image from 'next/image';
import Link from 'next/link';
import Logo from 'public/logo.svg';
type NavProps = {
type NavProperties = {
user: Record<string, unknown>;
signOut: () => void;
};
const Nav = ({ user, signOut }: NavProps): JSX.Element => {
const Nav = ({ user, signOut }: NavProperties): JSX.Element => {
// Modify you menu directly here
const NavMenu = (
<>

View File

@@ -2,12 +2,15 @@ import { Dialog, Transition } from '@headlessui/react';
import { Fragment } from 'react';
type PaymentModalProps = {
type PaymentModalProperties = {
open: boolean;
setPayment: (arg0: boolean) => void;
setPayment: (argument0: boolean) => void;
};
const PaymentModal = ({ open, setPayment }: PaymentModalProps): JSX.Element => {
const PaymentModal = ({
open,
setPayment,
}: PaymentModalProperties): JSX.Element => {
function closeModal() {
setPayment(false);
}

View File

@@ -12,12 +12,12 @@ import { SupabaseClient } from '@supabase/supabase-js';
import { supabase } from 'utils/supabaseClient';
import { useAuth } from 'utils/AuthContext';
type ContainerProps = {
type ContainerProperties = {
children: JSX.Element;
supabaseClient: SupabaseClient;
};
const Container = ({ children }: ContainerProps): JSX.Element => {
const Container = ({ children }: ContainerProperties): JSX.Element => {
const { user, signOut } = useAuth();
if (user)
return (

View File

@@ -4,13 +4,17 @@ This card is used on the landing page
import Image from 'next/image';
type CardLandingProps = {
type CardLandingProperties = {
image: string;
title: string;
text: string;
};
const CardLanding = ({ image, title, text }: CardLandingProps): JSX.Element => {
const CardLanding = ({
image,
title,
text,
}: CardLandingProperties): JSX.Element => {
return (
<div className="flex h-48 p-5 mb-5 w-80 sm:ml-5 bg-base-100">
<div>

View File

@@ -4,11 +4,11 @@ This card is used on the landing page
import { FiStar } from 'react-icons/fi';
type KeyFeatureProps = {
type KeyFeatureProperties = {
children: JSX.Element;
};
const KeyFeature = ({ children }: KeyFeatureProps): JSX.Element => (
const KeyFeature = ({ children }: KeyFeatureProperties): JSX.Element => (
<div className="flex p-5 mb-5 italic shadow-sm bg-base-100">
<div className="flex w-12 h-12 p-2 my-auto text-white rounded-sm bg-accent-focus">
<FiStar className="m-auto text-2xl" />

View File

@@ -3,7 +3,7 @@ import router from 'next/router';
import { toast } from 'react-toastify';
import { useState } from 'react';
type LoginProps = {
type LoginProperties = {
resetPassword: (email: string) => Promise<{ error: { message: string } }>;
signIn: ({}) => Promise<{
data: Record<string, unknown>;
@@ -11,24 +11,28 @@ type LoginProps = {
}>;
};
const Login = ({ resetPassword, signIn }: LoginProps): JSX.Element => {
const Login = ({ resetPassword, signIn }: LoginProperties): JSX.Element => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [forgot, setForgot] = useState(false);
const resetPasswordLogin = () => {
resetPassword(email).then((result: { error: { message: string } }) => {
if (result.error) {
toast.error(result.error.message);
} else toast.success('Check your email to reset your password!');
});
const resetPasswordLogin = async (): Promise<void> => {
await resetPassword(email).then(
(result: { error: { message: string } }) => {
if (result.error) {
toast.error(result.error.message);
} else toast.success('Check your email to reset your password!');
}
);
};
const login = (e: React.SyntheticEvent<HTMLButtonElement>) => {
e.preventDefault();
const login = async (
event: React.SyntheticEvent<HTMLButtonElement>
): Promise<void> => {
event.preventDefault();
// Handle the login. Go to the homepage if success or display an error.
signIn({
await signIn({
email,
password,
}).then(
@@ -37,7 +41,7 @@ const Login = ({ resetPassword, signIn }: LoginProps): JSX.Element => {
error: { message: string };
}) => {
if (result.data) {
router.push('/');
void router.push('/');
}
if (result.error) {
toast.error(result.error.message);
@@ -97,7 +101,7 @@ const Login = ({ resetPassword, signIn }: LoginProps): JSX.Element => {
<button
className="w-full btn btn-primary"
onClick={(event) => {
login(event);
void login(event);
}}>
Log in
</button>
@@ -113,7 +117,7 @@ const Login = ({ resetPassword, signIn }: LoginProps): JSX.Element => {
className="flex items-center justify-center px-4 py-2 space-x-2 transition-colors duration-300 border rounded-md focus:outline-none border-base-200 group hover:bg-base-300"
onClick={(event) => {
event.preventDefault();
signIn({ provider: 'google' });
void signIn({ provider: 'google' });
}}>
<div className="text-base-content">
<IoLogoGoogle />
@@ -154,7 +158,7 @@ const Login = ({ resetPassword, signIn }: LoginProps): JSX.Element => {
className="w-full btn btn-primary btn-sm"
onClick={(event) => {
event.preventDefault();
resetPasswordLogin();
void resetPasswordLogin();
}}>
Recover my password
</button>

View File

@@ -3,7 +3,7 @@ import router from 'next/router';
import { toast } from 'react-toastify';
import { useState } from 'react';
type SignUpPanelProps = {
type SignUpPanelProperties = {
signIn: ({}) => Promise<{
data: Record<string, unknown>;
error: { message: string };
@@ -14,19 +14,23 @@ type SignUpPanelProps = {
}>;
};
const SignUpPanel = ({ signIn, signUp }: SignUpPanelProps): JSX.Element => {
const SignUpPanel = ({
signIn,
signUp,
}: SignUpPanelProperties): JSX.Element => {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const signup = (e: React.SyntheticEvent<HTMLButtonElement>) => {
e.preventDefault();
const signup = async (
event: React.SyntheticEvent<HTMLButtonElement>
): Promise<void> => {
event.preventDefault();
// Handle the login. Go to the homepage if success or display an error.
signUp({
await signUp({
email,
password,
}).then((result) => {
console.log(result);
if (result.error) {
toast.error(result.error.message);
} else if (result.data?.confirmation_sent_at) {
@@ -35,7 +39,7 @@ const SignUpPanel = ({ signIn, signUp }: SignUpPanelProps): JSX.Element => {
'A confirmation email has been sent to you, watch your mailbox!'
);
} else if (result.data) {
router.push('/');
void router.push('/');
}
});
};
@@ -78,7 +82,7 @@ const SignUpPanel = ({ signIn, signUp }: SignUpPanelProps): JSX.Element => {
id="loginBtn"
className="w-full btn btn-primary"
onClick={(event) => {
signup(event);
void signup(event);
}}>
Sign Up
</button>
@@ -94,7 +98,7 @@ const SignUpPanel = ({ signIn, signUp }: SignUpPanelProps): JSX.Element => {
className="flex items-center justify-center px-4 py-2 space-x-2 transition-colors duration-300 border rounded-md focus:outline-none border-base-200 group hover:bg-base-300"
onClick={(event) => {
event.preventDefault();
signIn({ provider: 'google' });
void signIn({ provider: 'google' });
}}>
<div className="text-base-content">
<IoLogoGoogle />