add random candidato
All checks were successful
Frontend Build and Deploy / build (push) Successful in 1m2s
All checks were successful
Frontend Build and Deploy / build (push) Successful in 1m2s
This commit is contained in:
parent
1e4f288ec4
commit
2764dbdc4e
@ -3,6 +3,10 @@ export interface CandidateSearchResult {
|
|||||||
candidatos: Candidate[];
|
candidatos: Candidate[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RandomCandidate {
|
||||||
|
idCandidato: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Candidate {
|
export interface Candidate {
|
||||||
idCandidato: string;
|
idCandidato: string;
|
||||||
nome: string;
|
nome: string;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { BaseApiClient } from './base';
|
import { BaseApiClient } from './base';
|
||||||
import { API_CONFIG } from '../config/api';
|
import { API_CONFIG } from '../config/api';
|
||||||
import type { CandidateAssets, CandidateDetails, CandidateExpenses, CandidateIncome, CandidateRedesSociais, CandidateSearchResult, CpfRevealResult, OpenCandDataAvailabilityStats, PlatformStats } from './apiModels';
|
import type { CandidateAssets, CandidateDetails, CandidateExpenses, CandidateIncome, CandidateRedesSociais, CandidateSearchResult, CpfRevealResult, OpenCandDataAvailabilityStats, PlatformStats, RandomCandidate } from './apiModels';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OpenCand API client for interacting with the OpenCand platform
|
* OpenCand API client for interacting with the OpenCand platform
|
||||||
@ -34,6 +34,13 @@ export class OpenCandApi extends BaseApiClient {
|
|||||||
return this.get<CandidateSearchResult>(`/v1/candidato/search?q=${encodedQuery}`);
|
return this.get<CandidateSearchResult>(`/v1/candidato/search?q=${encodedQuery}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a random candidate from the database
|
||||||
|
*/
|
||||||
|
async getRandomCandidate(): Promise<RandomCandidate> {
|
||||||
|
return this.get<RandomCandidate>(`/v1/candidato/random`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get detailed information about a specific candidate by ID
|
* Get detailed information about a specific candidate by ID
|
||||||
*/
|
*/
|
||||||
|
@ -8,6 +8,7 @@ import BasicCandidateInfoComponent from './BasicCandidateInfoComponent';
|
|||||||
import SocialMediaComponent from './SocialMediaComponent';
|
import SocialMediaComponent from './SocialMediaComponent';
|
||||||
import IncomeExpenseComponent from './IncomeExpenseComponent';
|
import IncomeExpenseComponent from './IncomeExpenseComponent';
|
||||||
import Button from '../../shared/Button';
|
import Button from '../../shared/Button';
|
||||||
|
import RandomCandButton from '../../shared/RandomCandButton';
|
||||||
import ErrorPage from '../ErrorPage';
|
import ErrorPage from '../ErrorPage';
|
||||||
|
|
||||||
const CandidatePage: React.FC = () => {
|
const CandidatePage: React.FC = () => {
|
||||||
@ -126,14 +127,21 @@ const CandidatePage: React.FC = () => {
|
|||||||
<main className="flex-grow p-6 max-w-7xl mx-auto">
|
<main className="flex-grow p-6 max-w-7xl mx-auto">
|
||||||
{/* Header with back button */}
|
{/* Header with back button */}
|
||||||
<div className="mb-6">
|
<div className="mb-6">
|
||||||
<Button
|
<div className="flex items-center gap-4 mb-4">
|
||||||
onClick={() => navigate('/')}
|
<Button
|
||||||
className="flex items-center text-white mb-4"
|
onClick={() => navigate('/')}
|
||||||
hasAnimation={false}
|
className="flex items-center text-white"
|
||||||
>
|
hasAnimation={false}
|
||||||
<ArrowLeftIcon className="h-5 w-5 mr-2" />
|
>
|
||||||
Voltar à busca
|
<ArrowLeftIcon className="h-5 w-5 mr-2" />
|
||||||
</Button>
|
Voltar à busca
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<RandomCandButton
|
||||||
|
className="flex items-center text-white"
|
||||||
|
hasAnimation={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{candidateDetails && (
|
{candidateDetails && (
|
||||||
<h1 className="text-3xl font-bold text-white">{candidateDetails.nome}</h1>
|
<h1 className="text-3xl font-bold text-white">{candidateDetails.nome}</h1>
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import SearchBar from './SearchBar';
|
import SearchBar from './SearchBar';
|
||||||
|
import RandomCandButton from '../shared/RandomCandButton';
|
||||||
|
|
||||||
const HeroSection: React.FC = () => {
|
const HeroSection: React.FC = () => {
|
||||||
return (
|
return (
|
||||||
@ -17,6 +18,13 @@ const HeroSection: React.FC = () => {
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
|
|
||||||
|
<div className="mt-6 flex justify-center">
|
||||||
|
<RandomCandButton
|
||||||
|
className='hover:bg-white/15 hover:scale-[1.01] transition-all duration-200 duration-300 ease-in-out bg-white/5 backdrop-blur-sm'
|
||||||
|
hasAnimation={false}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
|
@ -31,12 +31,9 @@ const Button: React.FC<ButtonProps> = ({
|
|||||||
rounded-full
|
rounded-full
|
||||||
backdrop-blur-xs
|
backdrop-blur-xs
|
||||||
shadow-xl
|
shadow-xl
|
||||||
ring-1
|
|
||||||
transition-all
|
transition-all
|
||||||
duration-200
|
duration-200
|
||||||
hover:ring-indigo-400/20
|
|
||||||
hover:bg-gray-700/40
|
hover:bg-gray-700/40
|
||||||
ring-gray-900
|
|
||||||
text-white
|
text-white
|
||||||
transition-colors
|
transition-colors
|
||||||
${animationClasses} ${cursorClasses} ${className}`;
|
${animationClasses} ${cursorClasses} ${className}`;
|
||||||
|
40
src/shared/RandomCandButton.tsx
Normal file
40
src/shared/RandomCandButton.tsx
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import { ArrowPathIcon } from '@heroicons/react/24/outline';
|
||||||
|
import Button from './Button';
|
||||||
|
import { openCandApi } from '../api/openCandApi';
|
||||||
|
|
||||||
|
interface RandomCandButtonProps {
|
||||||
|
className?: string;
|
||||||
|
hasAnimation?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
const RandomCandButton: React.FC<RandomCandButtonProps> = ({
|
||||||
|
className = '',
|
||||||
|
hasAnimation = false
|
||||||
|
}) => {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const handleRandomCandidate = async () => {
|
||||||
|
try {
|
||||||
|
const randomCandidate = await openCandApi.getRandomCandidate();
|
||||||
|
navigate(`/candidato/${randomCandidate.idCandidato}`);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erro ao buscar candidato aleatório:', error);
|
||||||
|
// You might want to show a toast notification or error message to the user
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
onClick={handleRandomCandidate}
|
||||||
|
className={`flex items-center ${className}`}
|
||||||
|
hasAnimation={hasAnimation}
|
||||||
|
>
|
||||||
|
<ArrowPathIcon className="h-4 w-4 mr-2" />
|
||||||
|
Candidato aleatório
|
||||||
|
</Button>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default RandomCandButton;
|
Loading…
x
Reference in New Issue
Block a user