Skip to content

Commit

Permalink
add user validation
Browse files Browse the repository at this point in the history
  • Loading branch information
wrujel committed Oct 8, 2023
1 parent 041ed4a commit bff5efb
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 19 deletions.
47 changes: 35 additions & 12 deletions frontend/hooks/useUser.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,53 @@
import { useEffect, useState } from "react";
import { useRef, useState } from "react";
import toast from "react-hot-toast";
import getUser from "../services/getUsers";

const useUser = () => {
const [user, setUser] = useState("");
const [error, setError] = useState("");
const [loadUser, setLoadUser] = useState(false);
const previousUser = useRef(user);

// Validate user
useEffect(() => {
const validateUser = (user: string) => {
if (user === "") {
setError("Please enter a username");
return;
toast.error("Please enter a username");
return false;
}

if (user.match(/[^a-zA-Z0-9 ]/)) {
setError("Please enter only letters and numbers");
return;
toast.error("Please enter only letters and numbers");
return false;
}

if (user.length < 3) {
setError("Please enter at least 3 characters");
return;
toast.error("Please enter at least 3 characters");
return false;
}

setError("");
}, [user]);
return true;
};

return { user, setUser, error, setError };
const getUserData = async (user: string): Promise<boolean> => {
// Get repos from services
try {
setLoadUser(true);
previousUser.current = user;
const response = await getUser({ user });

if (!response.name) {
toast.error("No user found");
return false;
}
return true;
} catch (error: any) {
toast.error(error.message);
return false;
} finally {
setLoadUser(false);
}
};

return { user, setUser, validateUser, getUserData, loadUser };
};

export default useUser;
24 changes: 17 additions & 7 deletions frontend/pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import useData from "../hooks/useData";
import { Toaster } from "react-hot-toast";

const Home: NextPage = () => {
const { user, setUser } = useUser();
const { user, setUser, validateUser, getUserData, loadUser } = useUser();
const { getUserRepos, repo, setRepo, repos, setRepos, loadRepo } =
useRepos(user);
const {
Expand Down Expand Up @@ -55,9 +55,17 @@ const Home: NextPage = () => {
const debouncedGetUserRepos = useMemo(
() =>
debounce(async (user: string) => {
const resRepo = await getUserRepos(user);
const resBranch = await getRepoBranches(user, resRepo);
getBranchCommits(user, resRepo, resBranch);
if (!validateUser(user)) return;
const foundUser = await getUserData(user);
if (foundUser) {
const resRepo = await getUserRepos(user);
const resBranch = await getRepoBranches(user, resRepo);
getBranchCommits(user, resRepo, resBranch);
} else {
setRepos([]);
setBranches([]);
setCommits([]);
}
}, 500),
[]
);
Expand Down Expand Up @@ -128,15 +136,15 @@ const Home: NextPage = () => {
<Select
id="repos"
label="REPOSITORIES"
disabled={loadRepo || loadData}
disabled={loadUser || loadRepo || loadData}
data={repos}
option={repo}
onChange={onChangeRepo}
/>
<Select
id="branches"
label="BRANCHES"
disabled={loadBranch || loadRepo || loadData}
disabled={loadUser || loadBranch || loadRepo || loadData}
data={branches}
option={branch}
onChange={onChangeBranch}
Expand All @@ -147,7 +155,9 @@ const Home: NextPage = () => {
) : (
<Commit
commits={commits}
loadCommit={loadCommit || loadRepo || loadBranch || loadData}
loadCommit={
loadUser || loadCommit || loadRepo || loadBranch || loadData
}
/>
)}
</main>
Expand Down
46 changes: 46 additions & 0 deletions frontend/services/getUsers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { toast } from "react-hot-toast";
import { serverUrl, fetchMode, userUrl, headers } from "../utils/constants";

interface IParams {
user: string;
}

interface IUser {
name: string;
avatar_url: string;
html_url: string;
}

/**
* Function that fetch repositories data from server
* @param user github username
* @returns an array with all repositories of a user
*/
export default async function getUser(params: IParams): Promise<IUser> {
let userData: IUser = { name: "", avatar_url: "", html_url: "" };
try {
const { user } = params;

if (fetchMode === "client") {
const rawData = await fetch(`${userUrl}/${user}`, headers);
const data = await rawData.json();
userData = {
name: data.name,
avatar_url: data.avatar_url,
html_url: data.html_url,
};
} else {
const response = await fetch(`${serverUrl}/api/users`, {
method: "POST",
body: JSON.stringify({ user: user }),
headers: { "Content-Type": "application/json" },
});
userData = await response.json();
}

return userData;
} catch (error: any) {
toast.error("No user found");
return userData;
}
}

1 comment on commit bff5efb

@vercel
Copy link

@vercel vercel bot commented on bff5efb Oct 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

github-history – ./

github-history-wrujel.vercel.app
github-history-git-main-wrujel.vercel.app
github-history.vercel.app

Please sign in to comment.