Adição dos novos modelos e do tema escuro

This commit is contained in:
Lucas Rayan committed 2026-05-28 09:06:39 -03:00
1 parent e3b4600300
commit de4abf7cc7
42 files changed
+6551 -3891

No files matched your search

+89 -91
View File
@@ -1,101 +1,99 @@
"use client";
'use client';
import { Award, CheckCircle, HelpCircle, ExternalLink } from 'lucide-react';
export default function BoardCard({ board }) {
const mainFields = ['Nome', 'Link', 'Imagem', 'Loja Oficial'];
const technicalFields = Object.keys(board).filter(
key => !mainFields.includes(key) && board[key]
);
const mainFields = ['Nome', 'Link', 'Imagem', 'Loja Oficial'];
const technicalFields = Object.keys(board).filter(
key => !mainFields.includes(key) && board[key]
);
const hasFeature = (value) => {
const yesValues = ['sim', 'opcional'];
return yesValues.includes(value?.toString().toLowerCase().trim());
};
const hasFeature = (value) => {
const yesValues = ['sim', 'opcional'];
return yesValues.includes(value?.toString().toLowerCase().trim());
};
// Filtrar apenas características que têm "Sim" ou "Opcional"
const availableFeatures = technicalFields.filter(field => hasFeature(board[field]));
const optionalFeatures = technicalFields.filter(field =>
board[field]?.toString().toLowerCase().trim() === 'opcional'
);
// Filtrar apenas características que têm "Sim" ou "Opcional"
const availableFeatures = technicalFields.filter(field => hasFeature(board[field]));
const optionalFeatures = technicalFields.filter(field =>
board[field]?.toString().toLowerCase().trim() === 'opcional'
);
return (
<div className="bg-white rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-300 overflow-hidden group flex flex-col h-full">
{/* Imagem */}
{board.Imagem && (
<div
className="mx-auto w-fit"
dangerouslySetInnerHTML={{ __html: board.Imagem }}
/>
)}
return (
<div className="bg-white/80 dark:bg-slate-900/40 backdrop-blur-xl border border-slate-200/60 dark:border-slate-800/80 rounded-3xl shadow-lg hover:shadow-2xl hover:-translate-y-1.5 transition-all duration-300 overflow-hidden group flex flex-col h-full animate-fadeIn select-none">
{/* Image Container with premium glass background */}
{board.Imagem && (
<div
className="mx-auto w-full p-4 flex justify-center bg-white dark:bg-white border-b border-slate-100 dark:border-slate-850/40 shrink-0"
dangerouslySetInnerHTML={{ __html: board.Imagem }}
/>
)}
<div className="p-6 flex flex-col grow">
{/* Nome */}
<h3 className="text-xl font-bold text-gray-800 mb-2 line-clamp-2">
{board.Nome || 'Placa sem nome'}
</h3>
<div className="p-6 flex flex-col grow justify-between">
<div>
{/* Loja Oficial Badge */}
{board['Loja Oficial'] && board['Loja Oficial'].toLowerCase() === 'sim' && (
<div className="mb-2">
<span className="inline-flex items-center gap-1 bg-blue-500/10 text-blue-600 dark:text-blue-400 border border-blue-500/20 rounded-full px-2.5 py-0.5 text-[9px] font-bold uppercase tracking-wider">
<Award className="w-3.5 h-3.5 shrink-0" />
<span>Loja Oficial</span>
</span>
</div>
)}
{/* Loja Oficial */}
{board['Loja Oficial'] && board['Loja Oficial'].toLowerCase() === 'sim' && (
<div className="mb-4">
<p className="text-sm text-blue-600 flex items-center gap-1.5">
<svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M6.267 3.455a3.066 3.066 0 001.745-.723 3.066 3.066 0 013.976 0 3.066 3.066 0 001.745.723 3.066 3.066 0 012.812 2.812c.051.643.304 1.254.723 1.745a3.066 3.066 0 010 3.976 3.066 3.066 0 00-.723 1.745 3.066 3.066 0 01-2.812 2.812 3.066 3.066 0 00-1.745.723 3.066 3.066 0 01-3.976 0 3.066 3.066 0 00-1.745-.723 3.066 3.066 0 01-2.812-2.812 3.066 3.066 0 00-.723-1.745 3.066 3.066 0 010-3.976 3.066 3.066 0 00.723-1.745 3.066 3.066 0 012.812-2.812zm7.44 5.252a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
<span>Link da loja oficial do fabricante</span>
</p>
</div>
)}
{/* Nome */}
<h3 className="text-base font-display font-extrabold text-slate-850 dark:text-slate-100 mb-4 line-clamp-2 leading-snug group-hover:text-purple-650 dark:group-hover:text-purple-400 transition-colors">
{board.Nome || 'Placa Genérica'}
</h3>
{/* Características Técnicas */}
{availableFeatures.length > 0 && (
<div className="mb-4 grow">
<div className="flex items-center gap-2 mb-3">
<svg className="w-4 h-4 text-green-600" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clipRule="evenodd" />
</svg>
<h4 className="text-sm font-semibold text-gray-700">Recursos Disponíveis</h4>
</div>
<div className="flex flex-wrap gap-2">
{availableFeatures.map((field) => {
const isOptional = optionalFeatures.includes(field);
return (
<div
key={field}
className={`text-xs px-3 py-1.5 rounded-lg font-medium flex items-center gap-1 ${
isOptional
? 'bg-yellow-100 text-yellow-700 border border-yellow-200'
: 'bg-green-100 text-green-700 border border-green-200'
}`}
>
{isOptional ? (
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clipRule="evenodd" />
</svg>
) : (
<svg className="w-3 h-3" fill="currentColor" viewBox="0 0 20 20">
<path fillRule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clipRule="evenodd" />
</svg>
)}
<span>{field}</span>
</div>
);
})}
</div>
</div>
)}
{/* Características Técnicas */}
{availableFeatures.length > 0 && (
<div className="mb-6">
<h4 className="text-[9px] font-bold text-slate-400 dark:text-slate-500 uppercase tracking-widest flex items-center gap-1.5 mb-2.5">
<CheckCircle className="w-3.5 h-3.5 text-emerald-500" />
<span>Recursos Embarcados</span>
</h4>
<div className="flex flex-wrap gap-1.5">
{availableFeatures.map((field) => {
const isOptional = optionalFeatures.includes(field);
return (
<div
key={field}
className={`text-[9px] px-2 py-0.5 rounded-lg font-bold flex items-center gap-1 ${
isOptional
? 'bg-amber-500/10 dark:bg-amber-500/15 border border-amber-500/20 text-amber-600 dark:text-amber-400'
: 'bg-emerald-500/10 dark:bg-emerald-500/15 border border-emerald-500/20 text-emerald-600 dark:text-emerald-400'
}`}
>
{isOptional ? (
<HelpCircle className="w-2.5 h-2.5 shrink-0" />
) : (
<CheckCircle className="w-2.5 h-2.5 shrink-0" />
)}
<span>{field}</span>
</div>
);
})}
</div>
</div>
)}
</div>
{/* Link para mais informações - sempre no final */}
{board.Link && (
<a
href={board.Link}
target="_blank"
rel="noopener noreferrer"
className="block w-full bg-linear-to-r from-blue-600 to-purple-600 text-white text-center px-4 py-3 rounded-xl font-semibold hover:shadow-lg transform hover:-translate-y-1 transition-all duration-300 mt-auto"
>
Abrir no AliExpress 🔗
</a>
)}
</div>
</div>
);
{/* Link de Compra */}
{board.Link && (
<a
href={board.Link}
target="_blank"
rel="noopener noreferrer"
className="block w-full bg-slate-900 dark:bg-slate-100 text-white dark:text-slate-950 text-center px-4 py-3 rounded-xl font-bold text-xs uppercase tracking-wider hover:opacity-90 active:scale-98 transition-all shadow-md mt-auto flex items-center justify-center gap-1.5"
>
<span>Adquirir no AliExpress</span>
<ExternalLink className="w-3.5 h-3.5" />
</a>
)}
</div>
</div>
);
}