diff --git a/.eslintrc.json b/.eslintrc.json index ae922392..90745205 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -31,6 +31,4 @@ "consistent-return": "off", "react/jsx-no-bind": "off" } - - } diff --git a/package.json b/package.json index ebcf1362..d5fe1e13 100755 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "jspdf-autotable": "^3.5.28", "lodash": "^4.17.21", "lucide-react": "^0.233.0", + "moment": "^2.29.4", "react": "^18.2.0", "react-datepicker": "^4.8.0", "react-dom": "^18.2.0", diff --git a/src/components/action-buttons/approve-button-homologation/approve-button-homologation.spec.tsx b/src/components/action-buttons/approve-button-homologation/approve-button-homologation.spec.tsx new file mode 100644 index 00000000..4bbb925b --- /dev/null +++ b/src/components/action-buttons/approve-button-homologation/approve-button-homologation.spec.tsx @@ -0,0 +1,69 @@ +import React from 'react'; +import { render, fireEvent } from '@testing-library/react'; +import { vi } from 'vitest'; +import { ApproveButton } from '.'; + +describe('ApproveButton', () => { + const handleApproveHomolog = vi.fn(); + it('deve exibir o botão de aprovação e interagir corretamente', () => { + const passDateTime = new Date(); + + const { getByText, getByLabelText } = render( + + ); + + // Verificar se o botão de aprovação está presente + const button = getByText('Aprovar Atendimento'); + expect(button).toBeInTheDocument(); + + // Simular clique no botão de aprovação + fireEvent.click(button); + expect(handleApproveHomolog).toHaveBeenCalledTimes(1); + + // Verificar se o campo de data está presente e tem o valor correto + // const dateTimeInput = getByLabelText('Data do Evento') as HTMLInputElement; + // expect(dateTimeInput).toBeInTheDocument(); + // expect(dateTimeInput.value).toEqual( + // passDateTime.toISOString().substring(0, 16) + // ); + }); + + // it('deve adicionar e remover alertas corretamente', () => { + // const handleApproveHomolog = vi.fn(); + // const passDateTime = new Date(); + + // const { getByText, getByLabelText, queryByLabelText, getAllByLabelText } = render( + // + // ); + + // Simular clique no botão "Adicionar Alerta" + // const addButton = queryByLabelText('Adicionar Alerta'); + + // if (addButton) { + // fireEvent.click(addButton); + // expect(handleApproveHomolog).toHaveBeenCalledWith(handleApproveHomolog); + // } + + // Verificar se o campo de alerta foi adicionado + // const alertInputs = getAllByLabelText('alert_dates'); + // expect(alertInputs.length).toBe(1); + + // Simular clique no botão de remover alerta + // const deleteButton = getByLabelText('Excluir Alerta 1'); + // fireEvent.click(deleteButton); + + // Verificar se o campo de alerta foi removido + // const updatedAlertInputs = getAllByLabelText('alert_dates'); + // expect(updatedAlertInputs.length).toBe(0); + // }); +}); diff --git a/src/components/action-buttons/approve-button-homologation/index.tsx b/src/components/action-buttons/approve-button-homologation/index.tsx new file mode 100644 index 00000000..3c170441 --- /dev/null +++ b/src/components/action-buttons/approve-button-homologation/index.tsx @@ -0,0 +1,239 @@ +import { useCallback, useState } from 'react'; +import { FaPlus, FaTrash } from 'react-icons/fa'; +import { + Box, + Button, + Flex, + Grid, + Divider, + Heading, + Popover, + PopoverAnchor, + PopoverArrow, + PopoverBody, + PopoverCloseButton, + PopoverContent, + PopoverFooter, + PopoverHeader, + Text, + useDisclosure, +} from '@chakra-ui/react'; +import { Controller, useFieldArray, useForm } from 'react-hook-form'; +import { ActionButtonProps } from '../types'; +import { ActionButton } from '..'; +import { Input } from '@/components/form-fields/input'; +import { DeleteButton } from '../delete-button'; +import { IssuePayloadOpen } from '@/features/issues/types'; +import { parseSelectedDatetime } from '@/utils/format-date'; + +interface ApproveButtonProps extends ActionButtonProps { + handleApproveHomolog: (justify: string) => void; + passDateTime: Date; +} + +const tooltipStyle = { + bg: 'green.500', + color: 'white', +}; + +export function ApproveButton({ + label, + onClick, + passDateTime, + ...props +}: ApproveButtonProps) { + const { isOpen, onOpen, onClose } = useDisclosure(); + const [justification] = useState(''); + + const [isLoading, setIsLoading] = useState(false); + + const { control, watch, register } = useForm({ + defaultValues: { + dateTime: passDateTime ?? '', + }, + }); + + const { fields, append, remove } = useFieldArray({ + control, + shouldUnregister: true, + name: 'problem_types_payload', + }); + + const handleAddDate = useCallback(() => { + append({ label: '', value: '' }); + }, [append]); + + const handleRemoveDate = useCallback( + (index: number) => () => { + remove(index); + }, + [remove] + ); + + return ( + + + } + onClick={onOpen} + isLoading={isLoading} + color="red.500" + tooltipProps={tooltipStyle} + tabIndex={0} + {...props} + /> + + + + + + + + Confirmação + + + + + + ( + <> + + + {error ? error.message : null} + + + )} + /> + + + + Alertas + + + + {fields?.map((field, index) => { + return ( + + ( + + + + {error ? error.message : null} + + + )} + /> + + + + ); + })} + + + } + variant="outline" + color="primary" + tooltipProps={{ + placement: 'bottom', + }} + onClick={handleAddDate} + /> + + + + + + + + + + + + ); +} diff --git a/src/components/action-buttons/delete-button-homologation/delete-button-homologation.spec.tsx b/src/components/action-buttons/delete-button-homologation/delete-button-homologation.spec.tsx new file mode 100644 index 00000000..14ef68d6 --- /dev/null +++ b/src/components/action-buttons/delete-button-homologation/delete-button-homologation.spec.tsx @@ -0,0 +1,33 @@ +import { screen, render } from '@testing-library/react'; +import { DeleteButton } from '.'; + +describe('DeleteButton', () => { + it('has the correct aria-label', () => { + render( + {}} + handleDeleteHomolog={function (justify: string): void { + throw new Error('Function not implemented.'); + }} + /> + ); + expect(screen.getByText('Reprovar homologação')).toBeInTheDocument(); + }); + + it('should be able to call DeleteButton onClick function', async () => { + render( + {}} + handleDeleteHomolog={function (justify: string): void { + throw new Error('Function not implemented.'); + }} + /> + ); + + const button = screen.getByText('Reprovar homologação'); + + expect(button).toBeInTheDocument(); + }); +}); diff --git a/src/components/action-buttons/delete-button-homologation/index.tsx b/src/components/action-buttons/delete-button-homologation/index.tsx new file mode 100644 index 00000000..6f1444c4 --- /dev/null +++ b/src/components/action-buttons/delete-button-homologation/index.tsx @@ -0,0 +1,109 @@ +import { useState } from 'react'; +import { FaTrash } from 'react-icons/fa'; +import { + Button, + Flex, + Heading, + Popover, + PopoverAnchor, + PopoverArrow, + PopoverBody, + PopoverCloseButton, + PopoverContent, + PopoverFooter, + PopoverHeader, + Text, + Textarea, + useDisclosure, +} from '@chakra-ui/react'; +import { ActionButtonProps } from '../types'; +import { ActionButton } from '..'; + +interface DeleteButtonProps extends ActionButtonProps { + handleDeleteHomolog: (justify: string) => void; +} + +const tooltipStyle = { + bg: 'red.500', + color: 'white', +}; + +export function DeleteButton({ + label, + onClick, + ...props +}: DeleteButtonProps) { + const { isOpen, onOpen, onClose } = useDisclosure(); + const [justification, setJustification] = useState(''); + + const [isLoading, setIsLoading] = useState(false); + + return ( + + + } + onClick={onOpen} + isLoading={isLoading} + color="red.500" + tooltipProps={tooltipStyle} + tabIndex={0} + {...props} + /> + + + + + + + + Reprovar homologação + + + + + Você realmente deseja reprovar a homologação? + + Justifique o motivo da reprovação: + +