From 74b531bad286d45dd6f8fb9b9a3b233c04bf9ee4 Mon Sep 17 00:00:00 2001 From: rahmat-st Date: Tue, 4 Oct 2022 00:13:10 +0700 Subject: [PATCH] feat: prevent duplicated team name --- helpers/find.team.by.name.js | 12 +++++++ src/components/pages/team/hero/team.jsx | 45 +++++++++++++++++++------ src/pages/api/change-team.js | 26 ++++++++++++-- 3 files changed, 69 insertions(+), 14 deletions(-) create mode 100644 helpers/find.team.by.name.js diff --git a/helpers/find.team.by.name.js b/helpers/find.team.by.name.js new file mode 100644 index 00000000..8e3a54fc --- /dev/null +++ b/helpers/find.team.by.name.js @@ -0,0 +1,12 @@ +import prisma from '~/prisma/client'; + +export default async function findTeamByName(name) { + return prisma.team.findMany({ + where: { + name: { + equals: name, + mode: 'insensitive', + }, + }, + }); +} diff --git a/src/components/pages/team/hero/team.jsx b/src/components/pages/team/hero/team.jsx index 58778c4f..d710c5eb 100644 --- a/src/components/pages/team/hero/team.jsx +++ b/src/components/pages/team/hero/team.jsx @@ -7,6 +7,7 @@ import { useDebouncedCallback } from 'use-debounce'; import GitHubIcon from '../../../../icons/github.inline.svg'; const Team = ({ info }) => { + const [currentTeamName, setCurrentTeamName] = useState(info.team.name); // for disable state update button const [teamName, setTeamName] = useState(info.team.name); const [randomJoin, setRandomJoin] = useState(info.team.allowAutoAssign); const [contact, setContact] = useState(''); @@ -23,20 +24,35 @@ const Team = ({ info }) => { toast.success('Message sent!'); setContact(''); }, [contact]); - const debounce = useDebouncedCallback(async (name, allowAutoAssign) => { - await fetch('/api/change-team', { + + const updateTeamApi = (name, allowAutoAssign) => + fetch('/api/change-team', { headers: { Accept: 'application/json', 'Content-Type': 'application/json', }, method: 'POST', - body: JSON.stringify({ - name, - allowAutoAssign, - }), + body: JSON.stringify({ name, allowAutoAssign }), }); + + const debounceRandomJoin = useDebouncedCallback(async (allowAutoAssign) => { + await updateTeamApi(currentTeamName, allowAutoAssign); }, 500); + const updateTeamName = async () => { + const response = await updateTeamApi(teamName, randomJoin); + const json = await response.json(); + + if (response.ok) { + setCurrentTeamName(teamName); + toast.success('Team name updated successfully!'); + } else { + toast.error(json.error); + } + }; + + const handleChangeTeamName = (e) => setTeamName(e.target.value); + return ( <> {info.team.users.length < 5 && ( @@ -93,12 +109,19 @@ const Team = ({ info }) => { type="text" name="name" value={teamName} - onChange={(e) => { - setTeamName(e.target.value); - debounce(e.target.value, randomJoin); - }} + onChange={handleChangeTeamName} /> +
+ +
diff --git a/src/pages/api/change-team.js b/src/pages/api/change-team.js index eadf0409..087fb60f 100644 --- a/src/pages/api/change-team.js +++ b/src/pages/api/change-team.js @@ -1,14 +1,31 @@ +import findTeamByName from '~/helpers/find.team.by.name'; import findUserAndTeam from '~/helpers/find.user.and.team'; import prisma from '~/prisma/client'; export default async function handler(req, res) { if (!req.body.name || req.body.name.length < 2 || !req.body.hasOwnProperty('allowAutoAssign')) { - res.status(400).send('Invalid parameters'); + res.status(400).json({ + success: false, + error: 'Invalid parameters', + }); return; } + + const teams = await findTeamByName(req.body.name); + if (teams.length) { + res.status(400).json({ + success: false, + error: 'Team name already used!', + }); + return; + } + const { admin, team } = await findUserAndTeam(req, res); if (!admin && !team) { - res.status(400).send('Invalid call'); + res.status(400).json({ + success: false, + error: 'Invalid call', + }); return; } @@ -22,5 +39,8 @@ export default async function handler(req, res) { }, }); - res.status(200).send('changed'); + res.status(200).json({ + success: true, + message: 'Changed', + }); }