From aab9f91156572cfa3004859a179aa90cab7f4b44 Mon Sep 17 00:00:00 2001 From: Takeshi Kimata <117462761+kimatata@users.noreply.github.com> Date: Thu, 18 Jul 2024 10:39:07 +0900 Subject: [PATCH] refactor: usersControl --- backend/index.js | 4 +- backend/routes/users/find.js | 42 +++++++--------- backend/routes/users/search.js | 44 ++++++++++++++++ backend/routes/users/show.js | 36 ------------- .../[projectId]/members/AddMemberDialog.tsx | 4 +- .../[projectId]/members/membersControl.ts | 25 +--------- .../[projectId]/settings/SettingsPage.tsx | 28 +---------- frontend/utils/usersControl.ts | 50 +++++++++++++++++++ 8 files changed, 118 insertions(+), 115 deletions(-) create mode 100644 backend/routes/users/search.js delete mode 100644 backend/routes/users/show.js create mode 100644 frontend/utils/usersControl.ts diff --git a/backend/index.js b/backend/index.js index fe0d20c..2a6a03d 100644 --- a/backend/index.js +++ b/backend/index.js @@ -31,13 +31,13 @@ app.use('/', indexRoute); // "users" const usersIndexRoute = require('./routes/users/index')(sequelize); -const usersShowRoute = require('./routes/users/show')(sequelize); const usersFindRoute = require('./routes/users/find')(sequelize); +const usersSearchRoute = require('./routes/users/search')(sequelize); const signUpRoute = require('./routes/users/signup')(sequelize); const signInRoute = require('./routes/users/signin')(sequelize); app.use('/users', usersIndexRoute); -app.use('/users', usersShowRoute); app.use('/users', usersFindRoute); +app.use('/users', usersSearchRoute); app.use('/users', signUpRoute); app.use('/users', signInRoute); diff --git a/backend/routes/users/find.js b/backend/routes/users/find.js index 803c7d5..c3dc2c9 100644 --- a/backend/routes/users/find.js +++ b/backend/routes/users/find.js @@ -1,39 +1,31 @@ const express = require('express'); const router = express.Router(); const defineUser = require('../../models/users'); -const defineMember = require('../../models/members'); -const { DataTypes, Op } = require('sequelize'); +const { DataTypes } = require('sequelize'); module.exports = function (sequelize) { const { verifySignedIn } = require('../../middleware/auth')(sequelize); const User = defineUser(sequelize, DataTypes); - const Member = defineMember(sequelize, DataTypes); - router.get('/find', verifySignedIn, async (req, res) => { + router.get('/find/:userId', verifySignedIn, async (req, res) => { try { - const { projectId, search } = req.query; - if (!projectId || !search) { - return res.status(400).json({ error: 'projectId and search text are required' }); + const userId = req.params.userId; + if (!userId) { + return res.status(400).json({ error: 'userId is required' }); } - let where = { - [Op.or]: [{ email: { [Op.like]: `%${search}%` } }, { username: { [Op.like]: `%${search}%` } }], - }; - - let excludeIdArray = []; - const members = await Member.findAll({ - where: { projectId }, - attributes: ['userId'], - }); - excludeIdArray = members.map((member) => member.userId); - excludeIdArray.push(req.userId); - where.id = { [Op.notIn]: excludeIdArray }; - - const users = await User.findAll({ - where, - limit: 7, - }); - res.json(users); + try { + const user = await User.findByPk(userId, { + attributes: ['id', 'username', 'role', 'avatarPath'], + }); + if (!user) { + return res.status(404).send('User not found'); + } + res.json(user); + } catch (error) { + console.error(error); + res.status(500).send('Internal Server Error'); + } } catch (error) { console.error(error); res.status(500).send('Internal Server Error'); diff --git a/backend/routes/users/search.js b/backend/routes/users/search.js new file mode 100644 index 0000000..c936d61 --- /dev/null +++ b/backend/routes/users/search.js @@ -0,0 +1,44 @@ +const express = require('express'); +const router = express.Router(); +const defineUser = require('../../models/users'); +const defineMember = require('../../models/members'); +const { DataTypes, Op } = require('sequelize'); + +module.exports = function (sequelize) { + const { verifySignedIn } = require('../../middleware/auth')(sequelize); + const User = defineUser(sequelize, DataTypes); + const Member = defineMember(sequelize, DataTypes); + + router.get('/search', verifySignedIn, async (req, res) => { + try { + const { projectId, search } = req.query; + if (!projectId || !search) { + return res.status(400).json({ error: 'projectId and search text are required' }); + } + + let where = { + [Op.or]: [{ email: { [Op.like]: `%${search}%` } }, { username: { [Op.like]: `%${search}%` } }], + }; + + let excludeIdArray = []; + const members = await Member.findAll({ + where: { projectId }, + attributes: ['userId'], + }); + excludeIdArray = members.map((member) => member.userId); + excludeIdArray.push(req.userId); + where.id = { [Op.notIn]: excludeIdArray }; + + const users = await User.findAll({ + where, + limit: 7, + }); + res.json(users); + } catch (error) { + console.error(error); + res.status(500).send('Internal Server Error'); + } + }); + + return router; +}; diff --git a/backend/routes/users/show.js b/backend/routes/users/show.js deleted file mode 100644 index 7886717..0000000 --- a/backend/routes/users/show.js +++ /dev/null @@ -1,36 +0,0 @@ -const express = require('express'); -const router = express.Router(); -const defineUser = require('../../models/users'); -const { DataTypes } = require('sequelize'); - -module.exports = function (sequelize) { - const { verifySignedIn } = require('../../middleware/auth')(sequelize); - const User = defineUser(sequelize, DataTypes); - - router.get('/:userId', verifySignedIn, async (req, res) => { - try { - const userId = req.params.userId; - if (!userId) { - return res.status(400).json({ error: 'userId is required' }); - } - - try { - const user = await User.findByPk(userId, { - attributes: ['id', 'username', 'role', 'avatarPath'], - }); - if (!user) { - return res.status(404).send('User not found'); - } - res.json(user); - } catch (error) { - console.error(error); - res.status(500).send('Internal Server Error'); - } - } catch (error) { - console.error(error); - res.status(500).send('Internal Server Error'); - } - }); - - return router; -}; diff --git a/frontend/src/app/[locale]/projects/[projectId]/members/AddMemberDialog.tsx b/frontend/src/app/[locale]/projects/[projectId]/members/AddMemberDialog.tsx index bb6c334..32722aa 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/members/AddMemberDialog.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/members/AddMemberDialog.tsx @@ -5,7 +5,7 @@ import { Button, Input, Modal, ModalContent, ModalHeader, ModalBody, ModalFooter import { SettingsMessages } from '@/types/settings'; import { TokenContext } from '@/utils/TokenProvider'; import { UserType } from '@/types/user'; -import { searchUsers } from './membersControl'; +import { searchUsers } from '@/utils/usersControl'; import CandidatesTable from './CandidatesTable'; type Props = { @@ -32,7 +32,7 @@ export default function AddMemberDialog({ isOpen, projectId, onCancel, onAddMemb } try { - const data = await searchUsers(context.token.access_token, projectId, searchText); + const data = await searchUsers(context.token.access_token, Number(projectId), searchText); setCandidates(data); } catch (error: any) { console.error('Error in effect:', error.message); diff --git a/frontend/src/app/[locale]/projects/[projectId]/members/membersControl.ts b/frontend/src/app/[locale]/projects/[projectId]/members/membersControl.ts index d82fcbc..017ffbf 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/members/membersControl.ts +++ b/frontend/src/app/[locale]/projects/[projectId]/members/membersControl.ts @@ -24,29 +24,6 @@ async function fetchProjectMembers(jwt: string, projectId: string) { } } -async function searchUsers(jwt: string, projectId: string, searchText: string) { - const fetchOptions = { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${jwt}`, - }, - }; - - const url = `${apiServer}/users/find?projectId=${projectId}&search=${searchText}`; - - try { - const response = await fetch(url, fetchOptions); - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - const data = await response.json(); - return data; - } catch (error: any) { - console.error('Error fetching data:', error.message); - } -} - async function addMember(jwt: string, userId: string, projectId: string) { const fetchOptions = { method: 'POST', @@ -114,4 +91,4 @@ async function updateMember(jwt: string, userId: string, projectId: string, role } } -export { fetchProjectMembers, searchUsers, addMember, deleteMember, updateMember }; +export { fetchProjectMembers, addMember, deleteMember, updateMember }; diff --git a/frontend/src/app/[locale]/projects/[projectId]/settings/SettingsPage.tsx b/frontend/src/app/[locale]/projects/[projectId]/settings/SettingsPage.tsx index dee5498..960bbe2 100644 --- a/frontend/src/app/[locale]/projects/[projectId]/settings/SettingsPage.tsx +++ b/frontend/src/app/[locale]/projects/[projectId]/settings/SettingsPage.tsx @@ -11,9 +11,8 @@ import { ProjectType } from '@/types/project'; import DeleteConfirmDialog from '@/components/DeleteConfirmDialog'; import { useRouter } from '@/src/navigation'; import ProjectDialog from '@/components/ProjectDialog'; -import Config from '@/config/config'; import { UserType } from '@/types/user'; -const apiServer = Config.apiServer; +import { findUser } from '@/utils/usersControl'; type Props = { projectId: string; @@ -44,29 +43,6 @@ export default function SettingsPage({ projectId, messages, locale }: Props) { username: '', }); - async function fetchUser(jwt: string, userId: string) { - const fetchOptions = { - method: 'GET', - headers: { - 'Content-Type': 'application/json', - Authorization: `Bearer ${jwt}`, - }, - }; - - const url = `${apiServer}/users/${userId}`; - - try { - const response = await fetch(url, fetchOptions); - if (!response.ok) { - throw new Error(`HTTP error! Status: ${response.status}`); - } - const data = await response.json(); - return data; - } catch (error: any) { - console.error('Error fetching data:', error.message); - } - } - useEffect(() => { async function fetchDataEffect() { if (!context.isSignedIn()) { @@ -78,7 +54,7 @@ export default function SettingsPage({ projectId, messages, locale }: Props) { setProject(data); if (data.userId) { - const ownerData = await fetchUser(context.token.access_token, data.userId); + const ownerData = await findUser(context.token.access_token, data.userId); setOwner(ownerData); } else { console.error('failed to get project owner id'); diff --git a/frontend/utils/usersControl.ts b/frontend/utils/usersControl.ts new file mode 100644 index 0000000..e4851be --- /dev/null +++ b/frontend/utils/usersControl.ts @@ -0,0 +1,50 @@ +import Config from '@/config/config'; +const apiServer = Config.apiServer; + +async function findUser(jwt: string, userId: number) { + const fetchOptions = { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${jwt}`, + }, + }; + + const url = `${apiServer}/users/find/${userId}`; + + try { + const response = await fetch(url, fetchOptions); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + const data = await response.json(); + return data; + } catch (error: any) { + console.error('Error fetching data:', error.message); + } +} + +async function searchUsers(jwt: string, projectId: number, searchText: string) { + const fetchOptions = { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${jwt}`, + }, + }; + + const url = `${apiServer}/users/search?projectId=${projectId}&search=${searchText}`; + + try { + const response = await fetch(url, fetchOptions); + if (!response.ok) { + throw new Error(`HTTP error! Status: ${response.status}`); + } + const data = await response.json(); + return data; + } catch (error: any) { + console.error('Error fetching data:', error.message); + } +} + +export { findUser, searchUsers };