From b5314a8284b7b844a658e13aa26071ce7203aba6 Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Thu, 23 Apr 2026 17:46:50 -0300 Subject: [PATCH 01/11] feat: add domain layer --- .../models/forage-availability-model.ts | 45 +++++++++++++++++++ .../create-forage-availability-use-case.ts | 10 +++++ .../delete-forage-availability-use-case.ts | 9 ++++ .../get-forage-availabilities-use-case.ts | 12 +++++ .../get-forage-availability-use-case.ts | 11 +++++ .../forage-availability-use-cases/index.ts | 5 +++ .../update-forage-availability-use-case.ts | 11 +++++ 7 files changed, 103 insertions(+) create mode 100644 src/app/modules/forage-availability/domain/models/forage-availability-model.ts create mode 100644 src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/create-forage-availability-use-case.ts create mode 100644 src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/delete-forage-availability-use-case.ts create mode 100644 src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availabilities-use-case.ts create mode 100644 src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availability-use-case.ts create mode 100644 src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/index.ts create mode 100644 src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/update-forage-availability-use-case.ts diff --git a/src/app/modules/forage-availability/domain/models/forage-availability-model.ts b/src/app/modules/forage-availability/domain/models/forage-availability-model.ts new file mode 100644 index 00000000..520f0929 --- /dev/null +++ b/src/app/modules/forage-availability/domain/models/forage-availability-model.ts @@ -0,0 +1,45 @@ +import type { Option, WithId } from '@/core/domain/types' + +export type ForageAvailabilityDetailsModel = { + date: Date + forage: Option + entranceCm: string + residueCm: string + kgPerSquareMeter: string + paddockArea: string + efficiencyPercent: string + numberOfCows: string +} + +export type ForageAvailabilityDetailsApiResponse = { + date: string + forage: Option + entranceCm: string + residueCm: string + kgPerSquareMeter: string + paddockArea: string + efficiencyPercent: string + numberOfCows: string +} + +export type ForageAvailabilityModel = WithId<{ + date: Date + forage: string + entranceCm: string + residueCm: string + kgPerSquareMeter: string + paddockArea: string + efficiencyPercent: string + numberOfCows: string +}> + +export type ForageAvailabilityApiResponse = WithId<{ + date: string + forage: string + entranceCm: string + residueCm: string + kgPerSquareMeter: string + paddockArea: string + efficiencyPercent: string + numberOfCows: string +}> diff --git a/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/create-forage-availability-use-case.ts b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/create-forage-availability-use-case.ts new file mode 100644 index 00000000..af83360d --- /dev/null +++ b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/create-forage-availability-use-case.ts @@ -0,0 +1,10 @@ +import type { ForageAvailabilityDetailsModel } from '../../models/forage-availability-model' +import type { RequestInterface } from '@/core/domain/types' + +export type CreateForageAvailabilityUseCase = RequestInterface< + { + propertyId: number + forageAvailability: ForageAvailabilityDetailsModel + }, + void +> diff --git a/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/delete-forage-availability-use-case.ts b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/delete-forage-availability-use-case.ts new file mode 100644 index 00000000..0ec3baca --- /dev/null +++ b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/delete-forage-availability-use-case.ts @@ -0,0 +1,9 @@ +import { type RequestInterface } from '@/core/domain/types' + +export type DeleteForageAvailabilityUseCase = RequestInterface< + { + propertyId: number + id: number + }, + void +> diff --git a/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availabilities-use-case.ts b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availabilities-use-case.ts new file mode 100644 index 00000000..688dea2d --- /dev/null +++ b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availabilities-use-case.ts @@ -0,0 +1,12 @@ +import { + type RequestInterface, + type ListParams, + type ListResponse, +} from '@/core/domain/types' + +import { type ForageAvailabilityModel } from '../../models/forage-availability-model' + +export type GetForageAvailabilitiesUseCase = RequestInterface< + ListParams & { propertyId: number }, + ListResponse +> diff --git a/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availability-use-case.ts b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availability-use-case.ts new file mode 100644 index 00000000..678b78d1 --- /dev/null +++ b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/get-forage-availability-use-case.ts @@ -0,0 +1,11 @@ +import { type RequestInterface } from '@/core/domain/types' + +import { type ForageAvailabilityDetailsModel } from '../../models/forage-availability-model' + +export type GetForageAvailabilityUseCase = RequestInterface< + { + propertyId: number + id: number + }, + ForageAvailabilityDetailsModel +> diff --git a/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/index.ts b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/index.ts new file mode 100644 index 00000000..02426802 --- /dev/null +++ b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/index.ts @@ -0,0 +1,5 @@ +export * from './create-forage-availability-use-case' +export * from './delete-forage-availability-use-case' +export * from './get-forage-availabilities-use-case' +export * from './get-forage-availability-use-case' +export * from './update-forage-availability-use-case' diff --git a/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/update-forage-availability-use-case.ts b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/update-forage-availability-use-case.ts new file mode 100644 index 00000000..06ae2cf0 --- /dev/null +++ b/src/app/modules/forage-availability/domain/use-cases/forage-availability-use-cases/update-forage-availability-use-case.ts @@ -0,0 +1,11 @@ +import { type RequestInterface, type WithId } from '@/core/domain/types' + +import { type ForageAvailabilityDetailsModel } from '../../models/forage-availability-model' + +export type UpdateForageAvailabilityUseCase = RequestInterface< + { + propertyId: number + forageAvailability: WithId + }, + void +> From f837c33cd386e09d58c7e82a1da0e9fb93e5fe6f Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Thu, 23 Apr 2026 17:50:00 -0300 Subject: [PATCH 02/11] feat: add data layer --- .../forage-availability-use-cases/index.ts | 5 ++ ...ote-create-forage-availability-use-case.ts | 40 +++++++++ ...ote-delete-forage-availability-use-case.ts | 41 +++++++++ ...mote-get-forage-availabilities-use-case.ts | 89 +++++++++++++++++++ ...remote-get-forage-availability-use-case.ts | 60 +++++++++++++ ...ote-update-forage-availability-use-case.ts | 40 +++++++++ 6 files changed, 275 insertions(+) create mode 100644 src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/index.ts create mode 100644 src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts create mode 100644 src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case.ts create mode 100644 src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts create mode 100644 src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts create mode 100644 src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/index.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/index.ts new file mode 100644 index 00000000..27910dc2 --- /dev/null +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/index.ts @@ -0,0 +1,5 @@ +export * from './remote-create-forage-availability-use-case' +export * from './remote-delete-forage-availability-use-case' +export * from './remote-get-forage-availabilities-use-case' +export * from './remote-get-forage-availability-use-case' +export * from './remote-update-forage-availability-use-case' diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts new file mode 100644 index 00000000..a4d5bcbd --- /dev/null +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts @@ -0,0 +1,40 @@ +import { type HttpClient, HttpStatusCode } from '@/core/data/protocols/http' +import { + BadRequestError, + ForbiddenError, + UnexpectedError, +} from '@/core/domain/errors' + +import { type CreateForageAvailabilityUseCase } from '../../../domain/use-cases/forage-availability-use-cases' + +export class RemoteCreateForageAvailabilityUseCase + implements CreateForageAvailabilityUseCase +{ + constructor( + private readonly url: string, + private readonly httpClient: HttpClient + ) {} + + execute: CreateForageAvailabilityUseCase['execute'] = async ({ + propertyId, + forageAvailability, + }) => { + const { statusCode } = await this.httpClient.request({ + url: this.url.replace(':propertyId', propertyId.toString()), + method: 'post', + body: forageAvailability, + }) + + if (statusCode === HttpStatusCode.created) return + + if (statusCode === HttpStatusCode.badRequest) throw new BadRequestError() + + if (statusCode === HttpStatusCode.forbidden) { + throw new ForbiddenError( + 'Você não tem permissão para criar uma disponibilidade de forragem.' + ) + } + + throw new UnexpectedError() + } +} diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case.ts new file mode 100644 index 00000000..ccb1e8ca --- /dev/null +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case.ts @@ -0,0 +1,41 @@ +import { type HttpClient, HttpStatusCode } from '@/core/data/protocols/http' +import { + UnexpectedError, + NotFoundError, + ForbiddenError, +} from '@/core/domain/errors' + +import { type DeleteForageAvailabilityUseCase } from '../../../domain/use-cases/forage-availability-use-cases' + +export class RemoteDeleteForageAvailabilityUseCase + implements DeleteForageAvailabilityUseCase +{ + constructor( + private readonly url: string, + private readonly httpClient: HttpClient + ) {} + + execute: DeleteForageAvailabilityUseCase['execute'] = async ({ + propertyId, + id, + }) => { + const { statusCode } = await this.httpClient.request({ + url: `${this.url.replace(':propertyId', propertyId.toString())}/${id}`, + method: 'delete', + }) + + if (statusCode === HttpStatusCode.noContent) return + + if (statusCode === HttpStatusCode.notFound) { + throw new NotFoundError('Disponibilidade de Forragem') + } + + if (statusCode === HttpStatusCode.forbidden) { + throw new ForbiddenError( + 'Você não tem permissão para excluir uma disponibilidade de forragem.' + ) + } + + throw new UnexpectedError() + } +} diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts new file mode 100644 index 00000000..ebc9ddc3 --- /dev/null +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts @@ -0,0 +1,89 @@ +import { type HttpClient, HttpStatusCode } from '@/core/data/protocols/http' +import { + UnexpectedError, + NotFoundError, + ForbiddenError, +} from '@/core/domain/errors' +import { + type ListApiResponse, + type MapApiProperties, +} from '@/core/domain/types' + +import { + type ForageAvailabilityApiResponse, + type ForageAvailabilityModel, +} from '../../../domain/models/forage-availability-model' +import { type GetForageAvailabilitiesUseCase } from '../../../domain/use-cases/forage-availability-use-cases' + +export class RemoteGetForageAvailabilitiesUseCase + implements GetForageAvailabilitiesUseCase +{ + constructor( + private readonly url: string, + private readonly httpClient: HttpClient< + ForageAvailabilityModel, + ForageAvailabilityApiResponse, + ListApiResponse + > + ) {} + + execute: GetForageAvailabilitiesUseCase['execute'] = async ({ + propertyId, + filters, + pagination, + sort, + }) => { + const mapApiProperties: MapApiProperties< + ForageAvailabilityModel, + ForageAvailabilityApiResponse + > = { + id: 'id', + date: 'date', + forage: 'forage', + entranceCm: 'entranceCm', + residueCm: 'residueCm', + kgPerSquareMeter: 'kgPerSquareMeter', + paddockArea: 'paddockArea', + efficiencyPercent: 'efficiencyPercent', + numberOfCows: 'numberOfCows', + } + + const { statusCode, body } = await this.httpClient.request({ + url: `${this.url.replace(':propertyId', propertyId.toString())}/search`, + method: 'post', + filters, + pagination, + sort, + mapApiProperties, + }) + + if (statusCode === HttpStatusCode.ok && !!body) { + return { + resources: body.content.map((item) => ({ + id: item.id, + date: new Date(item.date), + forage: item.forage, + entranceCm: item.entranceCm, + residueCm: item.residueCm, + kgPerSquareMeter: item.kgPerSquareMeter, + paddockArea: item.paddockArea, + efficiencyPercent: item.efficiencyPercent, + numberOfCows: item.numberOfCows, + })), + totalPages: Math.ceil(body.numberOfElements / body.pageable.pageSize), + } + } + + if (statusCode === HttpStatusCode.notFound) { + throw new NotFoundError('Disponibilidade de Forragem') + } + + if (statusCode === HttpStatusCode.forbidden) { + throw new ForbiddenError( + 'Você não tem permissão para buscar as disponibilidades de forragem.' + ) + } + + throw new UnexpectedError() + } +} diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts new file mode 100644 index 00000000..d9f73f89 --- /dev/null +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts @@ -0,0 +1,60 @@ +import { type HttpClient, HttpStatusCode } from '@/core/data/protocols/http' +import { + BadRequestError, + ForbiddenError, + NotFoundError, + UnexpectedError, +} from '@/core/domain/errors' + +import { + type ForageAvailabilityDetailsApiResponse, + type ForageAvailabilityDetailsModel, +} from '../../../domain/models/forage-availability-model' +import { type GetForageAvailabilityUseCase } from '../../../domain/use-cases/forage-availability-use-cases' + +export class RemoteGetForageAvailabilityUseCase + implements GetForageAvailabilityUseCase +{ + constructor( + private readonly url: string, + private readonly httpClient: HttpClient< + ForageAvailabilityDetailsModel, + ForageAvailabilityDetailsApiResponse + > + ) {} + + execute: GetForageAvailabilityUseCase['execute'] = async ({ + propertyId, + id, + }) => { + const { statusCode, body } = await this.httpClient.request({ + url: `${this.url.replace(':propertyId', propertyId.toString())}/${id}`, + method: 'get', + }) + + if (statusCode === HttpStatusCode.ok && !!body) + return { + date: new Date(body.date), + forage: body.forage, + entranceCm: body.entranceCm, + residueCm: body.residueCm, + kgPerSquareMeter: body.kgPerSquareMeter, + paddockArea: body.paddockArea, + efficiencyPercent: body.efficiencyPercent, + numberOfCows: body.numberOfCows, + } + + if (statusCode === HttpStatusCode.badRequest) throw new BadRequestError() + + if (statusCode === HttpStatusCode.notFound) + throw new NotFoundError('Disponibilidade de Forragem') + + if (statusCode === HttpStatusCode.forbidden) { + throw new ForbiddenError( + 'Você não tem permissão para acessar os dados desta disponibilidade de forragem.' + ) + } + + throw new UnexpectedError() + } +} diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts new file mode 100644 index 00000000..d2567f82 --- /dev/null +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts @@ -0,0 +1,40 @@ +import { type HttpClient, HttpStatusCode } from '@/core/data/protocols/http' +import { + BadRequestError, + ForbiddenError, + UnexpectedError, +} from '@/core/domain/errors' + +import { type UpdateForageAvailabilityUseCase } from '../../../domain/use-cases/forage-availability-use-cases' + +export class RemoteUpdateForageAvailabilityUseCase + implements UpdateForageAvailabilityUseCase +{ + constructor( + private readonly url: string, + private readonly httpClient: HttpClient + ) {} + + execute: UpdateForageAvailabilityUseCase['execute'] = async ({ + propertyId, + forageAvailability: { id, ...forageAvailability }, + }) => { + const { statusCode } = await this.httpClient.request({ + url: `${this.url.replace(':propertyId', propertyId.toString())}/${id}`, + method: 'patch', + body: forageAvailability, + }) + + if (statusCode === HttpStatusCode.noContent) return + + if (statusCode === HttpStatusCode.badRequest) throw new BadRequestError() + + if (statusCode === HttpStatusCode.forbidden) { + throw new ForbiddenError( + 'Você não tem permissão para editar uma disponibilidade de forragem.' + ) + } + + throw new UnexpectedError() + } +} From 6be4b560a19bdcd9df85e70b5c60bf585892bdef Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Thu, 23 Apr 2026 17:52:03 -0300 Subject: [PATCH 03/11] feat: add scripts --- scripts/seed/data/forage-availabilities.mjs | 31 +++++++++++++++++++++ scripts/seed/data/index.mjs | 1 + 2 files changed, 32 insertions(+) create mode 100644 scripts/seed/data/forage-availabilities.mjs diff --git a/scripts/seed/data/forage-availabilities.mjs b/scripts/seed/data/forage-availabilities.mjs new file mode 100644 index 00000000..725ec182 --- /dev/null +++ b/scripts/seed/data/forage-availabilities.mjs @@ -0,0 +1,31 @@ +import { faker } from '@faker-js/faker/locale/pt_BR' + +import { foragesData } from './forages.mjs' + +export const forageAvailabilitiesDependencies = ['forages'] + +export const forageAvailabilitiesData = Array.from( + { + length: faker.number.int({ + min: 50, + max: 150, + }), + }, + (_, index) => { + const forage = faker.helpers.arrayElement(foragesData) + + return { + id: index + 1, + date: faker.date.recent(), + forage: forage.cultivation, + entranceCm: String(faker.number.int({ min: 20, max: 40 })), + residueCm: String(faker.number.int({ min: 5, max: 15 })), + kgPerSquareMeter: String( + faker.number.float({ min: 0.5, max: 3, fractionDigits: 2 }) + ), + paddockArea: String(faker.number.int({ min: 500, max: 5000 })), + efficiencyPercent: String(faker.number.int({ min: 60, max: 90 })), + numberOfCows: String(faker.number.int({ min: 10, max: 100 })), + } + } +) diff --git a/scripts/seed/data/index.mjs b/scripts/seed/data/index.mjs index b2db7148..11e67d51 100644 --- a/scripts/seed/data/index.mjs +++ b/scripts/seed/data/index.mjs @@ -1,4 +1,5 @@ export * from './forages.mjs' +export * from './forage-availabilities.mjs' export * from './improvements.mjs' export * from './machines.mjs' export * from './properties.mjs' From e7f752e3c392b8f2c39000551795b4f915f0329b Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Thu, 23 Apr 2026 17:53:06 -0300 Subject: [PATCH 04/11] feat: add main with factories layer --- .../use-cases/forage-availability-use-cases/index.ts | 5 +++++ ...ote-create-forage-availability-use-case-factory.ts | 11 +++++++++++ ...ote-delete-forage-availability-use-case-factory.ts | 11 +++++++++++ ...mote-get-forage-availabilities-use-case-factory.ts | 11 +++++++++++ ...remote-get-forage-availability-use-case-factory.ts | 11 +++++++++++ ...ote-update-forage-availability-use-case-factory.ts | 11 +++++++++++ 6 files changed, 60 insertions(+) create mode 100644 src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/index.ts create mode 100644 src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case-factory.ts create mode 100644 src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case-factory.ts create mode 100644 src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case-factory.ts create mode 100644 src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case-factory.ts create mode 100644 src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case-factory.ts diff --git a/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/index.ts b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/index.ts new file mode 100644 index 00000000..ee65939e --- /dev/null +++ b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/index.ts @@ -0,0 +1,5 @@ +export * from './remote-create-forage-availability-use-case-factory' +export * from './remote-delete-forage-availability-use-case-factory' +export * from './remote-get-forage-availabilities-use-case-factory' +export * from './remote-get-forage-availability-use-case-factory' +export * from './remote-update-forage-availability-use-case-factory' diff --git a/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case-factory.ts b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case-factory.ts new file mode 100644 index 00000000..724222da --- /dev/null +++ b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case-factory.ts @@ -0,0 +1,11 @@ +import { makeApiHttpClient } from '@/core/main/factories/http' + +import { RemoteCreateForageAvailabilityUseCase } from '../../../../data/use-cases/forage-availability-use-cases' +import { type CreateForageAvailabilityUseCase } from '../../../../domain/use-cases/forage-availability-use-cases' + +export function makeRemoteCreateForageAvailabilityUseCase(): CreateForageAvailabilityUseCase { + return new RemoteCreateForageAvailabilityUseCase( + '/properties/:propertyId/forage-availabilities', + makeApiHttpClient() + ) +} diff --git a/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case-factory.ts b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case-factory.ts new file mode 100644 index 00000000..dbb32cdb --- /dev/null +++ b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-delete-forage-availability-use-case-factory.ts @@ -0,0 +1,11 @@ +import { makeApiHttpClient } from '@/core/main/factories/http' + +import { RemoteDeleteForageAvailabilityUseCase } from '../../../../data/use-cases/forage-availability-use-cases' +import { type DeleteForageAvailabilityUseCase } from '../../../../domain/use-cases/forage-availability-use-cases' + +export function makeRemoteDeleteForageAvailabilityUseCase(): DeleteForageAvailabilityUseCase { + return new RemoteDeleteForageAvailabilityUseCase( + '/properties/:propertyId/forage-availabilities', + makeApiHttpClient() + ) +} diff --git a/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case-factory.ts b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case-factory.ts new file mode 100644 index 00000000..46b392ee --- /dev/null +++ b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case-factory.ts @@ -0,0 +1,11 @@ +import { makeApiHttpClient } from '@/core/main/factories/http' + +import { RemoteGetForageAvailabilitiesUseCase } from '../../../../data/use-cases/forage-availability-use-cases' +import { type GetForageAvailabilitiesUseCase } from '../../../../domain/use-cases/forage-availability-use-cases' + +export function makeRemoteGetForageAvailabilitiesUseCase(): GetForageAvailabilitiesUseCase { + return new RemoteGetForageAvailabilitiesUseCase( + '/properties/:propertyId/forage-availabilities', + makeApiHttpClient() + ) +} diff --git a/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case-factory.ts b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case-factory.ts new file mode 100644 index 00000000..558b1f9e --- /dev/null +++ b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case-factory.ts @@ -0,0 +1,11 @@ +import { makeApiHttpClient } from '@/core/main/factories/http' + +import { RemoteGetForageAvailabilityUseCase } from '../../../../data/use-cases/forage-availability-use-cases' +import { type GetForageAvailabilityUseCase } from '../../../../domain/use-cases/forage-availability-use-cases' + +export function makeRemoteGetForageAvailabilityUseCase(): GetForageAvailabilityUseCase { + return new RemoteGetForageAvailabilityUseCase( + '/properties/:propertyId/forage-availabilities', + makeApiHttpClient() + ) +} diff --git a/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case-factory.ts b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case-factory.ts new file mode 100644 index 00000000..080b1d9d --- /dev/null +++ b/src/app/modules/forage-availability/main/factories/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case-factory.ts @@ -0,0 +1,11 @@ +import { makeApiHttpClient } from '@/core/main/factories/http' + +import { RemoteUpdateForageAvailabilityUseCase } from '../../../../data/use-cases/forage-availability-use-cases' +import { type UpdateForageAvailabilityUseCase } from '../../../../domain/use-cases/forage-availability-use-cases' + +export function makeRemoteUpdateForageAvailabilityUseCase(): UpdateForageAvailabilityUseCase { + return new RemoteUpdateForageAvailabilityUseCase( + '/properties/:propertyId/forage-availabilities', + makeApiHttpClient() + ) +} From 2d73cf2d9b34de5d340fc5e32d2696346bfaee5e Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Thu, 23 Apr 2026 17:57:55 -0300 Subject: [PATCH 05/11] feat: add mocks layer --- .../create-forage-availability-handler.ts | 18 +++++ .../delete-forage-availability-handler.ts | 17 +++++ .../get-forage-availabilities-handler.ts | 72 +++++++++++++++++++ .../get-forage-availability-handler.ts | 42 +++++++++++ .../forage-availability-handlers/index.ts | 5 ++ .../update-forage-availability-handler.ts | 18 +++++ 6 files changed, 172 insertions(+) create mode 100644 src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/create-forage-availability-handler.ts create mode 100644 src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/delete-forage-availability-handler.ts create mode 100644 src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availabilities-handler.ts create mode 100644 src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availability-handler.ts create mode 100644 src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/index.ts create mode 100644 src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/update-forage-availability-handler.ts diff --git a/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/create-forage-availability-handler.ts b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/create-forage-availability-handler.ts new file mode 100644 index 00000000..3b8cc626 --- /dev/null +++ b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/create-forage-availability-handler.ts @@ -0,0 +1,18 @@ +import { HttpResponse, type PathParams } from 'msw' + +import { type ForageAvailabilityDetailsModel } from '@/app/modules/forage-availability/domain/models/forage-availability-model' +import { HttpStatusCode } from '@/core/data/protocols/http' +import { httpWithMiddleware } from '@/core/mocks/lib' +import { withAuth, withDelay } from '@/core/mocks/middleware' + +export const createForageAvailabilityHandler = httpWithMiddleware< + PathParams<'propertyId'>, + ForageAvailabilityDetailsModel, + never +>({ + routePath: '/api/properties/:propertyId/forage-availabilities', + method: 'post', + middlewares: [withDelay(), withAuth], + resolver: async () => + HttpResponse.json({}, { status: HttpStatusCode.created }), +}) diff --git a/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/delete-forage-availability-handler.ts b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/delete-forage-availability-handler.ts new file mode 100644 index 00000000..ecee9ae2 --- /dev/null +++ b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/delete-forage-availability-handler.ts @@ -0,0 +1,17 @@ +import { HttpResponse, type PathParams } from 'msw' + +import { HttpStatusCode } from '@/core/data/protocols/http' +import { httpWithMiddleware } from '@/core/mocks/lib' +import { withAuth, withDelay } from '@/core/mocks/middleware' + +export const deleteForageAvailabilityHandler = httpWithMiddleware< + PathParams<'propertyId' | 'id'>, + never, + never +>({ + routePath: '/api/properties/:propertyId/forage-availabilities/:id', + method: 'delete', + middlewares: [withDelay(), withAuth], + resolver: async () => + HttpResponse.json(undefined, { status: HttpStatusCode.noContent }), +}) diff --git a/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availabilities-handler.ts b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availabilities-handler.ts new file mode 100644 index 00000000..6cd26b64 --- /dev/null +++ b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availabilities-handler.ts @@ -0,0 +1,72 @@ +import { HttpResponse, type PathParams } from 'msw' + +import { type ForageAvailabilityApiResponse } from '@/app/modules/forage-availability/domain/models/forage-availability-model' +import { HttpStatusCode } from '@/core/data/protocols/http' +import { httpWithMiddleware } from '@/core/mocks/lib' +import { withAuth, withDelay } from '@/core/mocks/middleware' +import { type MockParams } from '@/core/mocks/types/mock-params-type' +import { type MockResponse } from '@/core/mocks/types/mock-response-type' +import { filterData, paginateData, sortData } from '@/core/mocks/utils' + +import forageAvailabilitiesData from '@database/forageAvailabilitiesData.json' + +export const getForageAvailabilitiesHandler = httpWithMiddleware< + PathParams<'propertyId'>, + MockParams, + MockResponse +>({ + routePath: '/api/properties/:propertyId/forage-availabilities/search', + method: 'post', + middlewares: [withDelay(), withAuth], + resolver: async ({ request }) => { + const { filters, page, rows, sort } = await request.json() + + if (!forageAvailabilitiesData.length) { + return HttpResponse.json( + { + content: [], + numberOfElements: 0, + pageable: { + pageSize: 0, + }, + }, + { + status: HttpStatusCode.ok, + } + ) + } + + let forageAvailabilities = + forageAvailabilitiesData as ForageAvailabilityApiResponse[] + + if (filters) { + forageAvailabilities = filterData( + filters, + forageAvailabilities + ) + } + if (sort) { + forageAvailabilities = sortData( + sort, + forageAvailabilities + ) + } + + const numberOfElements = forageAvailabilities.length + forageAvailabilities = paginateData( + { page, perPage: rows }, + forageAvailabilities + ) + + return HttpResponse.json( + { + content: forageAvailabilities, + numberOfElements, + pageable: { + pageSize: rows, + }, + }, + { status: HttpStatusCode.ok } + ) + }, +}) diff --git a/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availability-handler.ts b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availability-handler.ts new file mode 100644 index 00000000..a2617f67 --- /dev/null +++ b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/get-forage-availability-handler.ts @@ -0,0 +1,42 @@ +import { faker } from '@faker-js/faker/locale/pt_BR' +import { HttpResponse, type PathParams } from 'msw' + +import { type ForageAvailabilityDetailsApiResponse } from '@/app/modules/forage-availability/domain/models/forage-availability-model' +import { HttpStatusCode } from '@/core/data/protocols/http' +import { httpWithMiddleware } from '@/core/mocks/lib' +import { withAuth, withDelay } from '@/core/mocks/middleware' + +import forageAvailabilitiesData from '@database/forageAvailabilitiesData.json' + +export const getForageAvailabilityHandler = httpWithMiddleware< + PathParams<'propertyId' | 'id'>, + never, + ForageAvailabilityDetailsApiResponse +>({ + routePath: '/api/properties/:propertyId/forage-availabilities/:id', + method: 'get', + middlewares: [withDelay(), withAuth], + resolver: async ({ params }) => { + const id = Number(params.id) + const forageAvailability = forageAvailabilitiesData.find( + (item) => item.id === id + ) + + if (!forageAvailability) { + return HttpResponse.json({} as ForageAvailabilityDetailsApiResponse, { + status: HttpStatusCode.notFound, + }) + } + + const response: ForageAvailabilityDetailsApiResponse = { + ...forageAvailability, + date: forageAvailability.date.toString(), + forage: { + label: forageAvailability.forage, + value: faker.number.int({ min: 1, max: 1000 }), + }, + } + + return HttpResponse.json(response, { status: HttpStatusCode.ok }) + }, +}) diff --git a/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/index.ts b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/index.ts new file mode 100644 index 00000000..15a2f15f --- /dev/null +++ b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/index.ts @@ -0,0 +1,5 @@ +export * from './create-forage-availability-handler' +export * from './delete-forage-availability-handler' +export * from './get-forage-availabilities-handler' +export * from './get-forage-availability-handler' +export * from './update-forage-availability-handler' diff --git a/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/update-forage-availability-handler.ts b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/update-forage-availability-handler.ts new file mode 100644 index 00000000..1958a7b2 --- /dev/null +++ b/src/app/modules/forage-availability/mocks/handlers/forage-availability-handlers/update-forage-availability-handler.ts @@ -0,0 +1,18 @@ +import { HttpResponse, type PathParams } from 'msw' + +import { type ForageAvailabilityDetailsModel } from '@/app/modules/forage-availability/domain/models/forage-availability-model' +import { HttpStatusCode } from '@/core/data/protocols/http' +import { httpWithMiddleware } from '@/core/mocks/lib' +import { withAuth, withDelay } from '@/core/mocks/middleware' + +export const updateForageAvailabilityHandler = httpWithMiddleware< + PathParams<'propertyId' | 'id'>, + Omit, + never +>({ + routePath: '/api/properties/:propertyId/forage-availabilities/:id', + method: 'patch', + middlewares: [withDelay(), withAuth], + resolver: async () => + HttpResponse.json(undefined, { status: HttpStatusCode.noContent }), +}) From 9161aed2c8d82b3cd503873b592254b6fc084b59 Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Mon, 27 Apr 2026 11:08:16 -0300 Subject: [PATCH 06/11] feat: add presentation layer --- .../forage-availability-data-table.hook.tsx | 117 ++++++++++ .../forage-availability-data-table.tsx | 36 +++ .../forage-availability-data-table/index.ts | 1 + .../forage-availability-delete-dialog.tsx | 88 ++++++++ .../index.ts | 1 + .../contexts/forage-availability-context.tsx | 152 +++++++++++++ .../create-forage-availability-form.tsx | 117 ++++++++++ .../edit-forage-availability-form.tsx | 147 +++++++++++++ .../forage-availability-form-inputs.tsx | 205 ++++++++++++++++++ .../forage-availability-form.tsx | 18 ++ .../forage-availability-initial-form-data.ts | 13 ++ .../forms/forage-availability-form/index.ts | 1 + .../hooks/forage-availability-context.hook.ts | 15 ++ .../forage-availabilities-query.hook.ts | 60 +++++ .../queries/forage-availability-query.hook.ts | 39 ++++ .../screens/forage-availability-screen.tsx | 65 ++++++ .../forage-availability/presentation/types.ts | 5 + .../forage-availability-form-schema.ts | 23 ++ 18 files changed, 1103 insertions(+) create mode 100644 src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx create mode 100644 src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.tsx create mode 100644 src/app/modules/forage-availability/presentation/components/forage-availability-data-table/index.ts create mode 100644 src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx create mode 100644 src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/index.ts create mode 100644 src/app/modules/forage-availability/presentation/contexts/forage-availability-context.tsx create mode 100644 src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx create mode 100644 src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx create mode 100644 src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx create mode 100644 src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form.tsx create mode 100644 src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-initial-form-data.ts create mode 100644 src/app/modules/forage-availability/presentation/forms/forage-availability-form/index.ts create mode 100644 src/app/modules/forage-availability/presentation/hooks/forage-availability-context.hook.ts create mode 100644 src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts create mode 100644 src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts create mode 100644 src/app/modules/forage-availability/presentation/screens/forage-availability-screen.tsx create mode 100644 src/app/modules/forage-availability/presentation/types.ts create mode 100644 src/app/modules/forage-availability/presentation/validations/forage-availability-form-schema.ts diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx new file mode 100644 index 00000000..32906901 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx @@ -0,0 +1,117 @@ +import { useMemo, useState } from 'react' + +import { type ColumnDef } from '@tanstack/react-table' +import { format } from 'date-fns' +import { MoreHorizontalIcon, PencilIcon, Trash2Icon } from 'lucide-react' + +import { DropdownMenu } from '@/core/presentation/components/ui' +import { useDebounce } from '@/core/presentation/hooks' + +import { type ForageAvailabilityModel } from '../../../domain/models/forage-availability-model' +import { useForageAvailabilityContext } from '../../hooks/forage-availability-context.hook' +import { useForageAvailabilitiesQuery } from '../../hooks/queries/forage-availabilities-query.hook' +import { type ForageAvailabilitySort } from '../../types' + +export function useForageAvailabilityDataTable() { + const { + propertyId, + filters, + openEditForageAvailabilityForm, + openDeleteForageAvailabilityContainer, + } = useForageAvailabilityContext() + + const [page, setPage] = useState(1) + const [sort, setSort] = useState() + + const debouncedFilters = useDebounce({ value: filters }) + + const { isLoading, forageAvailabilities } = useForageAvailabilitiesQuery({ + propertyId, + filters: debouncedFilters, + page, + sort, + }) + + const columns = useMemo[]>( + () => [ + { + accessorKey: 'date', + header: 'Data', + cell: ({ row }) => format(row.original.date, 'dd/MM/yyyy'), + }, + { + accessorKey: 'forage', + header: 'Forrageira', + }, + { + accessorKey: 'entranceCm', + header: 'Entrada (cm)', + }, + { + accessorKey: 'residueCm', + header: 'Resíduo (cm)', + }, + { + accessorKey: 'kgPerSquareMeter', + header: 'Kg/m2', + }, + { + accessorKey: 'paddockArea', + header: 'Área Piquete (m2)', + }, + { + accessorKey: 'efficiencyPercent', + header: 'Eficiência (%)', + }, + { + accessorKey: 'numberOfCows', + header: 'Nº Vacas', + }, + { + id: 'row-actions', + header: '', + cell: ({ row }) => { + const { original: forageAvailability } = row + + return ( + + + + + + + openEditForageAvailabilityForm(forageAvailability) + } + > + Editar + + + + openDeleteForageAvailabilityContainer(forageAvailability) + } + > + Excluir + + + + ) + }, + }, + ], + [openDeleteForageAvailabilityContainer, openEditForageAvailabilityForm] + ) + + return { + columns, + forageAvailabilities, + isLoading, + page, + sort, + setSort, + setPage, + } +} diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.tsx b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.tsx new file mode 100644 index 00000000..376072ec --- /dev/null +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.tsx @@ -0,0 +1,36 @@ +import { DataTable } from '@/core/presentation/components/ui' + +import { type ForageAvailabilityModel } from '../../../domain/models/forage-availability-model' + +import { useForageAvailabilityDataTable } from './forage-availability-data-table.hook' + +export function ForageAvailabilityDataTable() { + const { + columns, + forageAvailabilities, + isLoading, + page, + sort, + setSort, + setPage, + } = useForageAvailabilityDataTable() + + return ( + + columns={columns} + data={forageAvailabilities.resources} + totalPages={forageAvailabilities.totalPages} + pagination={{ + currentPage: page, + onPageChange: setPage, + }} + sorting={{ + currentSorting: sort, + onSorting: setSort, + }} + loading={isLoading} + /> + ) +} + +ForageAvailabilityDataTable.displayName = 'ForageAvailabilityDataTable' diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/index.ts b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/index.ts new file mode 100644 index 00000000..85ff1f2d --- /dev/null +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/index.ts @@ -0,0 +1 @@ +export * from './forage-availability-data-table' diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx b/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx new file mode 100644 index 00000000..11c26ecb --- /dev/null +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx @@ -0,0 +1,88 @@ +import { useCallback } from 'react' + +import { useMutation, useQueryClient } from '@tanstack/react-query' +import { format } from 'date-fns' +import toast from 'react-hot-toast' + +import { AlertDialog } from '@/core/presentation/components/ui' + +import { makeRemoteDeleteForageAvailabilityUseCase } from '../../../main/factories/use-cases/forage-availability-use-cases' +import { useForageAvailabilityContext } from '../../hooks/forage-availability-context.hook' + +export function ForageAvailabilityDeleteDialog() { + const { + propertyId, + selectedForageAvailability, + isOpenDeleteForageAvailabilityContainer, + closeDeleteForageAvailabilityContainer, + } = useForageAvailabilityContext() + + const deleteForageAvailabilityUseCase = + makeRemoteDeleteForageAvailabilityUseCase() + + const queryClient = useQueryClient() + + const { mutateAsync: mutateHandleDeleteForageAvailability } = useMutation({ + mutationFn: deleteForageAvailabilityUseCase.execute, + }) + + const handleDeleteForageAvailability = useCallback(async () => { + if (!selectedForageAvailability?.id) { + toast.error('Erro ao remover disponibilidade de forragem') + return + } + + try { + await mutateHandleDeleteForageAvailability({ + propertyId, + id: selectedForageAvailability.id, + }) + + queryClient.invalidateQueries({ + queryKey: ['forage-availabilities'], + exact: false, + }) + + toast.success('Disponibilidade de forragem removida com sucesso') + } catch { + toast.error('Erro ao remover disponibilidade de forragem') + } finally { + closeDeleteForageAvailabilityContainer() + } + }, [ + closeDeleteForageAvailabilityContainer, + mutateHandleDeleteForageAvailability, + propertyId, + queryClient, + selectedForageAvailability, + ]) + + return ( + + + + + {`Deseja remover a disponibilidade de forragem de ${ + selectedForageAvailability?.date && + format(selectedForageAvailability.date, 'dd/MM/yyyy') + }?`} + + + Não será possível desfazer essa ação! + + + + Cancelar + + Remover + + + + + ) +} + +ForageAvailabilityDeleteDialog.displayName = 'ForageAvailabilityDeleteDialog' diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/index.ts b/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/index.ts new file mode 100644 index 00000000..4dd7188e --- /dev/null +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/index.ts @@ -0,0 +1 @@ +export * from './forage-availability-delete-dialog' diff --git a/src/app/modules/forage-availability/presentation/contexts/forage-availability-context.tsx b/src/app/modules/forage-availability/presentation/contexts/forage-availability-context.tsx new file mode 100644 index 00000000..a00dc590 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/contexts/forage-availability-context.tsx @@ -0,0 +1,152 @@ +import { + createContext, + useCallback, + useMemo, + useState, + type ReactNode, +} from 'react' + +import { useParams } from 'react-router-dom' + +import { type ForageAvailabilityModel } from '../../domain/models/forage-availability-model' +import { type ForageAvailabilityFilters } from '../types' + +export type ForageAvailabilityContextData = { + propertyId: number + selectedForageAvailability?: ForageAvailabilityModel + isOpenNewForageAvailabilityForm: boolean + isOpenEditForageAvailabilityForm: boolean + isOpenDeleteForageAvailabilityContainer: boolean + filters: ForageAvailabilityFilters + openNewForageAvailabilityForm: () => void + closeNewForageAvailabilityForm: () => void + openEditForageAvailabilityForm: ( + forageAvailability: ForageAvailabilityModel + ) => void + closeEditForageAvailabilityForm: () => void + openDeleteForageAvailabilityContainer: ( + forageAvailability: ForageAvailabilityModel + ) => void + closeDeleteForageAvailabilityContainer: () => void + handleChangeFilters: (newFilters: ForageAvailabilityFilters) => void + clearFilters: () => void +} + +export const ForageAvailabilityContext = + createContext( + {} as ForageAvailabilityContextData + ) + +type ForageAvailabilityProviderProps = { + children: ReactNode +} + +export function ForageAvailabilityProvider({ + children, +}: ForageAvailabilityProviderProps) { + const params = useParams<{ propertyId: string }>() + + const [selectedForageAvailability, setSelectedForageAvailability] = + useState() + const [isOpenNewForageAvailabilityForm, setIsOpenNewForageAvailabilityForm] = + useState(false) + const [ + isOpenEditForageAvailabilityForm, + setIsOpenEditForageAvailabilityForm, + ] = useState(false) + const [ + isOpenDeleteForageAvailabilityContainer, + setIsOpenDeleteForageAvailabilityContainer, + ] = useState(false) + const [filters, setFilters] = useState({}) + + const openNewForageAvailabilityForm = useCallback(() => { + setIsOpenNewForageAvailabilityForm(true) + }, []) + + const closeNewForageAvailabilityForm = useCallback(() => { + setIsOpenNewForageAvailabilityForm(false) + }, []) + + const openEditForageAvailabilityForm = useCallback( + (forageAvailability: ForageAvailabilityModel) => { + setSelectedForageAvailability(forageAvailability) + setIsOpenEditForageAvailabilityForm(true) + }, + [] + ) + + const closeEditForageAvailabilityForm = useCallback(() => { + setSelectedForageAvailability(undefined) + setIsOpenEditForageAvailabilityForm(false) + }, []) + + const openDeleteForageAvailabilityContainer = useCallback( + (forageAvailability: ForageAvailabilityModel) => { + setSelectedForageAvailability(forageAvailability) + setIsOpenDeleteForageAvailabilityContainer(true) + }, + [] + ) + + const closeDeleteForageAvailabilityContainer = useCallback(() => { + setSelectedForageAvailability(undefined) + setIsOpenDeleteForageAvailabilityContainer(false) + }, []) + + const handleChangeFilters = useCallback( + (newFilters: ForageAvailabilityFilters) => { + setFilters((prev) => ({ ...prev, ...newFilters })) + }, + [] + ) + + const clearFilters = useCallback(() => { + setFilters({}) + }, []) + + const value = useMemo( + () => ({ + propertyId: Number(params.propertyId), + selectedForageAvailability, + isOpenNewForageAvailabilityForm, + isOpenEditForageAvailabilityForm, + isOpenDeleteForageAvailabilityContainer, + filters, + openNewForageAvailabilityForm, + closeNewForageAvailabilityForm, + openEditForageAvailabilityForm, + closeEditForageAvailabilityForm, + openDeleteForageAvailabilityContainer, + closeDeleteForageAvailabilityContainer, + handleChangeFilters, + clearFilters, + }), + [ + params.propertyId, + selectedForageAvailability, + isOpenNewForageAvailabilityForm, + isOpenEditForageAvailabilityForm, + isOpenDeleteForageAvailabilityContainer, + filters, + openNewForageAvailabilityForm, + closeNewForageAvailabilityForm, + openEditForageAvailabilityForm, + closeEditForageAvailabilityForm, + openDeleteForageAvailabilityContainer, + closeDeleteForageAvailabilityContainer, + handleChangeFilters, + clearFilters, + ] + ) + + if (!params.propertyId) { + return null + } + + return ( + + {children} + + ) +} diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx new file mode 100644 index 00000000..927ff73d --- /dev/null +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx @@ -0,0 +1,117 @@ +import { useCallback } from 'react' + +import { zodResolver } from '@hookform/resolvers/zod' +import { useMutation, useQueryClient } from '@tanstack/react-query' +import toast from 'react-hot-toast' + +import { + Button, + Form, + ScrollArea, + Sheet, +} from '@/core/presentation/components/ui' +import { useHookForm } from '@/core/presentation/hooks' + +import { makeRemoteCreateForageAvailabilityUseCase } from '../../../main/factories/use-cases/forage-availability-use-cases' +import { useForageAvailabilityContext } from '../../hooks/forage-availability-context.hook' +import { + forageAvailabilityFormSchema, + type ForageAvailabilityFormSchema, +} from '../../validations/forage-availability-form-schema' + +import { ForageAvailabilityFormInputs } from './forage-availability-form-inputs' +import { FORAGE_AVAILABILITY_INITIAL_FORM_DATA } from './forage-availability-initial-form-data' + +export function CreateForageAvailabilityForm() { + const { + propertyId, + isOpenNewForageAvailabilityForm, + closeNewForageAvailabilityForm, + } = useForageAvailabilityContext() + + const createForageAvailabilityUseCase = + makeRemoteCreateForageAvailabilityUseCase() + + const queryClient = useQueryClient() + + const form = useHookForm({ + defaultValues: FORAGE_AVAILABILITY_INITIAL_FORM_DATA, + resolver: zodResolver(forageAvailabilityFormSchema), + }) + + const { mutateAsync: mutateHandleCreateForageAvailability } = useMutation({ + mutationFn: createForageAvailabilityUseCase.execute, + }) + + const handleCreateForageAvailability = useCallback( + async (data: ForageAvailabilityFormSchema) => { + try { + await mutateHandleCreateForageAvailability({ + propertyId, + forageAvailability: data, + }) + + queryClient.invalidateQueries({ + queryKey: ['forage-availabilities'], + exact: false, + }) + + toast.success('Disponibilidade de forragem cadastrada com sucesso') + + form.reset(FORAGE_AVAILABILITY_INITIAL_FORM_DATA) + + closeNewForageAvailabilityForm() + } catch { + toast.error('Erro ao cadastrar disponibilidade de forragem') + } + }, + [ + closeNewForageAvailabilityForm, + form, + mutateHandleCreateForageAvailability, + propertyId, + queryClient, + ] + ) + + return ( + + + + Nova Disponibilidade de Forragem + + Preencha o formulário para criar um novo registro + + + + + +
+ + +
+
+ + + + +
+
+ ) +} + +CreateForageAvailabilityForm.displayName = 'CreateForageAvailabilityForm' diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx new file mode 100644 index 00000000..6397eb60 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx @@ -0,0 +1,147 @@ +import { useCallback } from 'react' + +import { zodResolver } from '@hookform/resolvers/zod' +import { useMutation, useQueryClient } from '@tanstack/react-query' +import { format } from 'date-fns' +import toast from 'react-hot-toast' + +import { + Button, + Form, + Loading, + ScrollArea, + Sheet, +} from '@/core/presentation/components/ui' +import { useHookForm } from '@/core/presentation/hooks' + +import { makeRemoteUpdateForageAvailabilityUseCase } from '../../../main/factories/use-cases/forage-availability-use-cases' +import { useForageAvailabilityContext } from '../../hooks/forage-availability-context.hook' +import { useForageAvailabilityQuery } from '../../hooks/queries/forage-availability-query.hook' +import { + forageAvailabilityFormSchema, + type ForageAvailabilityFormSchema, +} from '../../validations/forage-availability-form-schema' + +import { ForageAvailabilityFormInputs } from './forage-availability-form-inputs' +import { FORAGE_AVAILABILITY_INITIAL_FORM_DATA } from './forage-availability-initial-form-data' + +export function EditForageAvailabilityForm() { + const { + propertyId, + isOpenEditForageAvailabilityForm, + closeEditForageAvailabilityForm, + selectedForageAvailability, + } = useForageAvailabilityContext() + + const { isLoading, forageAvailability } = useForageAvailabilityQuery({ + propertyId, + id: selectedForageAvailability!.id, + }) + + const updateForageAvailabilityUseCase = + makeRemoteUpdateForageAvailabilityUseCase() + + const queryClient = useQueryClient() + + const form = useHookForm({ + defaultValues: FORAGE_AVAILABILITY_INITIAL_FORM_DATA, + ...(forageAvailability && { + values: { + ...forageAvailability, + date: new Date(forageAvailability.date), + }, + }), + resolver: zodResolver(forageAvailabilityFormSchema), + }) + + const { mutateAsync: mutateHandleUpdateForageAvailability } = useMutation({ + mutationFn: updateForageAvailabilityUseCase.execute, + }) + + const handleUpdateForageAvailability = useCallback( + async (data: ForageAvailabilityFormSchema) => { + try { + if (!selectedForageAvailability?.id) { + toast.error('Erro ao atualizar disponibilidade de forragem') + return + } + + await mutateHandleUpdateForageAvailability({ + propertyId, + forageAvailability: { + ...data, + id: selectedForageAvailability.id, + }, + }) + + queryClient.invalidateQueries({ + queryKey: ['forage-availabilities'], + exact: false, + }) + + toast.success('Disponibilidade de forragem editada com sucesso') + form.reset(FORAGE_AVAILABILITY_INITIAL_FORM_DATA) + closeEditForageAvailabilityForm() + } catch { + toast.error('Erro ao salvar alterações') + } + }, + [ + closeEditForageAvailabilityForm, + form, + mutateHandleUpdateForageAvailability, + propertyId, + queryClient, + selectedForageAvailability, + ] + ) + + return ( + + + + {`Editar Disponibilidade de Forragem de ${ + selectedForageAvailability?.date && + format(selectedForageAvailability.date, 'dd/MM/yyyy') + }`} + + Preencha o formulário para editar o registro + + + + +
+ {isLoading ? ( +
+ +
+ ) : ( + + )} + +
+
+ + + + +
+
+ ) +} + +EditForageAvailabilityForm.displayName = 'EditForageAvailabilityForm' diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx new file mode 100644 index 00000000..64f0efeb --- /dev/null +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx @@ -0,0 +1,205 @@ +import { useState } from 'react' + +import { useFormContext } from 'react-hook-form' + +import { useAllForagesQuery } from '@/app/modules/forages/presentation/hooks/queries/all-forages-query.hook' +import { onlyNumbersAndDecimalMask, onlyNumbersMask } from '@/core/masker' +import { + Combobox, + DatePicker, + Form, + Input, +} from '@/core/presentation/components/ui' +import { Grouper } from '@/core/presentation/components/utils' +import { useDebounce } from '@/core/presentation/hooks' + +import { useForageAvailabilityContext } from '../../hooks/forage-availability-context.hook' +import { type ForageAvailabilityFormSchema } from '../../validations/forage-availability-form-schema' + +export function ForageAvailabilityFormInputs() { + const { propertyId } = useForageAvailabilityContext() + const form = useFormContext() + + const [searchForage, setSearchForage] = useState('') + const debouncedForage = useDebounce({ value: searchForage }) + + const { allForages, isLoading: isLoadingForages } = useAllForagesQuery({ + propertyId, + filters: { + cultivation: { + value: debouncedForage, + type: 'LIKE', + }, + }, + }) + + return ( + <> + ( + + Data* + + + + + + )} + /> + + ( + + Forrageira* + + + + + + )} + /> + + + ( + + Entrada (cm)* + + + + + + )} + /> + + ( + + Resíduo (cm)* + + + + + + )} + /> + + + + ( + + Kg/m2* + + + + + + )} + /> + + ( + + Área de Piquete (m2)* + + + + + + )} + /> + + + + ( + + Eficiência (%)* + + + + + + )} + /> + + ( + + Número de vacas* + + + + + + )} + /> + + + ) +} + +ForageAvailabilityFormInputs.displayName = 'ForageAvailabilityFormInputs' diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form.tsx new file mode 100644 index 00000000..3142b3c9 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form.tsx @@ -0,0 +1,18 @@ +import { CreateForageAvailabilityForm } from './create-forage-availability-form' +import { EditForageAvailabilityForm } from './edit-forage-availability-form' + +type ForageAvailabilityFormProps = { + id?: string | number +} + +export function ForageAvailabilityForm({ + id, +}: Readonly) { + if (id) { + return + } + + return +} + +ForageAvailabilityForm.displayName = 'ForageAvailabilityForm' diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-initial-form-data.ts b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-initial-form-data.ts new file mode 100644 index 00000000..b45455d3 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-initial-form-data.ts @@ -0,0 +1,13 @@ +import { type ForageAvailabilityFormSchema } from '../../validations/forage-availability-form-schema' + +export const FORAGE_AVAILABILITY_INITIAL_FORM_DATA: ForageAvailabilityFormSchema = + { + date: new Date(), + forage: { label: '', value: 0 }, + entranceCm: '', + residueCm: '', + kgPerSquareMeter: '', + paddockArea: '', + efficiencyPercent: '', + numberOfCows: '', + } diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/index.ts b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/index.ts new file mode 100644 index 00000000..2fa34be4 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/index.ts @@ -0,0 +1 @@ +export * from './forage-availability-form' diff --git a/src/app/modules/forage-availability/presentation/hooks/forage-availability-context.hook.ts b/src/app/modules/forage-availability/presentation/hooks/forage-availability-context.hook.ts new file mode 100644 index 00000000..3903c7c8 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/hooks/forage-availability-context.hook.ts @@ -0,0 +1,15 @@ +import { useContext } from 'react' + +import { ForageAvailabilityContext } from '../contexts/forage-availability-context' + +export function useForageAvailabilityContext() { + const context = useContext(ForageAvailabilityContext) + + if (!context) { + throw new Error( + 'useForageAvailabilityContext must be used within an ForageAvailabilityProvider' + ) + } + + return context +} diff --git a/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts new file mode 100644 index 00000000..7583e4fc --- /dev/null +++ b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts @@ -0,0 +1,60 @@ +import { useEffect } from 'react' + +import { useQuery } from '@tanstack/react-query' +import toast from 'react-hot-toast' + +import { makeRemoteGetForageAvailabilitiesUseCase } from '../../../main/factories/use-cases/forage-availability-use-cases' +import { + type ForageAvailabilityFilters, + type ForageAvailabilitySort, +} from '../../types' + +type Props = { + propertyId: number + filters: ForageAvailabilityFilters + page: number + sort?: ForageAvailabilitySort +} + +export function useForageAvailabilitiesQuery({ + propertyId, + filters, + page, + sort, +}: Props) { + const getForageAvailabilitiesUseCase = + makeRemoteGetForageAvailabilitiesUseCase() + + const { + data, + isError, + error, + isLoading, + refetch: refetchForageAvailabilities, + } = useQuery({ + queryKey: ['forage-availabilities', { page, sort, filters }], + queryFn: () => + getForageAvailabilitiesUseCase.execute({ + propertyId, + pagination: { page }, + sort, + filters, + }), + }) + + useEffect(() => { + if (isError) + toast.error( + error?.message ?? 'Erro ao buscar disponibilidades de forragem' + ) + }, [error, isError]) + + return { + forageAvailabilities: data ?? { + resources: [], + totalPages: 1, + }, + isLoading, + refetchForageAvailabilities, + } +} diff --git a/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts new file mode 100644 index 00000000..02ee7515 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts @@ -0,0 +1,39 @@ +import { useEffect } from 'react' + +import { useQuery } from '@tanstack/react-query' +import toast from 'react-hot-toast' + +import { makeRemoteGetForageAvailabilityUseCase } from '../../../main/factories/use-cases/forage-availability-use-cases' + +type Props = { + propertyId: number + id: number +} + +export function useForageAvailabilityQuery({ propertyId, id }: Props) { + const getForageAvailabilityUseCase = makeRemoteGetForageAvailabilityUseCase() + + const { + data: forageAvailability, + isError, + error, + isLoading, + refetch: refetchForageAvailability, + } = useQuery({ + queryKey: ['forage-availability', id], + queryFn: () => getForageAvailabilityUseCase.execute({ propertyId, id }), + }) + + useEffect(() => { + if (isError) + toast.error( + error?.message ?? 'Erro ao buscar disponibilidade de forragem' + ) + }, [error, isError]) + + return { + forageAvailability, + isLoading, + refetchForageAvailability, + } +} diff --git a/src/app/modules/forage-availability/presentation/screens/forage-availability-screen.tsx b/src/app/modules/forage-availability/presentation/screens/forage-availability-screen.tsx new file mode 100644 index 00000000..31168e1f --- /dev/null +++ b/src/app/modules/forage-availability/presentation/screens/forage-availability-screen.tsx @@ -0,0 +1,65 @@ +import { Button, Input } from '@/core/presentation/components/ui' + +import { ForageAvailabilityDataTable } from '../components/forage-availability-data-table' +import { ForageAvailabilityDeleteDialog } from '../components/forage-availability-delete-dialog' +import { + ForageAvailabilityContext, + ForageAvailabilityProvider, +} from '../contexts/forage-availability-context' +import { ForageAvailabilityForm } from '../forms/forage-availability-form' + +export function ForageAvailabilityScreen() { + return ( + + + {({ + selectedForageAvailability, + isOpenDeleteForageAvailabilityContainer, + isOpenNewForageAvailabilityForm, + isOpenEditForageAvailabilityForm, + filters, + handleChangeFilters, + openNewForageAvailabilityForm, + }) => ( +
+
+ + + { + handleChangeFilters({ + forage: { value: target.value, type: 'LIKE' }, + }) + }} + placeholder="Procurar por forrageira" + /> +
+ + + + {selectedForageAvailability && + isOpenDeleteForageAvailabilityContainer && ( + + )} + + {(isOpenNewForageAvailabilityForm || + isOpenEditForageAvailabilityForm) && ( + + )} +
+ )} +
+
+ ) +} + +ForageAvailabilityScreen.displayName = 'ForageAvailabilityScreen' diff --git a/src/app/modules/forage-availability/presentation/types.ts b/src/app/modules/forage-availability/presentation/types.ts new file mode 100644 index 00000000..c5637709 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/types.ts @@ -0,0 +1,5 @@ +import type { ForageAvailabilityModel } from '../domain/models/forage-availability-model' +import type { Filters, Sort } from '@/core/domain/types' + +export type ForageAvailabilityFilters = Filters +export type ForageAvailabilitySort = Sort diff --git a/src/app/modules/forage-availability/presentation/validations/forage-availability-form-schema.ts b/src/app/modules/forage-availability/presentation/validations/forage-availability-form-schema.ts new file mode 100644 index 00000000..621a9e81 --- /dev/null +++ b/src/app/modules/forage-availability/presentation/validations/forage-availability-form-schema.ts @@ -0,0 +1,23 @@ +import { z } from 'zod' + +import { optionSchema } from '@/core/validation/schemas' + +export const forageAvailabilityFormSchema = z.object({ + date: z.date({ + required_error: 'A data é obrigatória', + invalid_type_error: 'Data inválida', + }), + forage: optionSchema.refine((value) => value !== null, { + message: 'A forragem é obrigatória', + }), + entranceCm: z.string().min(1, 'A entrada é obrigatória'), + residueCm: z.string().min(1, 'O resíduo é obrigatório'), + kgPerSquareMeter: z.string().min(1, 'O kg/m2 é obrigatório'), + paddockArea: z.string().min(1, 'A área de piquete é obrigatória'), + efficiencyPercent: z.string().min(1, 'A eficiência é obrigatória'), + numberOfCows: z.string().min(1, 'O número de vacas é obrigatória'), +}) + +export type ForageAvailabilityFormSchema = z.infer< + typeof forageAvailabilityFormSchema +> From 64427cfd343ca5c624be37d1f5e21f1581bc10e9 Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Mon, 27 Apr 2026 11:10:55 -0300 Subject: [PATCH 07/11] feat: register property forage availability --- .../presentation/screens/property-screen.tsx | 6 ++++++ src/core/mocks/browser.ts | 19 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/src/app/modules/properties/presentation/screens/property-screen.tsx b/src/app/modules/properties/presentation/screens/property-screen.tsx index f6775a5a..eeb39798 100644 --- a/src/app/modules/properties/presentation/screens/property-screen.tsx +++ b/src/app/modules/properties/presentation/screens/property-screen.tsx @@ -4,6 +4,7 @@ import { useSearchParams } from 'react-router-dom' import { AnimalsScreen } from '@/app/modules/animals/presentation/screens/animals-screen' import { CultivationsScreen } from '@/app/modules/cultivations/presentation/screens/cultivations-screen' +import { ForageAvailabilityScreen } from '@/app/modules/forage-availability/presentation/screens/forage-availability-screen' import { ForagesScreen } from '@/app/modules/forages/presentation/screens/forages-screen' import { ImprovementsScreen } from '@/app/modules/improvements/presentation/screens/improvements-screen' import { MachinesScreen } from '@/app/modules/machines/presentation/screens/machines-screen' @@ -45,6 +46,11 @@ export function PropertyScreen() { name: 'Forrageiras', component: , }, + { + key: 'forage-availability', + name: 'Disponibilidade de Forragem', + component: , + }, { key: 'improvements', name: 'Benfeitorias', diff --git a/src/core/mocks/browser.ts b/src/core/mocks/browser.ts index 63f0f8d0..e1a2a95b 100644 --- a/src/core/mocks/browser.ts +++ b/src/core/mocks/browser.ts @@ -95,9 +95,17 @@ import { getCultivationPestsHandler, updateCultivationPestHandler, } from '@/app/modules/cultivations/mocks/handlers/cultivation-pests-handlers' +import { + createForageAvailabilityHandler, + deleteForageAvailabilityHandler, + getForageAvailabilitiesHandler, + getForageAvailabilityHandler, + updateForageAvailabilityHandler, +} from '@/app/modules/forage-availability/mocks/handlers/forage-availability-handlers' import { createForageHandler, deleteForageHandler, + getAllForagesHandler, getForageHandler, getForagesHandler, updateForageHandler, @@ -124,7 +132,6 @@ import { updateGeneralCultivationHandler, } from '@/app/modules/general-cultivations/mocks/handlers/general-cultivations-handlers' import { - createImprovementHandler, deleteImprovementHandler, getImprovementHandler, getImprovementsHandler, @@ -201,11 +208,12 @@ const handlers: HttpHandler[] = [ createForageHandler, deleteForageHandler, + getAllForagesHandler, getForageHandler, getForagesHandler, updateForageHandler, - createImprovementHandler, + createInputUseLocationHandler, deleteImprovementHandler, getImprovementHandler, getImprovementsHandler, @@ -217,6 +225,13 @@ const handlers: HttpHandler[] = [ getPropertyHandler, updatePropertyHandler, + createForageAvailabilityHandler, + deleteForageAvailabilityHandler, + getForageAvailabilitiesHandler, + getForageAvailabilityHandler, + updateForageAvailabilityHandler, + updateInputUseLocationHandler, + createMachineHandler, deleteMachineHandler, getMachineHandler, From d22f724c5a998d55028a91f1e68184e4cd167d13 Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Mon, 27 Apr 2026 14:02:59 -0300 Subject: [PATCH 08/11] fix: get all forages with list endpoint --- .../modules/forages/domain/use-cases/index.ts | 2 +- .../hooks/queries/all-forages-query.hook.ts | 46 +++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts diff --git a/src/app/modules/forages/domain/use-cases/index.ts b/src/app/modules/forages/domain/use-cases/index.ts index e36181db..7939d8cb 100644 --- a/src/app/modules/forages/domain/use-cases/index.ts +++ b/src/app/modules/forages/domain/use-cases/index.ts @@ -1,5 +1,5 @@ export * from './create-forage-use-case' export * from './delete-forage-use-case' -export * from './get-forages-use-case' export * from './get-forage-use-case' +export * from './get-forages-use-case' export * from './update-forage-use-case' diff --git a/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts b/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts new file mode 100644 index 00000000..9ce59e81 --- /dev/null +++ b/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts @@ -0,0 +1,46 @@ +import { useEffect } from 'react' + +import { useQuery } from '@tanstack/react-query' +import toast from 'react-hot-toast' + +import { toOption } from '@/core/utils/object/to-option' + +import { makeRemoteGetForagesUseCase } from '../../../main/factories/use-cases' + +import type { ForageFilters } from '../../types' + +type Props = { + propertyId: number + filters: ForageFilters +} + +export function useAllForagesQuery({ propertyId, filters }: Props) { + const getForagesUseCase = makeRemoteGetForagesUseCase() + + const { + data, + isError, + error, + isLoading, + refetch: refetchAllForages, + } = useQuery({ + queryKey: ['all-forages', { filters }], + queryFn: () => + getForagesUseCase.execute({ + propertyId, + filters, + pagination: { page: 1, perPage: 30 }, + }), + }) + + useEffect(() => { + if (isError) toast.error(error?.message ?? 'Erro ao buscar forrageiras') + }, [error, isError]) + + return { + allForages: + data?.resources.map((forage) => toOption(forage, 'cultivation')) ?? [], + isLoading, + refetchAllForages, + } +} From dd74efdcb67a300b3465dbd5c21a1bad0527b822 Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Mon, 27 Apr 2026 14:04:29 -0300 Subject: [PATCH 09/11] fix: get all animals with list endpoint --- .../remote-get-all-animals-use-case.ts | 53 ------------------- .../use-cases/get-all-animals-use-case.ts | 7 --- .../modules/animals/domain/use-cases/index.ts | 1 - .../animals/main/factories/use-cases/index.ts | 1 - ...remote-get-all-animals-use-case-factory.ts | 16 ------ .../mocks/handlers/get-all-animals-handler.ts | 31 ----------- .../modules/animals/mocks/handlers/index.ts | 1 - .../hooks/queries/all-animals-query.hook.ts | 9 ++-- 8 files changed, 5 insertions(+), 114 deletions(-) delete mode 100644 src/app/modules/animals/data/use-cases/remote-get-all-animals-use-case.ts delete mode 100644 src/app/modules/animals/domain/use-cases/get-all-animals-use-case.ts delete mode 100644 src/app/modules/animals/main/factories/use-cases/remote-get-all-animals-use-case-factory.ts delete mode 100644 src/app/modules/animals/mocks/handlers/get-all-animals-handler.ts diff --git a/src/app/modules/animals/data/use-cases/remote-get-all-animals-use-case.ts b/src/app/modules/animals/data/use-cases/remote-get-all-animals-use-case.ts deleted file mode 100644 index 82f66b30..00000000 --- a/src/app/modules/animals/data/use-cases/remote-get-all-animals-use-case.ts +++ /dev/null @@ -1,53 +0,0 @@ -import { type HttpClient, HttpStatusCode } from '@/core/data/protocols/http' -import { - UnexpectedError, - NotFoundError, - ForbiddenError, -} from '@/core/domain/errors' - -import type { - AnimalApiResponse, - AnimalModel, -} from '../../domain/models/animals-model' -import type { GetAllAnimalsUseCase } from '../../domain/use-cases' - -export class RemoteGetAllAnimalsUseCase implements GetAllAnimalsUseCase { - constructor( - private readonly url: string, - private readonly httpClient: HttpClient< - AnimalModel, - AnimalApiResponse, - AnimalApiResponse[] - > - ) {} - - execute: GetAllAnimalsUseCase['execute'] = async ({ propertyId }) => { - const url = this.url.replace(':propertyId', String(propertyId)) - - const { statusCode, body } = await this.httpClient.request({ - url: `${url}/all`, - method: 'get', - }) - - if (statusCode === HttpStatusCode.ok && !!body?.length) { - return body.map((item) => ({ - id: item.id, - name: item.name, - breed: item.breed, - weight: item.weight, - ecc: item.ecc, - milkProduction: item.milkProduction, - })) - } - - if (statusCode === HttpStatusCode.notFound) { - throw new NotFoundError('Animais') - } - - if (statusCode === HttpStatusCode.forbidden) { - throw new ForbiddenError('Você não tem permissão para buscar os animais') - } - - throw new UnexpectedError() - } -} diff --git a/src/app/modules/animals/domain/use-cases/get-all-animals-use-case.ts b/src/app/modules/animals/domain/use-cases/get-all-animals-use-case.ts deleted file mode 100644 index 594d3dea..00000000 --- a/src/app/modules/animals/domain/use-cases/get-all-animals-use-case.ts +++ /dev/null @@ -1,7 +0,0 @@ -import type { AnimalModel } from '../models/animals-model' -import type { RequestInterface } from '@/core/domain/types' - -export type GetAllAnimalsUseCase = RequestInterface< - { propertyId: number }, - AnimalModel[] -> diff --git a/src/app/modules/animals/domain/use-cases/index.ts b/src/app/modules/animals/domain/use-cases/index.ts index a809ca52..9e49b32c 100644 --- a/src/app/modules/animals/domain/use-cases/index.ts +++ b/src/app/modules/animals/domain/use-cases/index.ts @@ -1,6 +1,5 @@ export * from './create-animal-use-case' export * from './delete-animal-use-case' -export * from './get-all-animals-use-case' export * from './get-animals-use-case' export * from './get-animal-use-case' export * from './update-animal-use-case' diff --git a/src/app/modules/animals/main/factories/use-cases/index.ts b/src/app/modules/animals/main/factories/use-cases/index.ts index c6490021..e5b42f5f 100644 --- a/src/app/modules/animals/main/factories/use-cases/index.ts +++ b/src/app/modules/animals/main/factories/use-cases/index.ts @@ -1,6 +1,5 @@ export * from './remote-create-animal-use-case-factory' export * from './remote-delete-animal-use-case-factory' -export * from './remote-get-all-animals-use-case-factory' export * from './remote-get-animal-use-case-factory' export * from './remote-get-animals-use-case-factory' export * from './remote-update-animal-use-case-factory' diff --git a/src/app/modules/animals/main/factories/use-cases/remote-get-all-animals-use-case-factory.ts b/src/app/modules/animals/main/factories/use-cases/remote-get-all-animals-use-case-factory.ts deleted file mode 100644 index 5a57fba3..00000000 --- a/src/app/modules/animals/main/factories/use-cases/remote-get-all-animals-use-case-factory.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { makeApiHttpClient } from '@/core/main/factories/http' - -import { RemoteGetAllAnimalsUseCase } from '../../../data/use-cases/remote-get-all-animals-use-case' - -import type { - AnimalApiResponse, - AnimalModel, -} from '../../../domain/models/animals-model' -import type { GetAllAnimalsUseCase } from '../../../domain/use-cases' - -export function makeRemoteGetAllAnimalsUseCase(): GetAllAnimalsUseCase { - return new RemoteGetAllAnimalsUseCase( - 'properties/:propertyId/animals', - makeApiHttpClient() - ) -} diff --git a/src/app/modules/animals/mocks/handlers/get-all-animals-handler.ts b/src/app/modules/animals/mocks/handlers/get-all-animals-handler.ts deleted file mode 100644 index 5f6f2f5f..00000000 --- a/src/app/modules/animals/mocks/handlers/get-all-animals-handler.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { HttpResponse, type PathParams } from 'msw' - -import { HttpStatusCode } from '@/core/data/protocols/http' -import { httpWithMiddleware } from '@/core/mocks/lib' -import { withDelay, withAuth } from '@/core/mocks/middleware' - -import animalsData from '@database/animalsData.json' - -import type { AnimalApiResponse } from '../../domain/models/animals-model' -import type { MockParams } from '@/core/mocks/types/mock-params-type' - -export const getAllAnimalsHandler = httpWithMiddleware< - PathParams<'propertyId'>, - MockParams, - AnimalApiResponse[] ->({ - routePath: '/api/properties/:propertyId/animals/all', - method: 'get', - middlewares: [withDelay(), withAuth], - resolver: async () => { - if (!animalsData.length) { - return HttpResponse.json(null, { - status: 404, - }) - } - - return HttpResponse.json(animalsData as AnimalApiResponse[], { - status: HttpStatusCode.ok, - }) - }, -}) diff --git a/src/app/modules/animals/mocks/handlers/index.ts b/src/app/modules/animals/mocks/handlers/index.ts index 140e2263..cc4124dd 100644 --- a/src/app/modules/animals/mocks/handlers/index.ts +++ b/src/app/modules/animals/mocks/handlers/index.ts @@ -1,6 +1,5 @@ export * from './create-animal-handler' export * from './delete-animal-handler' -export * from './get-all-animals-handler' export * from './get-animal-handler' export * from './get-animals-handler' export * from './update-animal-handler' diff --git a/src/app/modules/animals/presentation/hooks/queries/all-animals-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/all-animals-query.hook.ts index 06384700..4d1d87ec 100644 --- a/src/app/modules/animals/presentation/hooks/queries/all-animals-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/all-animals-query.hook.ts @@ -3,7 +3,7 @@ import { useEffect } from 'react' import { useQuery } from '@tanstack/react-query' import toast from 'react-hot-toast' -import { makeRemoteGetAllAnimalsUseCase } from '@/app/modules/animals/main/factories/use-cases' +import { makeRemoteGetAnimalsUseCase } from '@/app/modules/animals/main/factories/use-cases' import { toOption } from '@/core/utils/object/to-option' type Props = { @@ -11,7 +11,7 @@ type Props = { } export function useAllAnimalsQuery({ propertyId }: Props) { - const getAllAnimalsUseCase = makeRemoteGetAllAnimalsUseCase() + const getAnimalsUseCase = makeRemoteGetAnimalsUseCase() const { data, @@ -22,8 +22,9 @@ export function useAllAnimalsQuery({ propertyId }: Props) { } = useQuery({ queryKey: ['all-animals', propertyId], queryFn: () => - getAllAnimalsUseCase.execute({ + getAnimalsUseCase.execute({ propertyId, + pagination: { page: 1, perPage: 30 }, }), }) @@ -33,7 +34,7 @@ export function useAllAnimalsQuery({ propertyId }: Props) { return { allAnimals: - data?.map((resource) => + data?.resources.map((resource) => toOption(resource, 'name', { breed: resource.breed, weight: resource.weight, From fdb9790607b7d59d584f832c1e43a9dabcc2aa5c Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Mon, 27 Apr 2026 18:15:04 -0300 Subject: [PATCH 10/11] fix: property id to invalidate queries and remove get all remote controller --- .../idr-web-module-generator/SKILL.md | 4 +++- .../animal-childbirth-delete-dialog.tsx | 2 +- .../animal-death-delete-dialog.tsx | 2 +- .../animal-delete-dialog/animal-delete-dialog.tsx | 2 +- .../animal-disease-delete-dialog.tsx | 2 +- .../animal-heifer-calf-stage-delete-dialog.tsx | 2 +- .../animal-insemination-delete-dialog.tsx | 2 +- .../animal-mastitis-delete-dialog.tsx | 2 +- .../animal-medication-delete-dialog.tsx | 2 +- .../animal-pregnancy-diagnosis-delete-dialog.tsx | 2 +- .../animal-purchase-delete-dialog.tsx | 2 +- .../animal-sale-delete-dialog.tsx | 2 +- .../create-animal-childbirth-form.tsx | 2 +- .../animal-childbirth-form/edit-animal-childbirth-form.tsx | 2 +- .../forms/animal-death-form/create-animal-death-form.tsx | 2 +- .../forms/animal-death-form/edit-animal-death-form.tsx | 2 +- .../animal-disease-form/create-animal-disease-form.tsx | 2 +- .../forms/animal-disease-form/edit-animal-disease-form.tsx | 2 +- .../presentation/forms/animal-form/create-animal-form.tsx | 2 +- .../presentation/forms/animal-form/edit-animal-form.tsx | 2 +- .../create-animal-heifer-calf-stage-form.tsx | 2 +- .../edit-animal-heifer-calf-stage-form.tsx | 2 +- .../create-animal-insemination-form.tsx | 2 +- .../edit-animal-insemination-form.tsx | 2 +- .../animal-mastitis-form/create-animal-mastitis-form.tsx | 2 +- .../animal-mastitis-form/edit-animal-mastitis-form.tsx | 2 +- .../create-animal-medication-form.tsx | 2 +- .../animal-medication-form/edit-animal-medication-form.tsx | 2 +- .../create-animal-pregnancy-diagnosis-form.tsx | 2 +- .../edit-animal-pregnancy-diagnosis-form.tsx | 2 +- .../animal-purchase-form/create-animal-purchase-form.tsx | 2 +- .../animal-purchase-form/edit-animal-purchase-form.tsx | 2 +- .../forms/animal-sale-form/create-animal-sale-form.tsx | 2 +- .../forms/animal-sale-form/edit-animal-sale-form.tsx | 2 +- .../hooks/queries/all-animals-with-filter-query.hook.ts | 3 ++- .../hooks/queries/animal-childbirth-query.hook.ts | 3 ++- .../hooks/queries/animal-childbirths-query.hook.ts | 3 ++- .../presentation/hooks/queries/animal-death-query.hook.ts | 3 ++- .../presentation/hooks/queries/animal-deaths-query.hook.ts | 3 ++- .../hooks/queries/animal-disease-query.hook.ts | 3 ++- .../hooks/queries/animal-diseases-query.hook.ts | 3 ++- .../hooks/queries/animal-heifer-calf-stage-query.hook.ts | 3 ++- .../hooks/queries/animal-heifer-calf-stages-query.hook.ts | 7 ++++++- .../hooks/queries/animal-insemination-query.hook.ts | 3 ++- .../hooks/queries/animal-inseminations-query.hook.ts | 3 ++- .../hooks/queries/animal-mastitides-query.hook.ts | 3 ++- .../hooks/queries/animal-mastitis-query.hook.ts | 3 ++- .../hooks/queries/animal-medication-query.hook.ts | 3 ++- .../hooks/queries/animal-medications-query.hook.ts | 3 ++- .../hooks/queries/animal-pregnancy-diagnoses-query.hook.ts | 7 ++++++- .../hooks/queries/animal-pregnancy-diagnosis-query.hook.ts | 3 ++- .../hooks/queries/animal-purchase-query.hook.ts | 3 ++- .../hooks/queries/animal-purchases-query.hook.ts | 3 ++- .../presentation/hooks/queries/animal-query.hook.ts | 3 ++- .../presentation/hooks/queries/animal-sale-query.hook.ts | 3 ++- .../presentation/hooks/queries/animal-sales-query.hook.ts | 3 ++- .../presentation/hooks/queries/animals-query.hook.ts | 3 ++- .../cultivation-disease-delete-dialog.tsx | 2 +- .../cultivation-pest-delete-dialog.tsx | 2 +- .../create-cultivation-disease-form.tsx | 2 +- .../edit-cultivation-disease-form.tsx | 2 +- .../cultivation-pest-form/create-cultivation-pest-form.tsx | 2 +- .../cultivation-pest-form/edit-cultivation-pest-form.tsx | 2 +- .../hooks/queries/cultivation-disease-query.hook.ts | 3 ++- .../hooks/queries/cultivation-diseases-query.hook.ts | 3 ++- .../hooks/queries/cultivation-pest-query.hook.ts | 3 ++- .../hooks/queries/cultivation-pests-query.hook.ts | 3 ++- .../forage-availability-delete-dialog.tsx | 2 +- .../create-forage-availability-form.tsx | 2 +- .../edit-forage-availability-form.tsx | 2 +- .../hooks/queries/forage-availabilities-query.hook.ts | 3 ++- .../hooks/queries/forage-availability-query.hook.ts | 3 ++- .../forage-delete-dialog/forage-delete-dialog.tsx | 2 +- .../presentation/forms/forage-form/create-forage-form.tsx | 2 +- .../presentation/forms/forage-form/edit-forage-form.tsx | 2 +- .../presentation/hooks/queries/all-forages-query.hook.ts | 3 ++- .../presentation/hooks/queries/forage-query.hook.ts | 3 ++- .../presentation/hooks/queries/forages-query.hook.ts | 3 ++- .../improvement-delete-dialog.tsx | 2 +- .../forms/improvement-form/create-improvement-form.tsx | 2 +- .../forms/improvement-form/edit-improvement-form.tsx | 2 +- .../presentation/hooks/queries/improvement-query.hook.ts | 3 ++- .../presentation/hooks/queries/improvements-query.hook.ts | 3 ++- .../machine-delete-dialog/machine-delete-dialog.tsx | 2 +- .../forms/machine-form/create-machine-form.tsx | 2 +- .../presentation/forms/machine-form/edit-machine-form.tsx | 2 +- .../presentation/hooks/queries/machine-query.hook.ts | 3 ++- .../presentation/hooks/queries/machines-query.hook.ts | 3 ++- .../nutritional-balancing-delete-dialog.tsx | 2 +- .../hooks/queries/nutritional-balancing-query.hook.ts | 3 ++- .../hooks/queries/nutritional-balancings-query.hook.ts | 3 ++- .../hooks/edit-nutritional-balancing-screen.hook.tsx | 2 +- .../hooks/new-nutritional-balancing-screen.hook.tsx | 2 +- src/core/mocks/browser.ts | 4 ---- 94 files changed, 141 insertions(+), 97 deletions(-) diff --git a/.agents/skills/idr-web-module-generator/idr-web-module-generator/SKILL.md b/.agents/skills/idr-web-module-generator/idr-web-module-generator/SKILL.md index 12f738d3..e270ce7c 100644 --- a/.agents/skills/idr-web-module-generator/idr-web-module-generator/SKILL.md +++ b/.agents/skills/idr-web-module-generator/idr-web-module-generator/SKILL.md @@ -101,7 +101,7 @@ This layer requires a highly specific file organization: - `index.ts` (exporting `{entity}-form.tsx`) - `{entity}-form.tsx` (Wrapper rendering `Create` or `Edit` based on `id` prop presence). - `create-{entity}-form.tsx` (using ``, form className `flex flex-col gap-4`, button text "Criar") - - `edit-{entity}-form.tsx` (fetches the item via Get One hook, displays `` while fetching, form className `flex flex-col gap-4`, button text "Salvar") + - `edit-{entity}-form.tsx` (fetches the item via Get One hook, displays `` while fetching, form className `flex flex-col gap-4`, button text "Salvar". The `` MUST include a property from the model to identify the entity being edited, e.g., `{`Editar [Entidade] ${selectedEntity?.name}`}`) - `{entity}-form-inputs.tsx` (UI inputs mapped to `react-hook-form` via `useFormContext`. Use `useAll{Entities}Query` for Comboboxes/Selects) - `{entity}-initial-form-data.ts` (Empty initial data object) @@ -122,6 +122,8 @@ This layer requires a highly specific file organization: **Presentation Custom Messages:** You must also strictly adapt all success and error toasts, dialog titles, form titles, and action button labels present in the UI layers (`presentation/components`, `presentation/forms`, `presentation/screens`, `presentation/hooks/queries`) to the new entity name. For example, replace `toast.success('Local de utilização removido com sucesso')` with the appropriate label for the new entity. **Pay special attention to `useEffect` error toasts in query hooks** (`presentation/hooks/queries/{entity}-query.hook.ts`). +**Sub-modules and Prefixes:** When creating a sub-module (e.g., `input-use-active-ingredients` inside `input-uses`), ensure all file names, class names, and variable names use the full prefix (e.g., `InputUseActiveIngredient...`) to avoid name collisions within the same module or global namespace. The directory structure should remain consistent: `src/app/modules/{parent-module}/{layer}/.../{sub-module}-...`. + **Form Inputs and Placeholders:** Inside `presentation/forms/{entity}-form-inputs.tsx`, you must adapt all `` and `` to match the new entity's fields and context. Avoid leaving generic labels like "Descrição" if the field is "Nome", and update examples in placeholders (e.g., from "Ex: Galpão" to "Ex: Fertilizantes"). **Constants and Variables:** All constant names, like `INITIAL_FORM_DATA` or `FORM_SCHEMA`, should also be renamed to match the new entity prefix (e.g., `PRODUCT_CATEGORY_INITIAL_FORM_DATA`). Ensure that all imports of these constants are also updated accordingly. diff --git a/src/app/modules/animals/presentation/components/animal-childbirth-delete-dialog/animal-childbirth-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-childbirth-delete-dialog/animal-childbirth-delete-dialog.tsx index c1141fb5..58819b03 100644 --- a/src/app/modules/animals/presentation/components/animal-childbirth-delete-dialog/animal-childbirth-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-childbirth-delete-dialog/animal-childbirth-delete-dialog.tsx @@ -40,7 +40,7 @@ export function AnimalChildbirthDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-childbirths'], + queryKey: ['animal-childbirths', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-death-delete-dialog/animal-death-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-death-delete-dialog/animal-death-delete-dialog.tsx index 06cadd83..fb9b7ec5 100644 --- a/src/app/modules/animals/presentation/components/animal-death-delete-dialog/animal-death-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-death-delete-dialog/animal-death-delete-dialog.tsx @@ -40,7 +40,7 @@ export function AnimalDeathDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-deaths'], + queryKey: ['animal-deaths', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-delete-dialog/animal-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-delete-dialog/animal-delete-dialog.tsx index 3cd27b9b..b670db74 100644 --- a/src/app/modules/animals/presentation/components/animal-delete-dialog/animal-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-delete-dialog/animal-delete-dialog.tsx @@ -37,7 +37,7 @@ export function AnimalDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animals'], + queryKey: ['animals', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-disease-delete-dialog/animal-disease-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-disease-delete-dialog/animal-disease-delete-dialog.tsx index f29b7153..7cd9ccef 100644 --- a/src/app/modules/animals/presentation/components/animal-disease-delete-dialog/animal-disease-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-disease-delete-dialog/animal-disease-delete-dialog.tsx @@ -40,7 +40,7 @@ export function AnimalDiseaseDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-diseases'], + queryKey: ['animal-diseases', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-heifer-calf-stage-delete-dialog/animal-heifer-calf-stage-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-heifer-calf-stage-delete-dialog/animal-heifer-calf-stage-delete-dialog.tsx index 4c71190a..5c50a1bc 100644 --- a/src/app/modules/animals/presentation/components/animal-heifer-calf-stage-delete-dialog/animal-heifer-calf-stage-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-heifer-calf-stage-delete-dialog/animal-heifer-calf-stage-delete-dialog.tsx @@ -41,7 +41,7 @@ export function AnimalHeiferCalfStageDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-heifer-calf-stages'], + queryKey: ['animal-heifer-calf-stages', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-insemination-delete-dialog/animal-insemination-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-insemination-delete-dialog/animal-insemination-delete-dialog.tsx index d9a772e4..2973a093 100644 --- a/src/app/modules/animals/presentation/components/animal-insemination-delete-dialog/animal-insemination-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-insemination-delete-dialog/animal-insemination-delete-dialog.tsx @@ -41,7 +41,7 @@ export function AnimalInseminationDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-inseminations'], + queryKey: ['animal-inseminations', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-mastitis-delete-dialog/animal-mastitis-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-mastitis-delete-dialog/animal-mastitis-delete-dialog.tsx index ddad5669..b126932e 100644 --- a/src/app/modules/animals/presentation/components/animal-mastitis-delete-dialog/animal-mastitis-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-mastitis-delete-dialog/animal-mastitis-delete-dialog.tsx @@ -40,7 +40,7 @@ export function AnimalMastitisDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-mastitides'], + queryKey: ['animal-mastitides', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-medication-delete-dialog/animal-medication-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-medication-delete-dialog/animal-medication-delete-dialog.tsx index 06e724ea..24bfc12d 100644 --- a/src/app/modules/animals/presentation/components/animal-medication-delete-dialog/animal-medication-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-medication-delete-dialog/animal-medication-delete-dialog.tsx @@ -41,7 +41,7 @@ export function AnimalMedicationDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-medications'], + queryKey: ['animal-medications', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-pregnancy-diagnosis-delete-dialog/animal-pregnancy-diagnosis-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-pregnancy-diagnosis-delete-dialog/animal-pregnancy-diagnosis-delete-dialog.tsx index 15188e85..ee7267ea 100644 --- a/src/app/modules/animals/presentation/components/animal-pregnancy-diagnosis-delete-dialog/animal-pregnancy-diagnosis-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-pregnancy-diagnosis-delete-dialog/animal-pregnancy-diagnosis-delete-dialog.tsx @@ -44,7 +44,7 @@ export function AnimalPregnancyDiagnosisDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-pregnancy-diagnoses'], + queryKey: ['animal-pregnancy-diagnoses', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-purchase-delete-dialog/animal-purchase-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-purchase-delete-dialog/animal-purchase-delete-dialog.tsx index 2d622b7d..7c05830e 100644 --- a/src/app/modules/animals/presentation/components/animal-purchase-delete-dialog/animal-purchase-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-purchase-delete-dialog/animal-purchase-delete-dialog.tsx @@ -40,7 +40,7 @@ export function AnimalPurchaseDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-purchases'], + queryKey: ['animal-purchases', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/components/animal-sale-delete-dialog/animal-sale-delete-dialog.tsx b/src/app/modules/animals/presentation/components/animal-sale-delete-dialog/animal-sale-delete-dialog.tsx index 15d90667..b246c2e0 100644 --- a/src/app/modules/animals/presentation/components/animal-sale-delete-dialog/animal-sale-delete-dialog.tsx +++ b/src/app/modules/animals/presentation/components/animal-sale-delete-dialog/animal-sale-delete-dialog.tsx @@ -40,7 +40,7 @@ export function AnimalSaleDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['animal-sales'], + queryKey: ['animal-sales', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-childbirth-form/create-animal-childbirth-form.tsx b/src/app/modules/animals/presentation/forms/animal-childbirth-form/create-animal-childbirth-form.tsx index 56bf957c..b425095a 100644 --- a/src/app/modules/animals/presentation/forms/animal-childbirth-form/create-animal-childbirth-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-childbirth-form/create-animal-childbirth-form.tsx @@ -54,7 +54,7 @@ export function CreateAnimalChildbirthForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-childbirths'], + queryKey: ['animal-childbirths', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-childbirth-form/edit-animal-childbirth-form.tsx b/src/app/modules/animals/presentation/forms/animal-childbirth-form/edit-animal-childbirth-form.tsx index 94cb34d2..da113c1f 100644 --- a/src/app/modules/animals/presentation/forms/animal-childbirth-form/edit-animal-childbirth-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-childbirth-form/edit-animal-childbirth-form.tsx @@ -77,7 +77,7 @@ export function EditAnimalChildbirthForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-childbirths'], + queryKey: ['animal-childbirths', propertyId], exact: false, }) toast.success('Parto de animal foi editado com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-death-form/create-animal-death-form.tsx b/src/app/modules/animals/presentation/forms/animal-death-form/create-animal-death-form.tsx index fb6f7a2c..8336c3bc 100644 --- a/src/app/modules/animals/presentation/forms/animal-death-form/create-animal-death-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-death-form/create-animal-death-form.tsx @@ -53,7 +53,7 @@ export function CreateAnimalDeathForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-deaths'], + queryKey: ['animal-deaths', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-death-form/edit-animal-death-form.tsx b/src/app/modules/animals/presentation/forms/animal-death-form/edit-animal-death-form.tsx index 8dd22851..cff34105 100644 --- a/src/app/modules/animals/presentation/forms/animal-death-form/edit-animal-death-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-death-form/edit-animal-death-form.tsx @@ -75,7 +75,7 @@ export function EditAnimalDeathForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-deaths'], + queryKey: ['animal-deaths', propertyId], exact: false, }) toast.success('Óbito do animal foi editado com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-disease-form/create-animal-disease-form.tsx b/src/app/modules/animals/presentation/forms/animal-disease-form/create-animal-disease-form.tsx index 4a83573f..7dd1474a 100644 --- a/src/app/modules/animals/presentation/forms/animal-disease-form/create-animal-disease-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-disease-form/create-animal-disease-form.tsx @@ -53,7 +53,7 @@ export function CreateAnimalDiseaseForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-diseases'], + queryKey: ['animal-diseases', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-disease-form/edit-animal-disease-form.tsx b/src/app/modules/animals/presentation/forms/animal-disease-form/edit-animal-disease-form.tsx index 1da9f963..342540fa 100644 --- a/src/app/modules/animals/presentation/forms/animal-disease-form/edit-animal-disease-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-disease-form/edit-animal-disease-form.tsx @@ -75,7 +75,7 @@ export function EditAnimalDiseaseForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-diseases'], + queryKey: ['animal-diseases', propertyId], exact: false, }) toast.success('Doença de animal foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-form/create-animal-form.tsx b/src/app/modules/animals/presentation/forms/animal-form/create-animal-form.tsx index 1c6bb0c9..eaf70e0b 100644 --- a/src/app/modules/animals/presentation/forms/animal-form/create-animal-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-form/create-animal-form.tsx @@ -55,7 +55,7 @@ export function CreateAnimalForm() { }, }) queryClient.invalidateQueries({ - queryKey: ['animals'], + queryKey: ['animals', propertyId], exact: false, }) toast.success('Animal foi cadastrado com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-form/edit-animal-form.tsx b/src/app/modules/animals/presentation/forms/animal-form/edit-animal-form.tsx index bca89d49..67d27941 100644 --- a/src/app/modules/animals/presentation/forms/animal-form/edit-animal-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-form/edit-animal-form.tsx @@ -76,7 +76,7 @@ export function EditAnimalForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animals'], + queryKey: ['animals', propertyId], exact: false, }) toast.success('Animal foi editado com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/create-animal-heifer-calf-stage-form.tsx b/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/create-animal-heifer-calf-stage-form.tsx index f069f584..4baa756c 100644 --- a/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/create-animal-heifer-calf-stage-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/create-animal-heifer-calf-stage-form.tsx @@ -70,7 +70,7 @@ export function CreateAnimalHeiferCalfStageForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-heifer-calf-stages'], + queryKey: ['animal-heifer-calf-stages', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/edit-animal-heifer-calf-stage-form.tsx b/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/edit-animal-heifer-calf-stage-form.tsx index 210d5c96..81c04e93 100644 --- a/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/edit-animal-heifer-calf-stage-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-heifer-calf-stage-form/edit-animal-heifer-calf-stage-form.tsx @@ -87,7 +87,7 @@ export function EditAnimalHeiferCalfStageForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-heifer-calf-stages'], + queryKey: ['animal-heifer-calf-stages', propertyId], exact: false, }) toast.success('Fase bezerra novilha foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-insemination-form/create-animal-insemination-form.tsx b/src/app/modules/animals/presentation/forms/animal-insemination-form/create-animal-insemination-form.tsx index cae63d57..646994b9 100644 --- a/src/app/modules/animals/presentation/forms/animal-insemination-form/create-animal-insemination-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-insemination-form/create-animal-insemination-form.tsx @@ -54,7 +54,7 @@ export function CreateAnimalInseminationForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-inseminations'], + queryKey: ['animal-inseminations', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-insemination-form/edit-animal-insemination-form.tsx b/src/app/modules/animals/presentation/forms/animal-insemination-form/edit-animal-insemination-form.tsx index f139c9b3..e7e02c11 100644 --- a/src/app/modules/animals/presentation/forms/animal-insemination-form/edit-animal-insemination-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-insemination-form/edit-animal-insemination-form.tsx @@ -76,7 +76,7 @@ export function EditAnimalInseminationForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-inseminations'], + queryKey: ['animal-inseminations', propertyId], exact: false, }) toast.success('Inseminação Artificial foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-mastitis-form/create-animal-mastitis-form.tsx b/src/app/modules/animals/presentation/forms/animal-mastitis-form/create-animal-mastitis-form.tsx index c34427ed..3ac37d76 100644 --- a/src/app/modules/animals/presentation/forms/animal-mastitis-form/create-animal-mastitis-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-mastitis-form/create-animal-mastitis-form.tsx @@ -53,7 +53,7 @@ export function CreateAnimalMastitisForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-mastitides'], + queryKey: ['animal-mastitides', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-mastitis-form/edit-animal-mastitis-form.tsx b/src/app/modules/animals/presentation/forms/animal-mastitis-form/edit-animal-mastitis-form.tsx index 27c4efad..63a7904d 100644 --- a/src/app/modules/animals/presentation/forms/animal-mastitis-form/edit-animal-mastitis-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-mastitis-form/edit-animal-mastitis-form.tsx @@ -73,7 +73,7 @@ export function EditAnimalMastitisForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-mastitides'], + queryKey: ['animal-mastitides', propertyId], exact: false, }) toast.success('Mastite foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-medication-form/create-animal-medication-form.tsx b/src/app/modules/animals/presentation/forms/animal-medication-form/create-animal-medication-form.tsx index d1894268..cf76f504 100644 --- a/src/app/modules/animals/presentation/forms/animal-medication-form/create-animal-medication-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-medication-form/create-animal-medication-form.tsx @@ -54,7 +54,7 @@ export function CreateAnimalMedicationForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-medications'], + queryKey: ['animal-medications', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-medication-form/edit-animal-medication-form.tsx b/src/app/modules/animals/presentation/forms/animal-medication-form/edit-animal-medication-form.tsx index cd81d3bb..723a6de8 100644 --- a/src/app/modules/animals/presentation/forms/animal-medication-form/edit-animal-medication-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-medication-form/edit-animal-medication-form.tsx @@ -86,7 +86,7 @@ export function EditAnimalMedicationForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-medications'], + queryKey: ['animal-medications', propertyId], exact: false, }) toast.success('Medicação do animal foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/create-animal-pregnancy-diagnosis-form.tsx b/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/create-animal-pregnancy-diagnosis-form.tsx index d40b7687..351c4907 100644 --- a/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/create-animal-pregnancy-diagnosis-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/create-animal-pregnancy-diagnosis-form.tsx @@ -55,7 +55,7 @@ export function CreateAnimalPregnancyDiagnosisForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-pregnancy-diagnoses'], + queryKey: ['animal-pregnancy-diagnoses', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/edit-animal-pregnancy-diagnosis-form.tsx b/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/edit-animal-pregnancy-diagnosis-form.tsx index e82952d2..dce9d8b2 100644 --- a/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/edit-animal-pregnancy-diagnosis-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-pregnancy-diagnosis-form/edit-animal-pregnancy-diagnosis-form.tsx @@ -77,7 +77,7 @@ export function EditAnimalPregnancyDiagnosisForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-pregnancy-diagnoses'], + queryKey: ['animal-pregnancy-diagnoses', propertyId], exact: false, }) toast.success('Diagnóstico de gestação atualizado com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-purchase-form/create-animal-purchase-form.tsx b/src/app/modules/animals/presentation/forms/animal-purchase-form/create-animal-purchase-form.tsx index e89e11ce..7135c3de 100644 --- a/src/app/modules/animals/presentation/forms/animal-purchase-form/create-animal-purchase-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-purchase-form/create-animal-purchase-form.tsx @@ -53,7 +53,7 @@ export function CreateAnimalPurchaseForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-purchases'], + queryKey: ['animal-purchases', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-purchase-form/edit-animal-purchase-form.tsx b/src/app/modules/animals/presentation/forms/animal-purchase-form/edit-animal-purchase-form.tsx index c9e4979d..42dac070 100644 --- a/src/app/modules/animals/presentation/forms/animal-purchase-form/edit-animal-purchase-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-purchase-form/edit-animal-purchase-form.tsx @@ -78,7 +78,7 @@ export function EditAnimalPurchaseForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-purchases'], + queryKey: ['animal-purchases', propertyId], exact: false, }) toast.success('Compra de animal foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/forms/animal-sale-form/create-animal-sale-form.tsx b/src/app/modules/animals/presentation/forms/animal-sale-form/create-animal-sale-form.tsx index 69b91dbf..320c5d8a 100644 --- a/src/app/modules/animals/presentation/forms/animal-sale-form/create-animal-sale-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-sale-form/create-animal-sale-form.tsx @@ -53,7 +53,7 @@ export function CreateAnimalSaleForm() { }) queryClient.invalidateQueries({ - queryKey: ['animal-sales'], + queryKey: ['animal-sales', propertyId], exact: false, }) diff --git a/src/app/modules/animals/presentation/forms/animal-sale-form/edit-animal-sale-form.tsx b/src/app/modules/animals/presentation/forms/animal-sale-form/edit-animal-sale-form.tsx index 34d9f232..556d7aa1 100644 --- a/src/app/modules/animals/presentation/forms/animal-sale-form/edit-animal-sale-form.tsx +++ b/src/app/modules/animals/presentation/forms/animal-sale-form/edit-animal-sale-form.tsx @@ -78,7 +78,7 @@ export function EditAnimalSaleForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['animal-sales'], + queryKey: ['animal-sales', propertyId], exact: false, }) toast.success('Venda de animal foi editada com sucesso') diff --git a/src/app/modules/animals/presentation/hooks/queries/all-animals-with-filter-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/all-animals-with-filter-query.hook.ts index ef8bf22f..44ee99ff 100644 --- a/src/app/modules/animals/presentation/hooks/queries/all-animals-with-filter-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/all-animals-with-filter-query.hook.ts @@ -28,7 +28,8 @@ export function useAllAnimalsWithFilterQuery({ isLoading, refetch: refetchAllAnimals, } = useQuery({ - queryKey: ['all-animals', { filters }], + queryKey: ['all-animals', propertyId, { filters }], + enabled: !!propertyId, queryFn: () => getAnimalsUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-childbirth-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-childbirth-query.hook.ts index 920e766d..aa5a3f62 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-childbirth-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-childbirth-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalChildbirthQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalChildbirth, } = useQuery({ - queryKey: ['animal-childbirth', id], + queryKey: ['animal-childbirth', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalChildbirthUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-childbirths-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-childbirths-query.hook.ts index ed59e8ac..ddcdd335 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-childbirths-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-childbirths-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalChildbirthsQuery({ isLoading, refetch: refetchAnimalChildbirths, } = useQuery({ - queryKey: ['animal-childbirths', { page, sort, filters }], + queryKey: ['animal-childbirths', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalChildbirthsUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-death-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-death-query.hook.ts index f1b0e59e..c53d6a3d 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-death-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-death-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalDeathQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalDeath, } = useQuery({ - queryKey: ['animal-death', id], + queryKey: ['animal-death', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalDeathUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-deaths-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-deaths-query.hook.ts index 2cc80a8a..6798df99 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-deaths-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-deaths-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalDeathsQuery({ isLoading, refetch: refetchAnimalDeaths, } = useQuery({ - queryKey: ['animal-deaths', { page, sort, filters }], + queryKey: ['animal-deaths', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalDeathsUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-disease-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-disease-query.hook.ts index 400c6e61..5ea2921c 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-disease-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-disease-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalDiseaseQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalDisease, } = useQuery({ - queryKey: ['animal-disease', id], + queryKey: ['animal-disease', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalDiseaseUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-diseases-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-diseases-query.hook.ts index 8d4fc416..63f91911 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-diseases-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-diseases-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalDiseasesQuery({ isLoading, refetch: refetchAnimalDiseases, } = useQuery({ - queryKey: ['animal-diseases', { page, sort, filters }], + queryKey: ['animal-diseases', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalDiseasesUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stage-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stage-query.hook.ts index 5120f292..127a3935 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stage-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stage-query.hook.ts @@ -26,7 +26,8 @@ export function useAnimalHeiferCalfStageQuery({ isLoading, refetch: refetchAnimalHeiferCalfStage, } = useQuery({ - queryKey: ['animal-heifer-calf-stage', id], + queryKey: ['animal-heifer-calf-stage', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalHeiferCalfStageUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stages-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stages-query.hook.ts index 46ba265c..09d880ef 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stages-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-heifer-calf-stages-query.hook.ts @@ -35,7 +35,12 @@ export function useAnimalHeiferCalfStagesQuery({ isLoading, refetch: refetchAnimalHeiferCalfStages, } = useQuery({ - queryKey: ['animal-heifer-calf-stages', { page, sort, filters }], + queryKey: [ + 'animal-heifer-calf-stages', + propertyId, + { page, sort, filters }, + ], + enabled: !!propertyId, queryFn: () => getAnimalHeiferCalfStagesUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-insemination-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-insemination-query.hook.ts index 0bc399fc..499b42a2 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-insemination-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-insemination-query.hook.ts @@ -25,7 +25,8 @@ export function useAnimalInseminationQuery({ isLoading, refetch: refetchAnimalInsemination, } = useQuery({ - queryKey: ['animal-insemination', id], + queryKey: ['animal-insemination', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalInseminationUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-inseminations-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-inseminations-query.hook.ts index 95faa696..9394ca76 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-inseminations-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-inseminations-query.hook.ts @@ -35,7 +35,8 @@ export function useAnimalInseminationsQuery({ isLoading, refetch: refetchAnimalInseminations, } = useQuery({ - queryKey: ['animal-inseminations', { page, sort, filters }], + queryKey: ['animal-inseminations', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalInseminationsUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-mastitides-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-mastitides-query.hook.ts index 0df74592..70934b9d 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-mastitides-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-mastitides-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalMastitidesQuery({ isLoading, refetch: refetchAnimalMastitides, } = useQuery({ - queryKey: ['animal-mastitides', { page, sort, filters }], + queryKey: ['animal-mastitides', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalMastitidesUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-mastitis-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-mastitis-query.hook.ts index ba55b4a5..eedd42a5 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-mastitis-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-mastitis-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalMastitisQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalMastitis, } = useQuery({ - queryKey: ['animal-mastitis', id], + queryKey: ['animal-mastitis', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalMastitisUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-medication-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-medication-query.hook.ts index 571e7f0d..d4db9fd6 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-medication-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-medication-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalMedicationQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalMedication, } = useQuery({ - queryKey: ['animal-medication', id], + queryKey: ['animal-medication', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalMedicationUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-medications-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-medications-query.hook.ts index 7f0e809a..c79ccc76 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-medications-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-medications-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalMedicationsQuery({ isLoading, refetch: refetchAnimalMedications, } = useQuery({ - queryKey: ['animal-medications', { page, sort, filters }], + queryKey: ['animal-medications', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalMedicationsUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnoses-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnoses-query.hook.ts index 33b2668f..e8630eb3 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnoses-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnoses-query.hook.ts @@ -35,7 +35,12 @@ export function useAnimalPregnancyDiagnosesQuery({ isLoading, refetch: refetchAnimalPregnancyDiagnoses, } = useQuery({ - queryKey: ['animal-pregnancy-diagnoses', { page, sort, filters }], + queryKey: [ + 'animal-pregnancy-diagnoses', + propertyId, + { page, sort, filters }, + ], + enabled: !!propertyId, queryFn: () => getAnimalPregnancyDiagnosesUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnosis-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnosis-query.hook.ts index a9df9e1d..aabf44e9 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnosis-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-pregnancy-diagnosis-query.hook.ts @@ -26,7 +26,8 @@ export function useAnimalPregnancyDiagnosisQuery({ isLoading, refetch: refetchAnimalPregnancyDiagnosis, } = useQuery({ - queryKey: ['animal-pregnancy-diagnosis', id], + queryKey: ['animal-pregnancy-diagnosis', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalPregnancyDiagnosisUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-purchase-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-purchase-query.hook.ts index d7e02973..07f44fa5 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-purchase-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-purchase-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalPurchaseQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalPurchase, } = useQuery({ - queryKey: ['animal-purchase', id], + queryKey: ['animal-purchase', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalPurchaseUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-purchases-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-purchases-query.hook.ts index 8ab34a8e..f11261e4 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-purchases-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-purchases-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalPurchasesQuery({ isLoading, refetch: refetchAnimalPurchases, } = useQuery({ - queryKey: ['animal-purchases', { page, sort, filters }], + queryKey: ['animal-purchases', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalPurchasesUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-query.hook.ts index 0cdde7e3..561ecf43 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-query.hook.ts @@ -20,7 +20,8 @@ export function useAnimalQuery({ id, propertyId }: Props) { isLoading, refetch: refetchAnimal, } = useQuery({ - queryKey: ['animal', id], + queryKey: ['animal', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-sale-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-sale-query.hook.ts index 91594014..8944f9db 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-sale-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-sale-query.hook.ts @@ -21,7 +21,8 @@ export function useAnimalSaleQuery({ id, propertyId, animalId }: Props) { isLoading, refetch: refetchAnimalSale, } = useQuery({ - queryKey: ['animal-sale', id], + queryKey: ['animal-sale', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getAnimalSaleUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animal-sales-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animal-sales-query.hook.ts index 5872f6e2..f66d8119 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animal-sales-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animal-sales-query.hook.ts @@ -34,7 +34,8 @@ export function useAnimalSalesQuery({ isLoading, refetch: refetchAnimalSales, } = useQuery({ - queryKey: ['animal-sales', { page, sort, filters }], + queryKey: ['animal-sales', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalSalesUseCase.execute({ propertyId, diff --git a/src/app/modules/animals/presentation/hooks/queries/animals-query.hook.ts b/src/app/modules/animals/presentation/hooks/queries/animals-query.hook.ts index 52578409..e53862de 100644 --- a/src/app/modules/animals/presentation/hooks/queries/animals-query.hook.ts +++ b/src/app/modules/animals/presentation/hooks/queries/animals-query.hook.ts @@ -24,7 +24,8 @@ export function useAnimalsQuery({ propertyId, filters, page, sort }: Props) { isLoading, refetch: refetchAnimals, } = useQuery({ - queryKey: ['animals', { page, sort, filters }], + queryKey: ['animals', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getAnimalsUseCase.execute({ propertyId, diff --git a/src/app/modules/cultivations/presentation/components/cultivation-disease-delete-dialog/cultivation-disease-delete-dialog.tsx b/src/app/modules/cultivations/presentation/components/cultivation-disease-delete-dialog/cultivation-disease-delete-dialog.tsx index 36304b64..658baf68 100644 --- a/src/app/modules/cultivations/presentation/components/cultivation-disease-delete-dialog/cultivation-disease-delete-dialog.tsx +++ b/src/app/modules/cultivations/presentation/components/cultivation-disease-delete-dialog/cultivation-disease-delete-dialog.tsx @@ -38,7 +38,7 @@ export function CultivationDiseaseDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['cultivation-diseases'], + queryKey: ['cultivation-diseases', propertyId], exact: false, }) diff --git a/src/app/modules/cultivations/presentation/components/cultivation-pest-delete-dialog/cultivation-pest-delete-dialog.tsx b/src/app/modules/cultivations/presentation/components/cultivation-pest-delete-dialog/cultivation-pest-delete-dialog.tsx index fc3a896a..8e2c65b8 100644 --- a/src/app/modules/cultivations/presentation/components/cultivation-pest-delete-dialog/cultivation-pest-delete-dialog.tsx +++ b/src/app/modules/cultivations/presentation/components/cultivation-pest-delete-dialog/cultivation-pest-delete-dialog.tsx @@ -37,7 +37,7 @@ export function CultivationPestDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['cultivation-pests'], + queryKey: ['cultivation-pests', propertyId], exact: false, }) diff --git a/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/create-cultivation-disease-form.tsx b/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/create-cultivation-disease-form.tsx index 73cf911d..e4463898 100644 --- a/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/create-cultivation-disease-form.tsx +++ b/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/create-cultivation-disease-form.tsx @@ -52,7 +52,7 @@ export function CreateCultivationDiseaseForm() { }) queryClient.invalidateQueries({ - queryKey: ['cultivation-diseases'], + queryKey: ['cultivation-diseases', propertyId], exact: false, }) diff --git a/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/edit-cultivation-disease-form.tsx b/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/edit-cultivation-disease-form.tsx index 758067bf..b92b15d4 100644 --- a/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/edit-cultivation-disease-form.tsx +++ b/src/app/modules/cultivations/presentation/forms/cultivation-disease-form/edit-cultivation-disease-form.tsx @@ -72,7 +72,7 @@ export function EditCultivationDiseaseForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['cultivation-diseases'], + queryKey: ['cultivation-diseases', propertyId], exact: false, }) toast.success('Doença do cultivo foi editada com sucesso') diff --git a/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/create-cultivation-pest-form.tsx b/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/create-cultivation-pest-form.tsx index 8e1d7e9c..8a96a9e8 100644 --- a/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/create-cultivation-pest-form.tsx +++ b/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/create-cultivation-pest-form.tsx @@ -51,7 +51,7 @@ export function CreateCultivationPestForm() { }) queryClient.invalidateQueries({ - queryKey: ['cultivation-pests'], + queryKey: ['cultivation-pests', propertyId], exact: false, }) diff --git a/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/edit-cultivation-pest-form.tsx b/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/edit-cultivation-pest-form.tsx index 0618772a..3abe9116 100644 --- a/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/edit-cultivation-pest-form.tsx +++ b/src/app/modules/cultivations/presentation/forms/cultivation-pest-form/edit-cultivation-pest-form.tsx @@ -71,7 +71,7 @@ export function EditCultivationPestForm() { propertyId, }) queryClient.invalidateQueries({ - queryKey: ['cultivation-pests'], + queryKey: ['cultivation-pests', propertyId], exact: false, }) toast.success('Praga do cultivo foi editada com sucesso') diff --git a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-disease-query.hook.ts b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-disease-query.hook.ts index d3f65248..86af9534 100644 --- a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-disease-query.hook.ts +++ b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-disease-query.hook.ts @@ -20,7 +20,8 @@ export function useCultivationDiseaseQuery({ id, propertyId }: Props) { isLoading, refetch: refetchCultivationDisease, } = useQuery({ - queryKey: ['cultivation-disease', id], + queryKey: ['cultivation-disease', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getCultivationDiseaseUseCase.execute({ propertyId, diff --git a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-diseases-query.hook.ts b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-diseases-query.hook.ts index 2be9f8c6..0a7cc679 100644 --- a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-diseases-query.hook.ts +++ b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-diseases-query.hook.ts @@ -33,7 +33,8 @@ export function useCultivationDiseasesQuery({ isLoading, refetch: refetchCultivationDiseases, } = useQuery({ - queryKey: ['cultivation-diseases', { page, sort, filters }], + queryKey: ['cultivation-diseases', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getCultivationDiseasesUseCase.execute({ propertyId, diff --git a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pest-query.hook.ts b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pest-query.hook.ts index 18938d1f..a24569a3 100644 --- a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pest-query.hook.ts +++ b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pest-query.hook.ts @@ -20,7 +20,8 @@ export function useCultivationPestQuery({ id, propertyId }: Props) { isLoading, refetch: refetchCultivationPest, } = useQuery({ - queryKey: ['cultivation-pest', id], + queryKey: ['cultivation-pest', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getCultivationPestUseCase.execute({ propertyId, diff --git a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pests-query.hook.ts b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pests-query.hook.ts index d3cb0d56..682a591c 100644 --- a/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pests-query.hook.ts +++ b/src/app/modules/cultivations/presentation/hooks/queries/cultivation-pests-query.hook.ts @@ -32,7 +32,8 @@ export function useCultivationPestsQuery({ isLoading, refetch: refetchCultivationPests, } = useQuery({ - queryKey: ['cultivation-pests', { page, sort, filters }], + queryKey: ['cultivation-pests', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getCultivationPestsUseCase.execute({ propertyId, diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx b/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx index 11c26ecb..d8f7457a 100644 --- a/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-delete-dialog/forage-availability-delete-dialog.tsx @@ -39,7 +39,7 @@ export function ForageAvailabilityDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['forage-availabilities'], + queryKey: ['forage-availabilities', propertyId], exact: false, }) diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx index 927ff73d..cd08b04d 100644 --- a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/create-forage-availability-form.tsx @@ -52,7 +52,7 @@ export function CreateForageAvailabilityForm() { }) queryClient.invalidateQueries({ - queryKey: ['forage-availabilities'], + queryKey: ['forage-availabilities', propertyId], exact: false, }) diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx index 6397eb60..05b75395 100644 --- a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/edit-forage-availability-form.tsx @@ -75,7 +75,7 @@ export function EditForageAvailabilityForm() { }) queryClient.invalidateQueries({ - queryKey: ['forage-availabilities'], + queryKey: ['forage-availabilities', propertyId], exact: false, }) diff --git a/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts index 7583e4fc..be7952b2 100644 --- a/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts +++ b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availabilities-query.hook.ts @@ -32,7 +32,8 @@ export function useForageAvailabilitiesQuery({ isLoading, refetch: refetchForageAvailabilities, } = useQuery({ - queryKey: ['forage-availabilities', { page, sort, filters }], + queryKey: ['forage-availabilities', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getForageAvailabilitiesUseCase.execute({ propertyId, diff --git a/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts index 02ee7515..92db239c 100644 --- a/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts +++ b/src/app/modules/forage-availability/presentation/hooks/queries/forage-availability-query.hook.ts @@ -20,7 +20,8 @@ export function useForageAvailabilityQuery({ propertyId, id }: Props) { isLoading, refetch: refetchForageAvailability, } = useQuery({ - queryKey: ['forage-availability', id], + queryKey: ['forage-availability', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getForageAvailabilityUseCase.execute({ propertyId, id }), }) diff --git a/src/app/modules/forages/presentation/components/forage-delete-dialog/forage-delete-dialog.tsx b/src/app/modules/forages/presentation/components/forage-delete-dialog/forage-delete-dialog.tsx index b61a38ae..804cba35 100644 --- a/src/app/modules/forages/presentation/components/forage-delete-dialog/forage-delete-dialog.tsx +++ b/src/app/modules/forages/presentation/components/forage-delete-dialog/forage-delete-dialog.tsx @@ -37,7 +37,7 @@ export function ForageDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['forages'], + queryKey: ['forages', propertyId], exact: false, }) diff --git a/src/app/modules/forages/presentation/forms/forage-form/create-forage-form.tsx b/src/app/modules/forages/presentation/forms/forage-form/create-forage-form.tsx index 97de40f9..711f2e5a 100644 --- a/src/app/modules/forages/presentation/forms/forage-form/create-forage-form.tsx +++ b/src/app/modules/forages/presentation/forms/forage-form/create-forage-form.tsx @@ -48,7 +48,7 @@ export function CreateForageForm() { }) queryClient.invalidateQueries({ - queryKey: ['forages'], + queryKey: ['forages', propertyId], exact: false, }) diff --git a/src/app/modules/forages/presentation/forms/forage-form/edit-forage-form.tsx b/src/app/modules/forages/presentation/forms/forage-form/edit-forage-form.tsx index f61fd31b..b06423b8 100644 --- a/src/app/modules/forages/presentation/forms/forage-form/edit-forage-form.tsx +++ b/src/app/modules/forages/presentation/forms/forage-form/edit-forage-form.tsx @@ -74,7 +74,7 @@ export function EditForageForm() { }) queryClient.invalidateQueries({ - queryKey: ['forages'], + queryKey: ['forages', propertyId], exact: false, }) diff --git a/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts b/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts index 9ce59e81..eea68177 100644 --- a/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts +++ b/src/app/modules/forages/presentation/hooks/queries/all-forages-query.hook.ts @@ -24,7 +24,8 @@ export function useAllForagesQuery({ propertyId, filters }: Props) { isLoading, refetch: refetchAllForages, } = useQuery({ - queryKey: ['all-forages', { filters }], + queryKey: ['all-forages', propertyId, { filters }], + enabled: !!propertyId, queryFn: () => getForagesUseCase.execute({ propertyId, diff --git a/src/app/modules/forages/presentation/hooks/queries/forage-query.hook.ts b/src/app/modules/forages/presentation/hooks/queries/forage-query.hook.ts index 865e1bfa..0d38ba5c 100644 --- a/src/app/modules/forages/presentation/hooks/queries/forage-query.hook.ts +++ b/src/app/modules/forages/presentation/hooks/queries/forage-query.hook.ts @@ -19,7 +19,8 @@ export function useForageQuery({ id, propertyId }: Props) { isLoading, refetch: refetchForage, } = useQuery({ - queryKey: ['forages', id], + queryKey: ['forages', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getForageUseCase.execute({ propertyId, diff --git a/src/app/modules/forages/presentation/hooks/queries/forages-query.hook.ts b/src/app/modules/forages/presentation/hooks/queries/forages-query.hook.ts index 83898742..21ef21eb 100644 --- a/src/app/modules/forages/presentation/hooks/queries/forages-query.hook.ts +++ b/src/app/modules/forages/presentation/hooks/queries/forages-query.hook.ts @@ -24,7 +24,8 @@ export function useForagesQuery({ propertyId, filters, page, sort }: Props) { isLoading, refetch: refetchForages, } = useQuery({ - queryKey: ['forages', { page, sort, filters }], + queryKey: ['forages', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getForagesUseCase.execute({ propertyId, diff --git a/src/app/modules/improvements/presentation/components/improvement-delete-dialog/improvement-delete-dialog.tsx b/src/app/modules/improvements/presentation/components/improvement-delete-dialog/improvement-delete-dialog.tsx index f6b0e522..f52cc8b7 100644 --- a/src/app/modules/improvements/presentation/components/improvement-delete-dialog/improvement-delete-dialog.tsx +++ b/src/app/modules/improvements/presentation/components/improvement-delete-dialog/improvement-delete-dialog.tsx @@ -37,7 +37,7 @@ export function ImprovementDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['improvements'], + queryKey: ['improvements', propertyId], exact: false, }) diff --git a/src/app/modules/improvements/presentation/forms/improvement-form/create-improvement-form.tsx b/src/app/modules/improvements/presentation/forms/improvement-form/create-improvement-form.tsx index f298c25b..49db4d19 100644 --- a/src/app/modules/improvements/presentation/forms/improvement-form/create-improvement-form.tsx +++ b/src/app/modules/improvements/presentation/forms/improvement-form/create-improvement-form.tsx @@ -48,7 +48,7 @@ export function CreateImprovementForm() { }) queryClient.invalidateQueries({ - queryKey: ['improvements'], + queryKey: ['improvements', propertyId], exact: false, }) diff --git a/src/app/modules/improvements/presentation/forms/improvement-form/edit-improvement-form.tsx b/src/app/modules/improvements/presentation/forms/improvement-form/edit-improvement-form.tsx index 6aca4814..2d9ae7e8 100644 --- a/src/app/modules/improvements/presentation/forms/improvement-form/edit-improvement-form.tsx +++ b/src/app/modules/improvements/presentation/forms/improvement-form/edit-improvement-form.tsx @@ -76,7 +76,7 @@ export function EditImprovementForm() { }) queryClient.invalidateQueries({ - queryKey: ['improvements'], + queryKey: ['improvements', propertyId], exact: false, }) diff --git a/src/app/modules/improvements/presentation/hooks/queries/improvement-query.hook.ts b/src/app/modules/improvements/presentation/hooks/queries/improvement-query.hook.ts index b1de97a6..650d00d1 100644 --- a/src/app/modules/improvements/presentation/hooks/queries/improvement-query.hook.ts +++ b/src/app/modules/improvements/presentation/hooks/queries/improvement-query.hook.ts @@ -19,7 +19,8 @@ export function useImprovementQuery({ id, propertyId }: Props) { isLoading, refetch: refetchImprovement, } = useQuery({ - queryKey: ['improvement', id], + queryKey: ['improvement', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getImprovementUseCase.execute({ propertyId, diff --git a/src/app/modules/improvements/presentation/hooks/queries/improvements-query.hook.ts b/src/app/modules/improvements/presentation/hooks/queries/improvements-query.hook.ts index 3fb15af8..423c0214 100644 --- a/src/app/modules/improvements/presentation/hooks/queries/improvements-query.hook.ts +++ b/src/app/modules/improvements/presentation/hooks/queries/improvements-query.hook.ts @@ -29,7 +29,8 @@ export function useImprovementsQuery({ isLoading, refetch: refetchImprovements, } = useQuery({ - queryKey: ['improvements', { page, sort, filters }], + queryKey: ['improvements', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getImprovementsUseCase.execute({ propertyId, diff --git a/src/app/modules/machines/presentation/components/machine-delete-dialog/machine-delete-dialog.tsx b/src/app/modules/machines/presentation/components/machine-delete-dialog/machine-delete-dialog.tsx index 9d482665..9b7cc155 100644 --- a/src/app/modules/machines/presentation/components/machine-delete-dialog/machine-delete-dialog.tsx +++ b/src/app/modules/machines/presentation/components/machine-delete-dialog/machine-delete-dialog.tsx @@ -37,7 +37,7 @@ export function MachineDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['machines'], + queryKey: ['machines', propertyId], exact: false, }) diff --git a/src/app/modules/machines/presentation/forms/machine-form/create-machine-form.tsx b/src/app/modules/machines/presentation/forms/machine-form/create-machine-form.tsx index eb0726bf..3434ba99 100644 --- a/src/app/modules/machines/presentation/forms/machine-form/create-machine-form.tsx +++ b/src/app/modules/machines/presentation/forms/machine-form/create-machine-form.tsx @@ -47,7 +47,7 @@ export function CreateMachineForm() { machine: data, }) queryClient.invalidateQueries({ - queryKey: ['machines'], + queryKey: ['machines', propertyId], exact: false, }) toast.success('Máquina foi cadastrada com sucesso') diff --git a/src/app/modules/machines/presentation/forms/machine-form/edit-machine-form.tsx b/src/app/modules/machines/presentation/forms/machine-form/edit-machine-form.tsx index 3e16f707..69e65ca2 100644 --- a/src/app/modules/machines/presentation/forms/machine-form/edit-machine-form.tsx +++ b/src/app/modules/machines/presentation/forms/machine-form/edit-machine-form.tsx @@ -76,7 +76,7 @@ export function EditMachineForm() { }) queryClient.invalidateQueries({ - queryKey: ['machines'], + queryKey: ['machines', propertyId], exact: false, }) diff --git a/src/app/modules/machines/presentation/hooks/queries/machine-query.hook.ts b/src/app/modules/machines/presentation/hooks/queries/machine-query.hook.ts index 129a6287..ccb6f48e 100644 --- a/src/app/modules/machines/presentation/hooks/queries/machine-query.hook.ts +++ b/src/app/modules/machines/presentation/hooks/queries/machine-query.hook.ts @@ -19,7 +19,8 @@ export function useMachineQuery({ id, propertyId }: Props) { isLoading, refetch: refetchMachine, } = useQuery({ - queryKey: ['machine', id], + queryKey: ['machine', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getMachineUseCase.execute({ propertyId, diff --git a/src/app/modules/machines/presentation/hooks/queries/machines-query.hook.ts b/src/app/modules/machines/presentation/hooks/queries/machines-query.hook.ts index 5e346418..ab562db2 100644 --- a/src/app/modules/machines/presentation/hooks/queries/machines-query.hook.ts +++ b/src/app/modules/machines/presentation/hooks/queries/machines-query.hook.ts @@ -24,7 +24,8 @@ export function useMachinesQuery({ propertyId, filters, page, sort }: Props) { isLoading, refetch: refetchMachines, } = useQuery({ - queryKey: ['machines', { page, sort, filters }], + queryKey: ['machines', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getMachinesUseCase.execute({ propertyId, diff --git a/src/app/modules/nutritional-balancings/presentation/components/nutritional-balancing-delete-dialog/nutritional-balancing-delete-dialog.tsx b/src/app/modules/nutritional-balancings/presentation/components/nutritional-balancing-delete-dialog/nutritional-balancing-delete-dialog.tsx index 0253cf23..72c5d9d2 100644 --- a/src/app/modules/nutritional-balancings/presentation/components/nutritional-balancing-delete-dialog/nutritional-balancing-delete-dialog.tsx +++ b/src/app/modules/nutritional-balancings/presentation/components/nutritional-balancing-delete-dialog/nutritional-balancing-delete-dialog.tsx @@ -39,7 +39,7 @@ export function NutritionalBalancingDeleteDialog() { }) queryClient.invalidateQueries({ - queryKey: ['nutritional-balancings'], + queryKey: ['nutritional-balancings', propertyId], exact: false, }) diff --git a/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancing-query.hook.ts b/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancing-query.hook.ts index 8abf984e..8c89504e 100644 --- a/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancing-query.hook.ts +++ b/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancing-query.hook.ts @@ -21,7 +21,8 @@ export function useNutritionalBalancingQuery({ id, propertyId }: Props) { isLoading, refetch: refetchNutritionalBalancing, } = useQuery({ - queryKey: ['nutritional-balancing', id], + queryKey: ['nutritional-balancing', propertyId, id], + enabled: !!propertyId && !!id, queryFn: () => getNutritionalBalancingUseCase.execute({ propertyId, diff --git a/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancings-query.hook.ts b/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancings-query.hook.ts index e407093d..ce97bbc0 100644 --- a/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancings-query.hook.ts +++ b/src/app/modules/nutritional-balancings/presentation/hooks/queries/nutritional-balancings-query.hook.ts @@ -33,7 +33,8 @@ export function useNutritionalBalancingsQuery({ isLoading, refetch: refetchNutritionalBalancings, } = useQuery({ - queryKey: ['nutritional-balancings', { page, sort, filters }], + queryKey: ['nutritional-balancings', propertyId, { page, sort, filters }], + enabled: !!propertyId, queryFn: () => getNutritionalBalancingsUseCase.execute({ propertyId, diff --git a/src/app/modules/nutritional-balancings/presentation/screens/edit-nutritional-balancing-screen/hooks/edit-nutritional-balancing-screen.hook.tsx b/src/app/modules/nutritional-balancings/presentation/screens/edit-nutritional-balancing-screen/hooks/edit-nutritional-balancing-screen.hook.tsx index 16cc6a81..9af84167 100644 --- a/src/app/modules/nutritional-balancings/presentation/screens/edit-nutritional-balancing-screen/hooks/edit-nutritional-balancing-screen.hook.tsx +++ b/src/app/modules/nutritional-balancings/presentation/screens/edit-nutritional-balancing-screen/hooks/edit-nutritional-balancing-screen.hook.tsx @@ -132,7 +132,7 @@ export function useEditNutritionalBalancingScreen() { }) queryClient.invalidateQueries({ - queryKey: ['nutritional-balancings'], + queryKey: ['nutritional-balancings', propertyId], exact: false, }) diff --git a/src/app/modules/nutritional-balancings/presentation/screens/new-nutritional-balancing-screen/hooks/new-nutritional-balancing-screen.hook.tsx b/src/app/modules/nutritional-balancings/presentation/screens/new-nutritional-balancing-screen/hooks/new-nutritional-balancing-screen.hook.tsx index cd79ef88..a5b65191 100644 --- a/src/app/modules/nutritional-balancings/presentation/screens/new-nutritional-balancing-screen/hooks/new-nutritional-balancing-screen.hook.tsx +++ b/src/app/modules/nutritional-balancings/presentation/screens/new-nutritional-balancing-screen/hooks/new-nutritional-balancing-screen.hook.tsx @@ -165,7 +165,7 @@ export function useNewNutritionalBalancingScreen() { }) queryClient.invalidateQueries({ - queryKey: ['nutritional-balancings'], + queryKey: ['nutritional-balancings', propertyId], exact: false, }) diff --git a/src/core/mocks/browser.ts b/src/core/mocks/browser.ts index e1a2a95b..73fcd9f1 100644 --- a/src/core/mocks/browser.ts +++ b/src/core/mocks/browser.ts @@ -4,7 +4,6 @@ import { setupWorker } from 'msw/browser' import { createAnimalHandler, deleteAnimalHandler, - getAllAnimalsHandler, getAnimalHandler, getAnimalsHandler, updateAnimalHandler, @@ -105,7 +104,6 @@ import { import { createForageHandler, deleteForageHandler, - getAllForagesHandler, getForageHandler, getForagesHandler, updateForageHandler, @@ -201,14 +199,12 @@ const handlers: HttpHandler[] = [ createAnimalHandler, deleteAnimalHandler, - getAllAnimalsHandler, getAnimalHandler, getAnimalsHandler, updateAnimalHandler, createForageHandler, deleteForageHandler, - getAllForagesHandler, getForageHandler, getForagesHandler, updateForageHandler, From dbe7d6245b7726d1d2c8eddbb80cae82d57f1eb9 Mon Sep 17 00:00:00 2001 From: Guilherme Minozzi Date: Tue, 28 Apr 2026 11:09:53 -0300 Subject: [PATCH 11/11] fix: masks when get and post values --- scripts/seed/data/forage-availabilities.mjs | 18 +++++++------ ...ote-create-forage-availability-use-case.ts | 11 +++++++- ...mote-get-forage-availabilities-use-case.ts | 17 +++++++----- ...remote-get-forage-availability-use-case.ts | 17 +++++++----- ...ote-update-forage-availability-use-case.ts | 11 +++++++- .../models/forage-availability-model.ts | 24 ++++++++--------- .../forage-availability-data-table.hook.tsx | 4 +-- .../forage-availability-form-inputs.tsx | 26 +++++++++---------- src/core/masker/masks/index.ts | 1 + src/core/masker/masks/unmask-float.ts | 10 +++++++ 10 files changed, 90 insertions(+), 49 deletions(-) create mode 100644 src/core/masker/masks/unmask-float.ts diff --git a/scripts/seed/data/forage-availabilities.mjs b/scripts/seed/data/forage-availabilities.mjs index 725ec182..44763f19 100644 --- a/scripts/seed/data/forage-availabilities.mjs +++ b/scripts/seed/data/forage-availabilities.mjs @@ -18,14 +18,16 @@ export const forageAvailabilitiesData = Array.from( id: index + 1, date: faker.date.recent(), forage: forage.cultivation, - entranceCm: String(faker.number.int({ min: 20, max: 40 })), - residueCm: String(faker.number.int({ min: 5, max: 15 })), - kgPerSquareMeter: String( - faker.number.float({ min: 0.5, max: 3, fractionDigits: 2 }) - ), - paddockArea: String(faker.number.int({ min: 500, max: 5000 })), - efficiencyPercent: String(faker.number.int({ min: 60, max: 90 })), - numberOfCows: String(faker.number.int({ min: 10, max: 100 })), + entranceCm: faker.number.int({ min: 20, max: 40 }), + residueCm: faker.number.int({ min: 5, max: 15 }), + kgPerSquareMeter: faker.number.float({ + min: 0.5, + max: 3, + fractionDigits: 2, + }), + paddockArea: faker.number.int({ min: 500, max: 5000 }), + efficiencyPercent: faker.number.int({ min: 60, max: 90 }), + numberOfCows: faker.number.int({ min: 10, max: 100 }), } } ) diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts index a4d5bcbd..573c4ee0 100644 --- a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-create-forage-availability-use-case.ts @@ -4,6 +4,7 @@ import { ForbiddenError, UnexpectedError, } from '@/core/domain/errors' +import { onlyNumbersMask, unmaskFloat } from '@/core/masker' import { type CreateForageAvailabilityUseCase } from '../../../domain/use-cases/forage-availability-use-cases' @@ -22,7 +23,15 @@ export class RemoteCreateForageAvailabilityUseCase const { statusCode } = await this.httpClient.request({ url: this.url.replace(':propertyId', propertyId.toString()), method: 'post', - body: forageAvailability, + body: { + ...forageAvailability, + entranceCm: unmaskFloat(forageAvailability.entranceCm), + residueCm: unmaskFloat(forageAvailability.residueCm), + kgPerSquareMeter: unmaskFloat(forageAvailability.kgPerSquareMeter), + paddockArea: unmaskFloat(forageAvailability.paddockArea), + efficiencyPercent: unmaskFloat(forageAvailability.efficiencyPercent), + numberOfCows: Number(onlyNumbersMask(forageAvailability.numberOfCows)), + }, }) if (statusCode === HttpStatusCode.created) return diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts index ebc9ddc3..4742e6f7 100644 --- a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availabilities-use-case.ts @@ -8,6 +8,7 @@ import { type ListApiResponse, type MapApiProperties, } from '@/core/domain/types' +import { formatNumber } from '@/core/masker' import { type ForageAvailabilityApiResponse, @@ -63,12 +64,16 @@ export class RemoteGetForageAvailabilitiesUseCase id: item.id, date: new Date(item.date), forage: item.forage, - entranceCm: item.entranceCm, - residueCm: item.residueCm, - kgPerSquareMeter: item.kgPerSquareMeter, - paddockArea: item.paddockArea, - efficiencyPercent: item.efficiencyPercent, - numberOfCows: item.numberOfCows, + entranceCm: formatNumber(item.entranceCm, { suffix: 'cm' }), + residueCm: formatNumber(item.residueCm, { suffix: 'cm' }), + kgPerSquareMeter: formatNumber(item.kgPerSquareMeter, { + suffix: 'kg/m²', + }), + paddockArea: formatNumber(item.paddockArea, { suffix: 'm²' }), + efficiencyPercent: formatNumber(item.efficiencyPercent, { + suffix: '%', + }), + numberOfCows: item.numberOfCows.toString(), })), totalPages: Math.ceil(body.numberOfElements / body.pageable.pageSize), } diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts index d9f73f89..a5bacd6a 100644 --- a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-get-forage-availability-use-case.ts @@ -5,6 +5,7 @@ import { NotFoundError, UnexpectedError, } from '@/core/domain/errors' +import { formatNumber } from '@/core/masker' import { type ForageAvailabilityDetailsApiResponse, @@ -36,12 +37,16 @@ export class RemoteGetForageAvailabilityUseCase return { date: new Date(body.date), forage: body.forage, - entranceCm: body.entranceCm, - residueCm: body.residueCm, - kgPerSquareMeter: body.kgPerSquareMeter, - paddockArea: body.paddockArea, - efficiencyPercent: body.efficiencyPercent, - numberOfCows: body.numberOfCows, + entranceCm: formatNumber(body.entranceCm, { suffix: 'cm' }), + residueCm: formatNumber(body.residueCm, { suffix: 'cm' }), + kgPerSquareMeter: formatNumber(body.kgPerSquareMeter, { + suffix: 'kg/m²', + }), + paddockArea: formatNumber(body.paddockArea, { suffix: 'm²' }), + efficiencyPercent: formatNumber(body.efficiencyPercent, { + suffix: '%', + }), + numberOfCows: body.numberOfCows.toString(), } if (statusCode === HttpStatusCode.badRequest) throw new BadRequestError() diff --git a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts index d2567f82..1e143dc1 100644 --- a/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts +++ b/src/app/modules/forage-availability/data/use-cases/forage-availability-use-cases/remote-update-forage-availability-use-case.ts @@ -4,6 +4,7 @@ import { ForbiddenError, UnexpectedError, } from '@/core/domain/errors' +import { onlyNumbersMask, unmaskFloat } from '@/core/masker' import { type UpdateForageAvailabilityUseCase } from '../../../domain/use-cases/forage-availability-use-cases' @@ -22,7 +23,15 @@ export class RemoteUpdateForageAvailabilityUseCase const { statusCode } = await this.httpClient.request({ url: `${this.url.replace(':propertyId', propertyId.toString())}/${id}`, method: 'patch', - body: forageAvailability, + body: { + ...forageAvailability, + entranceCm: unmaskFloat(forageAvailability.entranceCm), + residueCm: unmaskFloat(forageAvailability.residueCm), + kgPerSquareMeter: unmaskFloat(forageAvailability.kgPerSquareMeter), + paddockArea: unmaskFloat(forageAvailability.paddockArea), + efficiencyPercent: unmaskFloat(forageAvailability.efficiencyPercent), + numberOfCows: Number(onlyNumbersMask(forageAvailability.numberOfCows)), + }, }) if (statusCode === HttpStatusCode.noContent) return diff --git a/src/app/modules/forage-availability/domain/models/forage-availability-model.ts b/src/app/modules/forage-availability/domain/models/forage-availability-model.ts index 520f0929..ea916843 100644 --- a/src/app/modules/forage-availability/domain/models/forage-availability-model.ts +++ b/src/app/modules/forage-availability/domain/models/forage-availability-model.ts @@ -14,12 +14,12 @@ export type ForageAvailabilityDetailsModel = { export type ForageAvailabilityDetailsApiResponse = { date: string forage: Option - entranceCm: string - residueCm: string - kgPerSquareMeter: string - paddockArea: string - efficiencyPercent: string - numberOfCows: string + entranceCm: number + residueCm: number + kgPerSquareMeter: number + paddockArea: number + efficiencyPercent: number + numberOfCows: number } export type ForageAvailabilityModel = WithId<{ @@ -36,10 +36,10 @@ export type ForageAvailabilityModel = WithId<{ export type ForageAvailabilityApiResponse = WithId<{ date: string forage: string - entranceCm: string - residueCm: string - kgPerSquareMeter: string - paddockArea: string - efficiencyPercent: string - numberOfCows: string + entranceCm: number + residueCm: number + kgPerSquareMeter: number + paddockArea: number + efficiencyPercent: number + numberOfCows: number }> diff --git a/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx index 32906901..035f03cc 100644 --- a/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx +++ b/src/app/modules/forage-availability/presentation/components/forage-availability-data-table/forage-availability-data-table.hook.tsx @@ -53,11 +53,11 @@ export function useForageAvailabilityDataTable() { }, { accessorKey: 'kgPerSquareMeter', - header: 'Kg/m2', + header: 'Kg/m²', }, { accessorKey: 'paddockArea', - header: 'Área Piquete (m2)', + header: 'Área Piquete (m²)', }, { accessorKey: 'efficiencyPercent', diff --git a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx index 64f0efeb..157cf937 100644 --- a/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx +++ b/src/app/modules/forage-availability/presentation/forms/forage-availability-form/forage-availability-form-inputs.tsx @@ -3,7 +3,7 @@ import { useState } from 'react' import { useFormContext } from 'react-hook-form' import { useAllForagesQuery } from '@/app/modules/forages/presentation/hooks/queries/all-forages-query.hook' -import { onlyNumbersAndDecimalMask, onlyNumbersMask } from '@/core/masker' +import { floatMask, onlyNumbersMask } from '@/core/masker' import { Combobox, DatePicker, @@ -89,8 +89,8 @@ export function ForageAvailabilityFormInputs() { floatMask(val, 'cm')} isError={!!fieldState.error} /> @@ -108,8 +108,8 @@ export function ForageAvailabilityFormInputs() { floatMask(val, 'cm')} isError={!!fieldState.error} /> @@ -125,12 +125,12 @@ export function ForageAvailabilityFormInputs() { name="kgPerSquareMeter" render={({ field, fieldState }) => ( - Kg/m2* + Kg/m²* floatMask(val, 'kg/m²')} isError={!!fieldState.error} /> @@ -144,12 +144,12 @@ export function ForageAvailabilityFormInputs() { name="paddockArea" render={({ field, fieldState }) => ( - Área de Piquete (m2)* + Área de Piquete (m²)* floatMask(val, 'm²')} isError={!!fieldState.error} /> @@ -169,8 +169,8 @@ export function ForageAvailabilityFormInputs() { floatMask(val, '%')} isError={!!fieldState.error} /> diff --git a/src/core/masker/masks/index.ts b/src/core/masker/masks/index.ts index 1a892a10..4b201abe 100644 --- a/src/core/masker/masks/index.ts +++ b/src/core/masker/masks/index.ts @@ -6,3 +6,4 @@ export * from './money-mask' export * from './only-numbers-mask' export * from './phone-mask' export * from './percent-mask' +export * from './unmask-float' diff --git a/src/core/masker/masks/unmask-float.ts b/src/core/masker/masks/unmask-float.ts new file mode 100644 index 00000000..21f3255a --- /dev/null +++ b/src/core/masker/masks/unmask-float.ts @@ -0,0 +1,10 @@ +export function unmaskFloat(value: string | number | undefined | null): number { + if (value === undefined || value === null) return 0 + if (typeof value === 'number') return value + + const stringValue = String(value) + const cleanValue = stringValue.replace(/\./g, '').replace(',', '.') + const numericString = cleanValue.replace(/[^\d.-]/g, '') + + return Number.parseFloat(numericString) || 0 +}