feat: otimizacao de responsividade para celulares e tablets em todas as telas e modais
This commit is contained in:
@@ -335,7 +335,7 @@ export const Layout: React.FC<LayoutProps> = ({ children }) => {
|
|||||||
"md:pl-68", // Push content on desktop
|
"md:pl-68", // Push content on desktop
|
||||||
"pt-16 md:pt-0" // Add padding on mobile for header
|
"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}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
|
|||||||
@@ -13,15 +13,15 @@ export const Modal: React.FC<ModalProps> = ({ isOpen, onClose, title, children,
|
|||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 backdrop-blur-sm p-4">
|
<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 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={`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-5 border-b border-border">
|
<div className="flex justify-between items-center p-4 sm:p-5 border-b border-border">
|
||||||
<h2 className="text-xl font-bold text-text-main">{title}</h2>
|
<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" aria-label="Fechar modal">
|
<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" />
|
<X className="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-6 overflow-y-auto">
|
<div className="p-4 sm:p-6 overflow-y-auto">
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -242,7 +242,7 @@ export const CreatePaintingSchemeModal: React.FC<CreatePaintingSchemeModalProps>
|
|||||||
required
|
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
|
<Select
|
||||||
name="type"
|
name="type"
|
||||||
label="Tipo de Tinta"
|
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} />
|
<Input name="solidsVolume" label="Sólidos Vol. (%)" type="number" value={formData.solidsVolume} onChange={handleChange} />
|
||||||
</div>
|
</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} />
|
<Input name="yieldTheoretical" label="Rendimento (m²/L)" type="number" step="0.01" value={formData.yieldTheoretical} onChange={handleChange} />
|
||||||
</div>
|
</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="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} />
|
<Input name="epsMax" label="EPS Máx (μm)" type="number" value={formData.epsMax} onChange={handleChange} />
|
||||||
</div>
|
</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="dilution" label="Diluição (%)" type="number" value={formData.dilution} onChange={handleChange} />
|
||||||
<Input name="manufacturer" label="Fabricante" value={formData.manufacturer} onChange={handleChange} />
|
<Input name="manufacturer" label="Fabricante" value={formData.manufacturer} onChange={handleChange} />
|
||||||
</div>
|
</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} />
|
<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">
|
<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>
|
<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>
|
||||||
|
|
||||||
<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>
|
<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
|
<Select
|
||||||
name="paintId"
|
name="paintId"
|
||||||
label="Produto (Tinta)"
|
label="Produto (Tinta)"
|
||||||
@@ -346,7 +346,7 @@ export const CreatePaintingSchemeModal: React.FC<CreatePaintingSchemeModalProps>
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</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
|
<Input
|
||||||
name="paintConsumption"
|
name="paintConsumption"
|
||||||
label="Consumo Tinta (L/Kg)"
|
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="name" label="Nome do Projeto" required value={formData.name} onChange={handleChange} />
|
||||||
<Input name="client" label="Cliente" required value={formData.client} 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} />
|
<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="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} />
|
<Input name="endDate" label="Fim Planejado" type="date" value={formData.endDate} onChange={handleChange} />
|
||||||
</div>
|
</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-6 text-center py-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<h3 className="text-xl font-bold text-text-main">Configurar Esquema de Pintura?</h3>
|
<h3 className="text-lg sm: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>
|
<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>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-4">
|
<div className="grid grid-cols-1 sm:grid-cols-2 gap-3 sm:gap-4">
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowImportModal(true)}
|
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">
|
<div className="p-3 rounded-full bg-surface-soft group-hover:bg-white text-primary transition-colors">
|
||||||
<FileDown size={24} />
|
<FileDown size={24} />
|
||||||
|
|||||||
@@ -121,11 +121,11 @@ export const AdminDashboard: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tabs Navigation */}
|
{/* 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
|
<button
|
||||||
onClick={() => setActiveTab('users')}
|
onClick={() => setActiveTab('users')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'users'
|
||||||
? "bg-surface text-primary shadow-sm border border-border/40"
|
? "bg-surface text-primary shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -137,7 +137,7 @@ export const AdminDashboard: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('organization')}
|
onClick={() => setActiveTab('organization')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'organization'
|
||||||
? "bg-surface text-primary shadow-sm border border-border/40"
|
? "bg-surface text-primary shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -149,7 +149,7 @@ export const AdminDashboard: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('settings')}
|
onClick={() => setActiveTab('settings')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'settings'
|
||||||
? "bg-surface text-primary shadow-sm border border-border/40"
|
? "bg-surface text-primary shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -161,7 +161,7 @@ export const AdminDashboard: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('backup')}
|
onClick={() => setActiveTab('backup')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'backup'
|
||||||
? "bg-surface text-primary shadow-sm border border-border/40"
|
? "bg-surface text-primary shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
|
|||||||
@@ -181,20 +181,20 @@ export const CalculatorDashboard: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
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 */}
|
{/* Header */}
|
||||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 pb-2">
|
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 md:gap-6 pb-2">
|
||||||
<div className="space-y-4">
|
<div className="space-y-2">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">Ferramentas & Cálculos</h1>
|
<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-sm text-text-muted font-medium tracking-wide">Utilitários técnicos para pintura industrial</p>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tabs */}
|
{/* Tabs */}
|
||||||
<div className="flex items-center justify-between border-b border-border/40 scrollbar-hide overflow-x-auto">
|
<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: 'conversion', label: 'Conversões', icon: ArrowRightLeft },
|
||||||
{ id: 'thickness', label: 'Espessura', icon: Ruler },
|
{ id: 'thickness', label: 'Espessura', icon: Ruler },
|
||||||
@@ -209,7 +209,7 @@ export const CalculatorDashboard: React.FC = () => {
|
|||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={clsx(
|
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
|
active
|
||||||
? 'border-primary text-primary'
|
? 'border-primary text-primary'
|
||||||
: 'border-transparent text-text-muted hover:text-text-main hover:border-border'
|
: 'border-transparent text-text-muted hover:text-text-main hover:border-border'
|
||||||
@@ -230,8 +230,8 @@ export const CalculatorDashboard: React.FC = () => {
|
|||||||
{/* 1. CONVERSION */}
|
{/* 1. CONVERSION */}
|
||||||
{activeTab === 'conversion' && (
|
{activeTab === 'conversion' && (
|
||||||
<div className="max-w-2xl mx-auto space-y-6 animate-in slide-in-from-bottom-4 duration-500">
|
<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">
|
<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-2 border-b border-border/40 pb-6">
|
<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>
|
<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>
|
<p className="text-sm text-text-muted">Microns (μm) ↔ Milesimos de Polegada (mils)</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -141,11 +141,11 @@ export const DeveloperDashboard: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Tabs Navigation */}
|
{/* 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
|
<button
|
||||||
onClick={() => setActiveTab('overview')}
|
onClick={() => setActiveTab('overview')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'overview'
|
||||||
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -157,7 +157,7 @@ export const DeveloperDashboard: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('organizations')}
|
onClick={() => setActiveTab('organizations')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'organizations'
|
||||||
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -169,7 +169,7 @@ export const DeveloperDashboard: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('users')}
|
onClick={() => setActiveTab('users')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'users'
|
||||||
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -181,7 +181,7 @@ export const DeveloperDashboard: React.FC = () => {
|
|||||||
<button
|
<button
|
||||||
onClick={() => setActiveTab('branding')}
|
onClick={() => setActiveTab('branding')}
|
||||||
className={clsx(
|
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'
|
activeTab === 'branding'
|
||||||
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
? "bg-surface text-indigo-500 shadow-sm border border-border/40"
|
||||||
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
: "text-text-muted hover:text-text-main hover:bg-surface-hover"
|
||||||
@@ -193,7 +193,7 @@ export const DeveloperDashboard: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Content Area */}
|
{/* 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' && (
|
{activeTab === 'overview' && (
|
||||||
<div className="p-12 flex flex-col items-center justify-center text-center h-full">
|
<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">
|
<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">
|
||||||
|
|||||||
@@ -201,17 +201,17 @@ export const ProjectDetails: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-8 animate-in fade-in duration-700">
|
<div className="space-y-8 animate-in fade-in duration-700">
|
||||||
{/* Page Header */}
|
{/* Page Header */}
|
||||||
<div className="flex flex-col md:flex-row md:items-end justify-between gap-6 pb-2">
|
<div className="flex flex-col md:flex-row md:items-end justify-between gap-4 md:gap-6 pb-2">
|
||||||
<div className="space-y-4">
|
<div className="space-y-3 sm:space-y-4">
|
||||||
<Link to="/projects">
|
<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">
|
<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" />
|
<ArrowLeft className="w-3 h-3 mr-2 group-hover:-translate-x-1 transition-transform" />
|
||||||
Voltar aos Projetos
|
Voltar aos Projetos
|
||||||
</button>
|
</button>
|
||||||
</Link>
|
</Link>
|
||||||
<div className="flex flex-col sm:flex-row sm:items-center gap-4">
|
<div className="flex flex-col sm:flex-row sm:items-center gap-2 sm:gap-4">
|
||||||
<h1 className="text-3xl md:text-4xl font-black text-text-main tracking-tight mb-0">{project.name}</h1>
|
<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 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">
|
<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" />
|
<Activity className="w-3 h-3 mr-2" />
|
||||||
Em Andamento
|
Em Andamento
|
||||||
</span>
|
</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-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 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>
|
</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>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isAdmin() && (
|
{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)}>
|
<Button variant="secondary" size="sm" onClick={() => setIsEditProjectModalOpen(true)}>
|
||||||
<Pencil className="w-4 h-4 mr-2" /> Editar Obra
|
<Pencil className="w-4 h-4 mr-2" /> Editar Obra
|
||||||
</Button>
|
</Button>
|
||||||
@@ -238,45 +238,45 @@ export const ProjectDetails: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Premium Summary Grid */}
|
{/* 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">
|
<div className="absolute top-0 right-0 p-8 opacity-5">
|
||||||
<Activity size={120} strokeWidth={1} />
|
<Activity size={120} strokeWidth={1} />
|
||||||
</div>
|
</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">
|
<div className="space-y-1">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Data de Início</span>
|
<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>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Previsão Término</span>
|
<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>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Peso da Obra (KGF)</span>
|
<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">
|
<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-sm text-text-muted">kg</span>
|
{project.weightKg ? Number(project.weightKg).toLocaleString('pt-BR') : '0'} <span className="text-xs sm:text-sm text-text-muted">kg</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Evolução%</span>
|
<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
|
{project.weightKg && project.paintedWeight !== undefined
|
||||||
? Math.min(Math.round((project.paintedWeight / project.weightKg) * 100), 100)
|
? Math.min(Math.round((project.paintedWeight / project.weightKg) * 100), 100)
|
||||||
: 0}
|
: 0}
|
||||||
<span className="text-sm">%</span>
|
<span className="text-xs sm:text-sm">%</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div className="space-y-1">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Localização/Amb.</span>
|
<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>
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<span className="text-[10px] font-bold text-text-muted uppercase tracking-widest block">Eng. Responsável</span>
|
<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="flex items-center gap-2">
|
||||||
<div className="w-2 h-2 rounded-full bg-blue-500"></div>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -284,7 +284,7 @@ export const ProjectDetails: React.FC = () => {
|
|||||||
|
|
||||||
{/* Navigation Tabs */}
|
{/* Navigation Tabs */}
|
||||||
<div className="flex items-center justify-between border-b border-border/40 scrollbar-hide overflow-x-auto">
|
<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) => {
|
{tabs.map((tab) => {
|
||||||
const Icon = tab.icon;
|
const Icon = tab.icon;
|
||||||
const active = activeTab === tab.id;
|
const active = activeTab === tab.id;
|
||||||
@@ -293,7 +293,7 @@ export const ProjectDetails: React.FC = () => {
|
|||||||
key={tab.id}
|
key={tab.id}
|
||||||
onClick={() => setActiveTab(tab.id)}
|
onClick={() => setActiveTab(tab.id)}
|
||||||
className={clsx(
|
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
|
active
|
||||||
? 'border-primary text-primary'
|
? 'border-primary text-primary'
|
||||||
: 'border-transparent text-text-muted hover:text-text-main hover:border-border'
|
: 'border-transparent text-text-muted hover:text-text-main hover:border-border'
|
||||||
|
|||||||
@@ -351,17 +351,17 @@ export const ProjectList: React.FC = () => {
|
|||||||
return (
|
return (
|
||||||
<div className="space-y-10 animate-in fade-in duration-700">
|
<div className="space-y-10 animate-in fade-in duration-700">
|
||||||
{/* Page Header */}
|
{/* 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="space-y-2">
|
||||||
<div className="flex items-center gap-3">
|
<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">
|
<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-6 h-6" />
|
<Activity className="w-5 h-5 sm:w-6 sm:h-6" />
|
||||||
</div>
|
</div>
|
||||||
<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'}
|
{viewStatus === 'active' ? 'Gestão de Obras' : 'Obras Arquivadas'}
|
||||||
</h1>
|
</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'
|
{viewStatus === 'active'
|
||||||
? 'Monitoramento e controle de esquemas industriais'
|
? 'Monitoramento e controle de esquemas industriais'
|
||||||
: 'Histórico de projetos concluídos e arquivados'}
|
: 'Histórico de projetos concluídos e arquivados'}
|
||||||
@@ -370,22 +370,22 @@ export const ProjectList: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex flex-wrap items-center gap-3">
|
<div className="flex flex-wrap items-center gap-2 sm:gap-3">
|
||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={() => setViewStatus(viewStatus === 'active' ? 'archived' : 'active')}
|
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'}
|
{viewStatus === 'active' ? 'Ver Arquivados' : 'Ver Ativos'}
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<div className="relative hidden lg:block group">
|
<div className="relative group flex-1 sm:flex-initial min-w-[140px]">
|
||||||
<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" />
|
<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
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Buscar obras..."
|
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}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
/>
|
/>
|
||||||
@@ -394,16 +394,16 @@ export const ProjectList: React.FC = () => {
|
|||||||
<Button
|
<Button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
onClick={handlePrintGeneral}
|
onClick={handlePrintGeneral}
|
||||||
className="shadow-sm"
|
className="shadow-sm text-xs sm:text-sm"
|
||||||
disabled={isPrintingGeneral || projects.length === 0}
|
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
|
Relatório Geral
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
{isAdmin && viewStatus === 'active' && (
|
{isAdmin && viewStatus === 'active' && (
|
||||||
<Button onClick={() => { setSelectedProject(undefined); setIsModalOpen(true); }} size="md" className="shadow-primary/30">
|
<Button onClick={() => { setSelectedProject(undefined); setIsModalOpen(true); }} size="md" className="shadow-primary/30 text-xs sm:text-sm">
|
||||||
<Plus className="w-5 h-5 mr-2" />
|
<Plus className="w-4 h-4 sm:w-5 sm:h-5 mr-1.5 sm:mr-2" />
|
||||||
Novo Projeto
|
Novo Projeto
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
@@ -412,7 +412,7 @@ export const ProjectList: React.FC = () => {
|
|||||||
|
|
||||||
|
|
||||||
{/* Quick Stats */}
|
{/* 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',
|
label: viewStatus === 'active' ? 'Projetos Ativos' : 'Projetos Arquivados',
|
||||||
@@ -452,7 +452,7 @@ export const ProjectList: React.FC = () => {
|
|||||||
<div
|
<div
|
||||||
key={i}
|
key={i}
|
||||||
onClick={stat.onClick}
|
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>
|
<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">
|
<div className="mt-2 flex items-baseline gap-2">
|
||||||
|
|||||||
@@ -926,25 +926,25 @@ export const YieldStudyDashboard: React.FC = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Cards de Resumo (Estilo do Relatório de Obras) */}
|
{/* Cards de Resumo (Estilo do Relatório de Obras) */}
|
||||||
<div className="grid grid-cols-4 gap-4 mb-8">
|
<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-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">Peso Total (Ton)</span>
|
<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>
|
<p className="text-[7px] text-gray-400 font-bold uppercase">Soma das categorias</p>
|
||||||
</div>
|
</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>
|
<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>
|
<p className="text-[7px] text-gray-400 font-bold uppercase">Baseado em L/t</p>
|
||||||
</div>
|
</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>
|
<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>
|
<p className="text-[7px] text-gray-400 font-bold uppercase">Baseado em m²</p>
|
||||||
</div>
|
</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>
|
<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>
|
<p className="text-[7px] text-gray-400 font-bold uppercase">Rendimento Global</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -955,39 +955,41 @@ export const YieldStudyDashboard: React.FC = () => {
|
|||||||
<h2 className="text-xs font-black uppercase tracking-[0.2em]">Detalhamento por Categoria</h2>
|
<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>
|
<p className="text-[8px] text-gray-500 font-bold uppercase">Visão analítica por geometria, peso e área</p>
|
||||||
</div>
|
</div>
|
||||||
<table className="w-full text-left border-collapse">
|
<div className="overflow-x-auto">
|
||||||
<thead>
|
<table className="w-full text-left border-collapse min-w-[500px]">
|
||||||
<tr className="border-b-2 border-black">
|
<thead>
|
||||||
<th className="py-2 text-[9px] font-black uppercase tracking-widest">Categoria / Tipo</th>
|
<tr className="border-b-2 border-black">
|
||||||
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-amber-600">Peso (T)</th>
|
<th className="py-2 text-[9px] font-black uppercase tracking-widest">Categoria / Tipo</th>
|
||||||
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-blue-600">Área (m²)</th>
|
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-amber-600">Peso (T)</th>
|
||||||
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-amber-600">Taxa (L/t)</th>
|
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-blue-600">Área (m²)</th>
|
||||||
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-blue-600">Efic. (%)</th>
|
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-amber-600">Taxa (L/t)</th>
|
||||||
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-right">Consumo (L)</th>
|
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-center text-blue-600">Efic. (%)</th>
|
||||||
</tr>
|
<th className="py-2 text-[9px] font-black uppercase tracking-widest text-right">Consumo (L)</th>
|
||||||
</thead>
|
|
||||||
<tbody className="divide-y divide-gray-100">
|
|
||||||
{selectedStudy.categories.map((cat, idx) => (
|
|
||||||
<tr key={cat.id || idx} className="border-b border-gray-100 italic">
|
|
||||||
<td className="py-3 pr-4">
|
|
||||||
<div className="text-[11px] font-black text-gray-800">{cat.name}</div>
|
|
||||||
</td>
|
|
||||||
<td className="py-3 text-center text-[10px] font-bold text-amber-700">{(cat.weight || 0).toFixed(2)}</td>
|
|
||||||
<td className="py-3 text-center text-[10px] font-bold text-blue-700">{cat.area ? Math.round(cat.area) : '--'}</td>
|
|
||||||
<td className="py-3 text-center text-[10px] font-bold text-amber-700">{cat.historicalYield}</td>
|
|
||||||
<td className="py-3 text-center text-[10px] font-bold text-blue-700">{cat.efficiency}%</td>
|
|
||||||
<td className="py-3 text-right">
|
|
||||||
<div className="text-[10px] font-black text-amber-700">{cat.litrosPeso} L <span className="text-[7px] uppercase font-bold text-gray-400 opacity-50">(p)</span></div>
|
|
||||||
{cat.litrosArea && <div className="text-[10px] font-black text-blue-700">{cat.litrosArea} L <span className="text-[7px] uppercase font-bold text-gray-400 opacity-50">(a)</span></div>}
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
</thead>
|
||||||
</tbody>
|
<tbody className="divide-y divide-gray-100">
|
||||||
</table>
|
{selectedStudy.categories.map((cat, idx) => (
|
||||||
|
<tr key={cat.id || idx} className="border-b border-gray-100 italic">
|
||||||
|
<td className="py-3 pr-4">
|
||||||
|
<div className="text-[11px] font-black text-gray-800">{cat.name}</div>
|
||||||
|
</td>
|
||||||
|
<td className="py-3 text-center text-[10px] font-bold text-amber-700">{(cat.weight || 0).toFixed(2)}</td>
|
||||||
|
<td className="py-3 text-center text-[10px] font-bold text-blue-700">{cat.area ? Math.round(cat.area) : '--'}</td>
|
||||||
|
<td className="py-3 text-center text-[10px] font-bold text-amber-700">{cat.historicalYield}</td>
|
||||||
|
<td className="py-3 text-center text-[10px] font-bold text-blue-700">{cat.efficiency}%</td>
|
||||||
|
<td className="py-3 text-right">
|
||||||
|
<div className="text-[10px] font-black text-amber-700">{cat.litrosPeso} L <span className="text-[7px] uppercase font-bold text-gray-400 opacity-50">(p)</span></div>
|
||||||
|
{cat.litrosArea && <div className="text-[10px] font-black text-blue-700">{cat.litrosArea} L <span className="text-[7px] uppercase font-bold text-gray-400 opacity-50">(a)</span></div>}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Parâmetros e Projeção */}
|
{/* 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>
|
<div>
|
||||||
<h3 className="text-[10px] font-black uppercase tracking-widest mb-4 border-b border-gray-200 pb-2">Especificações Técnicas</h3>
|
<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">
|
<div className="space-y-3">
|
||||||
|
|||||||
Reference in New Issue
Block a user