all about improvements
All checks were successful
Frontend Build and Deploy / build (push) Successful in 21s
All checks were successful
Frontend Build and Deploy / build (push) Successful in 21s
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import React, { useState, useMemo } from 'react';
|
||||
import { CurrencyDollarIcon, ChevronDownIcon, ChevronUpIcon } from '@heroicons/react/24/outline';
|
||||
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
|
||||
import { type Asset } from '../../api';
|
||||
|
||||
interface AssetsComponentProps {
|
||||
@@ -10,6 +11,16 @@ interface AssetsComponentProps {
|
||||
const AssetsComponent: React.FC<AssetsComponentProps> = ({ assets, isLoading }) => {
|
||||
const [expandedYears, setExpandedYears] = useState<Set<number>>(new Set());
|
||||
|
||||
const formatCurrencyCompact = (value: number) => {
|
||||
if (value >= 1000000) {
|
||||
return `R$ ${(value / 1000000).toFixed(1)}M`;
|
||||
} else if (value >= 1000) {
|
||||
return `R$ ${(value / 1000).toFixed(0)}K`;
|
||||
} else {
|
||||
return `R$ ${value.toFixed(0)}`;
|
||||
}
|
||||
};
|
||||
|
||||
const formatCurrency = (value: number) => {
|
||||
return new Intl.NumberFormat('pt-BR', {
|
||||
style: 'currency',
|
||||
@@ -56,7 +67,7 @@ const AssetsComponent: React.FC<AssetsComponentProps> = ({ assets, isLoading })
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.02] transition-all duration-200 p-6">
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.01] transition-all duration-200 p-6">
|
||||
<div className="flex items-center mb-6">
|
||||
<CurrencyDollarIcon className="h-8 w-8 text-purple-600 mr-3" />
|
||||
<h2 className="text-2xl font-bold text-gray-900">Patrimônio Declarado</h2>
|
||||
@@ -132,16 +143,87 @@ const AssetsComponent: React.FC<AssetsComponentProps> = ({ assets, isLoading })
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Total Assets */}
|
||||
<div className="mt-6 pt-4 border-t-2 border-gray-200">
|
||||
<div className="flex justify-between items-center">
|
||||
<span className="text-xl font-semibold text-gray-700">Total Geral Declarado:</span>
|
||||
<span className="text-2xl font-bold text-purple-600">
|
||||
{formatCurrency(getTotalAssets())}
|
||||
</span>
|
||||
{/* Assets Progression Graph */}
|
||||
{sortedYears.length > 1 && (
|
||||
<div className="mt-6 pt-6 border-t-2 border-gray-200">
|
||||
<h3 className="text-lg font-semibold text-gray-900 mb-4">Evolução Patrimonial Declarada</h3>
|
||||
<div className="bg-gradient-to-br from-purple-50 to-green-50 p-6 rounded-lg shadow-inner">
|
||||
<ResponsiveContainer width="100%" height={300}>
|
||||
<LineChart
|
||||
data={sortedYears.map(year => ({
|
||||
year,
|
||||
valor: getTotalForYear(groupedAssets[year])
|
||||
})).sort((a, b) => a.year - b.year)}
|
||||
margin={{
|
||||
top: 20,
|
||||
right: 30,
|
||||
left: 30,
|
||||
bottom: 20,
|
||||
}}
|
||||
>
|
||||
<CartesianGrid strokeDasharray="3 3" stroke="#e5e7eb" />
|
||||
<XAxis
|
||||
dataKey="year"
|
||||
stroke="#6b7280"
|
||||
fontSize={12}
|
||||
fontWeight={500}
|
||||
/>
|
||||
<YAxis
|
||||
stroke="#6b7280"
|
||||
fontSize={12}
|
||||
fontWeight={500}
|
||||
tickFormatter={(value) => formatCurrencyCompact(value)}
|
||||
width={75}
|
||||
/>
|
||||
<Tooltip
|
||||
contentStyle={{
|
||||
backgroundColor: '#fefefe',
|
||||
color: '#374151',
|
||||
border: '1px solid #e5e7eb',
|
||||
borderRadius: '8px',
|
||||
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1)',
|
||||
}}
|
||||
formatter={(value: number) => [formatCurrency(value), 'Patrimônio']}
|
||||
labelStyle={{ color: '#374151', fontWeight: 600 }}
|
||||
/>
|
||||
<Line
|
||||
type="monotone"
|
||||
dataKey="valor"
|
||||
stroke="url(#gradient)"
|
||||
strokeWidth={3}
|
||||
dot={{ fill: '#7c3aed', strokeWidth: 2, r: 6 }}
|
||||
activeDot={{ r: 8, fill: '#059669' }}
|
||||
/>
|
||||
<defs>
|
||||
<linearGradient id="gradient" x1="0%" y1="0%" x2="100%" y2="0%">
|
||||
<stop offset="0%" stopColor="#7c3aed" />
|
||||
<stop offset="100%" stopColor="#059669" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</LineChart>
|
||||
</ResponsiveContainer>
|
||||
<div className="mt-3 text-center">
|
||||
<p className="text-sm text-gray-600">
|
||||
Variação total: {' '}
|
||||
<span className={`font-semibold ${
|
||||
sortedYears.length > 1 &&
|
||||
getTotalForYear(groupedAssets[Math.max(...sortedYears)]) >
|
||||
getTotalForYear(groupedAssets[Math.min(...sortedYears)])
|
||||
? 'text-green-600'
|
||||
: 'text-red-600'
|
||||
}`}>
|
||||
{sortedYears.length > 1 &&
|
||||
formatCurrency(
|
||||
getTotalForYear(groupedAssets[Math.max(...sortedYears)]) -
|
||||
getTotalForYear(groupedAssets[Math.min(...sortedYears)])
|
||||
)
|
||||
}
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
) : (
|
||||
<div className="text-center text-gray-500 py-8">
|
||||
|
@@ -39,7 +39,7 @@ const BasicCandidateInfoComponent: React.FC<BasicCandidateInfoComponentProps> =
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.02] transition-all duration-200 p-6">
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.01] transition-all duration-200 p-6">
|
||||
<div className="flex items-center mb-6">
|
||||
<UserIcon className="h-8 w-8 text-blue-600 mr-3" />
|
||||
<h2 className="text-2xl font-bold text-gray-900">Informações Básicas</h2>
|
||||
|
@@ -22,7 +22,7 @@ const ElectionsComponent: React.FC<ElectionsComponentProps> = ({ elections, isLo
|
||||
|
||||
|
||||
return (
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.02] transition-all duration-200 p-6">
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.01] transition-all duration-200 p-6">
|
||||
<div className="flex items-center mb-6">
|
||||
<DocumentTextIcon className="h-8 w-8 text-green-600 mr-3" />
|
||||
<h2 className="text-2xl font-bold text-gray-900">Histórico de Eleições</h2>
|
||||
|
@@ -1,5 +1,18 @@
|
||||
import React from 'react';
|
||||
import { LinkIcon } from '@heroicons/react/24/outline';
|
||||
import {
|
||||
FaFacebook,
|
||||
FaInstagram,
|
||||
FaTwitter,
|
||||
FaTiktok,
|
||||
FaYoutube,
|
||||
FaLinkedin,
|
||||
FaWhatsapp,
|
||||
FaTelegram,
|
||||
FaSpotify,
|
||||
FaLink
|
||||
} from 'react-icons/fa';
|
||||
import { FaXTwitter, FaThreads } from 'react-icons/fa6';
|
||||
import { type RedeSocial } from '../../api';
|
||||
|
||||
interface SocialMediaComponentProps {
|
||||
@@ -7,12 +20,45 @@ interface SocialMediaComponentProps {
|
||||
isLoading: boolean;
|
||||
}
|
||||
|
||||
// Helper function to get social media icons
|
||||
const getSocialMediaIcon = (rede: string): React.ReactElement => {
|
||||
const iconClass = "h-5 w-5 mr-2";
|
||||
|
||||
switch (rede.toLowerCase()) {
|
||||
case 'facebook':
|
||||
return <FaFacebook className={`${iconClass} text-blue-600`} />;
|
||||
case 'instagram':
|
||||
return <FaInstagram className={`${iconClass} text-pink-600`} />;
|
||||
case 'x/twitter':
|
||||
case 'twitter':
|
||||
return <FaXTwitter className={`${iconClass} text-black`} />;
|
||||
case 'tiktok':
|
||||
return <FaTiktok className={`${iconClass} text-black`} />;
|
||||
case 'youtube':
|
||||
return <FaYoutube className={`${iconClass} text-red-600`} />;
|
||||
case 'linkedin':
|
||||
return <FaLinkedin className={`${iconClass} text-blue-700`} />;
|
||||
case 'whatsapp':
|
||||
return <FaWhatsapp className={`${iconClass} text-green-600`} />;
|
||||
case 'threads':
|
||||
return <FaThreads className={`${iconClass} text-black`} />;
|
||||
case 'telegram':
|
||||
return <FaTelegram className={`${iconClass} text-blue-500`} />;
|
||||
case 'spotify':
|
||||
return <FaSpotify className={`${iconClass} text-green-500`} />;
|
||||
case 'kwai':
|
||||
case 'outros':
|
||||
default:
|
||||
return <FaLink className={`${iconClass} text-gray-600`} />;
|
||||
}
|
||||
};
|
||||
|
||||
const SocialMediaComponent: React.FC<SocialMediaComponentProps> = ({
|
||||
redesSociais,
|
||||
isLoading
|
||||
}) => {
|
||||
return (
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.02] transition-all duration-200 p-6">
|
||||
<div className="bg-white/95 backdrop-blur-sm rounded-xl shadow-lg hover:shadow-xl transform hover:scale-[1.01] transition-all duration-200 p-6">
|
||||
<div className="flex items-center mb-6">
|
||||
<LinkIcon className="h-8 w-8 text-orange-600 mr-3" />
|
||||
<h2 className="text-2xl font-bold text-gray-900">Redes Sociais</h2>
|
||||
@@ -29,6 +75,7 @@ const SocialMediaComponent: React.FC<SocialMediaComponentProps> = ({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center mb-2">
|
||||
{getSocialMediaIcon(redeSocial.rede)}
|
||||
<span className="font-semibold text-gray-900 mr-2">{redeSocial.rede}</span>
|
||||
<span className="text-sm text-gray-500">({redeSocial.ano})</span>
|
||||
</div>
|
||||
|
@@ -29,7 +29,7 @@ const MatrixBackground: React.FC = () => {
|
||||
|
||||
// Configuration
|
||||
const config = {
|
||||
dotCount: 300,
|
||||
dotCount: 400,
|
||||
maxConnections: 3,
|
||||
connectionDistance: 150,
|
||||
dotSpeed: 0.3,
|
||||
|
Reference in New Issue
Block a user