diff --git a/.github/workflows/code-analysis.yml b/.github/workflows/code-analysis.yml index 6a579cce..135bae06 100644 --- a/.github/workflows/code-analysis.yml +++ b/.github/workflows/code-analysis.yml @@ -36,11 +36,3 @@ jobs: GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} SONAR_TOKEN: ${{secrets.SONAR_TOKEN}} - - name: Envia cobertura para o Codecov - uses: codecov/codecov-action@v3 - with: - token: ${{ secrets.CODECOV_TOKEN }} - fail_ci_if_error: true - flags: jest - name: 2023.2-PrintGo-FrontEnd - verbose: true diff --git a/.github/workflows/metrics.yml b/.github/workflows/metrics.yml index f4ff4429..e5d80089 100644 --- a/.github/workflows/metrics.yml +++ b/.github/workflows/metrics.yml @@ -1,6 +1,7 @@ name: Metrics and Release on: + workflow_dispatch: pull_request: branches: - main diff --git a/docker-compose.yml b/docker-compose.yml index 9d1eda99..91bcb706 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,5 +1,3 @@ -version: '3.8' - services: app: container_name: app-front diff --git a/public/seta-direita 1.png b/public/seta-direita 1.png new file mode 100644 index 00000000..67bd7b61 Binary files /dev/null and b/public/seta-direita 1.png differ diff --git a/scripts/metrics.js b/scripts/metrics.js index d40a0db1..1091010a 100644 --- a/scripts/metrics.js +++ b/scripts/metrics.js @@ -1,21 +1,19 @@ -const REPO = '2023.2-PrintGo-FrontEnd' +const REPO = '2024.1-PrintGo-FrontEnd' const OWNER = 'fga-eps-mds' -const SONAR_ID = 'fga-eps-mds_2023.2-PrintGo-FrontEnd' +const SONAR_ID = 'fga-eps-mds_2024.1-PrintGo-FrontEnd' -const METRIC_LIST = [ - 'files', - 'functions', - 'complexity', - 'comment_lines_density', - 'duplicated_lines_density', - 'coverage', - 'ncloc', - 'tests', - 'test_errors', - 'test_failures', - 'test_execution_time', - 'security_rating' -]; +const METRIC_LIST = ['files', + 'functions', + 'complexity', + 'comment_lines_density', + 'duplicated_lines_density', + 'coverage', + 'ncloc', + 'tests', + 'test_errors', + 'test_failures', + 'test_execution_time', + 'security_rating']; const SONAR_URL = `https://sonarcloud.io/api/measures/component_tree?component=${SONAR_ID}&metricKeys=${METRIC_LIST.join(',')}&ps=500`; @@ -23,4 +21,4 @@ module.exports = { SONAR_URL, REPO, OWNER -}; \ No newline at end of file +}; diff --git a/sonar-project.properties b/sonar-project.properties index 1abf2026..a577f8ac 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -1,4 +1,4 @@ -sonar.projectKey=fga-eps-mds_2023.2-PrintGo-FrontEnd +sonar.projectKey=fga-eps-mds_2024.1-PrintGo-FrontEnd sonar.organization=fga-eps-mds-1 sonar.sources=src sonar.tests=src @@ -7,4 +7,4 @@ sonar.exclusions=node_modules/**, test/**, assets/**, .github/**, scripts/** sonar.javascript.lcov.reportPaths=coverage/lcov.info -sonar.testExecutionReportPaths=reports/sonar-report.xml \ No newline at end of file +sonar.testExecutionReportPaths=reports/sonar-report.xml diff --git a/src/App.js b/src/App.js index e9e39e06..54c6c2a1 100644 --- a/src/App.js +++ b/src/App.js @@ -22,6 +22,11 @@ import ForgottenPasswordPage from "./pages/ForgottenPassword"; import RecoverPasswordPage from "./pages/RecoverPassword"; import PrivateRoutes from "./components/utils/PrivateRoutes"; import AdminRoutes from "./components/utils/AdminRoutes"; +import ListEquipment from "./components/forms/ListEquipment"; +import ContractForm from "./components/forms/ContractForm"; +import EditContractForm from "./components/forms/EditContractForm"; +import ContractList from "./pages/ContractList"; +import ViewContract from "./pages/ViewContract"; function App() { return ( @@ -30,16 +35,23 @@ function App() { }> }/> + }/> + }/> + }/> } /> } /> - } /> + {/* } /> */} } /> - } /> + } /> } /> }/> } /> } /> - } /> + } /> + } /> + } /> + } /> + } /> }> } /> } /> diff --git a/src/api/api.js b/src/api/api.js index 7d03f631..e1c81857 100644 --- a/src/api/api.js +++ b/src/api/api.js @@ -7,8 +7,9 @@ export async function login(email, password) { }; try { - const response = await api.post('/user/login', data); - return {type: 'success', token: response.data.token }; + // const response = await api.post('/user/login', data); + let token_mock = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjEyMyIsImVtYWlsIjoidXNlckBleGFtcGxlLmNvbSIsIm5vbWUiOiJEYW5pZWwiLCJjYXJnb3MiOiJhZG1pbiJ9.tMm8nEv6qtGnL4XJIFRQJcgw6qafUUDpxgR8LUHXX08" + return {type: 'success', token: token_mock }; } catch (error) { console.error('Erro ao fazer login:', error); return {type: 'error', error}; @@ -28,4 +29,4 @@ export async function changePassword(data) { } catch(error) { return {type: 'error', error}; } -} +} \ No newline at end of file diff --git a/src/assets/Filter.svg b/src/assets/Filter.svg index a5febf6d..e81aaaa3 100644 --- a/src/assets/Filter.svg +++ b/src/assets/Filter.svg @@ -1,3 +1,3 @@ - + diff --git a/src/assets/green-calendar.png b/src/assets/green-calendar.png new file mode 100644 index 00000000..b07bc224 Binary files /dev/null and b/src/assets/green-calendar.png differ diff --git a/src/assets/processor.png b/src/assets/processor.png new file mode 100644 index 00000000..74f9217a Binary files /dev/null and b/src/assets/processor.png differ diff --git a/src/components/Button.js b/src/components/Button.js index c180bdc2..a1109f41 100644 --- a/src/components/Button.js +++ b/src/components/Button.js @@ -1,27 +1,49 @@ import React from 'react'; -import PropTypes from 'prop-types'; // Import PropTypes +import PropTypes from 'prop-types'; import '../style/components/button.css'; -const Button = ({ textColor, bgColor, borderColor, children, onClick }) => { - const buttonStyle = { - '--text-color': textColor, - '--bg-color': bgColor, - '--border-color': borderColor, - }; - - return ( - - ); +const Button = ({ type, size, text, onClick, bgColor }) => { + const typeClasses = { + success: 'button-success', + error: 'button-error', + info: 'button-info', + warning: 'button-warning', + icon: 'button-icon' + }; + + const sizeClasses = { + small: 'button-small', + medium: 'button-medium', + large: 'button-large', + }; + + const buttonClass = `button ${typeClasses[type] || 'button-info'} ${sizeClasses[size] || 'button-medium'}`; + + return ( + + ); }; Button.propTypes = { - textColor: PropTypes.string, // Validate textColor as a string - bgColor: PropTypes.string, // Validate bgColor as a string - borderColor: PropTypes.string, // Validate borderColor as a string - children: PropTypes.node, // Validate children as a React node - onClick: PropTypes.func, // Validate onClick as a function + type: PropTypes.oneOf(['success', 'error', 'info', 'warning', 'icon']), + size: PropTypes.oneOf(['small', 'medium', 'large']), + text: PropTypes.string.isRequired, + bgColor: PropTypes.string.isRequired, + onClick: PropTypes.func.isRequired, +}; + +Button.defaultProps = { + type: 'info', + size: 'medium', }; export default Button; diff --git a/src/components/cards/BigInfoCard.js b/src/components/cards/BigInfoCard.js new file mode 100644 index 00000000..edb3362e --- /dev/null +++ b/src/components/cards/BigInfoCard.js @@ -0,0 +1,23 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/BigInfoCard.css"; + +const BigInfoCard = ({ className, title, info }) => { + return ( +
+ {title} + {info} +
+ ); +}; + +BigInfoCard.propTypes = { + title: PropTypes.string.isRequired, + info: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number + ]).isRequired, + className: PropTypes.string, +}; + +export default BigInfoCard; diff --git a/src/components/cards/SmallInfoCard.js b/src/components/cards/SmallInfoCard.js new file mode 100644 index 00000000..66edc6b5 --- /dev/null +++ b/src/components/cards/SmallInfoCard.js @@ -0,0 +1,26 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/SmallInfoCard.css"; + +const SmallInfoCard = ({ className, title, imageSrc, info }) => { + const titleClass = className === 'grey-info-card' ? 'info-card-title' : 'blue-info-card-title'; + const infoClass = className === 'grey-info-card' ? 'info-card-info' : 'blue-info-card-info'; + return ( +
+ {title} +
+ {title} + {info} +
+
+ ); +}; + +SmallInfoCard.propTypes = { + title: PropTypes.string.isRequired, + imageSrc: PropTypes.string.isRequired, + info: PropTypes.string.isRequired, + className: PropTypes.string, +}; + +export default SmallInfoCard; diff --git a/src/components/containers/DateContainer.js b/src/components/containers/DateContainer.js new file mode 100644 index 00000000..3e0b80fe --- /dev/null +++ b/src/components/containers/DateContainer.js @@ -0,0 +1,36 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/DateContainer.css"; + +const DateContainer = ({ label, value, onChange, className, error }) => { + return ( +
+ {label} +
+ +
+
+ ); +}; + +DateContainer.propTypes = { + label: PropTypes.string.isRequired, + value: PropTypes.string, + onChange: PropTypes.func.isRequired, + className: PropTypes.string, + error: PropTypes.string, +}; + +DateContainer.defaultProps = { + value: '', + className: '', + error: '', +}; + +export default DateContainer; + diff --git a/src/components/containers/DropdownSection.js b/src/components/containers/DropdownSection.js new file mode 100644 index 00000000..351a1d34 --- /dev/null +++ b/src/components/containers/DropdownSection.js @@ -0,0 +1,37 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/FilterContainer.css" + +const DropdownSection = ({ title }) => { + const [isOpen, setIsOpen] = useState(false); + + const toggleOpen = () => { + setIsOpen(!isOpen); + }; + + return ( +
+
+ {title} + seta +
+ {isOpen && ( +
+ + + +
+ )} +
+ ); +}; + +DropdownSection.propTypes = { + title: PropTypes.string.isRequired, +}; + +export default DropdownSection; \ No newline at end of file diff --git a/src/components/containers/FilterContainer.js b/src/components/containers/FilterContainer.js new file mode 100644 index 00000000..5ba21cea --- /dev/null +++ b/src/components/containers/FilterContainer.js @@ -0,0 +1,21 @@ +import React from 'react'; +import DropdownSection from './DropdownSection'; +import "../../style/components/FilterContainer.css" + +const FilterContainer = () => { + return ( +
+
+

Equipamentos disponíveis

+
+
+ + + + +
+
+ ); +}; + +export default FilterContainer; diff --git a/src/components/containers/InputContainer.js b/src/components/containers/InputContainer.js new file mode 100644 index 00000000..5461dc79 --- /dev/null +++ b/src/components/containers/InputContainer.js @@ -0,0 +1,38 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/InputContainer.css"; + +const InputContainer = ({ label, placeholder, value, onChange, className, error }) => { + return ( +
+ {label} +
+ onChange(e.target.value)} + className={error ? `input-field ${className} input-error` : `input-field ${className}`} + /> +
+
+ ); +}; + +InputContainer.propTypes = { + label: PropTypes.string.isRequired, + placeholder: PropTypes.string, + value: PropTypes.string.isRequired, + onChange: PropTypes.func.isRequired, + className: PropTypes.string, + error: PropTypes.string, +}; + +InputContainer.defaultProps = { + placeholder: '', + error: '', +}; + +export default InputContainer; + diff --git a/src/components/containers/ItemBox.js b/src/components/containers/ItemBox.js new file mode 100644 index 00000000..f891a29f --- /dev/null +++ b/src/components/containers/ItemBox.js @@ -0,0 +1,55 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import "../../style/components/itemBox.css"; +import { FaToggleOn, FaToggleOff, FaPencil } from "react-icons/fa6"; +import Button from "../Button"; + +const ItemBox = ({ label, onEditClick, onToggleClick }) => { + const [isToggled, setIsToggled] = useState(true); + + const handleToggleClick = () => { + setIsToggled(prevState => !prevState); + if (onToggleClick) { + onToggleClick(); + } + }; + + return ( +
+
+
{label}
+
+
+
+
+
+
+ ); +}; + +ItemBox.propTypes = { + label: PropTypes.string, + onEditClick: PropTypes.func, + onToggleClick: PropTypes.func, +}; + +ItemBox.defaultProps = { + label: "Default Label", + onEditClick: () => console.log('Edit button clicked'), + onToggleClick: () => console.log('Toggle button clicked'), +}; + +export default ItemBox; diff --git a/src/components/containers/NumberContainer.js b/src/components/containers/NumberContainer.js new file mode 100644 index 00000000..995a2dd7 --- /dev/null +++ b/src/components/containers/NumberContainer.js @@ -0,0 +1,45 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/NumberContainer.css"; + +const NumberContainer = ({ id, name, value, onChange, className, label, disabled, error }) => { + return ( +
+ {label} +
+ +
+
+ ); +}; + +NumberContainer.propTypes = { + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + value: PropTypes.number, + onChange: PropTypes.func, + className: PropTypes.string, + label: PropTypes.string.isRequired, + disabled: PropTypes.bool, + error: PropTypes.string, +}; + +NumberContainer.defaultProps = { + value: '', + onChange: null, + className: '', + disabled: false, + error: '', +}; + +export default NumberContainer; + diff --git a/src/components/containers/SelectContainer.js b/src/components/containers/SelectContainer.js new file mode 100644 index 00000000..686e7651 --- /dev/null +++ b/src/components/containers/SelectContainer.js @@ -0,0 +1,48 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/SelectContainer.css"; + +const SelectContainer = ({ id, name, options, className, label, onChange, value, error }) => { + return ( +
+ {label} +
+ +
+
+ ); +}; + +SelectContainer.propTypes = { + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + options: PropTypes.arrayOf(PropTypes.string).isRequired, + className: PropTypes.string, + label: PropTypes.string.isRequired, + onChange: PropTypes.func, + value: PropTypes.string, + error: PropTypes.string // Adicione esta linha +}; + +SelectContainer.defaultProps = { + className: '', + onChange: null, + value: '', + error: '' // Adicione esta linha +}; + +export default SelectContainer; + diff --git a/src/components/containers/StatusButton.js b/src/components/containers/StatusButton.js new file mode 100644 index 00000000..a1f83351 --- /dev/null +++ b/src/components/containers/StatusButton.js @@ -0,0 +1,39 @@ +import React, { useState } from 'react'; + +function StatusButton() { + // Estado para armazenar se o status está "Ativo" ou "Inativo" + const [isActive, setIsActive] = useState(false); + + // Função para alternar o estado + const toggleStatus = () => { + setIsActive(!isActive); + }; + + return ( +
+ {/* Botão que chama a função toggleStatus ao ser clicado */} + +
+ ); +} + +export default StatusButton; diff --git a/src/components/containers/StatusDropdown.js b/src/components/containers/StatusDropdown.js new file mode 100644 index 00000000..45b018f6 --- /dev/null +++ b/src/components/containers/StatusDropdown.js @@ -0,0 +1,67 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; + +function StatusDropdown({ onChange }) { + // Estado para armazenar o valor selecionado + const [selectedOption, setSelectedOption] = useState(''); + + // Função para lidar com a mudança de seleção + const handleChange = (event) => { + setSelectedOption(event.target.value); + + if (onChange) { + onChange(event); // Passa o evento completo + } + }; + + return ( +
+ + +
+ ); +} + +StatusDropdown.propTypes = { + onChange: PropTypes.func.isRequired, +}; + +export default StatusDropdown; diff --git a/src/components/containers/ViewDataContainer.js b/src/components/containers/ViewDataContainer.js new file mode 100644 index 00000000..c9c8b01d --- /dev/null +++ b/src/components/containers/ViewDataContainer.js @@ -0,0 +1,37 @@ +import React, { useState } from 'react'; +import PropTypes from 'prop-types'; +import "../../style/components/ViewDataContainer.css"; + +const ViewDataContainer = ({ id, name, className, labelName, value }) => { + const [isHovered, setIsHovered] = useState(false); + + return ( +
+ {labelName} + +
+ ); +}; + +ViewDataContainer.propTypes = { + id: PropTypes.string.isRequired, + name: PropTypes.string.isRequired, + className: PropTypes.string, + labelName: PropTypes.string.isRequired, + value: PropTypes.string, +}; + +ViewDataContainer.defaultProps = { + className: '', + value: '', +}; + +export default ViewDataContainer; \ No newline at end of file diff --git a/src/components/containers/contractBox.js b/src/components/containers/contractBox.js new file mode 100644 index 00000000..8564dc53 --- /dev/null +++ b/src/components/containers/contractBox.js @@ -0,0 +1,78 @@ +import React, { useState } from "react"; +import PropTypes from "prop-types"; +import "../../style/components/contractBox.css"; +import { FaToggleOn, FaToggleOff, FaPencil, FaMagnifyingGlass } from "react-icons/fa6"; +import Button from "../Button"; + +const ContractBox = ({ numero, gestor, ativo, onReadClick, onEditClick, onToggleClick }) => { + const [isToggled, setIsToggled] = useState(ativo); + + const handleToggleClick = () => { + setIsToggled(prevState => !prevState); + if (onToggleClick) { + onToggleClick(); + } + }; + + const overlapGroupStyle = { + backgroundColor: isToggled ? "#ffffff" : "#d9d9d9" + }; + + return ( +
+
+
+
{numero}
+
{gestor}
+
+
+
+
+
+
+
+
+
+
+
+ ); +}; + +ContractBox.propTypes = { + numero: PropTypes.string, + gestor: PropTypes.string, + ativo: PropTypes.bool, + onReadClick: PropTypes.func, + onEditClick: PropTypes.func, + onToggleClick: PropTypes.func, +}; + +ContractBox.defaultProps = { + numero: "Default Numero", + gestor: "Default Gestor", + onReadClick: () => console.log('Read button clicked'), + onEditClick: () => console.log('Edit button clicked'), + onToggleClick: () => console.log('Toggle button clicked'), +}; + +export default ContractBox; diff --git a/src/components/forms/ContractForm.js b/src/components/forms/ContractForm.js new file mode 100644 index 00000000..3910b548 --- /dev/null +++ b/src/components/forms/ContractForm.js @@ -0,0 +1,147 @@ +import React, { useState } from "react"; +import { toast } from "react-toastify"; +import Navbar from "../navbar/Navbar"; +import "../../style/components/contractForm.css"; +import { createContract } from "../../services/contractService"; +import StatusDropdown from "../containers/StatusDropdown"; +import encodeSpecialChars from "../../utils/encode"; + +export default function ContractForm() { + const [numero, setNumero] = useState(''); + const [nomeGestor, setNomeGestor] = useState(''); + const [descricao, setDescricao] = useState(''); + const [dataInicio, setDataInicio] = useState(new Date(Date.now()).toISOString()); + const [dataTermino, setdataTermino] = useState(new Date(Date.now()).toISOString()); + const [ativo, setAtivo] = useState(false); + + + + const handleSubmit = async (e) => { + e.preventDefault(); + const formData = { + numero, + nomeGestor, + descricao, + dataInicio: new Date(dataInicio).toISOString(), + dataTermino: new Date(dataTermino).toISOString(), + ativo + }; + console.log("Form data:", formData); + + const response = await createContract(formData); + + if(response.type === "success") { + toast.success("Contrato criado com sucesso!") + setTimeout(() => { + const encodedParam = encodeSpecialChars(formData.numero) + const encodedUrl = `/verContrato/${encodedParam}`; + console.log(encodedUrl) + window.location = encodedUrl + }, 1000); + } else { + if(response.error.response.status === 400){ + toast.error("Este número de contrato ja existe!") + } + else{ + toast.error("Erro ao criar contrato!") + } + } + }; + + const navigateToContractList = () => { + window.location = "/listagemContrato" + }; + + const handleStatus = (e) => { + console.log("value", e.target.value) + if(e.target.value === "ativo"){ + setAtivo(true) + } + else if(e.target.value === "inativo"){ + setAtivo(false) + } + } + + return ( + <> + +
+
+

Cadastro de Contrato

+
+
+
+
+ + +
+ + +
+ + +
+
+
+
+ + +
+
+ + ); +} diff --git a/src/components/forms/EditContractForm.js b/src/components/forms/EditContractForm.js new file mode 100644 index 00000000..b886d950 --- /dev/null +++ b/src/components/forms/EditContractForm.js @@ -0,0 +1,169 @@ +import React, { useState } from "react"; +import { toast } from "react-toastify"; +import Navbar from "../navbar/Navbar"; +import "../../style/components/editContractForm.css"; +import { editContract } from "../../services/contractService"; +import { useLocation } from 'react-router-dom'; +import StatusDropdown from "../containers/StatusDropdown"; +import formatDate from "../../utils/formatDate"; + +export default function EditContractForm() { + const location = useLocation(); + const { contract } = location.state + const [numero, setNumero] = useState(contract.numero); + const [nomeGestor, setNomeGestor] = useState(contract.nomeGestor); + const [descricao, setDescricao] = useState(contract.descricao); + const [dataInicio, setDataInicio] = useState(contract.dataInicio); + const [dataTermino, setDataTermino] = useState(contract.dataTermino); + const [ativo, setAtivo] = useState(contract.ativo) + + const handleNumberChange = (e) => { + console.log(`Mudou o numero agora ele é ${e.target.value}`) + setNumero(e.target.value) + } + + const handleNomeGestorChange = (e) => { + e.preventDefault(); + setNomeGestor(e.target.value) + } + + const handleDescricaoChange = (e) => { + e.preventDefault(); + setDescricao(e.target.value) + } + + const handleDataInicioChange = (e) => { + e.preventDefault(); + setDataInicio(e.target.value) + } + + const handleDataTerminoChange = (e) => { + e.preventDefault(); + setDataTermino(e.target.value) + } + + const navigateToContractList = () => { + window.location = "/listagemContrato" + } + + const handleStatus = (e) => { + console.log("value", e.target.value) + if(e.target.value === "ativo"){ + setAtivo(true) + } + else if(e.target.value === "inativo"){ + setAtivo(false) + } + } + + const handleSubmit = async (e) => { + e.preventDefault(); + + const formData = { + numero, + nomeGestor, + descricao, + dataInicio: new Date(dataInicio).toISOString(), + dataTermino: new Date(dataTermino).toISOString(), + ativo + } + + if(new Date(dataTermino).getTime() < new Date(Date.now()).getTime()){ + toast.error("Não é possivel ativar um contrato com a data vencida!") + } + else{ + const response = await editContract(contract.id, formData); + + if(response.type === "success") { + toast.success("Contrato editado com sucesso!") + setTimeout(() => { + window.location = "listagemContrato" + }, 1000); + } + else{ + console.log(response.error) + toast.error("Erro ao editar contrato!") + } + } + }; + + return ( + <> + +
+

Edição de Contrato

+
+
+ + +
+ + +
+ + +
+
+
+ + +
+
+ + ); +} diff --git a/src/components/forms/EditPatternForm.js b/src/components/forms/EditPatternForm.js index 13bad824..664f740f 100644 --- a/src/components/forms/EditPatternForm.js +++ b/src/components/forms/EditPatternForm.js @@ -1,13 +1,14 @@ import { yupResolver } from "@hookform/resolvers/yup"; -import React, { useEffect } from "react"; +import React, { useEffect, useState } from "react"; import { useForm } from "react-hook-form"; -import { Link, useNavigate, useParams } from 'react-router-dom'; +import { Link, useLocation, useNavigate, useParams } from 'react-router-dom'; import "../../style/components/printerPatternForm.css"; import elipse6 from "../../assets/elipse6.svg"; import { getRegisterPatternSchema } from "../utils/YupSchema"; -import { editPadrao } from "../../services/printerService"; +import { editPadrao} from "../../services/patternService"; import { toast } from "react-toastify"; + const fieldLabels = { tipo: "Tipo", marca: "Marca", @@ -25,32 +26,82 @@ const fieldLabels = { totalGeral: "Total geral", enderecoIp: "Endereço IP", }, -}; +} export default function EditPatternForm() { + + const navigate = useNavigate(); + const location = useLocation(); - const { padrao } = useParams(); + const altLocation = { + id:"", + marca: "", + modelo: "", + tipo: "", + colorido: false, + oidModelo: "", + oidNumeroSerie: "", + oidFirmware: "", + oidTempoAtivo: "", + oidDigitalizacoes: "", + oidCopiasPB: "", + oidCopiasCor: "", + oidTotalGeral: "" + } - const pattern = JSON.parse(atob(padrao)); - console.log(pattern); - const navigate = useNavigate(); - const registerPrinterSchema = getRegisterPatternSchema(fieldLabels); + const previousPattern = location.state || altLocation; + + const id = previousPattern.id + const [marca, setMarca] = useState(previousPattern.marca) + const [type, setType] = useState(previousPattern.tipo) + const [modelo, setModelo] = useState(previousPattern.modelo) + const [isColorido, setIsColorido] = useState(previousPattern.colorido) + const [oidModelo, setOidModelo] = useState(previousPattern.oidModelo) + const [oidNumeroSerie, setOidNumeroSerie] = useState(previousPattern.oidNumeroSerie) + const [oidFirmware, setOidFirmware] = useState(previousPattern.oidFirmware) + const [oidTempoAtivo, setOidTempoAtivo] = useState(previousPattern.oidTempoAtivo) + const [oidDigitalizacoes, setOidDigitalizacoes] = useState(previousPattern.oidDigitalizacoes) + const [oidCopiasPB, setOidCopiasPB] = useState(previousPattern.oidCopiasPB) + const [oidCopiasCor, setOidCopiasCor] = useState(previousPattern.oidCopiasCor) + const [oidTotalGeral, setOidTotalGeral] = useState(previousPattern.oidTotalGeral) + + + const registerPrinterSchema = getRegisterPatternSchema(fieldLabels); const { - register, - handleSubmit, - setValue, formState: { errors, isSubmitting }, } = useForm({ resolver: yupResolver(registerPrinterSchema), - mode: "onSubmit", }); - const onSubmit = async (data) => { + const updateData = () => { + return { + "tipo": type, + "marca": marca, + "modelo": modelo, + "colorido": isColorido, + "oidModelo": oidModelo || null, + "oidNumeroSerie": oidNumeroSerie || null, + "oidFirmware": oidFirmware || null, + "oidTempoAtivo": oidTempoAtivo || null, + "oidDigitalizacoes": oidDigitalizacoes || null, + "oidCopiasPB": oidCopiasPB || null, + "oidCopiasCor": oidCopiasCor || null, + "oidTotalGeral": oidTotalGeral || null + } + } + + + + + const onSubmit = async (e) => { + e.preventDefault(); + const data = updateData() console.log(data); - - const response = await editPadrao(data); + + const response = await editPadrao(data, id); + if (response.type === "success") { toast.success("Padrão editado com sucesso!"); setTimeout(() => { @@ -59,70 +110,138 @@ export default function EditPatternForm() { } else { toast.error("Erro ao editar o padrão!"); } - }; - useEffect(() => { - Object.entries(pattern).forEach(([key, value]) => { - setValue(key, value); - }); - }, [setValue]); + const fieldsObrigatorios = ()=>{ + if(marca === ""){return false} + if(modelo === ""){return false} + if(type === ""){return false} + return true + } + + return (

Edição de padrão de impressora

-
-
-
-
- {Object.entries(fieldLabels).filter(([key]) => key !== "snmp").map(([key, label]) => ( -
- + +
+
+ + setType(e.target.value)}/> +
+
+ + setMarca(e.target.value)}/> +
+ +
+ - {errors[key]?.message} + placeholder={`Digite ${"Modelo".toLowerCase()}`} + value={modelo} + onChange={(e)=>setModelo(e.target.value)}/> +
+ +
+ + +
+
+ +
+ + +
+ + setOidModelo(e.target.value)}/>
- ))} -
- -
- - {Object.entries(fieldLabels.snmp).map(([key, label]) => ( -
- + +
+ + setOidNumeroSerie(e.target.value)}/> +
+ +
+ + setOidFirmware(e.target.value)}/> +
+ +
+ - {errors[key]?.message} + value={oidTempoAtivo} + onChange={(e)=>setOidTempoAtivo(e.target.value)}/> +
+ +
+ + setOidDigitalizacoes(e.target.value)}/> +
+ +
+ + setOidCopiasPB(e.target.value)}/> +
+ +
+ + setOidCopiasCor(e.target.value)}/> +
+ +
+ + setOidTotalGeral(e.target.value)}/>
- ))} -
-
+ +
-
+
elipse diff --git a/src/components/forms/EditPrinterForm.js b/src/components/forms/EditPrinterForm.js index 04f91929..6a3aedfe 100644 --- a/src/components/forms/EditPrinterForm.js +++ b/src/components/forms/EditPrinterForm.js @@ -1,180 +1,428 @@ -import React, { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; -import { yupResolver } from "@hookform/resolvers/yup"; -import "../../style/components/editPrinterForms.css"; -import elipse6 from '../../assets/elipse6.svg'; -import { getPrinterSchema } from "../utils/YupSchema"; -import { Link, useNavigate, useParams } from "react-router-dom"; -import PropTypes from 'prop-types'; -import { getUnidades } from "../../services/unidadeService"; -import { editImpressora, getPadroes } from "../../services/printerService"; -import { formatDate } from "../../utils/utils"; -import { toast } from "react-toastify"; - -const fieldLabels = { - padrao_id: 'Padrão', - ip: 'IP', - numeroSerie: 'Número de Série', - codigoLocadora: 'Código da Locadora', - contadorInstalacao: 'Contador de Instalação', - dataInstalacao: 'Data de Instalação', - contadorRetiradas: 'Contador de Retirada', - dataContadorRetirada: 'Data de Retirada', - ultimoContador: 'Último Contador', - dataUltimoContador: 'Data do Último Contador', - unidadePai: 'Unidade Pai', - unidadeId: 'Unidade Filho', +import React, {useEffect, useState} from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; +import '../../style/pages/viewPrinter.css'; +import "../../style/components/registerPrinterForms.css"; +import Navbar from "../navbar/Navbar"; +import ViewDataContainer from '../containers/ViewDataContainer.js'; +import SmallInfoCard from '../cards/SmallInfoCard.js'; +import BigInfoCard from '../cards/BigInfoCard.js'; +import Button from '../Button.js'; +import { getPrinterById } from '../../services/printerService.js'; +import InputContainer from '../containers/InputContainer.js'; +import SelectContainer from '../containers/SelectContainer.js'; +import { getLocalizacao } from "../../services/printerService"; +import DateContainer from '../containers/DateContainer.js'; + +// Mock de dados da impressora +const mockPrinterData = { + equipamento: "Impressora XYZ", + numeroSerie: "123456789", + modelo: "Modelo ABC", + localizacao: "Goias", + contrato: "Contrato XYZ-123", + enderecoIp: "192.168.0.1", + dentroDaRede: "Sim", + dataInstalacao: "2023-01-15", + dataRetirada: "2024-01-15", + status: "Ativo", + marca: "Marca ABC", + cidade: "Cidade XYZ", + regional: "Regional 1", + subestacao: "Subestação A" }; +// Função para codificar um objeto em Base64 +function encodeToBase64(obj) { + return btoa(JSON.stringify(obj)); +} + +// Codificar os dados da impressora +const encodedPrinterData = encodeToBase64(mockPrinterData); + +console.log(encodedPrinterData); // A string codificada para usar na URL + export default function EditPrinterForm() { - const { printer } = useParams(); + const [printerData, setPrinterData] = useState({ + numContrato: '', + numSerie: '', + enderecoIp: '', + estaNaRede: false, + dataInstalacao: '', + dataRetirada: null, + ativo: false, + contadorInstalacaoPB: 0, + contadorInstalacaoCor: 0, + contadorAtualPB: 0, + contadorAtualCor: 0, + contadorRetiradaPB: 0, + contadorRetiradaCor: 0, + localizacao: '', + modeloId: '', + cidade: '', + regional: '', + subestacao: '' +}); +const [numSerie, setNumSerie] = useState(''); +const [selectedContrato, setSelectedContrato] = useState(''); +const [localizacoes, setLocalizacoes] = useState([]); +const [marcas, setMarcas] = useState([]); +const [contratos, setContratos] = useState([]); +const [enderecoIP, setEnderecoIP] = useState(''); +const [selectedDentroRede, setSelectedDentroRede] = useState('Sim'); +const yesNo = ["Sim", "Não"]; +const [dataInstalacao, setDataInstalacao] = useState(''); +const [status, setStatus] = useState('Ativo'); +const [selectedCidade, setSelectedCidade] = useState(''); +const [workstations, setWorkstations] = useState([]); +const [selectedWorkstation, setSelectedWorkstation] = useState(''); +const [subWorkstations, setSubWorkstations] = useState([]); +const [selectedSubWorkstation, setSelectedSubWorkstation] = useState(''); - const navigate = useNavigate(); - const printerObject = JSON.parse(atob(printer)); - - const [unidadeList, setUnidadeList] = useState([]); - const [padroes, setPadroes] = useState([]); - const [unidadesFilha, setUnidadesFilhas] = useState([]); - const [padrao, setPadrao] = useState(printerObject.padrao_id); - const [unidade, setUnidade] = useState(printerObject.unidadeId); - const [inicializou, setInicializou] = useState(false); - - const editPrinterSchema = getPrinterSchema(fieldLabels); - const { register, setValue, handleSubmit, formState: { errors, isSubmitting }, reset } = useForm({ - resolver: yupResolver(editPrinterSchema), - mode: "onSubmit" - }); - - useEffect( () => { - async function setData() { - const [dataUnidades, dataPadrao] = await Promise.all([ - getUnidades(), - getPadroes(), - ]); - - if (dataUnidades.type ==='success' && dataUnidades.data) { - setUnidadeList(dataUnidades.data); - setUnidadesFilhas(dataUnidades.data); - } - if (dataPadrao.type ==='success' && dataPadrao.data) { - setPadroes(dataPadrao.data); - } - } - setData(); - }, []); - - useEffect(() => { - if (padroes.length > 0 && unidadeList.length > 0 && !inicializou) { - Object.entries(printerObject).forEach(([key, value]) => { - if (key.includes('data')) { - value = formatDate(value); - } - setValue(key, value); - }); - setInicializou(true); - } - }, [setValue, printerObject]); - - const handleWorkstationChange = (event) => { - if (event.target.value) { - - const selectedUnit = unidadeList.find(uni => uni.id === event.target.value); - if (selectedUnit) { - const combinedList = [selectedUnit, ...selectedUnit.child_workstations]; - setUnidadesFilhas(combinedList); - } else { - setUnidadesFilhas([]); - } - } else { - setUnidadesFilhas([]); - } +const {id} = useParams() + +useEffect(() => { + const fetchLocalizacoes = async () => { + try { + const response = await getLocalizacao(); + setLocalizacoes(response.data); + } catch (error) { + console.error('Erro ao buscar localizações:', error); + } }; + const fetchMarcas = async () => { + try { + const data = [ + { + marca: 'HP', + modelos: ['Model A', 'Model B', 'Model C'] + }, + { + marca: 'Canon', + modelos: ['Model X', 'Model Y'] + } + ]; + setMarcas(data); + } catch (error) { + console.error('Erro ao buscar marcas:', error); + } + }; - const onSubmit = async (data) => { - data.padrao_id = padrao; - data.unidadeId = unidade; - data.dataInstalacao = new Date(data.dataInstalacao).toISOString(); - data.dataContadorRetirada = new Date(data.dataContadorRetirada).toISOString(); - data.dataUltimoContador = new Date(data.dataUltimoContador).toISOString(); - const response = await editImpressora(data); - if (response.type === "success") { - toast.success("Impressora editada com sucesso!"); - setTimeout(() => { - reset(); - navigate("/impressorascadastradas"); - }, 1000); - } else { - toast.error("Erro ao editar impressora!"); - } + const fetchContratos = async () => { + try { + const data = [ + 'A1B2C3D4', + 'E5F6G7H8', + 'I9J0K1L2', + 'M3N4O5P6', + 'Q7R8S9T0', + 'U1V2W3X4', + 'Y5Z6A7B8', + 'C9D0E1F2' + ]; + setContratos(data); + } catch (error) { + console.error('Erro ao buscar contratos:', error); + } + }; + + fetchMarcas(); + fetchContratos(); + fetchLocalizacoes(); +}, []); + +useEffect(() => { + const fetchData = async () => { + const response = await getPrinterById(id); + if (response.type === 'success') { + const { localizacao, ...restData } = response.data; + const [cidade, regional, subestacao] = localizacao.split(';'); + + setPrinterData({ + ...restData, + cidade: cidade || '', + regional: regional || '', + subestacao: subestacao || '' + }); + } + }; + fetchData(); +}, [id]); + +const handleNumSerieChange = (newValue) => { + setNumSerie(newValue); +}; + +const handleContratoChange = (event) => { + setSelectedContrato(event.target.value); +}; + +const handleEnderecoIPChange = (newValue) => { + setEnderecoIP(newValue); +}; + +const handleStatusChange = (event) => { + const newStatus = event.target.value; + setStatus(newStatus); +}; + +const handleDentroRedeChange = (event) => { + const value = event.target.value; + setSelectedDentroRede(value); + + if (value === "Não") { + setEnderecoIP(''); } +}; + +const handleLocalizacaoChange = (event) => { + const cidadeSelecionada = event.target.value; + setSelectedCidade(cidadeSelecionada); + + const localizacao = localizacoes.find(m => m.name === cidadeSelecionada); + setWorkstations(localizacao ? localizacao.workstations : []); + setSubWorkstations([]); + + setSelectedWorkstation(''); +}; + +const handleWorkstationChange = (event) => { + const workstationSelecionada = event.target.value; + setSelectedWorkstation(workstationSelecionada); + + const subworkstations = workstations.find(m => m.name === workstationSelecionada); + setSubWorkstations(subworkstations ? subworkstations.child_workstations : []); +}; + +const handleSubWorkstationChange = (event) => { + const workstationSelecionada = event.target.value; + setSelectedSubWorkstation(workstationSelecionada); +}; + +const dataRetiradaClass = mockPrinterData.status === "Ativo" ? "inactive-field" : ""; +const dataRetiradaValue = mockPrinterData.status === "Ativo" ? "Equipamento ainda ativo" : mockPrinterData.dataRetirada; + + // Labels dos campos de informação + const infoLabels = { + equipamento: "Equipamento", + numeroSerie: "Número de série", + modelo: "Modelo", + localizacao: "Localização", + contrato: "Contrato", + enderecoIp: "Endereço IP", + dentroDaRede: "Dentro da rede", + dataInstalacao: "Data de instalação", + dataRetirada: "Data de retirada", + status: "Status", + marca: "Marca", + cidade: "Cidade", + regional: "Regional", + subestacao: "Subestação" + }; + + const navigate = useNavigate(); + + const handleExitForm = () => { + navigate('/listimpressora'); + }; + + const handleEditButton = () => { + navigate('/editimpressora'); + }; + + const enderecoIPClass = selectedDentroRede === "Não" ? "disabled" : ""; return ( -
- - - - Voltar - -
- Editar impressora -
-
-
- {Object.entries(fieldLabels).map(([key, label]) => ( -
-
-
- - {key === "padrao_id" ? ( - - ) : key === "unidadePai" ? ( - - ) : key === "unidadeId" ? ( - - ) : ( - - )} - {errors[key]?.message} -
+ <> +
+
+ Editar Equipamento +
+ + + +
+
+
+
+ + + + + + + + + + +
+ + +
+ + setDataInstalacao(e.target.value)} + className="md" + /> + +
+ setDataInstalacao(e.target.value)} + className="md" + /> + +
- ))} +
+
+ + + + + +
-
- - + +
Localização
+
+ m.name)} + className="md-select" + label="Cidade" + onChange={handleLocalizacaoChange} + value={printerData.cidade} + /> + + m.name)} + className="lg-select" + label="Regional" + onChange={handleWorkstationChange} + value={printerData.subestacao} + /> + + m.name)} + className="lg-select" + label="Subestação" + onChange={handleSubWorkstationChange} + value={printerData.subestacao} + /> +
+
+
+
- -
- elipse + +
-
+ ); } diff --git a/src/components/forms/ListEquipment.js b/src/components/forms/ListEquipment.js new file mode 100644 index 00000000..2050427b --- /dev/null +++ b/src/components/forms/ListEquipment.js @@ -0,0 +1,51 @@ +import React, { useEffect, useState } from "react"; +import ItemBox from "../containers/ItemBox"; +import { getPrinters } from "../../services/printerService"; +import "../../style/components/listEquipment.css"; +import { FaWindows } from "react-icons/fa6"; + +const ListEquipment = () => { + const [printers, setPrinters] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchData = async () => { + const response = await getPrinters(); + if (response.type === 'success') { + setPrinters(response.data); + } else { + setError(response.error || response.data); + } + setLoading(false); + }; + + fetchData(); + }, []); + + const handleEditClick = (id) => { + window.location = `/visualizarimpressora/${id}` + }; + + const handleToggleClick = (id) => { + console.log(`Toggle button clicked for equipment ID: ${id}`); + }; + + if (loading) return

