From b04c0b878e1c817fc4b59f318871e63113a52cd3 Mon Sep 17 00:00:00 2001 From: canove Date: Tue, 15 Sep 2020 19:28:06 -0300 Subject: [PATCH] changed contacts routes to typescript --- backend/src/controllers/ContactController.ts | 174 ++++++++++++++++++ backend/src/controllers/UserController.ts | 11 +- backend/src/database/index.ts | 8 +- backend/src/models/Contact.ts | 45 +++++ backend/src/models/Setting.ts | 5 +- backend/src/models/Ticket.ts | 36 ++++ backend/src/models/User.ts | 17 +- backend/src/modelsOld/Contact.js | 58 +++--- backend/src/modelsOld/Ticket.js | 78 ++++---- backend/src/routes/authRoutes.ts | 7 +- backend/src/routes/contactRoutes.ts | 21 +++ backend/src/routes/index.ts | 4 +- backend/src/routes/routes/auth.js | 16 -- backend/src/routes/routes/contacts.js | 21 --- .../ContactServices/CreateContactService.ts | 32 ++++ .../ContactServices/DeleteContactService.ts | 16 ++ .../ContactServices/ListContactsService.ts | 50 +++++ .../ContactServices/ShowContactService.ts | 17 ++ .../ContactServices/UpdateContactService.ts | 39 ++++ .../services/UserServices/ListUsersService.ts | 10 +- ...{FindUserService.ts => ShowUserService.ts} | 4 +- 21 files changed, 536 insertions(+), 133 deletions(-) create mode 100644 backend/src/controllers/ContactController.ts create mode 100644 backend/src/models/Contact.ts create mode 100644 backend/src/models/Ticket.ts create mode 100644 backend/src/routes/contactRoutes.ts delete mode 100644 backend/src/routes/routes/auth.js delete mode 100644 backend/src/routes/routes/contacts.js create mode 100644 backend/src/services/ContactServices/CreateContactService.ts create mode 100644 backend/src/services/ContactServices/DeleteContactService.ts create mode 100644 backend/src/services/ContactServices/ListContactsService.ts create mode 100644 backend/src/services/ContactServices/ShowContactService.ts create mode 100644 backend/src/services/ContactServices/UpdateContactService.ts rename backend/src/services/UserServices/{FindUserService.ts => ShowUserService.ts} (76%) diff --git a/backend/src/controllers/ContactController.ts b/backend/src/controllers/ContactController.ts new file mode 100644 index 0000000..a2081ad --- /dev/null +++ b/backend/src/controllers/ContactController.ts @@ -0,0 +1,174 @@ +import { Request, Response } from "express"; + +import ListContactsService from "../services/ContactServices/ListContactsService"; +import CreateContactService from "../services/ContactServices/CreateContactService"; +import ShowContactService from "../services/ContactServices/ShowContactService"; +import UpdateContactService from "../services/ContactServices/UpdateContactService"; +import DeleteContactService from "../services/ContactServices/DeleteContactService"; + +// const Sequelize = require("sequelize"); +// const { Op } = require("sequelize"); + +// const Contact = require("../models/Contact"); +// const Whatsapp = require("../models/Whatsapp"); +// const ContactCustomField = require("../models/ContactCustomField"); + +// const { getIO } = require("../libs/socket"); +// const { getWbot } = require("../libs/wbot"); + +type RequestQuery = { + searchParam: string; + pageNumber: string; +}; + +export const index = async (req: Request, res: Response): Promise => { + const { searchParam, pageNumber } = req.query as RequestQuery; + + const { contacts, count, hasMore } = await ListContactsService({ + searchParam, + pageNumber + }); + + return res.json({ contacts, count, hasMore }); +}; + +interface ContactData { + name: string; + number: string; + email?: string; +} + +export const store = async (req: Request, res: Response): Promise => { + const { name, number, email }: ContactData = req.body; + + const contact = await CreateContactService({ name, number, email }); + + // const defaultWhatsapp = await Whatsapp.findOne({ + // where: { default: true } + // }); + + // if (!defaultWhatsapp) { + // return res + // .status(404) + // .json({ error: "No default WhatsApp found. Check Connection page." }); + // } + + // const wbot = getWbot(defaultWhatsapp); + // const io = getIO(); + + // try { + // const isValidNumber = await wbot.isRegisteredUser( + // `${newContact.number}@c.us` + // ); + // if (!isValidNumber) { + // return res + // .status(400) + // .json({ error: "The suplied number is not a valid Whatsapp number" }); + // } + // } catch (err) { + // console.log(err); + // return res.status(500).json({ + // error: "Could not check whatsapp contact. Check connection page." + // }); + // } + + // const profilePicUrl = await wbot.getProfilePicUrl( + // `${newContact.number}@c.us` + // ); + + // const contact = await Contact.create( + // { ...newContact, profilePicUrl }, + // { + // include: "extraInfo" + // } + // ); + + // io.emit("contact", { + // action: "create", + // contact: contact + // }); + + return res.status(200).json(contact); +}; + +export const show = async (req: Request, res: Response): Promise => { + const { contactId } = req.params; + + const contact = await ShowContactService(contactId); + + return res.status(200).json(contact); +}; + +export const update = async ( + req: Request, + res: Response +): Promise => { + const contactData = req.body; + + const { contactId } = req.params; + + const contact = await UpdateContactService({ contactData, contactId }); + + // const io = getIO(); + // const contact = await Contact.findByPk(contactId, { + // include: "extraInfo" + // }); + + // if (!contact) { + // return res.status(404).json({ error: "No contact found with this ID" }); + // } + + // if (updatedContact.extraInfo) { + // await Promise.all( + // updatedContact.extraInfo.map(async info => { + // await ContactCustomField.upsert({ ...info, contactId: contact.id }); + // }) + // ); + + // await Promise.all( + // contact.extraInfo.map(async oldInfo => { + // let stillExists = updatedContact.extraInfo.findIndex( + // info => info.id === oldInfo.id + // ); + + // if (stillExists === -1) { + // await ContactCustomField.destroy({ where: { id: oldInfo.id } }); + // } + // }) + // ); + // } + + // await contact.update(updatedContact); + + // io.emit("contact", { + // action: "update", + // contact: contact + // }); + + return res.status(200).json(contact); +}; + +export const remove = async ( + req: Request, + res: Response +): Promise => { + // const io = getIO(); + const { contactId } = req.params; + + await DeleteContactService(contactId); + + // const contact = await Contact.findByPk(contactId); + + // if (!contact) { + // return res.status(404).json({ error: "No contact found with this ID" }); + // } + + // await contact.destroy(); + + // io.emit("contact", { + // action: "delete", + // contactId: contactId + // }); + + return res.status(200).json({ message: "Contact deleted" }); +}; diff --git a/backend/src/controllers/UserController.ts b/backend/src/controllers/UserController.ts index 11f77db..062222c 100644 --- a/backend/src/controllers/UserController.ts +++ b/backend/src/controllers/UserController.ts @@ -6,14 +6,19 @@ import AppError from "../errors/AppError"; import CreateUserService from "../services/UserServices/CreateUserService"; import ListUsersService from "../services/UserServices/ListUsersService"; import UpdateUserService from "../services/UserServices/UpdateUserService"; -import FindUserService from "../services/UserServices/FindUserService"; +import ShowUserService from "../services/UserServices/ShowUserService"; import DeleteUserService from "../services/UserServices/DeleteUserService"; +type RequestQuery = { + searchParam: string; + pageNumber: string; +}; + export const index = async (req: Request, res: Response): Promise => { if (req.user.profile !== "admin") { throw new AppError("Only administrators can access this route.", 403); // should be handled better. } - const { searchParam, pageNumber } = req.query as any; + const { searchParam, pageNumber } = req.query as RequestQuery; const { users, count, hasMore } = await ListUsersService({ searchParam, @@ -48,7 +53,7 @@ export const store = async (req: Request, res: Response): Promise => { export const show = async (req: Request, res: Response): Promise => { const { userId } = req.params; - const user = await FindUserService(userId); + const user = await ShowUserService(userId); return res.status(200).json(user); }; diff --git a/backend/src/database/index.ts b/backend/src/database/index.ts index 60eb3dd..da0628b 100644 --- a/backend/src/database/index.ts +++ b/backend/src/database/index.ts @@ -1,13 +1,13 @@ import { Sequelize } from "sequelize-typescript"; import User from "../models/User"; import Setting from "../models/Setting"; +import Contact from "../models/Contact"; +import Ticket from "../models/Ticket"; // eslint-disable-next-line const dbConfig = require("../config/database"); // import dbConfig from "../config/database"; -// const Contact = require("../models/Contact"); -// const Ticket = require("../models/Ticket"); // const Message = require("../models/Message"); // const Whatsapp = require("../models/Whatsapp"); // const ContactCustomField = require("../models/ContactCustomField"); @@ -16,8 +16,8 @@ const sequelize = new Sequelize(dbConfig); const models = [ User, - // Contact, - // Ticket, + Contact, + Ticket, // Message, // Whatsapp, // ContactCustomField, diff --git a/backend/src/models/Contact.ts b/backend/src/models/Contact.ts new file mode 100644 index 0000000..99ec142 --- /dev/null +++ b/backend/src/models/Contact.ts @@ -0,0 +1,45 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + DataType, + PrimaryKey, + AutoIncrement, + AllowNull, + Unique, + Default +} from "sequelize-typescript"; + +@Table +class Contact extends Model { + @PrimaryKey + @AutoIncrement + @Column + id: number; + + @Column(DataType.STRING) + name: string; + + @AllowNull(false) + @Unique + @Column + number: string; + + @AllowNull(false) + @Default("") + @Column + email: string; + + @Column + profilePicUrl: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default Contact; diff --git a/backend/src/models/Setting.ts b/backend/src/models/Setting.ts index b58e57a..13ba0e1 100644 --- a/backend/src/models/Setting.ts +++ b/backend/src/models/Setting.ts @@ -4,16 +4,17 @@ import { CreatedAt, UpdatedAt, Model, + DataType, PrimaryKey } from "sequelize-typescript"; @Table class Setting extends Model { @PrimaryKey - @Column + @Column(DataType.STRING) key: string; - @Column + @Column(DataType.STRING) value: string; @CreatedAt diff --git a/backend/src/models/Ticket.ts b/backend/src/models/Ticket.ts new file mode 100644 index 0000000..1e8ce3e --- /dev/null +++ b/backend/src/models/Ticket.ts @@ -0,0 +1,36 @@ +import { + Table, + Column, + CreatedAt, + UpdatedAt, + Model, + DataType, + PrimaryKey +} from "sequelize-typescript"; + +@Table +class Ticket extends Model { + @PrimaryKey + @Column(DataType.NUMBER) + id: number; + + @Column({ defaultValue: "pending" }) + status: string; + + // @Column({ allowNull: false, unique: true }) + // userId: string; + + @Column(DataType.VIRTUAL) + unreadMessages: string; + + @Column(DataType.STRING) + lastMessage: string; + + @CreatedAt + createdAt: Date; + + @UpdatedAt + updatedAt: Date; +} + +export default Ticket; diff --git a/backend/src/models/User.ts b/backend/src/models/User.ts index 80fabc0..73981b6 100644 --- a/backend/src/models/User.ts +++ b/backend/src/models/User.ts @@ -7,20 +7,23 @@ import { DataType, BeforeCreate, BeforeUpdate, - PrimaryKey + PrimaryKey, + AutoIncrement, + Default } from "sequelize-typescript"; import { hash, compare } from "bcryptjs"; @Table class User extends Model { @PrimaryKey + @AutoIncrement @Column id: number; @Column name: string; - @Column(DataType.STRING) + @Column email: string; @Column(DataType.VIRTUAL) @@ -29,9 +32,8 @@ class User extends Model { @Column passwordHash: string; - @Column({ - defaultValue: "admin" - }) + @Default("admin") + @Column profile: string; @CreatedAt @@ -48,10 +50,7 @@ class User extends Model { } }; - public checkPassword = async ( - // maybe not work like this. - password: string - ): Promise => { + public checkPassword = async (password: string): Promise => { return compare(password, this.getDataValue("passwordHash")); }; } diff --git a/backend/src/modelsOld/Contact.js b/backend/src/modelsOld/Contact.js index 43ab6e5..6187477 100644 --- a/backend/src/modelsOld/Contact.js +++ b/backend/src/modelsOld/Contact.js @@ -1,29 +1,29 @@ -const Sequelize = require("sequelize"); - -class Contact extends Sequelize.Model { - static init(sequelize) { - super.init( - { - name: { type: Sequelize.STRING }, - number: { type: Sequelize.STRING, allowNull: false, unique: true }, - email: { type: Sequelize.STRING, allowNull: false, defaultValue: "" }, - profilePicUrl: { type: Sequelize.STRING }, - }, - { - sequelize, - } - ); - - return this; - } - - static associate(models) { - this.hasMany(models.Ticket, { foreignKey: "contactId", as: "contact" }); - this.hasMany(models.ContactCustomField, { - foreignKey: "contactId", - as: "extraInfo", - }); - } -} - -module.exports = Contact; +const Sequelize = require("sequelize"); + +class Contact extends Sequelize.Model { + static init(sequelize) { + super.init( + { + name: { type: Sequelize.STRING }, + number: { type: Sequelize.STRING, allowNull: false, unique: true }, + email: { type: Sequelize.STRING, allowNull: false, defaultValue: "" }, + profilePicUrl: { type: Sequelize.STRING } + }, + { + sequelize + } + ); + + return this; + } + + static associate(models) { + this.hasMany(models.Ticket, { foreignKey: "contactId", as: "contact" }); + this.hasMany(models.ContactCustomField, { + foreignKey: "contactId", + as: "extraInfo" + }); + } +} + +module.exports = Contact; diff --git a/backend/src/modelsOld/Ticket.js b/backend/src/modelsOld/Ticket.js index 771eba5..bcff844 100644 --- a/backend/src/modelsOld/Ticket.js +++ b/backend/src/modelsOld/Ticket.js @@ -2,49 +2,49 @@ const Sequelize = require("sequelize"); const Message = require("./Message"); class Ticket extends Sequelize.Model { - static init(sequelize) { - super.init( - { - status: { type: Sequelize.STRING, defaultValue: "pending" }, - userId: { type: Sequelize.INTEGER, defaultValue: null }, - unreadMessages: { type: Sequelize.VIRTUAL }, - lastMessage: { type: Sequelize.STRING }, - }, - { - sequelize, - } - ); + static init(sequelize) { + super.init( + { + status: { type: Sequelize.STRING, defaultValue: "pending" }, + userId: { type: Sequelize.INTEGER, defaultValue: null }, + unreadMessages: { type: Sequelize.VIRTUAL }, + lastMessage: { type: Sequelize.STRING } + }, + { + sequelize + } + ); - this.addHook("afterFind", async result => { - if (result && result.length > 0) { - await Promise.all( - result.map(async ticket => { - ticket.unreadMessages = await Message.count({ - where: { ticketId: ticket.id, read: false }, - }); - }) - ); - } - }); + this.addHook("afterFind", async result => { + if (result && result.length > 0) { + await Promise.all( + result.map(async ticket => { + ticket.unreadMessages = await Message.count({ + where: { ticketId: ticket.id, read: false } + }); + }) + ); + } + }); - this.addHook("beforeUpdate", async ticket => { - ticket.unreadMessages = await Message.count({ - where: { ticketId: ticket.id, read: false }, - }); - }); + this.addHook("beforeUpdate", async ticket => { + ticket.unreadMessages = await Message.count({ + where: { ticketId: ticket.id, read: false } + }); + }); - return this; - } + return this; + } - static associate(models) { - this.belongsTo(models.Contact, { foreignKey: "contactId", as: "contact" }); - this.belongsTo(models.User, { foreignKey: "userId", as: "user" }); - this.belongsTo(models.Whatsapp, { - foreignKey: "whatsappId", - as: "whatsapp", - }); - this.hasMany(models.Message, { foreignKey: "ticketId", as: "messages" }); - } + static associate(models) { + this.belongsTo(models.Contact, { foreignKey: "contactId", as: "contact" }); + this.belongsTo(models.User, { foreignKey: "userId", as: "user" }); + this.belongsTo(models.Whatsapp, { + foreignKey: "whatsappId", + as: "whatsapp" + }); + this.hasMany(models.Message, { foreignKey: "ticketId", as: "messages" }); + } } module.exports = Ticket; diff --git a/backend/src/routes/authRoutes.ts b/backend/src/routes/authRoutes.ts index 6f3b7da..b9f0f4a 100644 --- a/backend/src/routes/authRoutes.ts +++ b/backend/src/routes/authRoutes.ts @@ -1,5 +1,6 @@ -import { Router } from "express"; +import { Router, Request, Response } from "express"; import SessionController from "../controllers/SessionController"; +import isAuth from "../middleware/isAuth"; import * as UserController from "../controllers/UserController"; const authRoutes = Router(); @@ -8,4 +9,8 @@ authRoutes.post("/signup", UserController.store); authRoutes.post("/login", SessionController); +authRoutes.get("/check", isAuth, (req: Request, res: Response) => { + res.status(200).json({ authenticated: true }); +}); + export default authRoutes; diff --git a/backend/src/routes/contactRoutes.ts b/backend/src/routes/contactRoutes.ts new file mode 100644 index 0000000..b7a0222 --- /dev/null +++ b/backend/src/routes/contactRoutes.ts @@ -0,0 +1,21 @@ +import express from "express"; +import isAuth from "../middleware/isAuth"; + +import * as ContactController from "../controllers/ContactController"; +// import ImportPhoneContactsController from "../controllers/ImportPhoneContactsController"; + +const contactRoutes = express.Router(); + +// contactRoutes.post("/contacts/import", isAuth, ImportPhoneContactsController.store); + +contactRoutes.get("/contacts", isAuth, ContactController.index); + +contactRoutes.get("/contacts/:contactId", isAuth, ContactController.show); + +contactRoutes.post("/contacts", isAuth, ContactController.store); + +contactRoutes.put("/contacts/:contactId", isAuth, ContactController.update); + +contactRoutes.delete("/contacts/:contactId", isAuth, ContactController.remove); + +export default contactRoutes; diff --git a/backend/src/routes/index.ts b/backend/src/routes/index.ts index 42b4fdc..bbd3d46 100644 --- a/backend/src/routes/index.ts +++ b/backend/src/routes/index.ts @@ -3,10 +3,10 @@ import { Router } from "express"; import userRoutes from "./userRoutes"; import authRoutes from "./authRoutes"; import settingRoutes from "./settingRoutes"; +import contactRoutes from "./contactRoutes"; // const TicketsRoutes = require("./routes/tickets"); // const MessagesRoutes = require("./routes/messages"); -// const ContactsRoutes = require("./routes/contacts"); // const WhatsRoutes = require("./routes/whatsapp"); // const UsersRoutes = require("./routes/users"); @@ -15,9 +15,9 @@ const routes = Router(); routes.use(userRoutes); routes.use("/auth", authRoutes); routes.use(settingRoutes); +routes.use(contactRoutes); // routes.use(TicketsRoutes); // routes.use(MessagesRoutes); -// routes.use(ContactsRoutes); // routes.use(WhatsRoutes); export default routes; diff --git a/backend/src/routes/routes/auth.js b/backend/src/routes/routes/auth.js deleted file mode 100644 index 930d1e6..0000000 --- a/backend/src/routes/routes/auth.js +++ /dev/null @@ -1,16 +0,0 @@ -const express = require("express"); -const SessionController = require("../../controllers/SessionController"); -const UserController = require("../../controllers/UserController"); -const isAuth = require("../../middleware/is-auth"); - -const routes = express.Router(); - -routes.post("/signup", UserController.store); - -routes.post("/login", SessionController.store); - -routes.get("/check", isAuth, (req, res) => { - res.status(200).json({ authenticated: true }); -}); - -module.exports = routes; diff --git a/backend/src/routes/routes/contacts.js b/backend/src/routes/routes/contacts.js deleted file mode 100644 index 1d9bfa2..0000000 --- a/backend/src/routes/routes/contacts.js +++ /dev/null @@ -1,21 +0,0 @@ -const express = require("express"); -const isAuth = require("../../middleware/is-auth"); - -const ContactController = require("../../controllers/ContactController"); -const ImportPhoneContactsController = require("../../controllers/ImportPhoneContactsController"); - -const routes = express.Router(); - -routes.post("/contacts/import", isAuth, ImportPhoneContactsController.store); - -routes.get("/contacts", isAuth, ContactController.index); - -routes.get("/contacts/:contactId", isAuth, ContactController.show); - -routes.post("/contacts", isAuth, ContactController.store); - -routes.put("/contacts/:contactId", isAuth, ContactController.update); - -routes.delete("/contacts/:contactId", isAuth, ContactController.delete); - -module.exports = routes; diff --git a/backend/src/services/ContactServices/CreateContactService.ts b/backend/src/services/ContactServices/CreateContactService.ts new file mode 100644 index 0000000..1d11ca5 --- /dev/null +++ b/backend/src/services/ContactServices/CreateContactService.ts @@ -0,0 +1,32 @@ +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; + +interface Request { + name: string; + number: string; + email?: string; +} + +const CreateContactService = async ({ + name, + number, + email +}: Request): Promise => { + const numberExists = await Contact.findOne({ + where: { number } + }); + + if (numberExists) { + throw new AppError("A contact with this number already exists."); + } + + const contact = await Contact.create({ + name, + number, + email + }); + + return contact; +}; + +export default CreateContactService; diff --git a/backend/src/services/ContactServices/DeleteContactService.ts b/backend/src/services/ContactServices/DeleteContactService.ts new file mode 100644 index 0000000..478e117 --- /dev/null +++ b/backend/src/services/ContactServices/DeleteContactService.ts @@ -0,0 +1,16 @@ +import Contact from "../../models/Contact"; +import AppError from "../../errors/AppError"; + +const DeleteContactService = async (id: string): Promise => { + const contact = await Contact.findOne({ + where: { id } + }); + + if (!contact) { + throw new AppError("No contact found with this ID.", 404); + } + + await contact.destroy(); +}; + +export default DeleteContactService; diff --git a/backend/src/services/ContactServices/ListContactsService.ts b/backend/src/services/ContactServices/ListContactsService.ts new file mode 100644 index 0000000..52c7f8a --- /dev/null +++ b/backend/src/services/ContactServices/ListContactsService.ts @@ -0,0 +1,50 @@ +import { Sequelize, Op } from "sequelize"; +import Contact from "../../models/Contact"; + +interface Request { + searchParam?: string; + pageNumber?: string; +} + +interface Response { + contacts: Contact[]; + count: number; + hasMore: boolean; +} + +const ListContactsService = async ({ + searchParam = "", + pageNumber = "1" +}: Request): Promise => { + const whereCondition = { + [Op.or]: [ + { + name: Sequelize.where( + Sequelize.fn("LOWER", Sequelize.col("name")), + "LIKE", + `%${searchParam.toLowerCase()}%` + ) + }, + { number: { [Op.like]: `%${searchParam}%` } } + ] + }; + const limit = 20; + const offset = limit * (+pageNumber - 1); + + const { count, rows: contacts } = await Contact.findAndCountAll({ + where: whereCondition, + limit, + offset, + order: [["createdAt", "DESC"]] + }); + + const hasMore = count > offset + contacts.length; + + return { + contacts, + count, + hasMore + }; +}; + +export default ListContactsService; diff --git a/backend/src/services/ContactServices/ShowContactService.ts b/backend/src/services/ContactServices/ShowContactService.ts new file mode 100644 index 0000000..6905683 --- /dev/null +++ b/backend/src/services/ContactServices/ShowContactService.ts @@ -0,0 +1,17 @@ +import Contact from "../../models/Contact"; +import AppError from "../../errors/AppError"; + +const ShowContactService = async (id: string): Promise => { + const user = await Contact.findOne({ + where: { id }, + attributes: ["id", "name", "number", "email"] + }); + + if (!user) { + throw new AppError("No contact found with this ID.", 404); + } + + return user; +}; + +export default ShowContactService; diff --git a/backend/src/services/ContactServices/UpdateContactService.ts b/backend/src/services/ContactServices/UpdateContactService.ts new file mode 100644 index 0000000..5a001cd --- /dev/null +++ b/backend/src/services/ContactServices/UpdateContactService.ts @@ -0,0 +1,39 @@ +import AppError from "../../errors/AppError"; +import Contact from "../../models/Contact"; + +interface ContactData { + email?: string; + number?: string; + name?: string; +} + +interface Request { + contactData: ContactData; + contactId: string; +} + +const UpdateContactService = async ({ + contactData, + contactId +}: Request): Promise => { + const { email, name, number } = contactData; + + const contact = await Contact.findOne({ + where: { id: contactId }, + attributes: ["id", "name", "number", "email"] + }); + + if (!contact) { + throw new AppError("No contact found with this ID.", 404); + } + + await contact.update({ + name, + number, + email + }); + + return contact; +}; + +export default UpdateContactService; diff --git a/backend/src/services/UserServices/ListUsersService.ts b/backend/src/services/UserServices/ListUsersService.ts index 4430724..a603b1f 100644 --- a/backend/src/services/UserServices/ListUsersService.ts +++ b/backend/src/services/UserServices/ListUsersService.ts @@ -3,7 +3,7 @@ import User from "../../models/User"; interface Request { searchParam?: string; - pageNumber?: number; + pageNumber?: string; } interface Response { @@ -14,7 +14,7 @@ interface Response { const ListUsersService = async ({ searchParam = "", - pageNumber = 1 + pageNumber = "1" }: Request): Promise => { const whereCondition = { [Op.or]: [ @@ -28,8 +28,8 @@ const ListUsersService = async ({ { email: { [Op.like]: `%${searchParam.toLowerCase()}%` } } ] }; - const limit = 20; - const offset = limit * (pageNumber - 1); + const limit = 10; + const offset = limit * (+pageNumber - 1); const { count, rows: users } = await User.findAndCountAll({ where: whereCondition, @@ -39,7 +39,7 @@ const ListUsersService = async ({ order: [["createdAt", "DESC"]] }); - const hasMore = count > limit + users.length; + const hasMore = count > offset + users.length; return { users, diff --git a/backend/src/services/UserServices/FindUserService.ts b/backend/src/services/UserServices/ShowUserService.ts similarity index 76% rename from backend/src/services/UserServices/FindUserService.ts rename to backend/src/services/UserServices/ShowUserService.ts index 868bf15..06f65eb 100644 --- a/backend/src/services/UserServices/FindUserService.ts +++ b/backend/src/services/UserServices/ShowUserService.ts @@ -1,7 +1,7 @@ import User from "../../models/User"; import AppError from "../../errors/AppError"; -const FindUserService = async (id: string): Promise => { +const ShowUserService = async (id: string): Promise => { const user = await User.findOne({ where: { id }, attributes: ["name", "id", "email", "profile"] @@ -14,4 +14,4 @@ const FindUserService = async (id: string): Promise => { return user; }; -export default FindUserService; +export default ShowUserService;