feat: otimizacao de responsividade para celulares e tablets em todas as telas e modais

This commit is contained in:
2026-08-28 11:48:13 +00:00
parent dce4c04fa4
commit f91b513297
10 changed files with 117 additions and 115 deletions
+1 -1
View File
@@ -335,7 +335,7 @@ export const Layout: React.FC<LayoutProps> = ({ children }) => {
"md:pl-68", // Push content on desktop
"pt-16 md:pt-0" // Add padding on mobile for header
)}>
<div className="max-w-7xl mx-auto px-6 sm:px-10 lg:px-12 py-10 w-full animate-in fade-in slide-in-from-bottom-4 duration-500">
<div className="max-w-7xl mx-auto px-3.5 sm:px-6 md:px-8 lg:px-12 py-5 sm:py-8 md:py-10 w-full animate-in fade-in slide-in-from-bottom-4 duration-500">
{children}
</div>
</main>
+6 -6
View File
@@ -13,15 +13,15 @@ export const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children,
if (!isOpen) return null;
return (
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4">
<div className={`bg-surface rounded-2xl shadow-[var(--shadow-premium)] w-full ${maxWidth} max-h-[90vh] flex flex-col animate-in fade-in zoom-in duration-200 border border-border/40 relative`}>
<div className="flex justify-between items-center p-5 border-b border-border">
<h2 className="text-xl font-bold text-text-main">{title}</h2>
<button onClick={onClose} className="p-2 text-text-secondary hover:bg-surface-hover hover:text-text-main rounded-lg transition-colors" aria-label="Fechar modal">
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-2.5 sm:p-4">
<div className={`bg-surface rounded-2xl sm:rounded-3xl shadow-[var(--shadow-premium)] w-full ${maxWidth} max-h-[92vh] flex flex-col animate-in fade-in zoom-in duration-200 border border-border/40 relative overflow-hidden`}>
<div className="flex justify-between items-center p-4 sm:p-5 border-b border-border">
<h2 className="text-lg sm:text-xl font-bold text-text-main truncate pr-2">{title}</h2>
<button onClick={onClose} className="p-2 text-text-secondary hover:bg-surface-hover hover:text-text-main rounded-lg transition-colors shrink-0" aria-label="Fechar modal">
<X className="w-5 h-5" />
</button>
</div>
<div className="p-6 overflow-y-auto">
<div className="p-4 sm:p-6 overflow-y-auto">
{children}
</div>
</div>
@@ -242,7 +242,7 @@ export const CreatePaintingSchemeModal: React.FC<CreatePaintingSchemeModalProps>
required
/>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Select
name="type"
label="Tipo de Tinta"
@@ -259,18 +259,18 @@ export const CreatePaintingSchemeModal: React.FC<CreatePaintingSchemeModalProps>
<Input name="solidsVolume" label="Sólidos Vol. (%)" type="number" value={formData.solidsVolume} onChange={handleChange} />
</div>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Input name="yieldTheoretical" label="Rendimento (m²/L)" type="number" step="0.01" value={formData.yieldTheoretical} onChange={handleChange} />
</div>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Input name="epsMin" label="EPS Mín (μm)" type="number" value={formData.epsMin} onChange={handleChange} />
<Input name="epsMax" label="EPS Máx (μm)" type="number" value={formData.epsMax} onChange={handleChange} />
</div>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Input name="dilution" label="Diluição (%)" type="number" value={formData.dilution} onChange={handleChange} />
<Input name="manufacturer" label="Fabricante" value={formData.manufacturer} onChange={handleChange} />
</div>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Input name="color" label="Cor (Munsell/RAL)" placeholder="Ex: N6.5 ou RAL 7035" value={formData.color} onChange={handleChange} />
<div className="flex flex-col gap-1">
<label className="text-[10px] font-bold text-primary uppercase tracking-[0.15em] ml-1 mb-1">Cor Representativa</label>
@@ -299,9 +299,9 @@ export const CreatePaintingSchemeModal: React.FC<CreatePaintingSchemeModalProps>
/>
</div>
<div className="bg-surface-soft p-4 rounded-xl border border-border/40 mt-4">
<div className="bg-surface-soft p-3.5 sm:p-4 rounded-xl border border-border/40 mt-4">
<h3 className="text-sm font-bold text-text-main mb-3">Planejamento de Consumo (Opcional)</h3>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Select
name="paintId"
label="Produto (Tinta)"
@@ -346,7 +346,7 @@ export const CreatePaintingSchemeModal: React.FC<CreatePaintingSchemeModalProps>
/>
</div>
</div>
<div className="grid grid-cols-2 gap-4 mt-2">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4 mt-2">
<Input
name="paintConsumption"
label="Consumo Tinta (L/Kg)"
@@ -134,7 +134,7 @@ export const CreateProjectModal: React.FC<CreateProjectModalProps> = ({ isOpen,
<Input name="name" label="Nome do Projeto" required value={formData.name} onChange={handleChange} />
<Input name="client" label="Cliente" required value={formData.client} onChange={handleChange} />
<Input name="technician" label="Responsável Técnico" value={formData.technician} onChange={handleChange} />
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<Input name="startDate" label="Início Planejado" type="date" value={formData.startDate} onChange={handleChange} />
<Input name="endDate" label="Fim Planejado" type="date" value={formData.endDate} onChange={handleChange} />
</div>
@@ -161,14 +161,14 @@ export const CreateProjectModal: React.FC<CreateProjectModalProps> = ({ isOpen,
) : (
<div className="space-y-6 text-center py-4">
<div className="space-y-2">
<h3 className="text-xl font-bold text-text-main">Configurar Esquema de Pintura?</h3>
<p className="text-sm text-text-muted px-4">O projeto foi criado. Deseja adicionar um esquema de pintura agora?</p>
<h3 className="text-lg sm:text-xl font-bold text-text-main">Configurar Esquema de Pintura?</h3>
<p className="text-xs sm:text-sm text-text-muted px-2 sm:px-4">O projeto foi criado. Deseja adicionar um esquema de pintura agora?</p>
</div>
<div className="grid grid-cols-2 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
<button
onClick={() => setShowImportModal(true)}
className="flex flex-col items-center justify-center gap-3 p-6 rounded-2xl border-2 border-dashed border-border hover:border-primary hover:bg-primary/5 transition-all group"
className="flex flex-col items-center justify-center gap-3 p-4 sm:p-6 rounded-2xl border-2 border-dashed border-border hover:border-primary hover:bg-primary/5 transition-all group"
>
<div className="p-3 rounded-full bg-surface-soft group-hover:bg-white text-primary transition-colors">
<FileDown size={24} />
+5 -5
View File
@@ -121,11 +121,11 @@ export const AdminDashboard: React.FC = () => {
</div>
{/* Tabs Navigation */}
<div className="flex p-1 bg-surface-soft rounded-xl border border-border/40 w-fit">
<div className="flex p-1 bg-surface-soft rounded-xl border border-border/40 overflow-x-auto max-w-full scrollbar-hide">
<button
onClick={() => setActiveTab('users')}
className={clsx(
"flex items-center gap-2 px-6 py-2.5 text-sm font-bold rounded-lg transition-all",
"flex items-center gap-2 px-4 sm:px-6 py-2 sm:py-2.5 text-xs sm:text-sm font-bold rounded-lg transition-all shrink-0",
activeTab === 'users'
? "bg-surface text-primary shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -137,7 +137,7 @@ export const AdminDashboard: React.FC = () => {
<button
onClick={() => setActiveTab('organization')}
className={clsx(
"flex items-center gap-2 px-6 py-2.5 text-sm font-bold rounded-lg transition-all",
"flex items-center gap-2 px-4 sm:px-6 py-2 sm:py-2.5 text-xs sm:text-sm font-bold rounded-lg transition-all shrink-0",
activeTab === 'organization'
? "bg-surface text-primary shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -149,7 +149,7 @@ export const AdminDashboard: React.FC = () => {
<button
onClick={() => setActiveTab('settings')}
className={clsx(
"flex items-center gap-2 px-6 py-2.5 text-sm font-bold rounded-lg transition-all",
"flex items-center gap-2 px-4 sm:px-6 py-2 sm:py-2.5 text-xs sm:text-sm font-bold rounded-lg transition-all shrink-0",
activeTab === 'settings'
? "bg-surface text-primary shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -161,7 +161,7 @@ export const AdminDashboard: React.FC = () => {
<button
onClick={() => setActiveTab('backup')}
className={clsx(
"flex items-center gap-2 px-6 py-2.5 text-sm font-bold rounded-lg transition-all",
"flex items-center gap-2 px-4 sm:px-6 py-2 sm:py-2.5 text-xs sm:text-sm font-bold rounded-lg transition-all shrink-0",
activeTab === 'backup'
? "bg-surface text-primary shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
+9 -9
View File
@@ -181,20 +181,20 @@ export const CalculatorDashboard: React.FC = () => {
};
return (
<div className="space-y-8 animate-in fade-in duration-700">
<div className="space-y-6 sm:space-y-8 animate-in fade-in duration-700">
{/* Header */}
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 pb-2">
<div className="space-y-4">
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 md:gap-6 pb-2">
<div className="space-y-2">
<div>
<h1 className="text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">Ferramentas & Cálculos</h1>
<p className="text-sm text-text-muted font-medium tracking-wide">Utilitários técnicos para pintura industrial</p>
<h1 className="text-2xl sm:text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">Ferramentas & Cálculos</h1>
<p className="text-xs sm:text-sm text-text-muted font-medium tracking-wide">Utilitários técnicos para pintura industrial</p>
</div>
</div>
</div>
{/* Tabs */}
<div className="flex items-center justify-between border-b border-border/40 scrollbar-hide overflow-x-auto">
<nav className="flex space-x-10 min-w-max px-2" aria-label="Tabs">
<nav className="flex space-x-3 sm:space-x-6 md:space-x-10 min-w-max px-1" aria-label="Tabs">
{[
{ id: 'conversion', label: 'Conversões', icon: ArrowRightLeft },
{ id: 'thickness', label: 'Espessura', icon: Ruler },
@@ -209,7 +209,7 @@ export const CalculatorDashboard: React.FC = () => {
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={clsx(
'whitespace-nowrap py-5 px-1 border-b-2 font-bold text-xs uppercase tracking-[0.15em] flex items-center gap-3 transition-all relative',
'whitespace-nowrap py-3.5 sm:py-5 px-1 border-b-2 font-bold text-[11px] sm:text-xs uppercase tracking-[0.15em] flex items-center gap-2 sm:gap-3 transition-all relative',
active
? 'border-primary text-primary'
: 'border-transparent text-text-muted hover:text-text-main hover:border-border'
@@ -230,8 +230,8 @@ export const CalculatorDashboard: React.FC = () => {
{/* 1. CONVERSION */}
{activeTab === 'conversion' && (
<div className="max-w-2xl mx-auto space-y-6 animate-in slide-in-from-bottom-4 duration-500">
<Card className="p-8 space-y-8 bg-surface border-border/40 shadow-soft">
<div className="flex flex-col gap-2 border-b border-border/40 pb-6">
<Card className="p-4 sm:p-6 md:p-8 space-y-6 sm:space-y-8 bg-surface border-border/40 shadow-soft">
<div className="flex flex-col gap-1 sm:gap-2 border-b border-border/40 pb-4 sm:pb-6">
<h3 className="text-xl font-bold text-text-main">Conversor de Unidades</h3>
<p className="text-sm text-text-muted">Microns (μm) Milesimos de Polegada (mils)</p>
</div>
+6 -6
View File
@@ -141,11 +141,11 @@ export const DeveloperDashboard: React.FC = () => {
</div>
{/* Tabs Navigation */}
<div className="flex items-center gap-2 p-1 bg-surface-soft rounded-2xl border border-border/20 w-fit">
<div className="flex items-center gap-1.5 sm:gap-2 p-1 bg-surface-soft rounded-2xl border border-border/20 overflow-x-auto max-w-full scrollbar-hide">
<button
onClick={() => setActiveTab('overview')}
className={clsx(
"flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-xl transition-all",
"flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-2 text-xs sm:text-sm font-bold rounded-xl transition-all shrink-0",
activeTab === 'overview'
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -157,7 +157,7 @@ export const DeveloperDashboard: React.FC = () => {
<button
onClick={() => setActiveTab('organizations')}
className={clsx(
"flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-xl transition-all",
"flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-2 text-xs sm:text-sm font-bold rounded-xl transition-all shrink-0",
activeTab === 'organizations'
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -169,7 +169,7 @@ export const DeveloperDashboard: React.FC = () => {
<button
onClick={() => setActiveTab('users')}
className={clsx(
"flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-xl transition-all",
"flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-2 text-xs sm:text-sm font-bold rounded-xl transition-all shrink-0",
activeTab === 'users'
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -181,7 +181,7 @@ export const DeveloperDashboard: React.FC = () => {
<button
onClick={() => setActiveTab('branding')}
className={clsx(
"flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-xl transition-all",
"flex items-center gap-1.5 sm:gap-2 px-3 sm:px-4 py-2 text-xs sm:text-sm font-bold rounded-xl transition-all shrink-0",
activeTab === 'branding'
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
@@ -193,7 +193,7 @@ export const DeveloperDashboard: React.FC = () => {
</div>
{/* Content Area */}
<div className="bg-surface rounded-3xl border border-border/40 min-h-[500px] overflow-hidden">
<div className="bg-surface rounded-2xl sm:rounded-3xl border border-border/40 min-h-[450px] overflow-hidden">
{activeTab === 'overview' && (
<div className="p-12 flex flex-col items-center justify-center text-center h-full">
<div className="w-16 h-16 rounded-2xl bg-indigo-500/10 flex items-center justify-center mb-6 text-indigo-500 ring-1 ring-indigo-500/20">
+20 -20
View File
@@ -201,17 +201,17 @@ export const ProjectDetails: React.FC = () => {
return (
<div className="space-y-8 animate-in fade-in duration-700">
{/* Page Header */}
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 pb-2">
<div className="space-y-4">
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 md:gap-6 pb-2">
<div className="space-y-3 sm:space-y-4">
<Link to="/projects">
<button className="flex items-center text-[10px] font-bold text-text-muted uppercase tracking-[0.2em] hover:text-primary transition-colors group">
<ArrowLeft className="w-3 h-3 mr-2 group-hover:-translate-x-1 transition-transform" />
Voltar aos Projetos
</button>
</Link>
<div className="flex flex-col sm:flex-row sm:items-center gap-4">
<h1 className="text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">{project.name}</h1>
<span className="inline-flex items-center px-3 py-1 rounded-full bg-primary/10 text-primary text-[10px] font-black uppercase tracking-widest border border-primary/20 shadow-sm shadow-primary/5">
<div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
<h1 className="text-2xl sm:text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">{project.name}</h1>
<span className="inline-flex items-center w-fit px-3 py-1 rounded-full bg-primary/10 text-primary text-[10px] font-black uppercase tracking-widest border border-primary/20 shadow-sm shadow-primary/5">
<Activity className="w-3 h-3 mr-2" />
Em Andamento
</span>
@@ -221,12 +221,12 @@ export const ProjectDetails: React.FC = () => {
<div className="w-6 h-6 rounded-full bg-surface-highlight border-2 border-surface flex items-center justify-center text-[10px] font-bold">M</div>
<div className="w-6 h-6 rounded-full bg-primary/20 border-2 border-surface flex items-center justify-center text-[10px] font-bold text-primary">G</div>
</div>
<span className="text-sm text-text-secondary font-medium">{project.client} {project.environment}</span>
<span className="text-xs sm:text-sm text-text-secondary font-medium">{project.client} {project.environment}</span>
</div>
</div>
{isAdmin() && (
<div className="flex gap-3">
<div className="flex flex-wrap sm:flex-nowrap gap-2 sm:gap-3">
<Button variant="secondary" size="sm" onClick={() => setIsEditProjectModalOpen(true)}>
<Pencil className="w-4 h-4 mr-2" /> Editar Obra
</Button>
@@ -238,45 +238,45 @@ export const ProjectDetails: React.FC = () => {
</div>
{/* Premium Summary Grid */}
<div className="relative overflow-hidden rounded-3xl bg-surface border border-border/40 shadow-soft p-8">
<div className="relative overflow-hidden rounded-2xl sm:rounded-3xl bg-surface border border-border/40 shadow-soft p-4 sm:p-6 md:p-8">
<div className="absolute top-0 right-0 p-8 opacity-5">
<Activity size={120} strokeWidth={1} />
</div>
<div className="grid grid-cols-2 md:grid-cols-4 gap-8 relative z-10">
<div className="grid grid-cols-2 md:grid-cols-4 gap-4 sm:gap-6 md:gap-8 relative z-10">
<div className="space-y-1">
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Data de Início</span>
<p className="text-lg font-bold text-text-main">{project.startDate ? format(new Date(project.startDate), 'dd MMM, yyyy') : '-'}</p>
<p className="text-sm sm:text-base md:text-lg font-bold text-text-main">{project.startDate ? format(new Date(project.startDate), 'dd MMM, yyyy') : '-'}</p>
</div>
<div className="space-y-1">
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Previsão Término</span>
<p className="text-lg font-bold text-text-main">{project.endDate ? format(new Date(project.endDate), 'dd MMM, yyyy') : '-'}</p>
<p className="text-sm sm:text-base md:text-lg font-bold text-text-main">{project.endDate ? format(new Date(project.endDate), 'dd MMM, yyyy') : '-'}</p>
</div>
<div className="space-y-1">
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Peso da Obra (KGF)</span>
<p className="text-lg font-bold text-text-main">
{project.weightKg ? Number(project.weightKg).toLocaleString('pt-BR') : '0'} <span className="text-sm text-text-muted">kg</span>
<p className="text-sm sm:text-base md:text-lg font-bold text-text-main">
{project.weightKg ? Number(project.weightKg).toLocaleString('pt-BR') : '0'} <span className="text-xs sm:text-sm text-text-muted">kg</span>
</p>
</div>
<div className="space-y-1">
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Evolução%</span>
<p className="text-lg font-bold text-primary">
<p className="text-sm sm:text-base md:text-lg font-bold text-primary">
{project.weightKg && project.paintedWeight !== undefined
? Math.min(Math.round((project.paintedWeight / project.weightKg) * 100), 100)
: 0}
<span className="text-sm">%</span>
<span className="text-xs sm:text-sm">%</span>
</p>
</div>
</div>
<div className="mt-6 pt-6 border-t border-border/20 grid grid-cols-1 md:grid-cols-2 gap-6 relative z-10">
<div className="mt-4 sm:mt-6 pt-4 sm:pt-6 border-t border-border/20 grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-6 relative z-10">
<div className="space-y-1">
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Localização/Amb.</span>
<p className="text-sm font-medium text-text-secondary">{project.environment || '-'}</p>
<p className="text-xs sm:text-sm font-medium text-text-secondary">{project.environment || '-'}</p>
</div>
<div className="space-y-1">
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Eng. Responsável</span>
<div className="flex items-center gap-2">
<div className="w-2 h-2 rounded-full bg-blue-500"></div>
<p className="text-sm font-bold text-text-main">{project.technician || '-'}</p>
<p className="text-xs sm:text-sm font-bold text-text-main">{project.technician || '-'}</p>
</div>
</div>
</div>
@@ -284,7 +284,7 @@ export const ProjectDetails: React.FC = () => {
{/* Navigation Tabs */}
<div className="flex items-center justify-between border-b border-border/40 scrollbar-hide overflow-x-auto">
<nav className="flex space-x-10" aria-label="Tabs">
<nav className="flex space-x-4 sm:space-x-8 md:space-x-10 min-w-max px-1" aria-label="Tabs">
{tabs.map((tab) => {
const Icon = tab.icon;
const active = activeTab === tab.id;
@@ -293,7 +293,7 @@ export const ProjectDetails: React.FC = () => {
key={tab.id}
onClick={() => setActiveTab(tab.id)}
className={clsx(
'whitespace-nowrap py-5 px-1 border-b-2 font-bold text-xs uppercase tracking-[0.15em] flex items-center gap-3 transition-all relative',
'whitespace-nowrap py-3.5 sm:py-5 px-1 border-b-2 font-bold text-[11px] sm:text-xs uppercase tracking-[0.15em] flex items-center gap-2 sm:gap-3 transition-all relative',
active
? 'border-primary text-primary'
: 'border-transparent text-text-muted hover:text-text-main hover:border-border'
+17 -17
View File
@@ -351,17 +351,17 @@ export const ProjectList: React.FC = () => {
return (
<div className="space-y-10 animate-in fade-in duration-700">
{/* Page Header */}
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6">
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 md:gap-6">
<div className="space-y-2">
<div className="flex items-center gap-3">
<div className="w-12 h-12 rounded-2xl bg-primary/10 flex items-center justify-center text-primary shadow-sm">
<Activity className="w-6 h-6" />
<div className="w-10 h-10 sm:w-12 sm:h-12 rounded-2xl bg-primary/10 flex items-center justify-center text-primary shadow-sm shrink-0">
<Activity className="w-5 h-5 sm:w-6 sm:h-6" />
</div>
<div>
<h1 className="text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">
<h1 className="text-2xl sm:text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">
{viewStatus === 'active' ? 'Gestão de Obras' : 'Obras Arquivadas'}
</h1>
<p className="text-sm text-text-muted font-medium tracking-wide">
<p className="text-xs sm:text-sm text-text-muted font-medium tracking-wide">
{viewStatus === 'active'
? 'Monitoramento e controle de esquemas industriais'
: 'Histórico de projetos concluídos e arquivados'}
@@ -370,22 +370,22 @@ export const ProjectList: React.FC = () => {
</div>
</div>
<div className="flex flex-wrap items-center gap-3">
<div className="flex flex-wrap items-center gap-2 sm:gap-3">
<Button
variant="secondary"
onClick={() => setViewStatus(viewStatus === 'active' ? 'archived' : 'active')}
className={`shadow-sm ${viewStatus === 'archived' ? 'bg-indigo-500/10 text-indigo-500 border-indigo-500/20' : ''}`}
className={`shadow-sm text-xs sm:text-sm ${viewStatus === 'archived' ? 'bg-indigo-500/10 text-indigo-500 border-indigo-500/20' : ''}`}
>
{viewStatus === 'active' ? <Box className="w-5 h-5 mr-2" /> : <Activity className="w-5 h-5 mr-2" />}
{viewStatus === 'active' ? <Box className="w-4 h-4 sm:w-5 sm:h-5 mr-1.5 sm:mr-2" /> : <Activity className="w-4 h-4 sm:w-5 sm:h-5 mr-1.5 sm:mr-2" />}
{viewStatus === 'active' ? 'Ver Arquivados' : 'Ver Ativos'}
</Button>
<div className="relative hidden lg:block group">
<Search className="absolute left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-text-muted group-focus-within:text-primary transition-colors" />
<div className="relative group flex-1 sm:flex-initial min-w-[140px]">
<Search className="absolute left-3 sm:left-4 top-1/2 -translate-y-1/2 w-4 h-4 text-text-muted group-focus-within:text-primary transition-colors" />
<input
type="text"
placeholder="Buscar obras..."
className="h-12 w-48 bg-surface-soft border border-border/40 rounded-xl pl-12 pr-4 text-sm focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium"
className="h-10 sm:h-12 w-full sm:w-48 bg-surface-soft border border-border/40 rounded-xl pl-9 sm:pl-12 pr-3 sm:pr-4 text-xs sm:text-sm focus:ring-4 focus:ring-primary/10 focus:border-primary transition-all font-medium"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
@@ -394,16 +394,16 @@ export const ProjectList: React.FC = () => {
<Button
variant="secondary"
onClick={handlePrintGeneral}
className="shadow-sm"
className="shadow-sm text-xs sm:text-sm"
disabled={isPrintingGeneral || projects.length === 0}
>
<Printer className="w-5 h-5 mr-2" />
<Printer className="w-4 h-4 sm:w-5 sm:h-5 mr-1.5 sm:mr-2" />
Relatório Geral
</Button>
{isAdmin && viewStatus === 'active' && (
<Button onClick={() => { setSelectedProject(undefined); setIsModalOpen(true); }} size="md" className="shadow-primary/30">
<Plus className="w-5 h-5 mr-2" />
<Button onClick={() => { setSelectedProject(undefined); setIsModalOpen(true); }} size="md" className="shadow-primary/30 text-xs sm:text-sm">
<Plus className="w-4 h-4 sm:w-5 sm:h-5 mr-1.5 sm:mr-2" />
Novo Projeto
</Button>
)}
@@ -412,7 +412,7 @@ export const ProjectList: React.FC = () => {
{/* Quick Stats */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="grid grid-cols-2 lg:grid-cols-4 gap-3 sm:gap-4">
{[
{
label: viewStatus === 'active' ? 'Projetos Ativos' : 'Projetos Arquivados',
@@ -452,7 +452,7 @@ export const ProjectList: React.FC = () => {
<div
key={i}
onClick={stat.onClick}
className={`p-6 bg-surface border border-border/40 rounded-2xl shadow-sm group transition-all ${stat.interactive ? 'cursor-pointer hover:border-primary/40 hover:shadow-md active:scale-95' : ''}`}
className={`p-3.5 sm:p-5 md:p-6 bg-surface border border-border/40 rounded-2xl shadow-sm group transition-all ${stat.interactive ? 'cursor-pointer hover:border-primary/40 hover:shadow-md active:scale-95' : ''}`}
>
<span className="text-[10px] font-black text-text-muted uppercase tracking-[0.2em]">{stat.label}</span>
<div className="mt-2 flex items-baseline gap-2">
+13 -11
View File
@@ -926,25 +926,25 @@ export const YieldStudyDashboard: React.FC = () => {
</div>
{/* Cards de Resumo (Estilo do Relatório de Obras) */}
<div className="grid grid-cols-4 gap-4 mb-8">
<div className="border border-gray-300 rounded-xl p-4 space-y-1">
<div className="grid grid-cols-2 md:grid-cols-4 gap-3 sm:gap-4 mb-6 sm:mb-8">
<div className="border border-gray-300 rounded-xl p-3 sm:p-4 space-y-1">
<span className="text-[8px] font-black text-gray-500 uppercase tracking-widest">Peso Total (Ton)</span>
<div className="text-xl font-black">{(selectedStudy.totalWeight || 0).toFixed(2)}</div>
<div className="text-lg sm:text-xl font-black">{(selectedStudy.totalWeight || 0).toFixed(2)}</div>
<p className="text-[7px] text-gray-400 font-bold uppercase">Soma das categorias</p>
</div>
<div className="border border-gray-300 rounded-xl p-4 space-y-1">
<div className="border border-gray-300 rounded-xl p-3 sm:p-4 space-y-1">
<span className="text-[8px] font-black text-gray-500 uppercase tracking-widest">Tinta Total (Peso)</span>
<div className="text-xl font-black text-amber-600">{Math.round(selectedStudy.estimatedPaintVolume)} <span className="text-[10px]">L</span></div>
<div className="text-lg sm:text-xl font-black text-amber-600">{Math.round(selectedStudy.estimatedPaintVolume)} <span className="text-[10px]">L</span></div>
<p className="text-[7px] text-gray-400 font-bold uppercase">Baseado em L/t</p>
</div>
<div className="border border-gray-300 rounded-xl p-4 space-y-1">
<div className="border border-gray-300 rounded-xl p-3 sm:p-4 space-y-1">
<span className="text-[8px] font-black text-gray-500 uppercase tracking-widest">Tinta Total (Área)</span>
<div className="text-xl font-black text-blue-600">{Math.round(selectedStudy.estimatedPaintVolumeByArea || 0)} <span className="text-[10px]">L</span></div>
<div className="text-lg sm:text-xl font-black text-blue-600">{Math.round(selectedStudy.estimatedPaintVolumeByArea || 0)} <span className="text-[10px]">L</span></div>
<p className="text-[7px] text-gray-400 font-bold uppercase">Baseado em m²</p>
</div>
<div className="border border-gray-300 rounded-xl p-4 space-y-1 border-black bg-gray-50">
<div className="border border-gray-300 rounded-xl p-3 sm:p-4 space-y-1 border-black bg-gray-50">
<span className="text-[8px] font-black text-gray-500 uppercase tracking-widest">Taxa Média</span>
<div className="text-xl font-black">{selectedStudy.totalWeight > 0 ? ((selectedStudy.estimatedPaintVolume || 0) / selectedStudy.totalWeight).toFixed(2) : '0.00'} <span className="text-[10px]">L/t</span></div>
<div className="text-lg sm:text-xl font-black">{selectedStudy.totalWeight > 0 ? ((selectedStudy.estimatedPaintVolume || 0) / selectedStudy.totalWeight).toFixed(2) : '0.00'} <span className="text-[10px]">L/t</span></div>
<p className="text-[7px] text-gray-400 font-bold uppercase">Rendimento Global</p>
</div>
</div>
@@ -955,7 +955,8 @@ export const YieldStudyDashboard: React.FC = () => {
<h2 className="text-xs font-black uppercase tracking-[0.2em]">Detalhamento por Categoria</h2>
<p className="text-[8px] text-gray-500 font-bold uppercase">Visão analítica por geometria, peso e área</p>
</div>
<table className="w-full text-left border-collapse">
<div className="overflow-x-auto">
<table className="w-full text-left border-collapse min-w-[500px]">
<thead>
<tr className="border-b-2 border-black">
<th className="py-2 text-[9px] font-black uppercase tracking-widest">Categoria / Tipo</th>
@@ -985,9 +986,10 @@ export const YieldStudyDashboard: React.FC = () => {
</tbody>
</table>
</div>
</div>
{/* Parâmetros e Projeção */}
<div className="grid grid-cols-2 gap-8 mb-8">
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 sm:gap-8 mb-6 sm:mb-8">
<div>
<h3 className="text-[10px] font-black uppercase tracking-widest mb-4 border-b border-gray-200 pb-2">Especificações Técnicas</h3>
<div className="space-y-3">