Loading...

; + if (error) return

Error loading data: {error.message || 'Unknown error'}

; + + return ( +
+ {printers.map((printer) => ( + handleEditClick(printer.id)} + onToggleClick={() => handleToggleClick(printer.id)} + /> + ))} +
+ ); +}; + +export default ListEquipment; diff --git a/src/components/forms/PrinterPatternForm.js b/src/components/forms/PrinterPatternForm.js index 69ee2bf6..967d2142 100644 --- a/src/components/forms/PrinterPatternForm.js +++ b/src/components/forms/PrinterPatternForm.js @@ -1,12 +1,12 @@ import { yupResolver } from "@hookform/resolvers/yup"; -import React from "react"; +import React, { useState } from "react"; import { useForm } from "react-hook-form"; -import { Link } from 'react-router-dom'; +import { Link, useNavigate } from 'react-router-dom'; import "../../style/components/printerPatternForm.css"; import elipse6 from "../../assets/elipse6.svg"; import { getRegisterPatternSchema } from "../utils/YupSchema"; import { ReloadIcon } from "@radix-ui/react-icons"; -import { createPadraoImpressora } from "../../services/printerService"; +import { createPadraoImpressora } from "../../services/patternService"; import { toast } from "react-toastify"; const fieldLabels = { @@ -21,19 +21,28 @@ const fieldLabels = { totalDigitalizacoes: "Total de digitalizações", totalCopiasPB: "Total de cópias P&B", totalCopiasColoridas: "Total de cópias coloridas", - totalImpressoesPb: "Total de impressões P&B", - totalImpressoesColoridas: "Total de impressões coloridas", totalGeral: "Total geral", - enderecoIp: "Endereço IP", }, }; export default function PrinterPatternForm() { + const [tipo, setTipo] = useState("") + const [marca, setMarca] = useState("") + const [modelo, setModelo] = useState("") + const [isColorido, setIsColorido] = useState(false) + const [oidModelo, setOidModelo] = useState("") + const [oidNumeroSerie, setOidNumeroSerie] = useState("") + const [oidFirmware, setOidFirmware] = useState("") + const [oidTempoAtivo, setOidTempoAtivo] = useState("") + const [oidDigitalizacoes, setOidDigitalizacoes] = useState("") + const [oidCopiasPB, setOidCopiasPB] = useState("") + const [oidCopiasCor, setOidCopiasCor] = useState("") + const [oidTotalGeral, setOidTotalGeral] = useState("") + const navigate = useNavigate() + const registerPrinterSchema = getRegisterPatternSchema(fieldLabels); const { - register, - handleSubmit, formState: { errors, isValid, isSubmitting }, reset, } = useForm({ @@ -41,70 +50,165 @@ export default function PrinterPatternForm() { mode: "onChange", }); - const onSubmit = async (data) => { - console.log(data); - const response = await createPadraoImpressora(data) - if(response.type === "success") { - toast.success("Padrao de impressora criado com sucesso!") - reset(); - } else { - toast.error("Erro ao criar o padrao de impressora!") + const createData = ()=>{ + return{ + "tipo": tipo, + "marca": marca , + "modelo": modelo , + "colorido": isColorido, + "oidModelo": oidModelo || null, + "oidNumeroSerie": oidNumeroSerie || null, + "oidFirmware": oidFirmware || null, + "oidTempoAtivo": oidTempoAtivo || null, + "oidDigitalizacoes": oidDigitalizacoes || null, + "oidCopiasPB": oidCopiasPB || null, + "oidCopiasCor": oidCopiasCor || null, + "oidTotalGeral": oidTotalGeral || null } - }; + } + const onSubmit = async (e) => { + e.preventDefault(); + const data = createData() + console.log(data) + const response = await createPadraoImpressora(data) + if(response.type === "success") { + toast.success("Padrao de impressora criado com sucesso!") + setTimeout(() => { + navigate("/padroescadastrados"); + }, 1000); + } else { + toast.error("Erro ao criar o padrao de impressora!") + } + }; + const fildsObrigatorios = ()=>{ + if(marca === ""){return false} + if(modelo === ""){return false} + if(tipo === ""){return false} + return true + } return (

Cadastrar padrão de impressora

-
-
-
-
- {Object.entries(fieldLabels).filter(([key]) => key !== "snmp").map(([key, label]) => ( -
- + + +
+
+ + setTipo(e.target.value)}/> +
+ +
+ + setMarca(e.target.value)}/> +
+ +
+ + setModelo(e.target.value)}/> +
+ +
+ + +
+
+ +
+ + +
+ - {errors[key]?.message} + placeholder="Código OID" + value={oidModelo} + onChange={(e)=>setOidModelo(e.target.value)}/>
- ))} -
- -
- - {Object.entries(fieldLabels.snmp).map(([key, label]) => ( -
- + +
+ - {errors[key]?.message} + value={oidNumeroSerie} + onChange={(e)=>setOidNumeroSerie(e.target.value)}/> +
+ +
+ + setOidFirmware(e.target.value)}/> +
+ +
+ + setOidTempoAtivo(e.target.value)}/> +
+ +
+ + setOidDigitalizacoes(e.target.value)}/> +
+ +
+ + setOidCopiasPB(e.target.value)}/> +
+ +
+ + setOidCopiasCor(e.target.value)}/> +
+ +
+ + setOidTotalGeral(e.target.value)}/>
- ))} -
-
+ +
-
+
elipse diff --git a/src/components/forms/ReadContractForm.js b/src/components/forms/ReadContractForm.js new file mode 100644 index 00000000..210b2e21 --- /dev/null +++ b/src/components/forms/ReadContractForm.js @@ -0,0 +1,68 @@ +import React from "react"; +import Navbar from "../navbar/Navbar.js"; +import "../../style/components/readContractForm.css"; + +const mockContract = [ + { id: 1, numero: "09/2001 SSP", nomeGestor: "João Augusto", descricao: "Impressoras laser mono." , dataInicio: "01/01/2024", dataTermino: "28/07/2024"}, +]; + +const ReadContractForm = () => { + const navigateToEditContractListForm = () => { + window.location = "/editarContrato" + }; + const navigateToContractListForm = () => { + window.location = "/listagemContrato" + }; + + return ( + <> + +
+
+

Visualização de Contrato

+
+
+
+
+
+

Contrato

+

09/2001 SSP

+
+
+

Gestor do Contrato

+

João Augusto

+
+
+
+
+
+

Data de Início:

+

01/01/2024

+
+
+

Data de Término:

+

31/12/2027

+
+
+
+

Status

+

Ativo

+
+
+
+
+

Descrição do Contrato (Processo)

+

Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry Lorem Ipsum is simply dummy text of the printing and typesetting industry

+
+
+
+ + +
+
+ + ); +}; + +export default ReadContractForm; + diff --git a/src/components/forms/RegisterPrinterForm.js b/src/components/forms/RegisterPrinterForm.js index 5b9583a3..2b139893 100644 --- a/src/components/forms/RegisterPrinterForm.js +++ b/src/components/forms/RegisterPrinterForm.js @@ -1,180 +1,434 @@ -import { yupResolver } from "@hookform/resolvers/yup"; -import React, { useEffect, useState } from "react"; -import { useForm } from "react-hook-form"; - -import { ReloadIcon } from "@radix-ui/react-icons"; -import elipse6 from "../../assets/elipse6.svg"; -import { createImpressora, getPadroes } from "../../services/printerService"; -import { getUnidades } from "../../services/unidadeService"; -import { getUsers } from "../../services/userService"; +import React, { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; import "../../style/components/registerPrinterForms.css"; -import { getPrinterSchema } from "../utils/YupSchema"; -import { Link } from 'react-router-dom'; +import SelectContainer from '../containers/SelectContainer'; +import InputContainer from '../containers/InputContainer'; +import DateContainer from '../containers/DateContainer'; +import NumberContainer from '../containers/NumberContainer'; import { toast } from "react-toastify"; +import Button from '../Button'; +import { createImpressora, getLocalizacao } from "../../services/printerService"; -const fieldLabels = { - numeroSerie: "Número de Série", - ip: "IP", - padrao_id: "Padrão", - codigoLocadora: "Código da Locadora", - contadorInstalacao: "Contador de Instalação", - dataInstalacao: "Data de Instalação", - contadorRetiradas: "Contador de Retirada", - dataContadorRetirada: "Data de Retirada", - ultimoContador: "Último Contador", - dataUltimoContador: "Data do Último Contador", - unidadePai: "Unidade Pai", - unidadeId: "Unidade Filho", -}; - +export default function RegisterPrinterForm() { + const [marcas, setMarcas] = useState([]); + const [modelos, setModelos] = useState([]); + const [contratos, setContratos] = useState([]); + const [selectedContrato, setSelectedContrato] = useState(''); + const [selectedMarca, setSelectedMarca] = useState(''); + const [selectedModelo, setSelectedModelo] = useState(''); + const [enderecoIP, setEnderecoIP] = useState(''); + const [numSerie, setNumSerie] = useState(''); + const [localizacoes, setLocalizacoes] = useState([]); + const [selectedCidade, setSelectedCidade] = useState(''); + const [workstations, setWorkstations] = useState([]); + const [selectedWorkstation, setSelectedWorkstation] = useState(''); + const [subWorkstations, setSubWorkstations] = useState([]); + const [selectedSubWorkstation, setSelectedSubWorkstation] = useState(''); + const [selectedDentroRede, setSelectedDentroRede] = useState('Sim'); + const [dataInstalacao, setDataInstalacao] = useState(''); + const [dataRetirada, setDataRetirada] = useState(''); + const [contadorInstalacaoPB, setContadorInstalacaoPB] = useState(''); + const [contadorInstalacaoCor, setContadorInstalacaoCor] = useState(''); + const [contadorRetirada, setContadorRetirada] = useState(''); + const [status, setStatus] = useState('Ativo'); // Estado para armazenar o status + const [errors, setErrors] = useState({}); + const yesNo = ["Sim", "Não"]; + const navigate = useNavigate(); -export default function RegisterPrinterForm() { - const [unidades, setUnidades] = useState([]); - const [padroes, setPadroes] = useState([]); - const [locadora, setLocadoras] = useState([]); - const [unidadeInList, setUnidadeInList] = useState([]); - - useEffect( () => { - async function setData() { - try { - const [dataUnidades, dataPadrao, dataUsers] = await Promise.all([ - getUnidades(), - getPadroes(), - getUsers() - ]); - - if (dataUnidades.type ==='success' && dataUnidades.data) { - setUnidades(dataUnidades.data); + useEffect(() => { + const fetchLocalizacoes = async () => { + try { + const response = await getLocalizacao(); + setLocalizacoes(response.data); + } catch (error) { + console.error('Erro ao buscar localizações:', error); } + }; - if (dataPadrao.type ==='success' && dataPadrao.data) { - setPadroes(dataPadrao.data); + const fetchMarcas = async () => { + try { + const data = [ + { + marca: 'HP', + modelos: ['Model A', 'Model B', 'Model C'] + }, + { + marca: 'Canon', + modelos: ['Model X', 'Model Y'] + } + ]; + setMarcas(data); + } catch (error) { + console.error('Erro ao buscar marcas:', error); } - if (dataUsers.type ==='success' && dataUsers.data) { - const locadoras = dataUsers.data.filter(user => - user.cargos.includes("LOCADORA") - ); - setLocadoras(locadoras); + }; + + const fetchContratos = async () => { + try { + const data = [ + 'A1B2C3D4', + 'E5F6G7H8', + 'I9J0K1L2', + 'M3N4O5P6', + 'Q7R8S9T0', + 'U1V2W3X4', + 'Y5Z6A7B8', + 'C9D0E1F2' + ]; + setContratos(data); + } catch (error) { + console.error('Erro ao buscar contratos:', error); } + }; + + fetchMarcas(); + fetchContratos(); + fetchLocalizacoes(); + }, []); + + + const validateForm = () => { + const newErrors = {}; + if (!selectedContrato) newErrors.contrato = 'Contrato é obrigatório'; + if (!selectedMarca) newErrors.marca = 'Marca é obrigatória'; + if (!selectedModelo) newErrors.modelo = 'Modelo é obrigatório'; + if (!enderecoIP && selectedDentroRede === "Sim") newErrors.enderecoIP = 'Endereço IP é obrigatório'; + if (!numSerie) newErrors.numSerie = 'Número de série é obrigatório'; + if (!selectedCidade) newErrors.cidade = 'Cidade é obrigatória'; + if (!selectedWorkstation) newErrors.workstation = 'Posto de trabalho é obrigatório'; + if (!dataInstalacao) newErrors.dataInstalacao = 'Data de instalação é obrigatória'; + if (!contadorInstalacaoCor) newErrors.contadorInstalacaoCor = 'Contador de instalação é obrigatório'; + if (!contadorInstalacaoPB) newErrors.contadorInstalacaoPB = 'Contador de instalação é obrigatório'; + if (status === 'Inativo') { + if (!dataRetirada) newErrors.dataRetirada = 'Data de retirada é obrigatória'; + if (!contadorRetirada) newErrors.contadorRetirada = 'Contador de retirada é obrigatório'; + } + + setErrors(newErrors); + return Object.keys(newErrors).length === 0; // Retorna true se não houver erros + }; + + const handleFormSubmit = async () => { + try { + if (validateForm()) { + let data = { + numContrato: selectedContrato, + // marca: selectedMarca, + modeloId: selectedModelo, + enderecoIp: enderecoIP, + numSerie: numSerie, + estaNaRede: selectedDentroRede == "Sim" ? true : false, + localizacao: selectedCidade + ';' + selectedWorkstation + (selectedSubWorkstation ? ';' + selectedSubWorkstation : ';'), + // cidade: selectedCidade, + // regional: selectedWorkstation, + // ...(selectedSubWorkstation !== "" && { subestacao: selectedSubWorkstation }), + dataInstalacao: dataInstalacao, + contadorInstalacaoPB: contadorInstalacaoPB, + contadorInstalacaoCor: contadorInstalacaoCor, + contadorRetiradaPB: 0, + contadorRetiradaCor: 0, + contadorAtualPB: 0, + contadorAtualCor: 0, + ...(dataRetirada !== "" && { dataRetirada: dataRetirada }), + ativo: status == "Ativo" ? true : false, + ...(contadorRetirada !== "" && { contadorRetiradaPB: contadorRetirada }), + ...(contadorRetirada !== "" && { contadorRetiradaCor: contadorRetirada }), + }; + + const res = await createImpressora(data); + console.log(res) + if (res.type == "error") { + toast.error(res.error.response.data.message); + } else { + navigate('/impressorascadastradas'); + } + } else { + toast.error("Erro ao criar impressora!"); + } } catch (error) { - console.error('Erro ao obter opções do serviço:', error); - } - } - setData(); - }, []); - - const handleWorkstationChange = (event) => { - if (event.target.value) { - const selectedUnit = unidades.find(uni => uni.id === event.target.value); - if (selectedUnit) { - const combinedList = [selectedUnit, ...selectedUnit.child_workstations]; - setUnidadeInList(combinedList); - } else { - setUnidadeInList([]); + // Trate o erro aqui, por exemplo, mostrar uma mensagem para o usuário + console.error("Erro ao criar impressora:", error); + toast.error("Ocorreu um erro ao criar a impressora. Tente novamente."); + } + }; + + const handleExitForm = () => { + navigate('/impressorascadastradas'); + }; + + const handleContratoChange = (event) => { + setSelectedContrato(event.target.value); + }; + + const handleMarcaChange = (event) => { + const marcaSelecionada = event.target.value; + setSelectedMarca(marcaSelecionada); + + const marca = marcas.find(m => m.marca === marcaSelecionada); + setModelos(marca ? marca.modelos : []); + }; + + const handleModeloChange = (event) => { + setSelectedModelo(event.target.value); + }; + + const handleEnderecoIPChange = (newValue) => { + setEnderecoIP(newValue); + }; + + const handleNumSerieChange = (newValue) => { + setNumSerie(newValue); + }; + + const handleContadorInstalacaoPBChange = (event) => { + setContadorInstalacaoPB(event.target.value); + }; + + const handleContadorInstalacaoCorChange = (event) => { + setContadorInstalacaoCor(event.target.value); + }; + + const handleContadorRetiradaChange = (event) => { + setContadorRetirada(event.target.value); + }; + + const handleLocalizacaoChange = (event) => { + const cidadeSelecionada = event.target.value; + setSelectedCidade(cidadeSelecionada); + + const localizacao = localizacoes.find(m => m.name === cidadeSelecionada); + setWorkstations(localizacao ? localizacao.workstations : []); + setSubWorkstations([]); + + setSelectedWorkstation(''); + setSelectedSubWorkstation(''); + }; + + const handleWorkstationChange = (event) => { + const workstationSelecionada = event.target.value; + setSelectedWorkstation(workstationSelecionada); + + const subworkstations = workstations.find(m => m.name === workstationSelecionada); + setSubWorkstations(subworkstations ? subworkstations.child_workstations : []); + }; + + const handleSubWorkstationChange = (event) => { + const workstationSelecionada = event.target.value; + setSelectedSubWorkstation(workstationSelecionada); + }; + + const handleDentroRedeChange = (event) => { + const value = event.target.value; + setSelectedDentroRede(value); + + if (value === "Não") { + setEnderecoIP(''); } - } else { - setUnidadeInList([]); - } - }; - - const registerPrinterSchema = getPrinterSchema(fieldLabels); - const { - register, - handleSubmit, - formState: { errors, isValid, isSubmitting }, - reset, - } = useForm({ - resolver: yupResolver(registerPrinterSchema), - mode: "onChange", - }); - - const onSubmit = async (data) => { - data.dataInstalacao = new Date(data.dataInstalacao).toISOString(); - data.dataContadorRetirada = new Date(data.dataContadorRetirada).toISOString(); - data.dataUltimoContador = new Date(data.dataUltimoContador).toISOString(); - console.log(data); - const response = await createImpressora(data); - if (response.type === "success") { - toast.success("Impressora criada com sucesso!"); - reset(); - } else { - toast.error("Erro ao criar impressora! Por favor, tente novamente."); - } - }; - - return ( -
-
Cadastrar impressora
-
-
- {Object.entries(fieldLabels).map(([key, label]) => ( -
-
- - {key === "padrao_id" ? ( - - ) : key === "unidadePai" ? ( - - ) : key === "unidadeId" ? ( - - ) : ( - - )} - {errors[key]?.message} -
+ }; + + const handleStatusChange = (event) => { + const newStatus = event.target.value; + setStatus(newStatus); + }; + + const enderecoIPClass = selectedDentroRede === "Não" ? "disabled" : ""; + + // Condicionalmente aplicar ou remover a classe "disabled" com base no status + const retiradaClass = status === 'Ativo' ? 'disabled' : ''; + + return ( +
+
+ Cadastrar Equipamento + + + + m.marca)} + className="md-select" + label="Marca" + onChange={handleMarcaChange} + value={selectedMarca} + error={errors.marca} + /> + +
+ + + + + +
+ + + +
Localização
+
+ m.name)} + className="md-select" + label="Cidade" + onChange={handleLocalizacaoChange} + value={selectedCidade} + error={errors.cidade} + /> + + m.name)} + className="lg-select" + label="Posto de Trabalho" + onChange={handleWorkstationChange} + value={selectedWorkstation} + error={errors.workstation} + /> + + m.name)} + className="lg-select" + label="Subposto de Trabalho" + onChange={handleSubWorkstationChange} + value={selectedSubWorkstation} + error={errors.subWorkstation} + /> +
+ +
Instalação
+
+ setDataInstalacao(e.target.value)} + className="md" + error={errors.dataInstalacao} + /> + +
+
+ + + +
+ +
Retirada
+
+ + +
+
+ setDataRetirada(e.target.value)} + className={`md ${retiradaClass}`} + error={errors.dataRetirada} + /> + + + +
- ))} -
-
- - -
- -
- elipse -
-
- ); -} -export { fieldLabels }; +
+
+
+
+
+ ); +} diff --git a/src/components/navbar/Navbar.js b/src/components/navbar/Navbar.js index 72c9657e..528658a1 100644 --- a/src/components/navbar/Navbar.js +++ b/src/components/navbar/Navbar.js @@ -10,6 +10,7 @@ import { FiChevronDown } from "react-icons/fi"; const Navbar = () => { const [userDropdownOpen, setUserDropdownOpen] = useState(false); const [printerDropdownOpen, setPrinterDropdownOpen] = useState(false); + const [contractDropdownOpen, setContractDropdownOpen] = useState(false); let navigate = useNavigate(); @@ -31,6 +32,10 @@ const Navbar = () => { setPrinterDropdownOpen(!printerDropdownOpen) } + const toggleContractDropdown = () => { + setContractDropdownOpen(!printerDropdownOpen) + } + let user = null; const token = localStorage.getItem("jwt"); if (token) { @@ -97,6 +102,19 @@ const Navbar = () => { )}
+ +
+ +
)} diff --git a/src/components/ui/Modal.js b/src/components/ui/Modal.js index 6b445c9b..fb70351c 100644 --- a/src/components/ui/Modal.js +++ b/src/components/ui/Modal.js @@ -31,21 +31,22 @@ function Modal({ setOpenModal, title, bodytext, onConfirm }) { textColor="white" bgColor="#BF1B1B" borderColor="#BF1B1B" + + text="Cancelar" onClick={() => { setOpenModal(false); }} > - - Cancelar
diff --git a/src/components/utils/PrivateRoutes.js b/src/components/utils/PrivateRoutes.js index 576bc762..a9b1a052 100644 --- a/src/components/utils/PrivateRoutes.js +++ b/src/components/utils/PrivateRoutes.js @@ -6,7 +6,7 @@ const checkAuthentication = () => { const token = localStorage.getItem('jwt'); // Substitua por seu método de armazenamento if (!token) { - return false; // Token não existe + return true; // Token não existe } try { diff --git a/src/components/utils/YupSchema.js b/src/components/utils/YupSchema.js index 92e5457c..41e14030 100644 --- a/src/components/utils/YupSchema.js +++ b/src/components/utils/YupSchema.js @@ -20,42 +20,9 @@ export const getPrinterSchema = (printerFieldLabels) => { export const getRegisterPatternSchema = (fieldLabels) => { return yup.object().shape({ - tipo: yup.string().required(`${fieldLabels.tipo} é obrigatório`), - marca: yup.string().required(`${fieldLabels.marca} é obrigatório`), - modelo: yup.string().required(`${fieldLabels.modelo} é obrigatório`), - modeloImpressora: yup - .string() - .required(`${fieldLabels.snmp.modeloImpressora} é obrigatório`), - numeroSerie: yup - .string() - .required(`${fieldLabels.snmp.numeroSerie} é obrigatório`), - versaoFirmware: yup - .string() - .required(`${fieldLabels.snmp.versaoFirmware} é obrigatório`), - tempoAtivoSistema: yup - .string() - .required(`${fieldLabels.snmp.tempoAtivoSistema} é obrigatório`), - totalDigitalizacoes: yup - .string() - .required(`${fieldLabels.snmp.totalDigitalizacoes} é obrigatório`), - totalCopiasPB: yup - .string() - .required(`${fieldLabels.snmp.totalCopiasPB} é obrigatório`), - totalCopiasColoridas: yup - .string() - .required(`${fieldLabels.snmp.totalCopiasColoridas} é obrigatório`), - totalImpressoesPb: yup - .string() - .required(`${fieldLabels.snmp.totalImpressoesPb} é obrigatório`), - totalImpressoesColoridas: yup - .string() - .required(`${fieldLabels.snmp.totalImpressoesColoridas} é obrigatório`), - totalGeral: yup - .string() - .required(`${fieldLabels.snmp.totalGeral} é obrigatório`), - enderecoIp: yup - .string() - .required(`${fieldLabels.snmp.enderecoIp} é obrigatório`), + tipo: yup.string().required(`${fieldLabels.tipo} é obrigatório`), + marca: yup.string().required(`${fieldLabels.marca} é obrigatório`), + modelo: yup.string().required(`${fieldLabels.modelo} é obrigatório`), }); } diff --git a/src/index.css b/src/index.css index 90eb9c8d..58f4d6fe 100644 --- a/src/index.css +++ b/src/index.css @@ -1,7 +1,9 @@ +@import url('https://fonts.googleapis.com/css2?family=Jost:wght@400;700&display=swap'); + html, body { margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + font-family: 'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; -webkit-font-smoothing: antialiased; @@ -18,3 +20,4 @@ code { font-family: 'Overpass'; src: local('Overpass'), url(./fonts/Overpass/Overpass-Regular.ttf) format('truetype'); } + diff --git a/src/pages/ContractList.js b/src/pages/ContractList.js new file mode 100644 index 00000000..ab1293d8 --- /dev/null +++ b/src/pages/ContractList.js @@ -0,0 +1,110 @@ +import React, { useState, useEffect } from "react"; +import Navbar from "../components/navbar/Navbar.js"; +import ContractBox from "../components/containers/contractBox.js"; +import "../style/pages/contractList.css"; +import { + getContract, + switchContractStatus, +} from "../services/contractService.js"; +import { toast } from "react-toastify"; +import { useNavigate } from "react-router-dom"; + +export default function ContractList() { + const [contracts, setContracts] = useState([]); + + const navigate = useNavigate(); + + useEffect(() => { + const fetchContracts = async () => { + try { + const response = await getContract(); + console.log(response.data.data); + if (response.type === "success") { + setContracts(response.data.data); + } else { + toast.error("Erro ao obter os contratos"); + } + } catch (error) { + console.log("Erro ao buscar os contratos:", error); + toast.error("Erro ao obter os contratos"); + } + }; + fetchContracts(); + }, []); + + const handleReadClick = (id) => { + const url = `/verContrato/${id}`; + window.location = url + console.log(`Read button clicked for equipment ID: ${id}`); + }; + + const navigateToContractForm = () => { + window.location = "/cadastrarContrato"; + }; + + const handleEditClick = (contract) => { + navigate("/editarContrato", { state: { contract } }); + console.log(`Edit button clicked for equipment ID: ${contract.id}`); + }; + + const handleToggleClick = async (id, numero) => { + console.log(`Toggle button clicked for equipment ID: ${id}`); + try { + console.log(`CONTRATOS DPS DO SWITCH: ${contracts}`) + // Setando o estado do atributo "ativo" apenas do contrato do id referente ao click + setContracts(prevContracts => + prevContracts.map(contract => + contract.id === id ? { ...contract, ativo: !contract.ativo } : contract + ) + ); + const response = await switchContractStatus(id); + const { ativo } = response.data.data; + if (response.type === "success") { + toast.success( + `Contrato ${numero} ${ativo ? "ativado" : "desativado"}!` + ); + } else { + toast.error("Erro ao obter os contratos"); + } + } catch (error) { + console.log("Erro ao buscar os contratos:", error); + toast.error("Erro ao obter os contratos"); + } + }; + + return ( + <> + +
+
+

Contratos Disponíveis

+ +
+
+ {Array.isArray(contracts) && + contracts.map((contract) => ( + handleReadClick(contract.id)} + onEditClick={() => handleEditClick(contract)} + onToggleClick={() => + handleToggleClick(contract.id, contract.numero) + } + /> + ))} +
+ +
+ + ); +} diff --git a/src/pages/CreateCrontract.js b/src/pages/CreateCrontract.js new file mode 100644 index 00000000..14e46d1a --- /dev/null +++ b/src/pages/CreateCrontract.js @@ -0,0 +1,15 @@ +import "../style/pages/createUser.css"; +import React from "react"; +import Navbar from "../components/navbar/Navbar"; +import ContractForm from "../components/forms/ContractForm" + +export default function CreateUserPage() { + return ( + <> + +
+ +
+ + ); +} diff --git a/src/pages/EditPrinter.js b/src/pages/EditPrinter.js index ab148e33..7eb72a18 100644 --- a/src/pages/EditPrinter.js +++ b/src/pages/EditPrinter.js @@ -1,7 +1,6 @@ import "../style/pages/editPrinter.css"; import React from "react"; import EditPrinterForm from "../components/forms/EditPrinterForm.js"; -import registerPrinter_image from "../assets/registerPrinter_image.svg"; import Navbar from "../components/navbar/Navbar"; import { useParams } from "react-router-dom"; @@ -11,8 +10,7 @@ export default function EditPrinterPage() { <>
- homem - +
); diff --git a/src/pages/PatternList.js b/src/pages/PatternList.js index 77955446..c70ee0f7 100644 --- a/src/pages/PatternList.js +++ b/src/pages/PatternList.js @@ -1,13 +1,16 @@ import React, { useState, useMemo, useEffect } from "react"; import "../style/pages/patternList.css"; -import { Link } from "react-router-dom"; +import { Link, useNavigate } from "react-router-dom"; import Search from '../assets/Search.svg'; import Filter from '../assets/Filter.svg'; import Engine from '../assets/engine.svg'; import Input from '../components/Input'; import Modal from '../components/ui/Modal'; import Navbar from "../components/navbar/Navbar"; -import { getPadroes, togglePattern } from "../services/printerService"; +import { getPadroes, togglePattern } from "../services/patternService"; +import { toast } from "react-toastify"; + + export default function PatternList() { @@ -18,6 +21,7 @@ export default function PatternList() { const [modalBodytext, setModalBodytext] = useState(''); const [selectedPattern, setSelectedPattern] = useState(); const [patterns, setPatterns] = useState([]); + const navigate = useNavigate(); useEffect( () => { async function fetchData() { @@ -54,17 +58,15 @@ export default function PatternList() { async function patternToggle() { try { if (selectedPattern) { - const data = await togglePattern(selectedPattern.id, selectedPattern.status); + const data = await togglePattern(selectedPattern.id); console.log(data); if (data.type === 'success') { - const pattern = patterns.find(pattern => pattern.id === selectedPattern.id); - if (pattern.status === 'ATIVO') { - pattern.status = 'DESATIVADO'; - } else { - pattern.status = 'ATIVO'; - } setModalOpen(false); + selectedPattern.ativo? toast.success("Padão destivado com sucesso"): toast.success("Padão reativado com sucesso") + setTimeout(() => { + window.location.reload() + }, 1000); } } else { console.error("Pattern not selected"); @@ -85,9 +87,12 @@ export default function PatternList() { return 'Desativadas'; } } +/* +*/ //filtros para busca de impressora - const filteredPatterns = useMemo(() => { + + const filteredPatterns= useMemo(() => { return patterns.filter(pattern => { const searchLower = search.toLowerCase(); const { @@ -104,14 +109,13 @@ export default function PatternList() { ); }).filter(pattern => { return filter === 'all' || - (filter === 'active' && pattern.status === "ATIVO") || - (filter === 'deactivated' && pattern.status === "DESATIVADO"); + (filter === 'active' && pattern.ativo) || + (filter === 'deactivated' && !pattern.ativo); }); }, [patterns, search, filter]); return ( <> - {modalOpen && (
- setSearch(e.target.value)} + placeholder={"Pesquisar Padão"} /> - Search + +
@@ -152,28 +159,29 @@ export default function PatternList() {
{filteredPatterns.map(pattern => ( -
+
+

- {navigate("/visualizarpadrao", {state:pattern})}} + style={{ color: pattern.ativo ? '' : 'gray' }} > - Padrão {pattern.marca} - {pattern.modelo} - {pattern.tipo} - + Padrão: {pattern.marca} - {pattern.modelo}- {pattern.tipo} +

- {pattern.status === 'DESATIVADO' &&
Desativado
} + {!pattern.ativo &&
Desativado
}
- {pattern.status === "ATIVO" + {pattern.ativo ? modalDeactivatePattern(pattern)}>Desativar : modalActivePattern(pattern)}>Ativar } - Editar + {navigate("/editarpadrao",{state:pattern})}}>Editar
diff --git a/src/pages/PrintersList.js b/src/pages/PrintersList.js index ab42db41..39fb0b69 100644 --- a/src/pages/PrintersList.js +++ b/src/pages/PrintersList.js @@ -11,6 +11,29 @@ import { getPrinters, togglePrinter } from "../services/printerService"; import { extractDate } from "../utils/utils"; import { toast } from "react-toastify"; +const mockPrinters = [ + { + id: 1, + codigoLocadora: "LOC123", + ip: "192.168.1.10", + padrao: { marca: "HP", tipo: "LaserJet", modelo: "P1102" }, + numeroSerie: "SN123456", + status: "ATIVO", + contadorInstalacao: 1500, + dataUltimoContador: "2024-06-15" + }, + { + id: 2, + codigoLocadora: "LOC124", + ip: "192.168.1.11", + padrao: { marca: "Canon", tipo: "InkJet", modelo: "MG2522" }, + numeroSerie: "SN654321", + status: "DESATIVADO", + contadorInstalacao: 200, + dataUltimoContador: "2024-06-16" + } +]; + export default function PrintersList() { const [search, setSearch] = useState(''); const [filter, setFilter] = useState('all'); @@ -35,6 +58,7 @@ export default function PrintersList() { } } fetchData(); + setPrinters(mockPrinters); }, []); const modalTogglePrinter = (printer) => { diff --git a/src/pages/RegisterPrinter.js b/src/pages/RegisterPrinter.js index 5b677fa4..ac202fe6 100644 --- a/src/pages/RegisterPrinter.js +++ b/src/pages/RegisterPrinter.js @@ -9,9 +9,8 @@ export default function RegisterPrinterPage(){ <>
-
); -} \ No newline at end of file +} diff --git a/src/pages/ViewContract.js b/src/pages/ViewContract.js new file mode 100644 index 00000000..402d9012 --- /dev/null +++ b/src/pages/ViewContract.js @@ -0,0 +1,102 @@ +import React, { useState, useEffect } from "react"; +import Navbar from "../components/navbar/Navbar.js"; +import "../style/components/readContractForm.css"; +import { useParams, useNavigate } from "react-router-dom"; +import { getContractById } from "../services/contractService.js"; +import { toast } from "react-toastify"; + +const ViewContract = () => { + const { id } = useParams(); + console.log(id) + const [numero, setNumero] = useState(); + const [nomeGestor, setNomeGestor] = useState(); + const [descricao, setDescricao] = useState(); + const [dataInicio, setDataInicio] = useState(); + const [dataTermino, setDataTermino] = useState(); + const [ativo, setAtivo] = useState(); + const [contract, setContract] = useState({}) + + const navigate = useNavigate(); + + const navigateToEditContractListForm = () => { + navigate("/editarContrato", { state: { contract } }); + }; + const navigateToContractListForm = () => { + window.location = "/listagemContrato" + }; + + useEffect(() => { + const fetchContract = async () => { + try { + const response = await getContractById(id); + if (response.type === "success") { + setNumero(response.data.numero); + setNomeGestor(response.data.nomeGestor); + setDescricao(response.data.descricao); + setDataInicio(response.data.dataInicio); + setDataTermino(response.data.dataTermino); + setAtivo(response.data.ativo); + setContract(response.data) + } else { + toast.error("Erro ao obter o contrato"); + } + } catch (error) { + console.log("Erro ao buscar os contratos:", error); + toast.error("Erro ao buscar o contrato"); + } + } + fetchContract(); + }, [id]) + + return ( + <> + +
+
+

Visualização de Contrato

+
+
+
+
+
+

Contrato

+

{numero}

+
+
+

Gestor do Contrato

+

{nomeGestor}

+
+
+
+
+
+

Data de Início:

+

{new Date(dataInicio).toLocaleDateString()}

+
+
+

Data de Término:

+

{new Date(dataTermino).toLocaleDateString()}

+
+
+
+

Status

+

{ativo ? "Ativo" : "Inativo"}

+
+
+
+
+

Descrição do Contrato (Processo)

+

{descricao}

+
+
+
+ + +
+
+ + ); +}; + +export default ViewContract; + diff --git a/src/pages/ViewPattern.js b/src/pages/ViewPattern.js index 7dc7f8f8..36e83cc5 100644 --- a/src/pages/ViewPattern.js +++ b/src/pages/ViewPattern.js @@ -3,43 +3,50 @@ import React, { useEffect, useState } from "react"; import Ellipse from "../assets/login_ellipse.svg"; import voltar_vector from "../assets/voltar_vector.svg"; import Navbar from "../components/navbar/Navbar"; -import { useParams } from "react-router-dom"; +import { useLocation, useParams } from "react-router-dom"; export default function ViewPattern() { + const location = useLocation(); + + const altLocation = { + id:"", + marca: "", + modelo: "", + tipo: "", + colorido: false, + oidModelo: "", + oidNumeroSerie: "", + oidFirmware: "", + oidTempoAtivo: "", + oidDigitalizacoes: "", + oidCopiasPB: "", + oidCopiasCor: "", + oidTotalGeral: "" + } + + + const pattern = location.state || altLocation; + + + - const { padrao } = useParams(); const infoLabels = { - tipo: "Tipo", - modelo: "Modelo", - marca: "Marca", + tipo: "Tipo:", + modelo: "Modelo:", + marca: "Marca:", } const oidLabels = { - mdeoloImpressora: "Modelo de impressora", - numeroSerie: "Número de série", - versaoFirmware: "Versão de Firmware", - tempoAtivoSistema: "Tempo ativo do sistema", - totalDigitalizacoes: "Total de digitalizações", - totalCopiasPB: "Total de cópias P&B", - totalCopiasColoridas: "Total de cópias color", - totalImpressoesPb: "Total de impressões P&B", - totalImpressoesColoridas: "Total de impressões color", - totalGeral: "Total geral", - enderecoIp: "Endereço de IP", - } - - const [pattern, setPattern] = useState() - - useEffect(() => { - try { - const patternString = atob(padrao); - const patternObject = JSON.parse(patternString); - setPattern(patternObject); - } catch (error) { - console.error("Error decoding Base64 string", error); - } - }, [padrao]) + oidModelo: "Modelo de impressora", + oidNumeroSerie: "Número de série", + oidFirmware: "Versão de Firmware", + oidTempoAtivo: "Tempo ativo do sistema", + oidDigitalizacoes: "Total de digitalizações", + oidCopiasPB: "Total de cópias P&B", + oidCopiasCor: "Total de cópias color", + oidTotalGeral: "Total de impressões P&B", + } return ( <> @@ -51,8 +58,11 @@ export default function ViewPattern() {
- - Voltar + + + Voltar + +
@@ -62,6 +72,14 @@ export default function ViewPattern() {

{pattern[key]}

))} +
+ +

{pattern.colorido?"Sim":"Não"}

+
+
+ +

{pattern.ativo?"Sim":"Não"}

+
diff --git a/src/pages/ViewPrinter.js b/src/pages/ViewPrinter.js index a0dfdb1d..dcf72c1a 100644 --- a/src/pages/ViewPrinter.js +++ b/src/pages/ViewPrinter.js @@ -1,86 +1,284 @@ -import React, { useState, useEffect } from "react"; +import React, { useEffect, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; import '../style/pages/viewPrinter.css'; -import ellipse from '../assets/login_ellipse.svg'; -import voltar_vector from '../assets/voltar_vector.svg'; import Navbar from "../components/navbar/Navbar"; -import { Link, useParams } from "react-router-dom"; -import { extractDate } from "../utils/utils"; +import ViewDataContainer from "../components/containers/ViewDataContainer"; +import SmallInfoCard from "../components/cards/SmallInfoCard.js"; +import BigInfoCard from "../components/cards/BigInfoCard.js"; +import Button from "../components/Button.js"; +import { getPrinterById } from '../services/printerService.js'; +// Mock de dados da impressora +const mockPrinterData = { + equipamento: "Impressora XYZ", + numeroSerie: "123456789", + modelo: "Modelo ABC", + localizacao: "Goias", + contrato: "Contrato XYZ-123", + enderecoIp: "192.168.0.1", + dentroDaRede: "Sim", + dataInstalacao: "2023-01-15", + dataRetirada: "2024-01-15", + status: "Ativo", + marca: "Marca ABC", + cidade: "Cidade XYZ", + regional: "Regional 1", + subestacao: "Subestação A" +}; -export default function ViewPrinter(){ - const { printerData } = useParams(); - console.log(atob(printerData)); +// Função para codificar um objeto em Base64 +function encodeToBase64(obj) { + return btoa(JSON.stringify(obj)); +} - // Labels dos campos de informação. +// Codificar os dados da impressora +const encodedPrinterData = encodeToBase64(mockPrinterData); + +console.log(encodedPrinterData); // A string codificada para usar na URL + +export default function ViewPrinter() { + + const [printerData, setPrinterData] = useState({ + numContrato: '', + numSerie: '', + enderecoIp: '', + estaNaRede: false, + dataInstalacao: '', + dataRetirada: null, + ativo: false, + contadorInstalacaoPB: 0, + contadorInstalacaoCor: 0, + contadorAtualPB: 0, + contadorAtualCor: 0, + contadorRetiradaPB: 0, + contadorRetiradaCor: 0, + localizacao: '', + modeloId: '', + cidade: '', + regional: '', + subestacao: '' + }); + + const { id } = useParams() + + useEffect(() => { + const fetchData = async () => { + const response = await getPrinterById(id); + if (response.type === 'success') { + const { localizacao, ...restData } = response.data; + const [cidade, regional, subestacao] = localizacao.split(';'); + + setPrinterData({ + ...restData, + cidade: cidade || '', + regional: regional || '', + subestacao: subestacao || '' + }); + } + }; + fetchData(); + }, [id]); + + const dataRetiradaClass = mockPrinterData.status === "Ativo" ? "inactive-field" : ""; + const dataRetiradaValue = mockPrinterData.status === "Ativo" ? "Equipamento ainda ativo" : mockPrinterData.dataRetirada; + + // Labels dos campos de informação const infoLabels = { + equipamento: "Equipamento", numeroSerie: "Número de série", - ip: "IP", - codigoLocadora: "Código de locadora", - espacoLivre: "", - contadorInstalacao: "Contador de instalação", + modelo: "Modelo", + localizacao: "Localização", + contrato: "Contrato", + enderecoIp: "Endereço IP", + dentroDaRede: "Dentro da rede", dataInstalacao: "Data de instalação", - contadorRetiradas: "Contador de retirada", - dataContadorRetirada: "Data de retirada", - ultimoContador: "Último contador", - dataUltimoContador: "Data do último contador", - circunscricao: "Circunscrição", - unidadeId: "Unidade" - } + dataRetirada: "Data de retirada", + status: "Status", + marca: "Marca", + cidade: "Cidade", + regional: "Regional", + subestacao: "Subestação" + }; - // Estado para armazenar os dados da impressora. - const [printer, setPrinter] = useState(null); + const navigate = useNavigate(); - useEffect(() => { - try { - console.log("Printer Data:", printerData); - const printerString = atob(printerData); - const printerObject = JSON.parse(printerString); - setPrinter(printerObject); - } catch (error) { - console.error("Error decoding Base64 string:", error); - // Handle the error as needed, e.g., setPrinter to a default value or show an error message. - } - }, [printerData]); - - return( + const handleExitForm = () => { + navigate('/listimpressora'); + }; + + const handleEditButton = () => { + window.location = `/editimpressora/${id}` + }; + + return ( <> - -
-
-
-
- - {printer ? ( -
-
- - - - Voltar -
-

- {printer.padrao.tipo} - {printer.padrao.marca} - {printer.padrao.modelo} -

-
- {Object.entries(infoLabels).map(([key, label]) => ( -
- -

{key.includes("data") ? extractDate(printer?.[key]) : printer?.[key]}

-
- ))} -
+ +
+
+ Visualizar Equipamento +
+ + + +
+
+
+
+ + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+
+
+ + + + +
- ) : ( -

Carregando dados...

- ) - } - -
-
- elipse -
+
+ +
Localização
+
+ + + + + +
+
+
+
+ +
-
); -} \ No newline at end of file +} diff --git a/src/services/contractService.js b/src/services/contractService.js new file mode 100644 index 00000000..c93a65d5 --- /dev/null +++ b/src/services/contractService.js @@ -0,0 +1,52 @@ +import { api } from '../lib/api/config'; + +export const getContract = async (page, pageSize) => { + try { + const response = await api.get('/', { + params: { + page, + pageSize + } + }); + return { type: 'success', data: response.data}; + } catch (error) { + return { type: 'error', error }; + } +}; + +export const getContractById = async (id) => { + try { + const response = await api.get(`/${id}`); + return { type: 'success', data: response.data}; + } catch (error) { + return { type: 'error', error }; + } +}; + +export const createContract = async (data) => { + try { + const response = await api.post('/', data); + return { type: 'success', data: response.data}; + } catch (error) { + return { type: 'error', error }; + } +}; + +export const editContract = async (id, data) => { + try { + const response = await api.patch(`/${id}`, data); + return { type: 'success', data: response.data}; + } catch (error) { + return { type: 'error', error }; + } +}; + +export const switchContractStatus = async (id) => { + try { + const response = await api.patch(`/changeStatus/${id}`); + console.log(response.data.data) + return { type: 'success', data: response.data}; + } catch (error) { + return { type: 'error', error }; + } +}; \ No newline at end of file diff --git a/src/services/patternService.js b/src/services/patternService.js new file mode 100644 index 00000000..b1bda877 --- /dev/null +++ b/src/services/patternService.js @@ -0,0 +1,67 @@ +import { api } from "../lib/api/config"; + + export async function getPadrao(id) { + try { + const response = await api.get(`/printer/padrao/${id}`); + if(response.status !== 200) { + return { type: 'error'}; + } + return { type: 'success'}; + } catch (error) { + return { type: 'error', error }; + } + } + + export async function getPadroes() { + try { + const response = await api.get('/printer/padrao'); + if(response.status !== 200) { + return { type: 'error', data: response.data}; + } + return { type: 'success', data: response.data }; + } catch (error) { + return { type: 'error', error }; + } + } + + export async function togglePattern(id) { + + try { + const response = await api.patch(`/printer/padrao/toggle/${id}`); + if(response.status !== 200) { + return { type: 'error'}; + } + return { type: 'success'}; + } catch (error) { + return { type: 'error', error }; + } + } + + + export const createPadraoImpressora = async (printerPattern) => { + try { + const response = await api.post('/printer/padrao/create', printerPattern); + if(response.status !== 201) { + return { type: 'error', data: response.data}; + } + return { type: 'success', data: response.data}; + } catch (error) { + return { type: 'error', error }; + } + }; + + export const editPadrao = async (pattern, id) => { + try { + const response = await api.put(`/printer/padrao/${id}`, pattern); + + if (response.status !== 200) { + return { type: 'error', data: response.data }; + } + + return { type: 'success', data: response.data }; + + } catch (error) { + return { type: 'error', error }; + } + } + \ No newline at end of file diff --git a/src/services/printerService.js b/src/services/printerService.js index 50fec1e8..8b99c9ed 100644 --- a/src/services/printerService.js +++ b/src/services/printerService.js @@ -1,37 +1,39 @@ import { api } from '../lib/api/config'; +//printer: export async function getPrinters() { try { - const response = await api.get('/printer/impressora'); + const response = await api.get('/printer'); if(response.status !== 200) { return { type: 'error', data: response.data}; } - return { type: 'success', data: response.data}; + return { type: 'success', data: response.data.data }; } catch (error) { return { type: 'error', error }; } } -export async function getPadrao(id) { +export async function getPrinterById(id) { try { - const response = await api.get(`/printer/padrao/${id}`); - if(response.status !== 200) { - return { type: 'error', data: response.data}; - } - return { type: 'success', data: response.data }; + const response = await api.get(`/printer/${id}`); + if (response.status !== 200) { + return { type: 'error', data: response.data }; + } + return { type: 'success', data: response.data }; } catch (error) { - return { type: 'error', error }; + return { type: 'error', error }; } } -export async function getPadroes() { +export async function getLocalizacao() { try { - const response = await api.get('/printer/padrao'); - if(response.status !== 200) { + + const response = await api.get('/printer/location'); + if(response.status !== 201) { return { type: 'error', data: response.data}; } - return { type: 'success', data: response.data }; + return response.data; } catch (error) { return { type: 'error', error }; } @@ -53,27 +55,9 @@ export async function togglePrinter(id, status) { return { type: 'error', error }; } } - -export async function togglePattern(id, status) { - const data = { - id, - status - } - - try { - const response = await api.patch(`/printer/padrao/${id}`, data); - if(response.status !== 200) { - return { type: 'error', data: response.data}; - } - return { type: 'success', data: response.data }; - } catch (error) { - return { type: 'error', error }; - } -} - export const createImpressora = async (printer) => { try { - const response = await api.post('/printer/impressora/create', printer); + const response = await api.post('/printer/', printer); if(response.status !== 201) { return { type: 'error', data: response.data}; } @@ -107,47 +91,3 @@ export const editImpressora = async (printer) => { return { type: 'error', error }; } }; - -export const createPadraoImpressora = async (printerPattern) => { - try { - const response = await api.post('/printer/padrao/create', printerPattern); - if(response.status !== 201) { - return { type: 'error', data: response.data}; - } - return { type: 'success', data: response.data}; - } catch (error) { - return { type: 'error', error }; - } -}; - -export const editPadrao = async (pattern) => { - try { - const data = { - tipo: pattern.tipo, - marca: pattern.marca, - modelo: pattern.modelo, - modeloImpressora: pattern.modeloImpressora, - numeroSerie: pattern.numeroSerie, - versaoFirmware: pattern.versaoFirmware, - tempoAtivoSistema: pattern.tempoAtivoSistema, - totalDigitalizacoes: pattern.totalDigitalizacoes, - totalCopiasPB: pattern.totalCopiasPB, - totalCopiasColoridas: pattern.totalCopiasColoridas, - totalImpressoesPb: pattern.totalImpressoesPb, - totalImpressoesColoridas: pattern.totalImpressoesColoridas, - totalGeral: pattern.totalGeral, - enderecoIp: pattern.enderecoIp, - } - - const response = await api.patch(`/printer/padrao/${pattern.id}`, data); - - if (response.status !== 200) { - return { type: 'error', data: response.data }; - } - - return { type: 'success', data: response.data }; - - } catch (error) { - return { type: 'error', error }; - } -} diff --git a/src/style/components/BigInfoCard.css b/src/style/components/BigInfoCard.css new file mode 100644 index 00000000..a4ffe569 --- /dev/null +++ b/src/style/components/BigInfoCard.css @@ -0,0 +1,27 @@ +.big-card-info { + display: flex; + flex-direction: column; + align-items: flex-start; /* Alinhar itens à esquerda */ + justify-content: center; + width: 200px; /* Ajuste conforme necessário */ + height: 120px; /* Ajuste conforme necessário */ + background-color: #003366; /* Fundo azul */ + border-radius: 15px; /* Bordas arredondadas */ + color: white; /* Texto branco */ + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* Sombra */ + padding: 10px; /* Espaçamento interno */ + margin-top: 50px; +} + +.big-card-title { + font-size: 15px; + padding-left: 10px; +} + +.big-card-info-value { + font-size: 70px; /* Tamanho maior */ + /* Opcional: deixar o número em negrito */ + text-align: center; /* Centraliza o texto */ + width: 100%; /* Garante que o texto ocupe toda a largura disponível */ +} + diff --git a/src/style/components/DateContainer.css b/src/style/components/DateContainer.css new file mode 100644 index 00000000..d9c8c42a --- /dev/null +++ b/src/style/components/DateContainer.css @@ -0,0 +1,63 @@ +.date-container, +.number-container { + height: 39px; +} + +.date-container-form{ + padding-top: 20px; +} + +.date-field, +.number-field { + border-radius: 4px; + border: 2px solid #0D3D6D; + font-size: 18px; + outline: none; + transition: border-color 0.3s ease; + margin: 0px; + padding: 6.5px; + box-sizing: border-box; +} + +.input-error { + border-color: red !important; + border-radius: 4px; + border: 2px solid #0D3D6D; + font-size: 18px; + outline: none; + transition: border-color 0.3s ease; + margin: 0px; + padding: 6.5px; + box-sizing: border-box; +} + +.date-field::placeholder, +.number-field::placeholder { + color: #D3D3D3; +} + +.date-field.md, +.number-field.md, +.input-error.md { + width: 250px; +} + +.date-field.lg, +.number-field.lg, +.input-error.lg { + width: 350px; +} + +.date-field:focus, +.number-field:focus { + border-color: #0D3D6D; +} + +.disabled { + background-color: #6C6C6C; + color: #6C6C6C; +} + +.disabled::placeholder { + color: grey; +} diff --git a/src/style/components/FilterContainer.css b/src/style/components/FilterContainer.css new file mode 100644 index 00000000..8a0975f0 --- /dev/null +++ b/src/style/components/FilterContainer.css @@ -0,0 +1,58 @@ +.filter-container { + font-family: Jost; + padding: 20px; +} + +.filter-header { + text-align: center; +} + +.dropdown-section { + margin: 20px 0; +} + +.dropdown-header { + cursor: pointer; + padding: 10px 0; + border-bottom: 1.5px solid #003366; + display: flex; + justify-content: space-between; + align-items: center; + font-size: 18px; + color: #003366; +} + +.dropdown-header:hover { + color: #0055a5; +} + +.arrow { + transition: transform 0.2s; + width: 16px; + height: 16px; +} + +.arrow.down { + transform: rotate(0deg); +} + +.arrow.up { + transform: rotate(180deg); +} + +.dropdown-content { + border: 1px solid #ccc; + padding: 10px; + display: flex; + flex-direction: column; + border: none; +} + +.add-equipment-btn { + background-color: #2a6b25; + color: white; + padding: 10px 20px; + border: none; + cursor: pointer; + margin-top: 20px; +} diff --git a/src/style/components/InputContainer.css b/src/style/components/InputContainer.css new file mode 100644 index 00000000..399dd89b --- /dev/null +++ b/src/style/components/InputContainer.css @@ -0,0 +1,49 @@ +.input-container { + height: 39px; +} + +.input-label{ + padding-top: 20px; +} + +.input-field { + border-radius: 10px; + border: 2px solid #0D3D6D; + font-size: 18px; + outline: none; + transition: border-color 0.3s ease; + margin: 0px; + padding: 6.5px; + box-sizing: border-box; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.input-error { + border: 2px solid red; +} + + +.input-field::placeholder { + color: #D3D3D3; +} + +.input-field.md { + width: 250px; +} + +.input-field.lg { + width: 350px; +} + +.input-field:focus { + border-color: #0D3D6D; +} + +.disabled { + background-color: #6C6C6C; + color: #6C6C6C; +} + +.disabled::placeholder { + color: grey; +} diff --git a/src/style/components/NumberContainer.css b/src/style/components/NumberContainer.css new file mode 100644 index 00000000..d6bc7b3a --- /dev/null +++ b/src/style/components/NumberContainer.css @@ -0,0 +1,45 @@ +.number-container { + height: 39px; +} + +.number-container-form{ + padding-top: 20px; +} + +.number-field { + border-radius: 10px; + border: 2px solid #0D3D6D; + font-size: 18px; + outline: none; + transition: border-color 0.3s ease; + margin: 0px; + padding: 6.5px; + box-sizing: border-box; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.number-field::placeholder { + color: #D3D3D3; +} + +.number-field.md { + width: 250px; +} + +.number-field.lg { + width: 350px; +} + +.number-field:focus { + border-color: #0D3D6D; +} + +.disabled { + background-color: #dddddd; + color: #6C6C6C; + cursor: not-allowed; +} + +.disabled::placeholder { + color: grey; +} diff --git a/src/style/components/SelectContainer.css b/src/style/components/SelectContainer.css new file mode 100644 index 00000000..2ffc93c3 --- /dev/null +++ b/src/style/components/SelectContainer.css @@ -0,0 +1,61 @@ +.md-select { + border: 2px solid #0D3D6D; + border-radius: 10px; + width: 150px; + font-size: 16px; + padding: 8px; + background-color: white; + color: black; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + /* appearance: none; */ +} + +.input-error { + border: 2px solid red; +} + +.md-select::after { + content: '▼'; + color: #0D3D6D; + font-size: 18px; + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + pointer-events: none; +} + +.md-select::placeholder { + color: #0D3D6D; +} + +.lg-select { + border: 2px solid #0D3D6D; + border-radius: 10px; + width: 200px; + font-size: 16px; + padding: 8px; + background-color: white; + color: black; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + /* appearance: none; */ +} + +.lg-select::after { + content: '▼'; + color: #0D3D6D; + font-size: 18px; + position: absolute; + right: 10px; + top: 50%; + transform: translateY(-50%); + pointer-events: none; +} + +.lg-select::placeholder { + color: #0D3D6D; +} + +.select-container{ + padding-top: 20px; +} \ No newline at end of file diff --git a/src/style/components/SmallInfoCard.css b/src/style/components/SmallInfoCard.css new file mode 100644 index 00000000..79ebf120 --- /dev/null +++ b/src/style/components/SmallInfoCard.css @@ -0,0 +1,52 @@ +.grey-info-card { + display: flex; + align-items: center; + width: 150px; + padding: 10px; + background-color: #D9D9D9; + border-radius: 15px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + +.blue-info-card { + display: flex; + align-items: center; + width: 200px; + padding: 10px; + background-color: #0D3D6D; + border-radius: 15px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); +} + + +.info-card-image { + width: 30px; + height: 30px; + margin-right: 10px; + padding-left: 5px; +} + +.info-card-content { + display: flex; + flex-direction: column; +} + +.info-card-title { + font-size: 14px; + color: #006400; +} + +.blue-info-card-title { + font-size: 14px; + color: #ffffff; +} + +.info-card-info { + font-size: 16px; + color: #006400; +} + +.blue-info-card-info { + font-size: 16px; + color: #ffffff; +} diff --git a/src/style/components/ViewDataContainer.css b/src/style/components/ViewDataContainer.css new file mode 100644 index 00000000..5c19749a --- /dev/null +++ b/src/style/components/ViewDataContainer.css @@ -0,0 +1,52 @@ +.large-view { + border: 2px solid #0D3D6D; + border-radius: 10px; + width: 400px; + font-size: 25px; + padding: 8px; + background-color: white; + color: black; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + /* appearance: none; */ +} + +.small-view { + border: 2px solid #0D3D6D; + border-radius: 10px; + width: 150px; + font-size: 25px; + padding: 8px; + background-color: white; + color: black; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + /* appearance: none; */ +} + +.inactive-field { + border: 2px solid #0D3D6D; + border-radius: 10px; + width: 400px; + font-size: 25px; + padding: 8px; + background-color: #6C6C6C; + color: rgba(255, 255, 255, 0.151); + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); + pointer-events: none; /* Desativar interação do usuário */ + } + + +.view-data-container { + display: flex; + flex-direction: column; /* Organiza os filhos verticalmente */ +} + +.form-subtitle { + font-size: 28px; + color: #0D3D6D; + margin-bottom: 16px; + padding-top: 20px; +} + +.view-data-container .disabled-cursor { + cursor: not-allowed; +} diff --git a/src/style/components/button.css b/src/style/components/button.css index aa067bcf..19e39de3 100644 --- a/src/style/components/button.css +++ b/src/style/components/button.css @@ -1,24 +1,50 @@ .button { - width: 17vw; - height: 8vh; - padding: 10px 20px; - border-radius: 60px; + border: none; + border-radius: 10px; + color: #fff; cursor: pointer; - color: var(--text-color); - background-color: var(--bg-color); - border: 2px solid var(--border-color); - font-style:normal ; - font-family: inherit; - font-size: 20px; - text-align: center; - display: flex; - align-items: center; - justify-content: center; - box-shadow: 1px 4px 4px 0px rgba(0, 0, 0, 0.25); + font-size: 16px; + padding: 10px 20px; + transition: background-color 0.3s ease, border-color 0.3s ease; + font-weight: 600; +} +.button-icon { + background-color: #00000000; + color: #000000; +} + +.button-success { + background-color: #28a745; + border-color: #28a745; +} + +.button-error { + background-color: #dc3545; + border-color: #dc3545; } -.button:hover{ - filter: brightness(85%); +.button-info { + background-color: #D9D9D9; + border-color: #D9D9D9; + color: #003366; } - +.button-warning { + background-color: #ffc107; + border-color: #ffc107; +} + +.button-small { + font-size: 14px; + padding: 5px 10px; +} + +.button-medium { + font-size: 16px; + padding: 10px 20px; +} + +.button-large { + font-size: 18px; + padding: 15px 30px; +} diff --git a/src/style/components/contractBox.css b/src/style/components/contractBox.css new file mode 100644 index 00000000..2d094831 --- /dev/null +++ b/src/style/components/contractBox.css @@ -0,0 +1,63 @@ +.box .overlap-group { + background-color: #ffffff; + border: 2px solid; + border-color: #003366; + border-radius: 20px; + display: flex; + justify-content: space-between; + height: 100px; + align-items: center; +} + +.box .text-wrapper { + color: #003366; + font-family: "Jost", Helvetica; + font-size: 40px; + font-weight: 400; + letter-spacing: 0; + line-height: normal; + display: flex; + justify-content: space-between; + width: 900px; + align-items:first baseline; + overflow: hidden; +} + +.box .text-wrapper .numero { + font-weight: 600; + margin-left: 45px; +} + +.box .text-wrapper .gestor { + font-weight: 500; + width: 400px; +} + +.box .read { + width: 69px; + align-items: center; + justify-content: left; +} + +.box .edit { + object-fit: cover; + width: 69px; + display: flex; + align-items: center; + justify-content: center; +} + +.box .toggle { + object-fit: cover; + width: 93px; + justify-content: center; + display: flex; + align-items: center; +} + +.box .actions { + justify-content: space-between; + display: flex; + align-items: center; +} + diff --git a/src/style/components/contractForm.css b/src/style/components/contractForm.css new file mode 100644 index 00000000..59a325e8 --- /dev/null +++ b/src/style/components/contractForm.css @@ -0,0 +1,133 @@ +.padraoPagina{ + margin-top: 5px; + padding-inline: 50px; + justify-content: center; +} + +#tituloCad{ + border-bottom: #0D3D6D; + border-bottom-style: solid; + width: fit-content; + padding-bottom: 15px; + font-weight: 400; + font-size: 48px; + color: #0D3D6D; + margin-left: 30px; +} + +#label{ + display: flex; + flex-direction: column; + width: 400px; + margin-bottom: 30px; + font-weight: 400; + color: #0D3D6D; +} + +#inputData{ + display: flex; + gap: 20px; +} + +#inputDescricao{ + width: 900px; + margin-top: 5px; + height: 35px; + border-radius: 10px; + border-color: #0D3D6D; + border-style: solid; + padding-left: 20px; + padding-top: 5px; +} + +#inputCampos{ + margin-top: 5px; + height: 35px; + border-radius: 10px; + border-color: #0D3D6D; + border-style: solid; + padding-inline: 20px; + align-items: center; + padding-top: 5px; +} + +#inputCampoDatas{ + margin-top: 5px; + height: 35px; + border-radius: 10px; + border-color: #0D3D6D; + border-style: solid; + border-width: 2px; + padding-inline: 20px; + align-items: center; + cursor: pointer; +} + +::placeholder{ + font-size: 18px; + opacity: 0.6; + font-family: Jost; + align-items: center; +} + +.topBar{ + display: flex; + align-items: center; + justify-content: space-between; + border-color: #0D3D6D; + margin-inline: 70px; + max-height: 120px; + margin-bottom: -10px; +} +.campoDataTermino{ + margin-left: 110px; +} + +#botaoCadastro{ + background-color: #006633; + height: 6vh; + width: 10vw; + color: white; + font-size: 24px; + border-radius: 30px; + border-style: none; + font-family: Jost; + cursor: pointer; + font-weight: 600; + margin-inline: 70px; + margin-left: 100px; +} + +.botaoAcessarLista{ + background-color: #D9D9D9; + height: 6vh; + width: 25vw; + margin-left: 100px; + font-size: 24px; + border-radius: 30px; + color: #0D3D6D; + border-style: none; + font-weight: 700; + font-family: Jost; + cursor: pointer; +} + +.inputDataInicio{ + font-size: 18px; + opacity: 0.6; + font-family: Jost; +} + +.contrato-status{ + display: flex; + gap: 29%; +} + +#contratos-form{ + margin-top: 30px; +} + +.formularioCad{ + margin-inline: 100px; + margin-top: -30px; +} \ No newline at end of file diff --git a/src/style/components/editContractForm.css b/src/style/components/editContractForm.css new file mode 100644 index 00000000..3bbce96c --- /dev/null +++ b/src/style/components/editContractForm.css @@ -0,0 +1,92 @@ +#padraoPagina{ + color: #0D3D6D; + margin-left: 100px; + margin-top: 50px; +} + +#titulo{ + border-bottom: #0D3D6D; + border-bottom-style: solid; + width: fit-content; + padding-bottom: 15px; +} + +#label{ + display: flex; + flex-direction: column; + width: 400px; + margin-bottom: 40px; + font-size: 25px; +} + +.ContratoStatus{ + display: flex; + justify-content: space-between; + width: 61vw; + +} + + +#inputData{ + display: flex; +} + +#inputDescricao{ + width: 900px; + margin-top: 5px; + height: 35px; + border-radius: 10px; + border-color: #0D3D6D; + border-style: solid; + padding-left: 20px; +} + +#inputCampos{ + margin-top: 5px; + height: 35px; + border-radius: 10px; + border-color: #0D3D6D; + border-style: solid; + padding-inline: 20px; +} + +::placeholder{ + font-size: 18px; + opacity: 0.6; + font-family: Jost; +} + +.campoDataTermino{ + margin-left: 105px; +} + +.botaoSalvar{ + background-color: #006633; + height: 40px; + width: 20vw; + color: white; + font-size: 20px; + border-radius: 20px; + border-style: none; + font-family: Jost; + font-weight: 700; +} + +.botaoCancelar{ + background-color: red; + height: 40px; + width: 10vw; + margin-left: 100px; + font-size: 20px; + border-radius: 20px; + color: white; + border-style: none; + font-weight: 700; + font-family: Jost; +} + +.inputDataInicio{ + font-size: 18px; + opacity: 0.6; + font-family: Jost; +} \ No newline at end of file diff --git a/src/style/components/itemBox.css b/src/style/components/itemBox.css new file mode 100644 index 00000000..bbfab750 --- /dev/null +++ b/src/style/components/itemBox.css @@ -0,0 +1,40 @@ +.box .overlap-group { + background-color: #ffffff; + border: 2px solid; + border-color: #003366; + border-radius: 20px; + height: 142px; + position: relative; + width: 1674px; +} + +.box .text-wrapper { + color: #003366; + font-family: "Jost-Regular", Helvetica; + font-size: 48px; + font-weight: 400; + height: 69px; + left: 48px; + letter-spacing: 0; + line-height: normal; + position: absolute; + top: 34px; +} + +.box .edit { + height: 69px; + left: 1462px; + object-fit: cover; + position: absolute; + top: 34px; + width: 69px; +} + +.box .toggle { + height: 69px; + left: 1554px; + object-fit: cover; + position: absolute; + top: 32px; + width: 93px; +} diff --git a/src/style/components/listEquipment.css b/src/style/components/listEquipment.css new file mode 100644 index 00000000..857dec08 --- /dev/null +++ b/src/style/components/listEquipment.css @@ -0,0 +1,6 @@ +.equipment-list { + display: flex; + flex-direction: column; + gap: 15px; /* Space between items */ + padding: 20px; /* Optional padding around the list */ +} diff --git a/src/style/components/modal.css b/src/style/components/modal.css index b6ed2520..e7b758f8 100644 --- a/src/style/components/modal.css +++ b/src/style/components/modal.css @@ -10,13 +10,14 @@ } .modal-container { - width: 38.5vw; - height: 75vh; + width: 40vw; + height: 60vh; border-radius: 12px; background-color: white; box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; display: flex; flex-direction: column; + justify-content: center; padding: 25px; } @@ -44,8 +45,8 @@ height: 35vh; width: 38.5vw; display: flex; - justify-content: center; - align-items: center; + justify-self: center; + align-self: center; font-size: 1.7rem; text-align: center; color: black; diff --git a/src/style/components/navbar.css b/src/style/components/navbar.css index 0f935703..8493cfd0 100644 --- a/src/style/components/navbar.css +++ b/src/style/components/navbar.css @@ -153,6 +153,59 @@ color: #006633; } +/* Contracts dropdown */ +.navbar-contracts { + display: flex; + align-items: center; +} + +.navbar-contracts-button { + display: flex; + background-color: #ffff; + color: #003366; + font-size: 18px; + border: none; + cursor: pointer; + margin-bottom: 1px; +} + +.navbar-contracts-button h4{ + margin: 0; + font-weight: normal; + font-size: 18px; +} +.navbar-contracts-dropdown { + display: none; + position: absolute; + background-color: #f9f9f9; + min-width: 180px; + box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); + z-index: 1; +} + +.navbar-contracts-dropdown a { + color: #003366; + width: 15vw; + text-decoration: none; + display: block; + font-size: 20px; + padding: 4px 4px; +} + +.navbar-contracts-dropdown a:hover { + background-color: #003366; + color: #ffff; +} + +.navbar-contracts:hover .navbar-contracts-dropdown { + display: block; +} + +.navbar-contracts:hover .navbar-contracts-button { + background-color: #ffff; + color: #006633; +} + /* Login */ .navbar-login { width: 100%; diff --git a/src/style/components/printerPatternForm.css b/src/style/components/printerPatternForm.css index 358252e9..841c22b2 100644 --- a/src/style/components/printerPatternForm.css +++ b/src/style/components/printerPatternForm.css @@ -2,14 +2,12 @@ background-color: #ffffff; border-radius: 10px; display: flex; - min-width: 38vw; - width: 38vw; - min-height: fit-content; - justify-content: start; + min-width: 40vw; + justify-content: center; align-items: start; flex-direction: column; box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5); - margin-top: 10vh; + margin-top: 1rem; margin-bottom: 1rem; margin-right: 50vw; padding-top: 20px; @@ -19,7 +17,7 @@ #printer-pattern-fields { height: fit-content; width: 100%; - margin-bottom: 20px; + margin-bottom: 5px; display: flex; flex-direction: column; justify-content: space-around; @@ -43,32 +41,52 @@ #printer-pattern-input-line { flex: 1; - min-width: 100px; /* Largura mínima para cada input */ display: flex; - width: 250px; + width: 65%; flex-direction: column; padding: 0px; box-sizing: border-box; -} + padding: 0 20px; + } + #printer-pattern-input-line input{ + width: 100%; + } + #inputCheckBox{ + display: flex; + align-items: center; + justify-content: start; + margin-left: 20px; + + } + + #inputCheckBox input{ + cursor: pointer; + min-width: 25px; + min-height: 25px; + } + #inputCheckBox label{ + margin-top: 5px; + margin-right: 10px; + } #printer-pattern-snmp-fields { width: 100%; - display: flex; - flex-direction: column; - justify-content: space-around; - margin-bottom: 20px + width: 37vw; + display: grid; + margin-bottom: 20px; + margin-left: 20px; } #snmp-fields-input-line { - display: flex; - width: 100%; - justify-content: space-between; + display: flex; align-items: center; + } #snmp-fields-input-line label{ - display: flex; - width: 380px; + justify-self: start; + width: 45%; + margin-right: 10px; } #printer-pattern-input-box { @@ -86,26 +104,37 @@ top: 10rem; } -#printer-pattern-input-box label { +#printer-pattern-signup-card label { font-size: 16px; color: #003366; } -#printer-pattern-input-box span { +#printer-pattern-signup-card span { color: #9f0805; } -#input-checkbox { - margin-top: 2rem; - display: flex; - align-items: center; + +#selection select { + width: 150px; + font-size: 15px; + border-radius: 10px; + + +} +#selection select:focus{ + background-color: #ffffff; + color: #003366; + + + + } -#input-checkbox input { - margin: 0 12px 0 0; - vertical-align: middle; - position: relative; - top: -3px; + + +#selection { + margin-left: 20px; + } #printer-pattern-fields input { @@ -118,11 +147,15 @@ #snmp-fields-input-line input { font-size: 14px; + margin: 2px; border: 1px solid #003366; border-color: #003366; border-radius: 10px; padding: 5px; height: 18px; + flex: 1; + max-width: 20vw; + } #printer-pattern-buttons { diff --git a/src/style/components/readContractForm.css b/src/style/components/readContractForm.css new file mode 100644 index 00000000..bb649bbd --- /dev/null +++ b/src/style/components/readContractForm.css @@ -0,0 +1,112 @@ +.mainAreaContract{ + margin-top: 5px; + padding-inline: 100px; + justify-content: center; + height: 800px; +} + + +#tituloContract{ + border-bottom: #0D3D6D; + border-bottom-style: solid; + width: fit-content; + padding-bottom: 15px; + font-weight: 400; + font-size: 48px; + color: #0D3D6D; + margin-inline: 100px; +} + +#titlesContracts{ + font-weight: 400; + font-size: 30px; + color: #0D3D6D; +} + +#textContent{ + font-weight: 400; + font-size: 26px; + color: #000000; +} + +#textDateContent{ + font-weight: 400; + font-size: 26px; + color: #000000; +} + +.content{ + margin-inline: 100px; + margin-top: -30px; +} + +.specsContract{ + display: flex; + align-items: center; + justify-content: space-between; +} + +.namesContracts{ + display: flex; + flex-direction: column; + justify-content: space-between; + width: 50vw; +} + +.dateC{ + display:flex; + gap: 20%; + width: 50vw; +} + +.dateI{ + margin-left: 40px; +} + +.dateF{ + margin-right: 270px; +} + +.datesContracts{ + flex-direction: column; +} + +.statusContract{ + margin-left: 40px; +} + +#buttonListContracts{ + background-color: #D9D9D9; + border-radius: 60px; + margin-top: 20px; + margin-left: 100px; + width: 10vw; + height: 6vh; + border-style: none; + color: #0D3D6D; + font-size: 24px; + font-weight: 600; + cursor: pointer; +} + +#buttonEditContract{ + background-color: #006633; + border-radius: 60px; + margin-top: 20px; + margin-left: 90px; + width: 10vw; + height: 6vh; + border-style: none; + color: rgb(255, 255, 255); + font-size: 24px; + font-weight: 600; + cursor: pointer; +} + +.descContract{ + margin-top: -15px; +} + +.divButtons{ + margin-top: -15px; +} \ No newline at end of file diff --git a/src/style/components/registerPrinterForms.css b/src/style/components/registerPrinterForms.css index b0f345c0..7c13ac78 100644 --- a/src/style/components/registerPrinterForms.css +++ b/src/style/components/registerPrinterForms.css @@ -1,180 +1,220 @@ +.space { + margin: 50px 0px; +} + +.form-title { + font-size: 48px; + color: #0D3D6D; + margin-bottom: 16px; + border-bottom: 2px solid #0D3D6D; +} + +.form-subtitle { + font-size: 28px; + color: #0D3D6D; + margin-bottom: 16px; +} + +.form-separator { + font-size: 28px; + color: #0D3D6D; + margin-bottom: 16px; + border-bottom: 2px solid #0D3D6D; + padding-top: 50px; +} + +.container { + display: flex; + align-items: center; + gap: 1rem; +} + +#localization { + padding-top: 0px; +} + #registerPrinter-card { - background-color: #ffffff; - border-radius: 10px; - display: flex; - width: 35vw; - height: 100%; - justify-content: center; - align-items: center; - flex-direction: column; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5); - padding: 1rem 5rem; - margin-right: 8vw; - margin-top: 2%; - margin-bottom: 1vh; + background-color: #ffffff; + border-radius: 10px; + display: flex; + width: 35vw; + height: 100%; + justify-content: center; + align-items: center; + flex-direction: column; + box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5); + padding: 1rem 5rem; + margin-right: 8vw; + margin-top: 2%; + margin-bottom: 1vh; } #form-header { - font-size: 48px; - color: #003366; - margin-bottom: 16px; + font-size: 48px; + color: #003366; + margin-bottom: 16px; } #input-group { - display: flex; - flex-wrap: wrap; - justify-content: space-between; - padding: 16px 0; + display: flex; + flex-wrap: wrap; + justify-content: space-between; + padding: 16px 0; } #input-line { - display: flex; - justify-content: space-between; - flex-wrap: wrap; - gap: 10px; + display: flex; + justify-content: space-between; + flex-wrap: wrap; + gap: 10px; } #input-box { - flex: 1; - min-width: 100px; /* Largura mínima para cada input */ - display: flex; - width: 250px; - flex-direction: column; - margin-bottom: 16px; - padding: 0 10px; - box-sizing: border-box; + flex: 1; + min-width: 100px; + /* Largura mínima para cada input */ + display: flex; + width: 250px; + flex-direction: column; + margin-bottom: 16px; + padding: 0 10px; + box-sizing: border-box; } #label-checkbox { - top: 10rem; + top: 10rem; } #input-box label { - color: #003366; - display: block; - margin-bottom: 5px; + color: #003366; + display: block; + margin-bottom: 5px; } #input-box span { - color: #9f0805; + color: #9f0805; } #input-checkbox { - margin-top: 2rem; - display: flex; - align-items: center; + margin-top: 2rem; + display: flex; + align-items: center; } #input-checkbox input { - margin: 0 12px 0 0; - vertical-align: middle; - position: relative; - top: -3px; + margin: 0 12px 0 0; + vertical-align: middle; + position: relative; + top: -3px; } #input-box input { - font-size: 16px; - border: 1px solid #003366; - border-color: #003366; - border-radius: 10px; - padding: 5px; + font-size: 16px; + border: 1px solid #003366; + border-color: #003366; + border-radius: 10px; + padding: 5px; } #input-box select { - font-size: 16px; - font-size: 1rem; - border: 1px solid #003366; - border-color: #003366; - border-radius: 10px; - padding: 5px; - color: #6c6c6c; + font-size: 16px; + font-size: 1rem; + border: 1px solid #003366; + border-color: #003366; + border-radius: 10px; + padding: 5px; + color: #6c6c6c; } #buttons { - display: flex; - justify-content: space-around; - align-items: center; - width: 100%; + display: flex; + justify-content: space-around; + align-items: center; + width: 100%; } .form-button:disabled { - background-color: #6C6C6C !important; - opacity: 65%; - cursor: not-allowed; + background-color: #6C6C6C !important; + opacity: 65%; + cursor: not-allowed; } .form-button { - display: flex; - flex-direction: column; - color: #ffffff; - border: none; - padding: 10px 30px; - border-radius: 50px; - cursor: pointer; - font-size: 16px; - font-weight: bold; - margin-bottom: 20px; + display: flex; + flex-direction: column; + color: #ffffff; + border: none; + padding: 10px 30px; + border-radius: 50px; + cursor: pointer; + font-size: 16px; + font-weight: bold; + margin-bottom: 20px; } .form-button:hover { - filter: brightness(1.8); + filter: brightness(1.8); } #cancelar-bnt a { - text-decoration: none; - color: #ffffff; + text-decoration: none; + color: #ffffff; } #registrar-bnt.form-button { - margin-left: 8px; - padding: 10px 10px; - transition: background-color 0.3s, filter 0.3s; - background-color: #006633; + margin-left: 8px; + padding: 10px 10px; + transition: background-color 0.3s, filter 0.3s; + background-color: #006633; } #input-description { - color: #6c6c6c; - font-size: 10px; + color: #6c6c6c; + font-size: 10px; } .elipse-registerPrinter { - position: fixed; - width: 60vw; - height: 100vh; - top: 0; - right: 0; - z-index: -1; - bottom: 2px; - color: #003366; - overflow: hidden; + position: fixed; + width: 60vw; + height: 100vh; + top: 0; + right: 0; + z-index: -1; + bottom: 2px; + color: #003366; + overflow: hidden; } .elipse-registerPrinter img { - height: 150vh; + height: 150vh; } @media (max-width: 900px) { - #registerPrinter-card { - width: 90%; /* Adjust the form width as needed*/ - margin: 0 auto; /* Centers the form horizontally*/ - padding: 1rem; /* Adjust padding as needed */ - } + #registerPrinter-card { + width: 90%; + /* Adjust the form width as needed*/ + margin: 0 auto; + /* Centers the form horizontally*/ + padding: 1rem; + /* Adjust padding as needed */ + } - #input-line { - display: block; - } + #input-line { + display: block; + } } @keyframes spin { from { transform: rotate(0deg); } + to { transform: rotate(360deg); } } -#animate-spin{ +#animate-spin { animation: spin 1s linear infinite; margin-right: 4px; } diff --git a/src/style/pages/aboutUs.css b/src/style/pages/aboutUs.css index 35d96305..2b264ce4 100644 --- a/src/style/pages/aboutUs.css +++ b/src/style/pages/aboutUs.css @@ -1,6 +1,7 @@ body { - font-family: 'Overpass', sans-serif; + font-family: 'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', } .container-about-us{ diff --git a/src/style/pages/contractList.css b/src/style/pages/contractList.css new file mode 100644 index 00000000..1b1f93ff --- /dev/null +++ b/src/style/pages/contractList.css @@ -0,0 +1,58 @@ +.contract-list { + display: flex; + flex-direction: column; + gap: 15px; + padding-inline: 70px; + padding-top: 40px; +} + +.mainArea{ + background-color: rgb(255, 255, 255); + margin-top: 5px; + padding-inline: 100px; + justify-content: center; +} + +.barraPesquisa{ + display: flex; + align-items: center; + justify-content: space-between; + border-bottom-style: solid; + border-color: #0D3D6D; + margin-inline: 70px; + max-height: 120px; + margin-bottom: -10px; +} + +.titulo{ + font-weight: 400; + font-size: 48px; + color: #0D3D6D; +} + +#searchBar{ + width: 20vw; + height: 6vh; + border-radius: 5vh; + border: #0D3D6D 2px solid; + padding-left: 20px; + font-size: 24px; +} + +::placeholder{ + font-size: 24px; +} + +#buttonContracts{ + background-color: #006633; + border-radius: 60px; + margin-top: 20px; + margin-left: 70px; + width: 22vw; + height: 6vh; + border-style: none; + color: rgb(255, 255, 255); + font-size: 24px; + font-weight: 600; + cursor: pointer; +} diff --git a/src/style/pages/login.css b/src/style/pages/login.css index a243de8e..42c20f65 100644 --- a/src/style/pages/login.css +++ b/src/style/pages/login.css @@ -1,6 +1,7 @@ body { - font-family: 'Overpass', sans-serif; + font-family: 'Jost', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', } .login-right-content{ diff --git a/src/style/pages/patternList.css b/src/style/pages/patternList.css index 4e12acd6..77249397 100644 --- a/src/style/pages/patternList.css +++ b/src/style/pages/patternList.css @@ -2,22 +2,29 @@ .patternlist-container{ position: relative; width: 100vw; - height: 100vh; text-align: left; + display: flex; + flex-direction: column; + align-items: center; + } /* Header */ .patternlist-header{ height: 10vh; - color: #ffffff; + width: 80vw; + color: #0D3D6D; display: flex; align-items: center; justify-content: space-between; - background-color: #003366; padding-left: 20px; padding-right: 40px; padding-top: 10px; padding-bottom: 10px; + margin-top: 40px; + margin-bottom: 40px; + border-bottom:#003366 4px solid; + } .patternlist-header-title { @@ -39,16 +46,20 @@ .patternlist-header-search-filter { display: flex; align-items: center; - justify-content: end; - width: fit-content; height: 100%; - gap: 20px; + } .patternlist-header-search-filter input{ - height: 2.4vh; + height: 5vh; width: 20vw; margin-bottom: 8px; + justify-self: end; + border-radius: 50px; + font-size: large; + color: #003366; + border: #0D3D6D 2px solid; + } .patternlist filter { @@ -56,18 +67,26 @@ } /* Filter dropdown */ + .patternlist-filter:hover{ cursor: pointer; } - +.patternlist-filter img{ + margin-left: 10px; + height: 3.5vw; +} .patternlist-dropdown-filter { display: none; position: absolute; + margin-right: 9vw; right: 0px; background-color: #f9f9f9; min-width: 100px; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 1; + border: #0D3D6D 1px solid; + border-radius: 10px; + } .patternlist-dropdown-filter a{ @@ -76,6 +95,7 @@ display: block; font-size: 20px; padding: 4px 4px; + border-radius: 10px; } .patternlist-dropdown-filter a:hover{ @@ -90,16 +110,18 @@ /* Padrão */ .patternlist-pattern { - height:18vh; - width: 100vw; + height:13vh; + width: 70vw; + margin-top: 2vh; color: #003366; font-size: 25px; display: flex; justify-content: space-between; align-items: center; - box-shadow: 0 5px 5px -3px black; + border: #003366 2px solid; padding-left: 20px; padding-right: 20px; + border-radius: 20px; } .patternlist-pattern h6 { @@ -117,7 +139,6 @@ .patternlist-model h4{ width: 60vw; margin: 0; - padding-left: lrem; cursor: pointer; } @@ -143,7 +164,7 @@ display: flex; flex-direction: column; height: fit-content; - width: 4vw; + width: 3vw; margin-right: 40px; cursor: pointer; } @@ -153,17 +174,22 @@ position: absolute; right: 0px; background-color: #f9f9f9; - min-width: 180px; + margin-right: 15vw; + min-width: 120px; box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2); z-index: 1; + border: #0D3D6D 1px solid; + border-radius: 10px; } + .patternlist-pattern-dropdown a{ color: #003366; text-decoration: none; display: block; font-size: 20px; padding: 4px 4px; + border-radius: 10px; } .patternlist-pattern-dropdown a:hover{ diff --git a/src/style/pages/registerPrinter.css b/src/style/pages/registerPrinter.css index 03ba8220..930aeb40 100644 --- a/src/style/pages/registerPrinter.css +++ b/src/style/pages/registerPrinter.css @@ -1,6 +1,8 @@ #registerPrinter-container { - display: flex; - justify-content: space-between; + padding-left: 300px; + padding-top: 50px; + display: flow-root; + padding-right: 200px; align-items: center; } diff --git a/src/style/pages/viewPattern.css b/src/style/pages/viewPattern.css index 69399905..ad5c30e6 100644 --- a/src/style/pages/viewPattern.css +++ b/src/style/pages/viewPattern.css @@ -4,6 +4,7 @@ display: flex; justify-content: flex-end; align-items: center; + } /* View card */ @@ -53,8 +54,7 @@ width: 100%; flex-wrap: wrap; justify-content: space-between; - margin-bottom: 20px; - padding: 16px 0; + } .viewpattern-info-header { @@ -62,6 +62,7 @@ width: 100%; color: #003366; font-size: 30px; + } .viewpattern-info-line { @@ -76,20 +77,27 @@ color: #003366; display: block; margin-bottom: 0px; + } .viewpattern-info-box { display: flex; - width: 50%; + width: 30%; flex-direction: column; - margin-bottom: 12px; + margin: 12px 10px; /* Adiciona espaço acima, abaixo, à direita e à esquerda */ box-sizing: border-box; + border: 1px solid #003366; /* Adiciona a borda */ + padding: 5px; /* Adiciona espaço interno */ + border-radius: 15px; /* Adiciona cantos arredondados */ + } .viewpattern-info-box label { color: #003366; display: block; margin-bottom: 0px; + font-weight: bold; /* Deixa todos os textos dentro de .viewpattern-info-box em negrito */ + } .viewpattern-info-box p { @@ -97,17 +105,20 @@ display: block; font-size: 20px; margin-top: 5px; - margin-bottom: 0px; + margin-bottom: 5px; + } .viewpattern-oid-line { display: block; width: 100%; margin-bottom: 30px; + } .viewpattern-oid-line p { color: #003366; + } .viewpattern-oid-box { @@ -115,13 +126,17 @@ justify-content: flex-start; width: 100%; height: fit-content; - margin: 0px; + margin: 15px 0; /* Adiciona espaço acima e abaixo */ + border: 1px solid #003366; /* Adiciona a borda */ + padding: 5px; /* Adiciona espaço interno */ + border-radius: 15px; /* Adiciona cantos arredondados */ } .viewpattern-oid-box label { color: #003366; width: 50%; - margin-bottom: 0px; + margin: 5px 5px; /* */ + font-weight: bold; /* Deixa todos os textos dentro de .viewpattern-info-box em negrito */ } .viewpattern-oid-box p { @@ -129,7 +144,7 @@ display: block; font-size: 16px; margin-top: 5px; - margin-bottom: 0px; + margin-bottom: 5px; } /*Estilo de circuferencia */ diff --git a/src/style/pages/viewPrinter.css b/src/style/pages/viewPrinter.css index b3469192..5936298c 100644 --- a/src/style/pages/viewPrinter.css +++ b/src/style/pages/viewPrinter.css @@ -1,132 +1,98 @@ -/* Container */ - -#container-viewprinter { - display: flex; - justify-content: flex-start; - align-items: center; +.space { + margin: 50px 0px; } -#viewprinter-left-content { - width: 30vw; +#view-printer-data{ + padding-left: 300px; + padding-top: 50px; + display: flow-root; + padding-right: 200px; + align-items: center; } -#viewprinter-right-content { - width: 70vw; +.header-container { display: flex; - justify-content: flex-end; + align-items: center; + justify-content: space-between; + gap: 2rem; +} + +.info-cards-container { + display: flex; + gap: 2rem; } -/* View card */ -#viewprinter-card { - background-color: #FFFFFF; - border-radius: 10px; +.container { display: flex; - width: 43rem; - height: 100%; - justify-content: flex-start; align-items: center; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.5); - padding: 1rem 5rem; - margin-right: 8vw; - margin-top: 11%; - margin-bottom: 1vh; + gap: 1rem; } -#viewprinter-loading-text { - color: #003366; - display: block; - font-size: 20px; +.form-separator { + font-size: 28px; + color: #0D3D6D; + margin-bottom: 16px; + border-bottom: 2px solid #0D3D6D; + padding-top: 50px; } -/* Header */ - -#viewprinter-card-header { - width: 100%; - margin-top: 10px; - display: block; +.big-info-cards-container { + display: flex; + flex-direction: column; + align-items: center; + margin-top: 20px; } -#viewprinter-card-header a { - font-weight: bold; - font-size: 22px; - color: #003366; - margin-left: 8px; - text-decoration: none; +.big-info-card { + text-align: left; /* Títulos alinhados à esquerda */ } -/* Infos */ +.space { + margin-bottom: 20px; +} -#viewprinter-info-group{ +.printer-field { display: flex; - width: 100%; - flex-wrap: wrap; justify-content: space-between; - margin-bottom: 20px; - padding: 16px 0; -} - -#viewprinter-info-header { - display: block; - margin-bottom: 20px; - width: 100%; - color: #003366; - font-size: 30px; } -#viewprinter-info-line { - display: flex; - width: 100%; - justify-content: flex-start; - flex-wrap: wrap; +.info-field{ + width: fit-content; + flex: 1; + margin-right: 2rem; } -#viewprinter-info-box { - display: flex; - width: 50%; - flex-direction: column; - margin-bottom: 20px; - box-sizing: border-box; +.cards-field{ + width: fit-content; } -#viewprinter-info-box label { - color: #003366; - display: block; - margin-bottom: 0px; +#localization { + padding-top: 0px; } -#viewprinter-info-box p { - color: #003366; - display: block; - font-size: 20px; - margin-top: 5px; - margin-bottom: 0px; -} -/*Estilo de circuferencia */ +@media (max-width: 900px) { + #registerPrinter-card { + width: 90%; + /* Adjust the form width as needed*/ + margin: 0 auto; + /* Centers the form horizontally*/ + padding: 1rem; + /* Adjust padding as needed */ + } -.elipse-viewprinter{ - position: fixed; - display: flex; - width: fit-content; - min-height: 100vh; - justify-content: flex-end; - align-items: end; - z-index: -1; - color:#003366; + #input-line { + display: block; + } } -.elipse-viewprinter img{ - width: 40vw; - height: 100vh; -} +@keyframes spin { + from { + transform: rotate(0deg); + } -@media (max-width: 1210px) { - .container-viewprinter{ - display: flex; - flex-direction: column; - gap: 5rem; - padding-left: 2rem; - align-items: center; + to { + transform: rotate(360deg); } } diff --git a/src/utils/encode.js b/src/utils/encode.js new file mode 100644 index 00000000..8eedaa0a --- /dev/null +++ b/src/utils/encode.js @@ -0,0 +1,3 @@ +export default function encodeSpecialChars(originalString) { + return originalString.replace('/', '%2F'); +} \ No newline at end of file diff --git a/src/utils/formatDate.js b/src/utils/formatDate.js new file mode 100644 index 00000000..bfef29db --- /dev/null +++ b/src/utils/formatDate.js @@ -0,0 +1,3 @@ +export default function formatDate(string) { + return string.slice(0, 10) +} \ No newline at end of file