From 29f9139b6c2feb511aee30f0351dbc20ccdeb129 Mon Sep 17 00:00:00 2001 From: VPS 4 Builder Date: Tue, 7 Jul 2026 02:36:17 +0200 Subject: [PATCH] feat(ui): centraliza estilo de filtros/busca (components/filterStyles) + SearchInput MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fonte única para os campos de filtro (inputNew/labelNew) e um componente SearchInput padrão (ícone + input arredondado, encaminha ref/props). Profissionais e Salas passam a importar do módulo (dedupe). Aplica SearchInput na busca do Orçamentos como 1ª adoção. Buscas que são autocomplete com dropdown (Pacientes, Relatórios) ficam para conversão cuidadosa caso a caso (não quebrar o dropdown). Co-Authored-By: Claude Opus 4.8 --- frontend/components/filterStyles.tsx | 28 +++++++++++++++++++ frontend/views/OrcamentosView.tsx | 12 ++------ .../views/plugins/ProfissionaisPlugin.tsx | 5 ++-- frontend/views/plugins/SalasPlugin.tsx | 5 ++-- 4 files changed, 34 insertions(+), 16 deletions(-) create mode 100644 frontend/components/filterStyles.tsx diff --git a/frontend/components/filterStyles.tsx b/frontend/components/filterStyles.tsx new file mode 100644 index 0000000..3162300 --- /dev/null +++ b/frontend/components/filterStyles.tsx @@ -0,0 +1,28 @@ +// Estilo PADRÃO de filtros/busca do app (fonte única). Referência visual: +// marketplace de profissionais / alugar salas. +import React, { forwardRef } from 'react'; +import { Search } from 'lucide-react'; + +// Classes de campo e rótulo dos filtros (select/input dentro do card de filtros). +export const inputNew = 'w-full px-4 py-3 bg-gray-50 border border-gray-200 rounded-xl text-sm font-semibold text-gray-700 outline-none focus:border-teal-400 focus:bg-white transition-colors'; +export const labelNew = 'text-[11px] font-bold text-gray-500 mb-1.5 block'; + +// Campo de BUSCA padrão (ícone à esquerda + input arredondado). Encaminha ref e +// todos os props nativos (value, onChange, onKeyDown, onFocus, autoFocus, etc.). +interface SearchInputProps extends React.InputHTMLAttributes { + /** classe do wrapper (ex.: largura: 'w-full' | 'min-w-[220px]'). */ + wrapperClassName?: string; +} +export const SearchInput = forwardRef( + ({ wrapperClassName = 'w-full', className = '', ...rest }, ref) => ( +
+ + +
+ ), +); +SearchInput.displayName = 'SearchInput'; diff --git a/frontend/views/OrcamentosView.tsx b/frontend/views/OrcamentosView.tsx index 27e5910..4eac342 100644 --- a/frontend/views/OrcamentosView.tsx +++ b/frontend/views/OrcamentosView.tsx @@ -6,6 +6,7 @@ import { useHybridBackend } from '../hooks/useHybridBackend.ts'; import { useToast } from '../contexts/ToastContext.tsx'; import { useConfirm } from '../contexts/ConfirmContext.tsx'; import { PageHeader } from '../components/PageHeader.tsx'; +import { SearchInput } from '../components/filterStyles.tsx'; import { OrcamentoModal, DEFAULT_CLAUSULAS } from './OrcamentoModal.tsx'; type StatusFilter = 'TODOS' | 'Ativo' | 'Rascunho' | 'Assinado' | 'Encerrado'; @@ -148,16 +149,7 @@ export const OrcamentosView: React.FC = () => { {/* Search + status filters */}
-
- - setSearch(e.target.value)} - /> -
+ setSearch(e.target.value)} />
{STATUS_TABS.map(s => (